Guest User

Untitled

a guest
Mar 18th, 2016
618
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 422.15 KB | None | 0 0
  1. (function($) {
  2. if (!$.fn.on) {
  3. $.fn.on = function(events, selector, data, handler) {
  4. var self = this;
  5. var args = arguments.length;
  6. if (args > 3) {
  7. return self.delegate(selector, events, data, handler)
  8. } else if (args > 2) {
  9. if (typeof selector === "string") {
  10. return self.delegate(selector, events, data)
  11. } else {
  12. return self.bind(events, selector, data)
  13. }
  14. } else {
  15. return self.bind(events, selector)
  16. }
  17. }
  18. }
  19. if (!$.fn.off) {
  20. $.fn.off = function(events, selector, handler) {
  21. var self = this;
  22. var args = arguments.length;
  23. if (typeof selector === "string") {
  24. if (args > 2) {
  25. return self.undelegate(selector, events, handler)
  26. } else if (args > 1) {
  27. return self.undelegate(selector, events)
  28. } else {
  29. return self.undelegate()
  30. }
  31. } else {
  32. if (args > 1) {
  33. handler = selector;
  34. return self.unbind(events, handler)
  35. } else if (args > 0) {
  36. return self.unbind(events)
  37. } else {
  38. return self.unbind()
  39. }
  40. }
  41. }
  42. }
  43. })(this.jQuery);
  44. (function(_global) {
  45. "use strict";
  46. var shim = {};
  47. if (typeof exports === "undefined") {
  48. if (typeof define == "function" && typeof define.amd == "object" && define.amd) {
  49. shim.exports = {};
  50. define(function() {
  51. return shim.exports
  52. })
  53. } else {
  54. shim.exports = typeof window !== "undefined" ? window : _global
  55. }
  56. } else {
  57. shim.exports = exports
  58. }(function(exports) {
  59. if (!GLMAT_EPSILON) {
  60. var GLMAT_EPSILON = 1e-6
  61. }
  62. if (!GLMAT_ARRAY_TYPE) {
  63. var GLMAT_ARRAY_TYPE = typeof Float32Array !== "undefined" ? Float32Array : Array
  64. }
  65. if (!GLMAT_RANDOM) {
  66. var GLMAT_RANDOM = Math.random
  67. }
  68. var glMatrix = {};
  69. glMatrix.setMatrixArrayType = function(type) {
  70. GLMAT_ARRAY_TYPE = type
  71. };
  72. if (typeof exports !== "undefined") {
  73. exports.glMatrix = glMatrix
  74. }
  75. var degree = Math.PI / 180;
  76. glMatrix.toRadian = function(a) {
  77. return a * degree
  78. };
  79. var vec2 = {};
  80. vec2.create = function() {
  81. var out = new GLMAT_ARRAY_TYPE(2);
  82. out[0] = 0;
  83. out[1] = 0;
  84. return out
  85. };
  86. vec2.clone = function(a) {
  87. var out = new GLMAT_ARRAY_TYPE(2);
  88. out[0] = a[0];
  89. out[1] = a[1];
  90. return out
  91. };
  92. vec2.fromValues = function(x, y) {
  93. var out = new GLMAT_ARRAY_TYPE(2);
  94. out[0] = x;
  95. out[1] = y;
  96. return out
  97. };
  98. vec2.copy = function(out, a) {
  99. out[0] = a[0];
  100. out[1] = a[1];
  101. return out
  102. };
  103. vec2.set = function(out, x, y) {
  104. out[0] = x;
  105. out[1] = y;
  106. return out
  107. };
  108. vec2.add = function(out, a, b) {
  109. out[0] = a[0] + b[0];
  110. out[1] = a[1] + b[1];
  111. return out
  112. };
  113. vec2.subtract = function(out, a, b) {
  114. out[0] = a[0] - b[0];
  115. out[1] = a[1] - b[1];
  116. return out
  117. };
  118. vec2.sub = vec2.subtract;
  119. vec2.multiply = function(out, a, b) {
  120. out[0] = a[0] * b[0];
  121. out[1] = a[1] * b[1];
  122. return out
  123. };
  124. vec2.mul = vec2.multiply;
  125. vec2.divide = function(out, a, b) {
  126. out[0] = a[0] / b[0];
  127. out[1] = a[1] / b[1];
  128. return out
  129. };
  130. vec2.div = vec2.divide;
  131. vec2.min = function(out, a, b) {
  132. out[0] = Math.min(a[0], b[0]);
  133. out[1] = Math.min(a[1], b[1]);
  134. return out
  135. };
  136. vec2.max = function(out, a, b) {
  137. out[0] = Math.max(a[0], b[0]);
  138. out[1] = Math.max(a[1], b[1]);
  139. return out
  140. };
  141. vec2.scale = function(out, a, b) {
  142. out[0] = a[0] * b;
  143. out[1] = a[1] * b;
  144. return out
  145. };
  146. vec2.scaleAndAdd = function(out, a, b, scale) {
  147. out[0] = a[0] + b[0] * scale;
  148. out[1] = a[1] + b[1] * scale;
  149. return out
  150. };
  151. vec2.distance = function(a, b) {
  152. var x = b[0] - a[0],
  153. y = b[1] - a[1];
  154. return Math.sqrt(x * x + y * y)
  155. };
  156. vec2.dist = vec2.distance;
  157. vec2.squaredDistance = function(a, b) {
  158. var x = b[0] - a[0],
  159. y = b[1] - a[1];
  160. return x * x + y * y
  161. };
  162. vec2.sqrDist = vec2.squaredDistance;
  163. vec2.length = function(a) {
  164. var x = a[0],
  165. y = a[1];
  166. return Math.sqrt(x * x + y * y)
  167. };
  168. vec2.len = vec2.length;
  169. vec2.squaredLength = function(a) {
  170. var x = a[0],
  171. y = a[1];
  172. return x * x + y * y
  173. };
  174. vec2.sqrLen = vec2.squaredLength;
  175. vec2.negate = function(out, a) {
  176. out[0] = -a[0];
  177. out[1] = -a[1];
  178. return out
  179. };
  180. vec2.normalize = function(out, a) {
  181. var x = a[0],
  182. y = a[1];
  183. var len = x * x + y * y;
  184. if (len > 0) {
  185. len = 1 / Math.sqrt(len);
  186. out[0] = a[0] * len;
  187. out[1] = a[1] * len
  188. }
  189. return out
  190. };
  191. vec2.dot = function(a, b) {
  192. return a[0] * b[0] + a[1] * b[1]
  193. };
  194. vec2.cross = function(out, a, b) {
  195. var z = a[0] * b[1] - a[1] * b[0];
  196. out[0] = out[1] = 0;
  197. out[2] = z;
  198. return out
  199. };
  200. vec2.lerp = function(out, a, b, t) {
  201. var ax = a[0],
  202. ay = a[1];
  203. out[0] = ax + t * (b[0] - ax);
  204. out[1] = ay + t * (b[1] - ay);
  205. return out
  206. };
  207. vec2.random = function(out, scale) {
  208. scale = scale || 1;
  209. var r = GLMAT_RANDOM() * 2 * Math.PI;
  210. out[0] = Math.cos(r) * scale;
  211. out[1] = Math.sin(r) * scale;
  212. return out
  213. };
  214. vec2.transformMat2 = function(out, a, m) {
  215. var x = a[0],
  216. y = a[1];
  217. out[0] = m[0] * x + m[2] * y;
  218. out[1] = m[1] * x + m[3] * y;
  219. return out
  220. };
  221. vec2.transformMat2d = function(out, a, m) {
  222. var x = a[0],
  223. y = a[1];
  224. out[0] = m[0] * x + m[2] * y + m[4];
  225. out[1] = m[1] * x + m[3] * y + m[5];
  226. return out
  227. };
  228. vec2.transformMat3 = function(out, a, m) {
  229. var x = a[0],
  230. y = a[1];
  231. out[0] = m[0] * x + m[3] * y + m[6];
  232. out[1] = m[1] * x + m[4] * y + m[7];
  233. return out
  234. };
  235. vec2.transformMat4 = function(out, a, m) {
  236. var x = a[0],
  237. y = a[1];
  238. out[0] = m[0] * x + m[4] * y + m[12];
  239. out[1] = m[1] * x + m[5] * y + m[13];
  240. return out
  241. };
  242. vec2.forEach = function() {
  243. var vec = vec2.create();
  244. return function(a, stride, offset, count, fn, arg) {
  245. var i, l;
  246. if (!stride) {
  247. stride = 2
  248. }
  249. if (!offset) {
  250. offset = 0
  251. }
  252. if (count) {
  253. l = Math.min(count * stride + offset, a.length)
  254. } else {
  255. l = a.length
  256. }
  257. for (i = offset; i < l; i += stride) {
  258. vec[0] = a[i];
  259. vec[1] = a[i + 1];
  260. fn(vec, vec, arg);
  261. a[i] = vec[0];
  262. a[i + 1] = vec[1]
  263. }
  264. return a
  265. }
  266. }();
  267. vec2.str = function(a) {
  268. return "vec2(" + a[0] + ", " + a[1] + ")"
  269. };
  270. if (typeof exports !== "undefined") {
  271. exports.vec2 = vec2
  272. }
  273. var vec3 = {};
  274. vec3.create = function() {
  275. var out = new GLMAT_ARRAY_TYPE(3);
  276. out[0] = 0;
  277. out[1] = 0;
  278. out[2] = 0;
  279. return out
  280. };
  281. vec3.clone = function(a) {
  282. var out = new GLMAT_ARRAY_TYPE(3);
  283. out[0] = a[0];
  284. out[1] = a[1];
  285. out[2] = a[2];
  286. return out
  287. };
  288. vec3.fromValues = function(x, y, z) {
  289. var out = new GLMAT_ARRAY_TYPE(3);
  290. out[0] = x;
  291. out[1] = y;
  292. out[2] = z;
  293. return out
  294. };
  295. vec3.copy = function(out, a) {
  296. out[0] = a[0];
  297. out[1] = a[1];
  298. out[2] = a[2];
  299. return out
  300. };
  301. vec3.set = function(out, x, y, z) {
  302. out[0] = x;
  303. out[1] = y;
  304. out[2] = z;
  305. return out
  306. };
  307. vec3.add = function(out, a, b) {
  308. out[0] = a[0] + b[0];
  309. out[1] = a[1] + b[1];
  310. out[2] = a[2] + b[2];
  311. return out
  312. };
  313. vec3.subtract = function(out, a, b) {
  314. out[0] = a[0] - b[0];
  315. out[1] = a[1] - b[1];
  316. out[2] = a[2] - b[2];
  317. return out
  318. };
  319. vec3.sub = vec3.subtract;
  320. vec3.multiply = function(out, a, b) {
  321. out[0] = a[0] * b[0];
  322. out[1] = a[1] * b[1];
  323. out[2] = a[2] * b[2];
  324. return out
  325. };
  326. vec3.mul = vec3.multiply;
  327. vec3.divide = function(out, a, b) {
  328. out[0] = a[0] / b[0];
  329. out[1] = a[1] / b[1];
  330. out[2] = a[2] / b[2];
  331. return out
  332. };
  333. vec3.div = vec3.divide;
  334. vec3.min = function(out, a, b) {
  335. out[0] = Math.min(a[0], b[0]);
  336. out[1] = Math.min(a[1], b[1]);
  337. out[2] = Math.min(a[2], b[2]);
  338. return out
  339. };
  340. vec3.max = function(out, a, b) {
  341. out[0] = Math.max(a[0], b[0]);
  342. out[1] = Math.max(a[1], b[1]);
  343. out[2] = Math.max(a[2], b[2]);
  344. return out
  345. };
  346. vec3.scale = function(out, a, b) {
  347. out[0] = a[0] * b;
  348. out[1] = a[1] * b;
  349. out[2] = a[2] * b;
  350. return out
  351. };
  352. vec3.scaleAndAdd = function(out, a, b, scale) {
  353. out[0] = a[0] + b[0] * scale;
  354. out[1] = a[1] + b[1] * scale;
  355. out[2] = a[2] + b[2] * scale;
  356. return out
  357. };
  358. vec3.distance = function(a, b) {
  359. var x = b[0] - a[0],
  360. y = b[1] - a[1],
  361. z = b[2] - a[2];
  362. return Math.sqrt(x * x + y * y + z * z)
  363. };
  364. vec3.dist = vec3.distance;
  365. vec3.squaredDistance = function(a, b) {
  366. var x = b[0] - a[0],
  367. y = b[1] - a[1],
  368. z = b[2] - a[2];
  369. return x * x + y * y + z * z
  370. };
  371. vec3.sqrDist = vec3.squaredDistance;
  372. vec3.length = function(a) {
  373. var x = a[0],
  374. y = a[1],
  375. z = a[2];
  376. return Math.sqrt(x * x + y * y + z * z)
  377. };
  378. vec3.len = vec3.length;
  379. vec3.squaredLength = function(a) {
  380. var x = a[0],
  381. y = a[1],
  382. z = a[2];
  383. return x * x + y * y + z * z
  384. };
  385. vec3.sqrLen = vec3.squaredLength;
  386. vec3.negate = function(out, a) {
  387. out[0] = -a[0];
  388. out[1] = -a[1];
  389. out[2] = -a[2];
  390. return out
  391. };
  392. vec3.normalize = function(out, a) {
  393. var x = a[0],
  394. y = a[1],
  395. z = a[2];
  396. var len = x * x + y * y + z * z;
  397. if (len > 0) {
  398. len = 1 / Math.sqrt(len);
  399. out[0] = a[0] * len;
  400. out[1] = a[1] * len;
  401. out[2] = a[2] * len
  402. }
  403. return out
  404. };
  405. vec3.dot = function(a, b) {
  406. return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
  407. };
  408. vec3.cross = function(out, a, b) {
  409. var ax = a[0],
  410. ay = a[1],
  411. az = a[2],
  412. bx = b[0],
  413. by = b[1],
  414. bz = b[2];
  415. out[0] = ay * bz - az * by;
  416. out[1] = az * bx - ax * bz;
  417. out[2] = ax * by - ay * bx;
  418. return out
  419. };
  420. vec3.lerp = function(out, a, b, t) {
  421. var ax = a[0],
  422. ay = a[1],
  423. az = a[2];
  424. out[0] = ax + t * (b[0] - ax);
  425. out[1] = ay + t * (b[1] - ay);
  426. out[2] = az + t * (b[2] - az);
  427. return out
  428. };
  429. vec3.random = function(out, scale) {
  430. scale = scale || 1;
  431. var r = GLMAT_RANDOM() * 2 * Math.PI;
  432. var z = GLMAT_RANDOM() * 2 - 1;
  433. var zScale = Math.sqrt(1 - z * z) * scale;
  434. out[0] = Math.cos(r) * zScale;
  435. out[1] = Math.sin(r) * zScale;
  436. out[2] = z * scale;
  437. return out
  438. };
  439. vec3.transformMat4 = function(out, a, m) {
  440. var x = a[0],
  441. y = a[1],
  442. z = a[2];
  443. out[0] = m[0] * x + m[4] * y + m[8] * z + m[12];
  444. out[1] = m[1] * x + m[5] * y + m[9] * z + m[13];
  445. out[2] = m[2] * x + m[6] * y + m[10] * z + m[14];
  446. return out
  447. };
  448. vec3.transformMat3 = function(out, a, m) {
  449. var x = a[0],
  450. y = a[1],
  451. z = a[2];
  452. out[0] = x * m[0] + y * m[3] + z * m[6];
  453. out[1] = x * m[1] + y * m[4] + z * m[7];
  454. out[2] = x * m[2] + y * m[5] + z * m[8];
  455. return out
  456. };
  457. vec3.transformQuat = function(out, a, q) {
  458. var x = a[0],
  459. y = a[1],
  460. z = a[2],
  461. qx = q[0],
  462. qy = q[1],
  463. qz = q[2],
  464. qw = q[3],
  465. ix = qw * x + qy * z - qz * y,
  466. iy = qw * y + qz * x - qx * z,
  467. iz = qw * z + qx * y - qy * x,
  468. iw = -qx * x - qy * y - qz * z;
  469. out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
  470. out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
  471. out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
  472. return out
  473. };
  474. vec3.rotateX = function(out, a, b, c) {
  475. var p = [],
  476. r = [];
  477. p[0] = a[0] - b[0];
  478. p[1] = a[1] - b[1];
  479. p[2] = a[2] - b[2];
  480. r[0] = p[0];
  481. r[1] = p[1] * Math.cos(c) - p[2] * Math.sin(c);
  482. r[2] = p[1] * Math.sin(c) + p[2] * Math.cos(c);
  483. out[0] = r[0] + b[0];
  484. out[1] = r[1] + b[1];
  485. out[2] = r[2] + b[2];
  486. return out
  487. };
  488. vec3.rotateY = function(out, a, b, c) {
  489. var p = [],
  490. r = [];
  491. p[0] = a[0] - b[0];
  492. p[1] = a[1] - b[1];
  493. p[2] = a[2] - b[2];
  494. r[0] = p[2] * Math.sin(c) + p[0] * Math.cos(c);
  495. r[1] = p[1];
  496. r[2] = p[2] * Math.cos(c) - p[0] * Math.sin(c);
  497. out[0] = r[0] + b[0];
  498. out[1] = r[1] + b[1];
  499. out[2] = r[2] + b[2];
  500. return out
  501. };
  502. vec3.rotateZ = function(out, a, b, c) {
  503. var p = [],
  504. r = [];
  505. p[0] = a[0] - b[0];
  506. p[1] = a[1] - b[1];
  507. p[2] = a[2] - b[2];
  508. r[0] = p[0] * Math.cos(c) - p[1] * Math.sin(c);
  509. r[1] = p[0] * Math.sin(c) + p[1] * Math.cos(c);
  510. r[2] = p[2];
  511. out[0] = r[0] + b[0];
  512. out[1] = r[1] + b[1];
  513. out[2] = r[2] + b[2];
  514. return out
  515. };
  516. vec3.forEach = function() {
  517. var vec = vec3.create();
  518. return function(a, stride, offset, count, fn, arg) {
  519. var i, l;
  520. if (!stride) {
  521. stride = 3
  522. }
  523. if (!offset) {
  524. offset = 0
  525. }
  526. if (count) {
  527. l = Math.min(count * stride + offset, a.length)
  528. } else {
  529. l = a.length
  530. }
  531. for (i = offset; i < l; i += stride) {
  532. vec[0] = a[i];
  533. vec[1] = a[i + 1];
  534. vec[2] = a[i + 2];
  535. fn(vec, vec, arg);
  536. a[i] = vec[0];
  537. a[i + 1] = vec[1];
  538. a[i + 2] = vec[2]
  539. }
  540. return a
  541. }
  542. }();
  543. vec3.str = function(a) {
  544. return "vec3(" + a[0] + ", " + a[1] + ", " + a[2] + ")"
  545. };
  546. if (typeof exports !== "undefined") {
  547. exports.vec3 = vec3
  548. }
  549. var vec4 = {};
  550. vec4.create = function() {
  551. var out = new GLMAT_ARRAY_TYPE(4);
  552. out[0] = 0;
  553. out[1] = 0;
  554. out[2] = 0;
  555. out[3] = 0;
  556. return out
  557. };
  558. vec4.clone = function(a) {
  559. var out = new GLMAT_ARRAY_TYPE(4);
  560. out[0] = a[0];
  561. out[1] = a[1];
  562. out[2] = a[2];
  563. out[3] = a[3];
  564. return out
  565. };
  566. vec4.fromValues = function(x, y, z, w) {
  567. var out = new GLMAT_ARRAY_TYPE(4);
  568. out[0] = x;
  569. out[1] = y;
  570. out[2] = z;
  571. out[3] = w;
  572. return out
  573. };
  574. vec4.copy = function(out, a) {
  575. out[0] = a[0];
  576. out[1] = a[1];
  577. out[2] = a[2];
  578. out[3] = a[3];
  579. return out
  580. };
  581. vec4.set = function(out, x, y, z, w) {
  582. out[0] = x;
  583. out[1] = y;
  584. out[2] = z;
  585. out[3] = w;
  586. return out
  587. };
  588. vec4.add = function(out, a, b) {
  589. out[0] = a[0] + b[0];
  590. out[1] = a[1] + b[1];
  591. out[2] = a[2] + b[2];
  592. out[3] = a[3] + b[3];
  593. return out
  594. };
  595. vec4.subtract = function(out, a, b) {
  596. out[0] = a[0] - b[0];
  597. out[1] = a[1] - b[1];
  598. out[2] = a[2] - b[2];
  599. out[3] = a[3] - b[3];
  600. return out
  601. };
  602. vec4.sub = vec4.subtract;
  603. vec4.multiply = function(out, a, b) {
  604. out[0] = a[0] * b[0];
  605. out[1] = a[1] * b[1];
  606. out[2] = a[2] * b[2];
  607. out[3] = a[3] * b[3];
  608. return out
  609. };
  610. vec4.mul = vec4.multiply;
  611. vec4.divide = function(out, a, b) {
  612. out[0] = a[0] / b[0];
  613. out[1] = a[1] / b[1];
  614. out[2] = a[2] / b[2];
  615. out[3] = a[3] / b[3];
  616. return out
  617. };
  618. vec4.div = vec4.divide;
  619. vec4.min = function(out, a, b) {
  620. out[0] = Math.min(a[0], b[0]);
  621. out[1] = Math.min(a[1], b[1]);
  622. out[2] = Math.min(a[2], b[2]);
  623. out[3] = Math.min(a[3], b[3]);
  624. return out
  625. };
  626. vec4.max = function(out, a, b) {
  627. out[0] = Math.max(a[0], b[0]);
  628. out[1] = Math.max(a[1], b[1]);
  629. out[2] = Math.max(a[2], b[2]);
  630. out[3] = Math.max(a[3], b[3]);
  631. return out
  632. };
  633. vec4.scale = function(out, a, b) {
  634. out[0] = a[0] * b;
  635. out[1] = a[1] * b;
  636. out[2] = a[2] * b;
  637. out[3] = a[3] * b;
  638. return out
  639. };
  640. vec4.scaleAndAdd = function(out, a, b, scale) {
  641. out[0] = a[0] + b[0] * scale;
  642. out[1] = a[1] + b[1] * scale;
  643. out[2] = a[2] + b[2] * scale;
  644. out[3] = a[3] + b[3] * scale;
  645. return out
  646. };
  647. vec4.distance = function(a, b) {
  648. var x = b[0] - a[0],
  649. y = b[1] - a[1],
  650. z = b[2] - a[2],
  651. w = b[3] - a[3];
  652. return Math.sqrt(x * x + y * y + z * z + w * w)
  653. };
  654. vec4.dist = vec4.distance;
  655. vec4.squaredDistance = function(a, b) {
  656. var x = b[0] - a[0],
  657. y = b[1] - a[1],
  658. z = b[2] - a[2],
  659. w = b[3] - a[3];
  660. return x * x + y * y + z * z + w * w
  661. };
  662. vec4.sqrDist = vec4.squaredDistance;
  663. vec4.length = function(a) {
  664. var x = a[0],
  665. y = a[1],
  666. z = a[2],
  667. w = a[3];
  668. return Math.sqrt(x * x + y * y + z * z + w * w)
  669. };
  670. vec4.len = vec4.length;
  671. vec4.squaredLength = function(a) {
  672. var x = a[0],
  673. y = a[1],
  674. z = a[2],
  675. w = a[3];
  676. return x * x + y * y + z * z + w * w
  677. };
  678. vec4.sqrLen = vec4.squaredLength;
  679. vec4.negate = function(out, a) {
  680. out[0] = -a[0];
  681. out[1] = -a[1];
  682. out[2] = -a[2];
  683. out[3] = -a[3];
  684. return out
  685. };
  686. vec4.normalize = function(out, a) {
  687. var x = a[0],
  688. y = a[1],
  689. z = a[2],
  690. w = a[3];
  691. var len = x * x + y * y + z * z + w * w;
  692. if (len > 0) {
  693. len = 1 / Math.sqrt(len);
  694. out[0] = a[0] * len;
  695. out[1] = a[1] * len;
  696. out[2] = a[2] * len;
  697. out[3] = a[3] * len
  698. }
  699. return out
  700. };
  701. vec4.dot = function(a, b) {
  702. return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]
  703. };
  704. vec4.lerp = function(out, a, b, t) {
  705. var ax = a[0],
  706. ay = a[1],
  707. az = a[2],
  708. aw = a[3];
  709. out[0] = ax + t * (b[0] - ax);
  710. out[1] = ay + t * (b[1] - ay);
  711. out[2] = az + t * (b[2] - az);
  712. out[3] = aw + t * (b[3] - aw);
  713. return out
  714. };
  715. vec4.random = function(out, scale) {
  716. scale = scale || 1;
  717. out[0] = GLMAT_RANDOM();
  718. out[1] = GLMAT_RANDOM();
  719. out[2] = GLMAT_RANDOM();
  720. out[3] = GLMAT_RANDOM();
  721. vec4.normalize(out, out);
  722. vec4.scale(out, out, scale);
  723. return out
  724. };
  725. vec4.transformMat4 = function(out, a, m) {
  726. var x = a[0],
  727. y = a[1],
  728. z = a[2],
  729. w = a[3];
  730. out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
  731. out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
  732. out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
  733. out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
  734. return out
  735. };
  736. vec4.transformQuat = function(out, a, q) {
  737. var x = a[0],
  738. y = a[1],
  739. z = a[2],
  740. qx = q[0],
  741. qy = q[1],
  742. qz = q[2],
  743. qw = q[3],
  744. ix = qw * x + qy * z - qz * y,
  745. iy = qw * y + qz * x - qx * z,
  746. iz = qw * z + qx * y - qy * x,
  747. iw = -qx * x - qy * y - qz * z;
  748. out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
  749. out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
  750. out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
  751. return out
  752. };
  753. vec4.forEach = function() {
  754. var vec = vec4.create();
  755. return function(a, stride, offset, count, fn, arg) {
  756. var i, l;
  757. if (!stride) {
  758. stride = 4
  759. }
  760. if (!offset) {
  761. offset = 0
  762. }
  763. if (count) {
  764. l = Math.min(count * stride + offset, a.length)
  765. } else {
  766. l = a.length
  767. }
  768. for (i = offset; i < l; i += stride) {
  769. vec[0] = a[i];
  770. vec[1] = a[i + 1];
  771. vec[2] = a[i + 2];
  772. vec[3] = a[i + 3];
  773. fn(vec, vec, arg);
  774. a[i] = vec[0];
  775. a[i + 1] = vec[1];
  776. a[i + 2] = vec[2];
  777. a[i + 3] = vec[3]
  778. }
  779. return a
  780. }
  781. }();
  782. vec4.str = function(a) {
  783. return "vec4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"
  784. };
  785. if (typeof exports !== "undefined") {
  786. exports.vec4 = vec4
  787. }
  788. var mat2 = {};
  789. mat2.create = function() {
  790. var out = new GLMAT_ARRAY_TYPE(4);
  791. out[0] = 1;
  792. out[1] = 0;
  793. out[2] = 0;
  794. out[3] = 1;
  795. return out
  796. };
  797. mat2.clone = function(a) {
  798. var out = new GLMAT_ARRAY_TYPE(4);
  799. out[0] = a[0];
  800. out[1] = a[1];
  801. out[2] = a[2];
  802. out[3] = a[3];
  803. return out
  804. };
  805. mat2.copy = function(out, a) {
  806. out[0] = a[0];
  807. out[1] = a[1];
  808. out[2] = a[2];
  809. out[3] = a[3];
  810. return out
  811. };
  812. mat2.identity = function(out) {
  813. out[0] = 1;
  814. out[1] = 0;
  815. out[2] = 0;
  816. out[3] = 1;
  817. return out
  818. };
  819. mat2.transpose = function(out, a) {
  820. if (out === a) {
  821. var a1 = a[1];
  822. out[1] = a[2];
  823. out[2] = a1
  824. } else {
  825. out[0] = a[0];
  826. out[1] = a[2];
  827. out[2] = a[1];
  828. out[3] = a[3]
  829. }
  830. return out
  831. };
  832. mat2.invert = function(out, a) {
  833. var a0 = a[0],
  834. a1 = a[1],
  835. a2 = a[2],
  836. a3 = a[3],
  837. det = a0 * a3 - a2 * a1;
  838. if (!det) {
  839. return null
  840. }
  841. det = 1 / det;
  842. out[0] = a3 * det;
  843. out[1] = -a1 * det;
  844. out[2] = -a2 * det;
  845. out[3] = a0 * det;
  846. return out
  847. };
  848. mat2.adjoint = function(out, a) {
  849. var a0 = a[0];
  850. out[0] = a[3];
  851. out[1] = -a[1];
  852. out[2] = -a[2];
  853. out[3] = a0;
  854. return out
  855. };
  856. mat2.determinant = function(a) {
  857. return a[0] * a[3] - a[2] * a[1]
  858. };
  859. mat2.multiply = function(out, a, b) {
  860. var a0 = a[0],
  861. a1 = a[1],
  862. a2 = a[2],
  863. a3 = a[3];
  864. var b0 = b[0],
  865. b1 = b[1],
  866. b2 = b[2],
  867. b3 = b[3];
  868. out[0] = a0 * b0 + a2 * b1;
  869. out[1] = a1 * b0 + a3 * b1;
  870. out[2] = a0 * b2 + a2 * b3;
  871. out[3] = a1 * b2 + a3 * b3;
  872. return out
  873. };
  874. mat2.mul = mat2.multiply;
  875. mat2.rotate = function(out, a, rad) {
  876. var a0 = a[0],
  877. a1 = a[1],
  878. a2 = a[2],
  879. a3 = a[3],
  880. s = Math.sin(rad),
  881. c = Math.cos(rad);
  882. out[0] = a0 * c + a2 * s;
  883. out[1] = a1 * c + a3 * s;
  884. out[2] = a0 * -s + a2 * c;
  885. out[3] = a1 * -s + a3 * c;
  886. return out
  887. };
  888. mat2.scale = function(out, a, v) {
  889. var a0 = a[0],
  890. a1 = a[1],
  891. a2 = a[2],
  892. a3 = a[3],
  893. v0 = v[0],
  894. v1 = v[1];
  895. out[0] = a0 * v0;
  896. out[1] = a1 * v0;
  897. out[2] = a2 * v1;
  898. out[3] = a3 * v1;
  899. return out
  900. };
  901. mat2.str = function(a) {
  902. return "mat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"
  903. };
  904. mat2.frob = function(a) {
  905. return Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2))
  906. };
  907. mat2.LDU = function(L, D, U, a) {
  908. L[2] = a[2] / a[0];
  909. U[0] = a[0];
  910. U[1] = a[1];
  911. U[3] = a[3] - L[2] * U[1];
  912. return [L, D, U]
  913. };
  914. if (typeof exports !== "undefined") {
  915. exports.mat2 = mat2
  916. }
  917. var mat2d = {};
  918. mat2d.create = function() {
  919. var out = new GLMAT_ARRAY_TYPE(6);
  920. out[0] = 1;
  921. out[1] = 0;
  922. out[2] = 0;
  923. out[3] = 1;
  924. out[4] = 0;
  925. out[5] = 0;
  926. return out
  927. };
  928. mat2d.clone = function(a) {
  929. var out = new GLMAT_ARRAY_TYPE(6);
  930. out[0] = a[0];
  931. out[1] = a[1];
  932. out[2] = a[2];
  933. out[3] = a[3];
  934. out[4] = a[4];
  935. out[5] = a[5];
  936. return out
  937. };
  938. mat2d.copy = function(out, a) {
  939. out[0] = a[0];
  940. out[1] = a[1];
  941. out[2] = a[2];
  942. out[3] = a[3];
  943. out[4] = a[4];
  944. out[5] = a[5];
  945. return out
  946. };
  947. mat2d.identity = function(out) {
  948. out[0] = 1;
  949. out[1] = 0;
  950. out[2] = 0;
  951. out[3] = 1;
  952. out[4] = 0;
  953. out[5] = 0;
  954. return out
  955. };
  956. mat2d.invert = function(out, a) {
  957. var aa = a[0],
  958. ab = a[1],
  959. ac = a[2],
  960. ad = a[3],
  961. atx = a[4],
  962. aty = a[5];
  963. var det = aa * ad - ab * ac;
  964. if (!det) {
  965. return null
  966. }
  967. det = 1 / det;
  968. out[0] = ad * det;
  969. out[1] = -ab * det;
  970. out[2] = -ac * det;
  971. out[3] = aa * det;
  972. out[4] = (ac * aty - ad * atx) * det;
  973. out[5] = (ab * atx - aa * aty) * det;
  974. return out
  975. };
  976. mat2d.determinant = function(a) {
  977. return a[0] * a[3] - a[1] * a[2]
  978. };
  979. mat2d.multiply = function(out, a, b) {
  980. var a0 = a[0],
  981. a1 = a[1],
  982. a2 = a[2],
  983. a3 = a[3],
  984. a4 = a[4],
  985. a5 = a[5],
  986. b0 = b[0],
  987. b1 = b[1],
  988. b2 = b[2],
  989. b3 = b[3],
  990. b4 = b[4],
  991. b5 = b[5];
  992. out[0] = a0 * b0 + a2 * b1;
  993. out[1] = a1 * b0 + a3 * b1;
  994. out[2] = a0 * b2 + a2 * b3;
  995. out[3] = a1 * b2 + a3 * b3;
  996. out[4] = a0 * b4 + a2 * b5 + a4;
  997. out[5] = a1 * b4 + a3 * b5 + a5;
  998. return out
  999. };
  1000. mat2d.mul = mat2d.multiply;
  1001. mat2d.rotate = function(out, a, rad) {
  1002. var a0 = a[0],
  1003. a1 = a[1],
  1004. a2 = a[2],
  1005. a3 = a[3],
  1006. a4 = a[4],
  1007. a5 = a[5],
  1008. s = Math.sin(rad),
  1009. c = Math.cos(rad);
  1010. out[0] = a0 * c + a2 * s;
  1011. out[1] = a1 * c + a3 * s;
  1012. out[2] = a0 * -s + a2 * c;
  1013. out[3] = a1 * -s + a3 * c;
  1014. out[4] = a4;
  1015. out[5] = a5;
  1016. return out
  1017. };
  1018. mat2d.scale = function(out, a, v) {
  1019. var a0 = a[0],
  1020. a1 = a[1],
  1021. a2 = a[2],
  1022. a3 = a[3],
  1023. a4 = a[4],
  1024. a5 = a[5],
  1025. v0 = v[0],
  1026. v1 = v[1];
  1027. out[0] = a0 * v0;
  1028. out[1] = a1 * v0;
  1029. out[2] = a2 * v1;
  1030. out[3] = a3 * v1;
  1031. out[4] = a4;
  1032. out[5] = a5;
  1033. return out
  1034. };
  1035. mat2d.translate = function(out, a, v) {
  1036. var a0 = a[0],
  1037. a1 = a[1],
  1038. a2 = a[2],
  1039. a3 = a[3],
  1040. a4 = a[4],
  1041. a5 = a[5],
  1042. v0 = v[0],
  1043. v1 = v[1];
  1044. out[0] = a0;
  1045. out[1] = a1;
  1046. out[2] = a2;
  1047. out[3] = a3;
  1048. out[4] = a0 * v0 + a2 * v1 + a4;
  1049. out[5] = a1 * v0 + a3 * v1 + a5;
  1050. return out
  1051. };
  1052. mat2d.str = function(a) {
  1053. return "mat2d(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ")"
  1054. };
  1055. mat2d.frob = function(a) {
  1056. return Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + 1)
  1057. };
  1058. if (typeof exports !== "undefined") {
  1059. exports.mat2d = mat2d
  1060. }
  1061. var mat3 = {};
  1062. mat3.create = function() {
  1063. var out = new GLMAT_ARRAY_TYPE(9);
  1064. out[0] = 1;
  1065. out[1] = 0;
  1066. out[2] = 0;
  1067. out[3] = 0;
  1068. out[4] = 1;
  1069. out[5] = 0;
  1070. out[6] = 0;
  1071. out[7] = 0;
  1072. out[8] = 1;
  1073. return out
  1074. };
  1075. mat3.fromMat4 = function(out, a) {
  1076. out[0] = a[0];
  1077. out[1] = a[1];
  1078. out[2] = a[2];
  1079. out[3] = a[4];
  1080. out[4] = a[5];
  1081. out[5] = a[6];
  1082. out[6] = a[8];
  1083. out[7] = a[9];
  1084. out[8] = a[10];
  1085. return out
  1086. };
  1087. mat3.clone = function(a) {
  1088. var out = new GLMAT_ARRAY_TYPE(9);
  1089. out[0] = a[0];
  1090. out[1] = a[1];
  1091. out[2] = a[2];
  1092. out[3] = a[3];
  1093. out[4] = a[4];
  1094. out[5] = a[5];
  1095. out[6] = a[6];
  1096. out[7] = a[7];
  1097. out[8] = a[8];
  1098. return out
  1099. };
  1100. mat3.copy = function(out, a) {
  1101. out[0] = a[0];
  1102. out[1] = a[1];
  1103. out[2] = a[2];
  1104. out[3] = a[3];
  1105. out[4] = a[4];
  1106. out[5] = a[5];
  1107. out[6] = a[6];
  1108. out[7] = a[7];
  1109. out[8] = a[8];
  1110. return out
  1111. };
  1112. mat3.identity = function(out) {
  1113. out[0] = 1;
  1114. out[1] = 0;
  1115. out[2] = 0;
  1116. out[3] = 0;
  1117. out[4] = 1;
  1118. out[5] = 0;
  1119. out[6] = 0;
  1120. out[7] = 0;
  1121. out[8] = 1;
  1122. return out
  1123. };
  1124. mat3.transpose = function(out, a) {
  1125. if (out === a) {
  1126. var a01 = a[1],
  1127. a02 = a[2],
  1128. a12 = a[5];
  1129. out[1] = a[3];
  1130. out[2] = a[6];
  1131. out[3] = a01;
  1132. out[5] = a[7];
  1133. out[6] = a02;
  1134. out[7] = a12
  1135. } else {
  1136. out[0] = a[0];
  1137. out[1] = a[3];
  1138. out[2] = a[6];
  1139. out[3] = a[1];
  1140. out[4] = a[4];
  1141. out[5] = a[7];
  1142. out[6] = a[2];
  1143. out[7] = a[5];
  1144. out[8] = a[8]
  1145. }
  1146. return out
  1147. };
  1148. mat3.invert = function(out, a) {
  1149. var a00 = a[0],
  1150. a01 = a[1],
  1151. a02 = a[2],
  1152. a10 = a[3],
  1153. a11 = a[4],
  1154. a12 = a[5],
  1155. a20 = a[6],
  1156. a21 = a[7],
  1157. a22 = a[8],
  1158. b01 = a22 * a11 - a12 * a21,
  1159. b11 = -a22 * a10 + a12 * a20,
  1160. b21 = a21 * a10 - a11 * a20,
  1161. det = a00 * b01 + a01 * b11 + a02 * b21;
  1162. if (!det) {
  1163. return null
  1164. }
  1165. det = 1 / det;
  1166. out[0] = b01 * det;
  1167. out[1] = (-a22 * a01 + a02 * a21) * det;
  1168. out[2] = (a12 * a01 - a02 * a11) * det;
  1169. out[3] = b11 * det;
  1170. out[4] = (a22 * a00 - a02 * a20) * det;
  1171. out[5] = (-a12 * a00 + a02 * a10) * det;
  1172. out[6] = b21 * det;
  1173. out[7] = (-a21 * a00 + a01 * a20) * det;
  1174. out[8] = (a11 * a00 - a01 * a10) * det;
  1175. return out
  1176. };
  1177. mat3.adjoint = function(out, a) {
  1178. var a00 = a[0],
  1179. a01 = a[1],
  1180. a02 = a[2],
  1181. a10 = a[3],
  1182. a11 = a[4],
  1183. a12 = a[5],
  1184. a20 = a[6],
  1185. a21 = a[7],
  1186. a22 = a[8];
  1187. out[0] = a11 * a22 - a12 * a21;
  1188. out[1] = a02 * a21 - a01 * a22;
  1189. out[2] = a01 * a12 - a02 * a11;
  1190. out[3] = a12 * a20 - a10 * a22;
  1191. out[4] = a00 * a22 - a02 * a20;
  1192. out[5] = a02 * a10 - a00 * a12;
  1193. out[6] = a10 * a21 - a11 * a20;
  1194. out[7] = a01 * a20 - a00 * a21;
  1195. out[8] = a00 * a11 - a01 * a10;
  1196. return out
  1197. };
  1198. mat3.determinant = function(a) {
  1199. var a00 = a[0],
  1200. a01 = a[1],
  1201. a02 = a[2],
  1202. a10 = a[3],
  1203. a11 = a[4],
  1204. a12 = a[5],
  1205. a20 = a[6],
  1206. a21 = a[7],
  1207. a22 = a[8];
  1208. return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20)
  1209. };
  1210. mat3.multiply = function(out, a, b) {
  1211. var a00 = a[0],
  1212. a01 = a[1],
  1213. a02 = a[2],
  1214. a10 = a[3],
  1215. a11 = a[4],
  1216. a12 = a[5],
  1217. a20 = a[6],
  1218. a21 = a[7],
  1219. a22 = a[8],
  1220. b00 = b[0],
  1221. b01 = b[1],
  1222. b02 = b[2],
  1223. b10 = b[3],
  1224. b11 = b[4],
  1225. b12 = b[5],
  1226. b20 = b[6],
  1227. b21 = b[7],
  1228. b22 = b[8];
  1229. out[0] = b00 * a00 + b01 * a10 + b02 * a20;
  1230. out[1] = b00 * a01 + b01 * a11 + b02 * a21;
  1231. out[2] = b00 * a02 + b01 * a12 + b02 * a22;
  1232. out[3] = b10 * a00 + b11 * a10 + b12 * a20;
  1233. out[4] = b10 * a01 + b11 * a11 + b12 * a21;
  1234. out[5] = b10 * a02 + b11 * a12 + b12 * a22;
  1235. out[6] = b20 * a00 + b21 * a10 + b22 * a20;
  1236. out[7] = b20 * a01 + b21 * a11 + b22 * a21;
  1237. out[8] = b20 * a02 + b21 * a12 + b22 * a22;
  1238. return out
  1239. };
  1240. mat3.mul = mat3.multiply;
  1241. mat3.translate = function(out, a, v) {
  1242. var a00 = a[0],
  1243. a01 = a[1],
  1244. a02 = a[2],
  1245. a10 = a[3],
  1246. a11 = a[4],
  1247. a12 = a[5],
  1248. a20 = a[6],
  1249. a21 = a[7],
  1250. a22 = a[8],
  1251. x = v[0],
  1252. y = v[1];
  1253. out[0] = a00;
  1254. out[1] = a01;
  1255. out[2] = a02;
  1256. out[3] = a10;
  1257. out[4] = a11;
  1258. out[5] = a12;
  1259. out[6] = x * a00 + y * a10 + a20;
  1260. out[7] = x * a01 + y * a11 + a21;
  1261. out[8] = x * a02 + y * a12 + a22;
  1262. return out
  1263. };
  1264. mat3.rotate = function(out, a, rad) {
  1265. var a00 = a[0],
  1266. a01 = a[1],
  1267. a02 = a[2],
  1268. a10 = a[3],
  1269. a11 = a[4],
  1270. a12 = a[5],
  1271. a20 = a[6],
  1272. a21 = a[7],
  1273. a22 = a[8],
  1274. s = Math.sin(rad),
  1275. c = Math.cos(rad);
  1276. out[0] = c * a00 + s * a10;
  1277. out[1] = c * a01 + s * a11;
  1278. out[2] = c * a02 + s * a12;
  1279. out[3] = c * a10 - s * a00;
  1280. out[4] = c * a11 - s * a01;
  1281. out[5] = c * a12 - s * a02;
  1282. out[6] = a20;
  1283. out[7] = a21;
  1284. out[8] = a22;
  1285. return out
  1286. };
  1287. mat3.scale = function(out, a, v) {
  1288. var x = v[0],
  1289. y = v[1];
  1290. out[0] = x * a[0];
  1291. out[1] = x * a[1];
  1292. out[2] = x * a[2];
  1293. out[3] = y * a[3];
  1294. out[4] = y * a[4];
  1295. out[5] = y * a[5];
  1296. out[6] = a[6];
  1297. out[7] = a[7];
  1298. out[8] = a[8];
  1299. return out
  1300. };
  1301. mat3.fromMat2d = function(out, a) {
  1302. out[0] = a[0];
  1303. out[1] = a[1];
  1304. out[2] = 0;
  1305. out[3] = a[2];
  1306. out[4] = a[3];
  1307. out[5] = 0;
  1308. out[6] = a[4];
  1309. out[7] = a[5];
  1310. out[8] = 1;
  1311. return out
  1312. };
  1313. mat3.fromQuat = function(out, q) {
  1314. var x = q[0],
  1315. y = q[1],
  1316. z = q[2],
  1317. w = q[3],
  1318. x2 = x + x,
  1319. y2 = y + y,
  1320. z2 = z + z,
  1321. xx = x * x2,
  1322. yx = y * x2,
  1323. yy = y * y2,
  1324. zx = z * x2,
  1325. zy = z * y2,
  1326. zz = z * z2,
  1327. wx = w * x2,
  1328. wy = w * y2,
  1329. wz = w * z2;
  1330. out[0] = 1 - yy - zz;
  1331. out[3] = yx - wz;
  1332. out[6] = zx + wy;
  1333. out[1] = yx + wz;
  1334. out[4] = 1 - xx - zz;
  1335. out[7] = zy - wx;
  1336. out[2] = zx - wy;
  1337. out[5] = zy + wx;
  1338. out[8] = 1 - xx - yy;
  1339. return out
  1340. };
  1341. mat3.normalFromMat4 = function(out, a) {
  1342. var a00 = a[0],
  1343. a01 = a[1],
  1344. a02 = a[2],
  1345. a03 = a[3],
  1346. a10 = a[4],
  1347. a11 = a[5],
  1348. a12 = a[6],
  1349. a13 = a[7],
  1350. a20 = a[8],
  1351. a21 = a[9],
  1352. a22 = a[10],
  1353. a23 = a[11],
  1354. a30 = a[12],
  1355. a31 = a[13],
  1356. a32 = a[14],
  1357. a33 = a[15],
  1358. b00 = a00 * a11 - a01 * a10,
  1359. b01 = a00 * a12 - a02 * a10,
  1360. b02 = a00 * a13 - a03 * a10,
  1361. b03 = a01 * a12 - a02 * a11,
  1362. b04 = a01 * a13 - a03 * a11,
  1363. b05 = a02 * a13 - a03 * a12,
  1364. b06 = a20 * a31 - a21 * a30,
  1365. b07 = a20 * a32 - a22 * a30,
  1366. b08 = a20 * a33 - a23 * a30,
  1367. b09 = a21 * a32 - a22 * a31,
  1368. b10 = a21 * a33 - a23 * a31,
  1369. b11 = a22 * a33 - a23 * a32,
  1370. det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
  1371. if (!det) {
  1372. return null
  1373. }
  1374. det = 1 / det;
  1375. out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
  1376. out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
  1377. out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
  1378. out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
  1379. out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
  1380. out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
  1381. out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
  1382. out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
  1383. out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
  1384. return out
  1385. };
  1386. mat3.str = function(a) {
  1387. return "mat3(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ")"
  1388. };
  1389. mat3.frob = function(a) {
  1390. return Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2))
  1391. };
  1392. if (typeof exports !== "undefined") {
  1393. exports.mat3 = mat3
  1394. }
  1395. var mat4 = {};
  1396. mat4.create = function() {
  1397. var out = new GLMAT_ARRAY_TYPE(16);
  1398. out[0] = 1;
  1399. out[1] = 0;
  1400. out[2] = 0;
  1401. out[3] = 0;
  1402. out[4] = 0;
  1403. out[5] = 1;
  1404. out[6] = 0;
  1405. out[7] = 0;
  1406. out[8] = 0;
  1407. out[9] = 0;
  1408. out[10] = 1;
  1409. out[11] = 0;
  1410. out[12] = 0;
  1411. out[13] = 0;
  1412. out[14] = 0;
  1413. out[15] = 1;
  1414. return out
  1415. };
  1416. mat4.clone = function(a) {
  1417. var out = new GLMAT_ARRAY_TYPE(16);
  1418. out[0] = a[0];
  1419. out[1] = a[1];
  1420. out[2] = a[2];
  1421. out[3] = a[3];
  1422. out[4] = a[4];
  1423. out[5] = a[5];
  1424. out[6] = a[6];
  1425. out[7] = a[7];
  1426. out[8] = a[8];
  1427. out[9] = a[9];
  1428. out[10] = a[10];
  1429. out[11] = a[11];
  1430. out[12] = a[12];
  1431. out[13] = a[13];
  1432. out[14] = a[14];
  1433. out[15] = a[15];
  1434. return out
  1435. };
  1436. mat4.copy = function(out, a) {
  1437. out[0] = a[0];
  1438. out[1] = a[1];
  1439. out[2] = a[2];
  1440. out[3] = a[3];
  1441. out[4] = a[4];
  1442. out[5] = a[5];
  1443. out[6] = a[6];
  1444. out[7] = a[7];
  1445. out[8] = a[8];
  1446. out[9] = a[9];
  1447. out[10] = a[10];
  1448. out[11] = a[11];
  1449. out[12] = a[12];
  1450. out[13] = a[13];
  1451. out[14] = a[14];
  1452. out[15] = a[15];
  1453. return out
  1454. };
  1455. mat4.identity = function(out) {
  1456. out[0] = 1;
  1457. out[1] = 0;
  1458. out[2] = 0;
  1459. out[3] = 0;
  1460. out[4] = 0;
  1461. out[5] = 1;
  1462. out[6] = 0;
  1463. out[7] = 0;
  1464. out[8] = 0;
  1465. out[9] = 0;
  1466. out[10] = 1;
  1467. out[11] = 0;
  1468. out[12] = 0;
  1469. out[13] = 0;
  1470. out[14] = 0;
  1471. out[15] = 1;
  1472. return out
  1473. };
  1474. mat4.transpose = function(out, a) {
  1475. if (out === a) {
  1476. var a01 = a[1],
  1477. a02 = a[2],
  1478. a03 = a[3],
  1479. a12 = a[6],
  1480. a13 = a[7],
  1481. a23 = a[11];
  1482. out[1] = a[4];
  1483. out[2] = a[8];
  1484. out[3] = a[12];
  1485. out[4] = a01;
  1486. out[6] = a[9];
  1487. out[7] = a[13];
  1488. out[8] = a02;
  1489. out[9] = a12;
  1490. out[11] = a[14];
  1491. out[12] = a03;
  1492. out[13] = a13;
  1493. out[14] = a23
  1494. } else {
  1495. out[0] = a[0];
  1496. out[1] = a[4];
  1497. out[2] = a[8];
  1498. out[3] = a[12];
  1499. out[4] = a[1];
  1500. out[5] = a[5];
  1501. out[6] = a[9];
  1502. out[7] = a[13];
  1503. out[8] = a[2];
  1504. out[9] = a[6];
  1505. out[10] = a[10];
  1506. out[11] = a[14];
  1507. out[12] = a[3];
  1508. out[13] = a[7];
  1509. out[14] = a[11];
  1510. out[15] = a[15]
  1511. }
  1512. return out
  1513. };
  1514. mat4.invert = function(out, a) {
  1515. var a00 = a[0],
  1516. a01 = a[1],
  1517. a02 = a[2],
  1518. a03 = a[3],
  1519. a10 = a[4],
  1520. a11 = a[5],
  1521. a12 = a[6],
  1522. a13 = a[7],
  1523. a20 = a[8],
  1524. a21 = a[9],
  1525. a22 = a[10],
  1526. a23 = a[11],
  1527. a30 = a[12],
  1528. a31 = a[13],
  1529. a32 = a[14],
  1530. a33 = a[15],
  1531. b00 = a00 * a11 - a01 * a10,
  1532. b01 = a00 * a12 - a02 * a10,
  1533. b02 = a00 * a13 - a03 * a10,
  1534. b03 = a01 * a12 - a02 * a11,
  1535. b04 = a01 * a13 - a03 * a11,
  1536. b05 = a02 * a13 - a03 * a12,
  1537. b06 = a20 * a31 - a21 * a30,
  1538. b07 = a20 * a32 - a22 * a30,
  1539. b08 = a20 * a33 - a23 * a30,
  1540. b09 = a21 * a32 - a22 * a31,
  1541. b10 = a21 * a33 - a23 * a31,
  1542. b11 = a22 * a33 - a23 * a32,
  1543. det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
  1544. if (!det) {
  1545. return null
  1546. }
  1547. det = 1 / det;
  1548. out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
  1549. out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
  1550. out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
  1551. out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
  1552. out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
  1553. out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
  1554. out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
  1555. out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
  1556. out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
  1557. out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
  1558. out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
  1559. out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
  1560. out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
  1561. out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
  1562. out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
  1563. out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
  1564. return out
  1565. };
  1566. mat4.adjoint = function(out, a) {
  1567. var a00 = a[0],
  1568. a01 = a[1],
  1569. a02 = a[2],
  1570. a03 = a[3],
  1571. a10 = a[4],
  1572. a11 = a[5],
  1573. a12 = a[6],
  1574. a13 = a[7],
  1575. a20 = a[8],
  1576. a21 = a[9],
  1577. a22 = a[10],
  1578. a23 = a[11],
  1579. a30 = a[12],
  1580. a31 = a[13],
  1581. a32 = a[14],
  1582. a33 = a[15];
  1583. out[0] = a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22);
  1584. out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));
  1585. out[2] = a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12);
  1586. out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));
  1587. out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));
  1588. out[5] = a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22);
  1589. out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));
  1590. out[7] = a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12);
  1591. out[8] = a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21);
  1592. out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));
  1593. out[10] = a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11);
  1594. out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));
  1595. out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));
  1596. out[13] = a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21);
  1597. out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));
  1598. out[15] = a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11);
  1599. return out
  1600. };
  1601. mat4.determinant = function(a) {
  1602. var a00 = a[0],
  1603. a01 = a[1],
  1604. a02 = a[2],
  1605. a03 = a[3],
  1606. a10 = a[4],
  1607. a11 = a[5],
  1608. a12 = a[6],
  1609. a13 = a[7],
  1610. a20 = a[8],
  1611. a21 = a[9],
  1612. a22 = a[10],
  1613. a23 = a[11],
  1614. a30 = a[12],
  1615. a31 = a[13],
  1616. a32 = a[14],
  1617. a33 = a[15],
  1618. b00 = a00 * a11 - a01 * a10,
  1619. b01 = a00 * a12 - a02 * a10,
  1620. b02 = a00 * a13 - a03 * a10,
  1621. b03 = a01 * a12 - a02 * a11,
  1622. b04 = a01 * a13 - a03 * a11,
  1623. b05 = a02 * a13 - a03 * a12,
  1624. b06 = a20 * a31 - a21 * a30,
  1625. b07 = a20 * a32 - a22 * a30,
  1626. b08 = a20 * a33 - a23 * a30,
  1627. b09 = a21 * a32 - a22 * a31,
  1628. b10 = a21 * a33 - a23 * a31,
  1629. b11 = a22 * a33 - a23 * a32;
  1630. return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06
  1631. };
  1632. mat4.multiply = function(out, a, b) {
  1633. var a00 = a[0],
  1634. a01 = a[1],
  1635. a02 = a[2],
  1636. a03 = a[3],
  1637. a10 = a[4],
  1638. a11 = a[5],
  1639. a12 = a[6],
  1640. a13 = a[7],
  1641. a20 = a[8],
  1642. a21 = a[9],
  1643. a22 = a[10],
  1644. a23 = a[11],
  1645. a30 = a[12],
  1646. a31 = a[13],
  1647. a32 = a[14],
  1648. a33 = a[15];
  1649. var b0 = b[0],
  1650. b1 = b[1],
  1651. b2 = b[2],
  1652. b3 = b[3];
  1653. out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  1654. out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  1655. out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  1656. out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  1657. b0 = b[4];
  1658. b1 = b[5];
  1659. b2 = b[6];
  1660. b3 = b[7];
  1661. out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  1662. out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  1663. out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  1664. out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  1665. b0 = b[8];
  1666. b1 = b[9];
  1667. b2 = b[10];
  1668. b3 = b[11];
  1669. out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  1670. out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  1671. out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  1672. out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  1673. b0 = b[12];
  1674. b1 = b[13];
  1675. b2 = b[14];
  1676. b3 = b[15];
  1677. out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  1678. out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  1679. out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  1680. out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  1681. return out
  1682. };
  1683. mat4.mul = mat4.multiply;
  1684. mat4.translate = function(out, a, v) {
  1685. var x = v[0],
  1686. y = v[1],
  1687. z = v[2],
  1688. a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23;
  1689. if (a === out) {
  1690. out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
  1691. out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
  1692. out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
  1693. out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]
  1694. } else {
  1695. a00 = a[0];
  1696. a01 = a[1];
  1697. a02 = a[2];
  1698. a03 = a[3];
  1699. a10 = a[4];
  1700. a11 = a[5];
  1701. a12 = a[6];
  1702. a13 = a[7];
  1703. a20 = a[8];
  1704. a21 = a[9];
  1705. a22 = a[10];
  1706. a23 = a[11];
  1707. out[0] = a00;
  1708. out[1] = a01;
  1709. out[2] = a02;
  1710. out[3] = a03;
  1711. out[4] = a10;
  1712. out[5] = a11;
  1713. out[6] = a12;
  1714. out[7] = a13;
  1715. out[8] = a20;
  1716. out[9] = a21;
  1717. out[10] = a22;
  1718. out[11] = a23;
  1719. out[12] = a00 * x + a10 * y + a20 * z + a[12];
  1720. out[13] = a01 * x + a11 * y + a21 * z + a[13];
  1721. out[14] = a02 * x + a12 * y + a22 * z + a[14];
  1722. out[15] = a03 * x + a13 * y + a23 * z + a[15]
  1723. }
  1724. return out
  1725. };
  1726. mat4.scale = function(out, a, v) {
  1727. var x = v[0],
  1728. y = v[1],
  1729. z = v[2];
  1730. out[0] = a[0] * x;
  1731. out[1] = a[1] * x;
  1732. out[2] = a[2] * x;
  1733. out[3] = a[3] * x;
  1734. out[4] = a[4] * y;
  1735. out[5] = a[5] * y;
  1736. out[6] = a[6] * y;
  1737. out[7] = a[7] * y;
  1738. out[8] = a[8] * z;
  1739. out[9] = a[9] * z;
  1740. out[10] = a[10] * z;
  1741. out[11] = a[11] * z;
  1742. out[12] = a[12];
  1743. out[13] = a[13];
  1744. out[14] = a[14];
  1745. out[15] = a[15];
  1746. return out
  1747. };
  1748. mat4.rotate = function(out, a, rad, axis) {
  1749. var x = axis[0],
  1750. y = axis[1],
  1751. z = axis[2],
  1752. len = Math.sqrt(x * x + y * y + z * z),
  1753. s, c, t, a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, b00, b01, b02, b10, b11, b12, b20, b21, b22;
  1754. if (Math.abs(len) < GLMAT_EPSILON) {
  1755. return null
  1756. }
  1757. len = 1 / len;
  1758. x *= len;
  1759. y *= len;
  1760. z *= len;
  1761. s = Math.sin(rad);
  1762. c = Math.cos(rad);
  1763. t = 1 - c;
  1764. a00 = a[0];
  1765. a01 = a[1];
  1766. a02 = a[2];
  1767. a03 = a[3];
  1768. a10 = a[4];
  1769. a11 = a[5];
  1770. a12 = a[6];
  1771. a13 = a[7];
  1772. a20 = a[8];
  1773. a21 = a[9];
  1774. a22 = a[10];
  1775. a23 = a[11];
  1776. b00 = x * x * t + c;
  1777. b01 = y * x * t + z * s;
  1778. b02 = z * x * t - y * s;
  1779. b10 = x * y * t - z * s;
  1780. b11 = y * y * t + c;
  1781. b12 = z * y * t + x * s;
  1782. b20 = x * z * t + y * s;
  1783. b21 = y * z * t - x * s;
  1784. b22 = z * z * t + c;
  1785. out[0] = a00 * b00 + a10 * b01 + a20 * b02;
  1786. out[1] = a01 * b00 + a11 * b01 + a21 * b02;
  1787. out[2] = a02 * b00 + a12 * b01 + a22 * b02;
  1788. out[3] = a03 * b00 + a13 * b01 + a23 * b02;
  1789. out[4] = a00 * b10 + a10 * b11 + a20 * b12;
  1790. out[5] = a01 * b10 + a11 * b11 + a21 * b12;
  1791. out[6] = a02 * b10 + a12 * b11 + a22 * b12;
  1792. out[7] = a03 * b10 + a13 * b11 + a23 * b12;
  1793. out[8] = a00 * b20 + a10 * b21 + a20 * b22;
  1794. out[9] = a01 * b20 + a11 * b21 + a21 * b22;
  1795. out[10] = a02 * b20 + a12 * b21 + a22 * b22;
  1796. out[11] = a03 * b20 + a13 * b21 + a23 * b22;
  1797. if (a !== out) {
  1798. out[12] = a[12];
  1799. out[13] = a[13];
  1800. out[14] = a[14];
  1801. out[15] = a[15]
  1802. }
  1803. return out
  1804. };
  1805. mat4.rotateX = function(out, a, rad) {
  1806. var s = Math.sin(rad),
  1807. c = Math.cos(rad),
  1808. a10 = a[4],
  1809. a11 = a[5],
  1810. a12 = a[6],
  1811. a13 = a[7],
  1812. a20 = a[8],
  1813. a21 = a[9],
  1814. a22 = a[10],
  1815. a23 = a[11];
  1816. if (a !== out) {
  1817. out[0] = a[0];
  1818. out[1] = a[1];
  1819. out[2] = a[2];
  1820. out[3] = a[3];
  1821. out[12] = a[12];
  1822. out[13] = a[13];
  1823. out[14] = a[14];
  1824. out[15] = a[15]
  1825. }
  1826. out[4] = a10 * c + a20 * s;
  1827. out[5] = a11 * c + a21 * s;
  1828. out[6] = a12 * c + a22 * s;
  1829. out[7] = a13 * c + a23 * s;
  1830. out[8] = a20 * c - a10 * s;
  1831. out[9] = a21 * c - a11 * s;
  1832. out[10] = a22 * c - a12 * s;
  1833. out[11] = a23 * c - a13 * s;
  1834. return out
  1835. };
  1836. mat4.rotateY = function(out, a, rad) {
  1837. var s = Math.sin(rad),
  1838. c = Math.cos(rad),
  1839. a00 = a[0],
  1840. a01 = a[1],
  1841. a02 = a[2],
  1842. a03 = a[3],
  1843. a20 = a[8],
  1844. a21 = a[9],
  1845. a22 = a[10],
  1846. a23 = a[11];
  1847. if (a !== out) {
  1848. out[4] = a[4];
  1849. out[5] = a[5];
  1850. out[6] = a[6];
  1851. out[7] = a[7];
  1852. out[12] = a[12];
  1853. out[13] = a[13];
  1854. out[14] = a[14];
  1855. out[15] = a[15]
  1856. }
  1857. out[0] = a00 * c - a20 * s;
  1858. out[1] = a01 * c - a21 * s;
  1859. out[2] = a02 * c - a22 * s;
  1860. out[3] = a03 * c - a23 * s;
  1861. out[8] = a00 * s + a20 * c;
  1862. out[9] = a01 * s + a21 * c;
  1863. out[10] = a02 * s + a22 * c;
  1864. out[11] = a03 * s + a23 * c;
  1865. return out
  1866. };
  1867. mat4.rotateZ = function(out, a, rad) {
  1868. var s = Math.sin(rad),
  1869. c = Math.cos(rad),
  1870. a00 = a[0],
  1871. a01 = a[1],
  1872. a02 = a[2],
  1873. a03 = a[3],
  1874. a10 = a[4],
  1875. a11 = a[5],
  1876. a12 = a[6],
  1877. a13 = a[7];
  1878. if (a !== out) {
  1879. out[8] = a[8];
  1880. out[9] = a[9];
  1881. out[10] = a[10];
  1882. out[11] = a[11];
  1883. out[12] = a[12];
  1884. out[13] = a[13];
  1885. out[14] = a[14];
  1886. out[15] = a[15]
  1887. }
  1888. out[0] = a00 * c + a10 * s;
  1889. out[1] = a01 * c + a11 * s;
  1890. out[2] = a02 * c + a12 * s;
  1891. out[3] = a03 * c + a13 * s;
  1892. out[4] = a10 * c - a00 * s;
  1893. out[5] = a11 * c - a01 * s;
  1894. out[6] = a12 * c - a02 * s;
  1895. out[7] = a13 * c - a03 * s;
  1896. return out
  1897. };
  1898. mat4.fromRotationTranslation = function(out, q, v) {
  1899. var x = q[0],
  1900. y = q[1],
  1901. z = q[2],
  1902. w = q[3],
  1903. x2 = x + x,
  1904. y2 = y + y,
  1905. z2 = z + z,
  1906. xx = x * x2,
  1907. xy = x * y2,
  1908. xz = x * z2,
  1909. yy = y * y2,
  1910. yz = y * z2,
  1911. zz = z * z2,
  1912. wx = w * x2,
  1913. wy = w * y2,
  1914. wz = w * z2;
  1915. out[0] = 1 - (yy + zz);
  1916. out[1] = xy + wz;
  1917. out[2] = xz - wy;
  1918. out[3] = 0;
  1919. out[4] = xy - wz;
  1920. out[5] = 1 - (xx + zz);
  1921. out[6] = yz + wx;
  1922. out[7] = 0;
  1923. out[8] = xz + wy;
  1924. out[9] = yz - wx;
  1925. out[10] = 1 - (xx + yy);
  1926. out[11] = 0;
  1927. out[12] = v[0];
  1928. out[13] = v[1];
  1929. out[14] = v[2];
  1930. out[15] = 1;
  1931. return out
  1932. };
  1933. mat4.fromQuat = function(out, q) {
  1934. var x = q[0],
  1935. y = q[1],
  1936. z = q[2],
  1937. w = q[3],
  1938. x2 = x + x,
  1939. y2 = y + y,
  1940. z2 = z + z,
  1941. xx = x * x2,
  1942. yx = y * x2,
  1943. yy = y * y2,
  1944. zx = z * x2,
  1945. zy = z * y2,
  1946. zz = z * z2,
  1947. wx = w * x2,
  1948. wy = w * y2,
  1949. wz = w * z2;
  1950. out[0] = 1 - yy - zz;
  1951. out[1] = yx + wz;
  1952. out[2] = zx - wy;
  1953. out[3] = 0;
  1954. out[4] = yx - wz;
  1955. out[5] = 1 - xx - zz;
  1956. out[6] = zy + wx;
  1957. out[7] = 0;
  1958. out[8] = zx + wy;
  1959. out[9] = zy - wx;
  1960. out[10] = 1 - xx - yy;
  1961. out[11] = 0;
  1962. out[12] = 0;
  1963. out[13] = 0;
  1964. out[14] = 0;
  1965. out[15] = 1;
  1966. return out
  1967. };
  1968. mat4.frustum = function(out, left, right, bottom, top, near, far) {
  1969. var rl = 1 / (right - left),
  1970. tb = 1 / (top - bottom),
  1971. nf = 1 / (near - far);
  1972. out[0] = near * 2 * rl;
  1973. out[1] = 0;
  1974. out[2] = 0;
  1975. out[3] = 0;
  1976. out[4] = 0;
  1977. out[5] = near * 2 * tb;
  1978. out[6] = 0;
  1979. out[7] = 0;
  1980. out[8] = (right + left) * rl;
  1981. out[9] = (top + bottom) * tb;
  1982. out[10] = (far + near) * nf;
  1983. out[11] = -1;
  1984. out[12] = 0;
  1985. out[13] = 0;
  1986. out[14] = far * near * 2 * nf;
  1987. out[15] = 0;
  1988. return out
  1989. };
  1990. mat4.perspective = function(out, fovy, aspect, near, far) {
  1991. var f = 1 / Math.tan(fovy / 2),
  1992. nf = 1 / (near - far);
  1993. out[0] = f / aspect;
  1994. out[1] = 0;
  1995. out[2] = 0;
  1996. out[3] = 0;
  1997. out[4] = 0;
  1998. out[5] = f;
  1999. out[6] = 0;
  2000. out[7] = 0;
  2001. out[8] = 0;
  2002. out[9] = 0;
  2003. out[10] = (far + near) * nf;
  2004. out[11] = -1;
  2005. out[12] = 0;
  2006. out[13] = 0;
  2007. out[14] = 2 * far * near * nf;
  2008. out[15] = 0;
  2009. return out
  2010. };
  2011. mat4.ortho = function(out, left, right, bottom, top, near, far) {
  2012. var lr = 1 / (left - right),
  2013. bt = 1 / (bottom - top),
  2014. nf = 1 / (near - far);
  2015. out[0] = -2 * lr;
  2016. out[1] = 0;
  2017. out[2] = 0;
  2018. out[3] = 0;
  2019. out[4] = 0;
  2020. out[5] = -2 * bt;
  2021. out[6] = 0;
  2022. out[7] = 0;
  2023. out[8] = 0;
  2024. out[9] = 0;
  2025. out[10] = 2 * nf;
  2026. out[11] = 0;
  2027. out[12] = (left + right) * lr;
  2028. out[13] = (top + bottom) * bt;
  2029. out[14] = (far + near) * nf;
  2030. out[15] = 1;
  2031. return out
  2032. };
  2033. mat4.lookAt = function(out, eye, center, up) {
  2034. var x0, x1, x2, y0, y1, y2, z0, z1, z2, len, eyex = eye[0],
  2035. eyey = eye[1],
  2036. eyez = eye[2],
  2037. upx = up[0],
  2038. upy = up[1],
  2039. upz = up[2],
  2040. centerx = center[0],
  2041. centery = center[1],
  2042. centerz = center[2];
  2043. if (Math.abs(eyex - centerx) < GLMAT_EPSILON && Math.abs(eyey - centery) < GLMAT_EPSILON && Math.abs(eyez - centerz) < GLMAT_EPSILON) {
  2044. return mat4.identity(out)
  2045. }
  2046. z0 = eyex - centerx;
  2047. z1 = eyey - centery;
  2048. z2 = eyez - centerz;
  2049. len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);
  2050. z0 *= len;
  2051. z1 *= len;
  2052. z2 *= len;
  2053. x0 = upy * z2 - upz * z1;
  2054. x1 = upz * z0 - upx * z2;
  2055. x2 = upx * z1 - upy * z0;
  2056. len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
  2057. if (!len) {
  2058. x0 = 0;
  2059. x1 = 0;
  2060. x2 = 0
  2061. } else {
  2062. len = 1 / len;
  2063. x0 *= len;
  2064. x1 *= len;
  2065. x2 *= len
  2066. }
  2067. y0 = z1 * x2 - z2 * x1;
  2068. y1 = z2 * x0 - z0 * x2;
  2069. y2 = z0 * x1 - z1 * x0;
  2070. len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
  2071. if (!len) {
  2072. y0 = 0;
  2073. y1 = 0;
  2074. y2 = 0
  2075. } else {
  2076. len = 1 / len;
  2077. y0 *= len;
  2078. y1 *= len;
  2079. y2 *= len
  2080. }
  2081. out[0] = x0;
  2082. out[1] = y0;
  2083. out[2] = z0;
  2084. out[3] = 0;
  2085. out[4] = x1;
  2086. out[5] = y1;
  2087. out[6] = z1;
  2088. out[7] = 0;
  2089. out[8] = x2;
  2090. out[9] = y2;
  2091. out[10] = z2;
  2092. out[11] = 0;
  2093. out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
  2094. out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
  2095. out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
  2096. out[15] = 1;
  2097. return out
  2098. };
  2099. mat4.str = function(a) {
  2100. return "mat4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ", " + a[9] + ", " + a[10] + ", " + a[11] + ", " + a[12] + ", " + a[13] + ", " + a[14] + ", " + a[15] + ")"
  2101. };
  2102. mat4.frob = function(a) {
  2103. return Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2) + Math.pow(a[9], 2) + Math.pow(a[10], 2) + Math.pow(a[11], 2) + Math.pow(a[12], 2) + Math.pow(a[13], 2) + Math.pow(a[14], 2) + Math.pow(a[15], 2))
  2104. };
  2105. if (typeof exports !== "undefined") {
  2106. exports.mat4 = mat4
  2107. }
  2108. var quat = {};
  2109. quat.create = function() {
  2110. var out = new GLMAT_ARRAY_TYPE(4);
  2111. out[0] = 0;
  2112. out[1] = 0;
  2113. out[2] = 0;
  2114. out[3] = 1;
  2115. return out
  2116. };
  2117. quat.rotationTo = function() {
  2118. var tmpvec3 = vec3.create();
  2119. var xUnitVec3 = vec3.fromValues(1, 0, 0);
  2120. var yUnitVec3 = vec3.fromValues(0, 1, 0);
  2121. return function(out, a, b) {
  2122. var dot = vec3.dot(a, b);
  2123. if (dot < -.999999) {
  2124. vec3.cross(tmpvec3, xUnitVec3, a);
  2125. if (vec3.length(tmpvec3) < 1e-6) vec3.cross(tmpvec3, yUnitVec3, a);
  2126. vec3.normalize(tmpvec3, tmpvec3);
  2127. quat.setAxisAngle(out, tmpvec3, Math.PI);
  2128. return out
  2129. } else if (dot > .999999) {
  2130. out[0] = 0;
  2131. out[1] = 0;
  2132. out[2] = 0;
  2133. out[3] = 1;
  2134. return out
  2135. } else {
  2136. vec3.cross(tmpvec3, a, b);
  2137. out[0] = tmpvec3[0];
  2138. out[1] = tmpvec3[1];
  2139. out[2] = tmpvec3[2];
  2140. out[3] = 1 + dot;
  2141. return quat.normalize(out, out)
  2142. }
  2143. }
  2144. }();
  2145. quat.setAxes = function() {
  2146. var matr = mat3.create();
  2147. return function(out, view, right, up) {
  2148. matr[0] = right[0];
  2149. matr[3] = right[1];
  2150. matr[6] = right[2];
  2151. matr[1] = up[0];
  2152. matr[4] = up[1];
  2153. matr[7] = up[2];
  2154. matr[2] = -view[0];
  2155. matr[5] = -view[1];
  2156. matr[8] = -view[2];
  2157. return quat.normalize(out, quat.fromMat3(out, matr))
  2158. }
  2159. }();
  2160. quat.clone = vec4.clone;
  2161. quat.fromValues = vec4.fromValues;
  2162. quat.copy = vec4.copy;
  2163. quat.set = vec4.set;
  2164. quat.identity = function(out) {
  2165. out[0] = 0;
  2166. out[1] = 0;
  2167. out[2] = 0;
  2168. out[3] = 1;
  2169. return out
  2170. };
  2171. quat.setAxisAngle = function(out, axis, rad) {
  2172. rad = rad * .5;
  2173. var s = Math.sin(rad);
  2174. out[0] = s * axis[0];
  2175. out[1] = s * axis[1];
  2176. out[2] = s * axis[2];
  2177. out[3] = Math.cos(rad);
  2178. return out
  2179. };
  2180. quat.add = vec4.add;
  2181. quat.multiply = function(out, a, b) {
  2182. var ax = a[0],
  2183. ay = a[1],
  2184. az = a[2],
  2185. aw = a[3],
  2186. bx = b[0],
  2187. by = b[1],
  2188. bz = b[2],
  2189. bw = b[3];
  2190. out[0] = ax * bw + aw * bx + ay * bz - az * by;
  2191. out[1] = ay * bw + aw * by + az * bx - ax * bz;
  2192. out[2] = az * bw + aw * bz + ax * by - ay * bx;
  2193. out[3] = aw * bw - ax * bx - ay * by - az * bz;
  2194. return out
  2195. };
  2196. quat.mul = quat.multiply;
  2197. quat.scale = vec4.scale;
  2198. quat.rotateX = function(out, a, rad) {
  2199. rad *= .5;
  2200. var ax = a[0],
  2201. ay = a[1],
  2202. az = a[2],
  2203. aw = a[3],
  2204. bx = Math.sin(rad),
  2205. bw = Math.cos(rad);
  2206. out[0] = ax * bw + aw * bx;
  2207. out[1] = ay * bw + az * bx;
  2208. out[2] = az * bw - ay * bx;
  2209. out[3] = aw * bw - ax * bx;
  2210. return out
  2211. };
  2212. quat.rotateY = function(out, a, rad) {
  2213. rad *= .5;
  2214. var ax = a[0],
  2215. ay = a[1],
  2216. az = a[2],
  2217. aw = a[3],
  2218. by = Math.sin(rad),
  2219. bw = Math.cos(rad);
  2220. out[0] = ax * bw - az * by;
  2221. out[1] = ay * bw + aw * by;
  2222. out[2] = az * bw + ax * by;
  2223. out[3] = aw * bw - ay * by;
  2224. return out
  2225. };
  2226. quat.rotateZ = function(out, a, rad) {
  2227. rad *= .5;
  2228. var ax = a[0],
  2229. ay = a[1],
  2230. az = a[2],
  2231. aw = a[3],
  2232. bz = Math.sin(rad),
  2233. bw = Math.cos(rad);
  2234. out[0] = ax * bw + ay * bz;
  2235. out[1] = ay * bw - ax * bz;
  2236. out[2] = az * bw + aw * bz;
  2237. out[3] = aw * bw - az * bz;
  2238. return out
  2239. };
  2240. quat.calculateW = function(out, a) {
  2241. var x = a[0],
  2242. y = a[1],
  2243. z = a[2];
  2244. out[0] = x;
  2245. out[1] = y;
  2246. out[2] = z;
  2247. out[3] = -Math.sqrt(Math.abs(1 - x * x - y * y - z * z));
  2248. return out
  2249. };
  2250. quat.dot = vec4.dot;
  2251. quat.lerp = vec4.lerp;
  2252. quat.slerp = function(out, a, b, t) {
  2253. var ax = a[0],
  2254. ay = a[1],
  2255. az = a[2],
  2256. aw = a[3],
  2257. bx = b[0],
  2258. by = b[1],
  2259. bz = b[2],
  2260. bw = b[3];
  2261. var omega, cosom, sinom, scale0, scale1;
  2262. cosom = ax * bx + ay * by + az * bz + aw * bw;
  2263. if (cosom < 0) {
  2264. cosom = -cosom;
  2265. bx = -bx;
  2266. by = -by;
  2267. bz = -bz;
  2268. bw = -bw
  2269. }
  2270. if (1 - cosom > 1e-6) {
  2271. omega = Math.acos(cosom);
  2272. sinom = Math.sin(omega);
  2273. scale0 = Math.sin((1 - t) * omega) / sinom;
  2274. scale1 = Math.sin(t * omega) / sinom
  2275. } else {
  2276. scale0 = 1 - t;
  2277. scale1 = t
  2278. }
  2279. out[0] = scale0 * ax + scale1 * bx;
  2280. out[1] = scale0 * ay + scale1 * by;
  2281. out[2] = scale0 * az + scale1 * bz;
  2282. out[3] = scale0 * aw + scale1 * bw;
  2283. return out
  2284. };
  2285. quat.invert = function(out, a) {
  2286. var a0 = a[0],
  2287. a1 = a[1],
  2288. a2 = a[2],
  2289. a3 = a[3],
  2290. dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3,
  2291. invDot = dot ? 1 / dot : 0;
  2292. out[0] = -a0 * invDot;
  2293. out[1] = -a1 * invDot;
  2294. out[2] = -a2 * invDot;
  2295. out[3] = a3 * invDot;
  2296. return out
  2297. };
  2298. quat.conjugate = function(out, a) {
  2299. out[0] = -a[0];
  2300. out[1] = -a[1];
  2301. out[2] = -a[2];
  2302. out[3] = a[3];
  2303. return out
  2304. };
  2305. quat.length = vec4.length;
  2306. quat.len = quat.length;
  2307. quat.squaredLength = vec4.squaredLength;
  2308. quat.sqrLen = quat.squaredLength;
  2309. quat.normalize = vec4.normalize;
  2310. quat.fromMat3 = function(out, m) {
  2311. var fTrace = m[0] + m[4] + m[8];
  2312. var fRoot;
  2313. if (fTrace > 0) {
  2314. fRoot = Math.sqrt(fTrace + 1);
  2315. out[3] = .5 * fRoot;
  2316. fRoot = .5 / fRoot;
  2317. out[0] = (m[7] - m[5]) * fRoot;
  2318. out[1] = (m[2] - m[6]) * fRoot;
  2319. out[2] = (m[3] - m[1]) * fRoot
  2320. } else {
  2321. var i = 0;
  2322. if (m[4] > m[0]) i = 1;
  2323. if (m[8] > m[i * 3 + i]) i = 2;
  2324. var j = (i + 1) % 3;
  2325. var k = (i + 2) % 3;
  2326. fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1);
  2327. out[i] = .5 * fRoot;
  2328. fRoot = .5 / fRoot;
  2329. out[3] = (m[k * 3 + j] - m[j * 3 + k]) * fRoot;
  2330. out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot;
  2331. out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot
  2332. }
  2333. return out
  2334. };
  2335. quat.str = function(a) {
  2336. return "quat(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"
  2337. };
  2338. if (typeof exports !== "undefined") {
  2339. exports.quat = quat
  2340. }
  2341. })(shim.exports)
  2342. })(this);
  2343. ! function(e) {
  2344. if ("object" == typeof exports && "undefined" != typeof module) module.exports = e();
  2345. else if ("function" == typeof define && define.amd) define([], e);
  2346. else {
  2347. var f;
  2348. "undefined" != typeof window ? f = window : "undefined" != typeof global ? f = global : "undefined" != typeof self && (f = self), f.pako = e()
  2349. }
  2350. }(function() {
  2351. var define, module, exports;
  2352. return function e(t, n, r) {
  2353. function s(o, u) {
  2354. if (!n[o]) {
  2355. if (!t[o]) {
  2356. var a = typeof require == "function" && require;
  2357. if (!u && a) return a(o, !0);
  2358. if (i) return i(o, !0);
  2359. throw new Error("Cannot find module '" + o + "'")
  2360. }
  2361. var f = n[o] = {
  2362. exports: {}
  2363. };
  2364. t[o][0].call(f.exports, function(e) {
  2365. var n = t[o][1][e];
  2366. return s(n ? n : e)
  2367. }, f, f.exports, e, t, n, r)
  2368. }
  2369. return n[o].exports
  2370. }
  2371. var i = typeof require == "function" && require;
  2372. for (var o = 0; o < r.length; o++) s(r[o]);
  2373. return s
  2374. }({
  2375. 1: [function(_dereq_, module, exports) {
  2376. "use strict";
  2377. var zlib_inflate = _dereq_("./zlib/inflate.js");
  2378. var utils = _dereq_("./utils/common");
  2379. var strings = _dereq_("./utils/strings");
  2380. var c = _dereq_("./zlib/constants");
  2381. var msg = _dereq_("./zlib/messages");
  2382. var zstream = _dereq_("./zlib/zstream");
  2383. var gzheader = _dereq_("./zlib/gzheader");
  2384. var Inflate = function(options) {
  2385. this.options = utils.assign({
  2386. chunkSize: 16384,
  2387. windowBits: 0,
  2388. to: ""
  2389. }, options || {});
  2390. var opt = this.options;
  2391. if (opt.raw && opt.windowBits >= 0 && opt.windowBits < 16) {
  2392. opt.windowBits = -opt.windowBits;
  2393. if (opt.windowBits === 0) {
  2394. opt.windowBits = -15
  2395. }
  2396. }
  2397. if (opt.windowBits >= 0 && opt.windowBits < 16 && !(options && options.windowBits)) {
  2398. opt.windowBits += 32
  2399. }
  2400. if (opt.windowBits > 15 && opt.windowBits < 48) {
  2401. if ((opt.windowBits & 15) === 0) {
  2402. opt.windowBits |= 15
  2403. }
  2404. }
  2405. this.err = 0;
  2406. this.msg = "";
  2407. this.ended = false;
  2408. this.chunks = [];
  2409. this.strm = new zstream;
  2410. this.strm.avail_out = 0;
  2411. var status = zlib_inflate.inflateInit2(this.strm, opt.windowBits);
  2412. if (status !== c.Z_OK) {
  2413. throw new Error(msg[status])
  2414. }
  2415. this.header = new gzheader;
  2416. zlib_inflate.inflateGetHeader(this.strm, this.header)
  2417. };
  2418. Inflate.prototype.push = function(data, mode) {
  2419. var strm = this.strm;
  2420. var chunkSize = this.options.chunkSize;
  2421. var status, _mode;
  2422. var next_out_utf8, tail, utf8str;
  2423. if (this.ended) {
  2424. return false
  2425. }
  2426. _mode = mode === ~~mode ? mode : mode === true ? c.Z_FINISH : c.Z_NO_FLUSH;
  2427. if (typeof data === "string") {
  2428. strm.input = strings.binstring2buf(data)
  2429. } else {
  2430. strm.input = data
  2431. }
  2432. strm.next_in = 0;
  2433. strm.avail_in = strm.input.length;
  2434. do {
  2435. if (strm.avail_out === 0) {
  2436. strm.output = new utils.Buf8(chunkSize);
  2437. strm.next_out = 0;
  2438. strm.avail_out = chunkSize
  2439. }
  2440. status = zlib_inflate.inflate(strm, c.Z_NO_FLUSH);
  2441. if (status !== c.Z_STREAM_END && status !== c.Z_OK) {
  2442. this.onEnd(status);
  2443. this.ended = true;
  2444. return false
  2445. }
  2446. if (strm.next_out) {
  2447. if (strm.avail_out === 0 || status === c.Z_STREAM_END || strm.avail_in === 0 && _mode === c.Z_FINISH) {
  2448. if (this.options.to === "string") {
  2449. next_out_utf8 = strings.utf8border(strm.output, strm.next_out);
  2450. tail = strm.next_out - next_out_utf8;
  2451. utf8str = strings.buf2string(strm.output, next_out_utf8);
  2452. strm.next_out = tail;
  2453. strm.avail_out = chunkSize - tail;
  2454. if (tail) {
  2455. utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0)
  2456. }
  2457. this.onData(utf8str)
  2458. } else {
  2459. this.onData(utils.shrinkBuf(strm.output, strm.next_out))
  2460. }
  2461. }
  2462. }
  2463. } while (strm.avail_in > 0 && status !== c.Z_STREAM_END);
  2464. if (status === c.Z_STREAM_END) {
  2465. _mode = c.Z_FINISH
  2466. }
  2467. if (_mode === c.Z_FINISH) {
  2468. status = zlib_inflate.inflateEnd(this.strm);
  2469. this.onEnd(status);
  2470. this.ended = true;
  2471. return status === c.Z_OK
  2472. }
  2473. return true
  2474. };
  2475. Inflate.prototype.onData = function(chunk) {
  2476. this.chunks.push(chunk)
  2477. };
  2478. Inflate.prototype.onEnd = function(status) {
  2479. if (status === c.Z_OK) {
  2480. if (this.options.to === "string") {
  2481. this.result = this.chunks.join("")
  2482. } else {
  2483. this.result = utils.flattenChunks(this.chunks)
  2484. }
  2485. }
  2486. this.chunks = [];
  2487. this.err = status;
  2488. this.msg = this.strm.msg
  2489. };
  2490.  
  2491. function inflate(input, options) {
  2492. var inflator = new Inflate(options);
  2493. inflator.push(input, true);
  2494. if (inflator.err) {
  2495. throw inflator.msg
  2496. }
  2497. return inflator.result
  2498. }
  2499.  
  2500. function inflateRaw(input, options) {
  2501. options = options || {};
  2502. options.raw = true;
  2503. return inflate(input, options)
  2504. }
  2505. exports.Inflate = Inflate;
  2506. exports.inflate = inflate;
  2507. exports.inflateRaw = inflateRaw;
  2508. exports.ungzip = inflate
  2509. }, {
  2510. "./utils/common": 2,
  2511. "./utils/strings": 3,
  2512. "./zlib/constants": 5,
  2513. "./zlib/gzheader": 7,
  2514. "./zlib/inflate.js": 9,
  2515. "./zlib/messages": 11,
  2516. "./zlib/zstream": 12
  2517. }],
  2518. 2: [function(_dereq_, module, exports) {
  2519. "use strict";
  2520. var TYPED_OK = typeof Uint8Array !== "undefined" && typeof Uint16Array !== "undefined" && typeof Int32Array !== "undefined";
  2521. exports.assign = function(obj) {
  2522. var sources = Array.prototype.slice.call(arguments, 1);
  2523. while (sources.length) {
  2524. var source = sources.shift();
  2525. if (!source) {
  2526. continue
  2527. }
  2528. if (typeof source !== "object") {
  2529. throw new TypeError(source + "must be non-object")
  2530. }
  2531. for (var p in source) {
  2532. if (source.hasOwnProperty(p)) {
  2533. obj[p] = source[p]
  2534. }
  2535. }
  2536. }
  2537. return obj
  2538. };
  2539. exports.shrinkBuf = function(buf, size) {
  2540. if (buf.length === size) {
  2541. return buf
  2542. }
  2543. if (buf.subarray) {
  2544. return buf.subarray(0, size)
  2545. }
  2546. buf.length = size;
  2547. return buf
  2548. };
  2549. var fnTyped = {
  2550. arraySet: function(dest, src, src_offs, len, dest_offs) {
  2551. if (src.subarray && dest.subarray) {
  2552. dest.set(src.subarray(src_offs, src_offs + len), dest_offs);
  2553. return
  2554. }
  2555. for (var i = 0; i < len; i++) {
  2556. dest[dest_offs + i] = src[src_offs + i]
  2557. }
  2558. },
  2559. flattenChunks: function(chunks) {
  2560. var i, l, len, pos, chunk, result;
  2561. len = 0;
  2562. for (i = 0, l = chunks.length; i < l; i++) {
  2563. len += chunks[i].length
  2564. }
  2565. result = new Uint8Array(len);
  2566. pos = 0;
  2567. for (i = 0, l = chunks.length; i < l; i++) {
  2568. chunk = chunks[i];
  2569. result.set(chunk, pos);
  2570. pos += chunk.length
  2571. }
  2572. return result
  2573. }
  2574. };
  2575. var fnUntyped = {
  2576. arraySet: function(dest, src, src_offs, len, dest_offs) {
  2577. for (var i = 0; i < len; i++) {
  2578. dest[dest_offs + i] = src[src_offs + i]
  2579. }
  2580. },
  2581. flattenChunks: function(chunks) {
  2582. return [].concat.apply([], chunks)
  2583. }
  2584. };
  2585. exports.setTyped = function(on) {
  2586. if (on) {
  2587. exports.Buf8 = Uint8Array;
  2588. exports.Buf16 = Uint16Array;
  2589. exports.Buf32 = Int32Array;
  2590. exports.assign(exports, fnTyped)
  2591. } else {
  2592. exports.Buf8 = Array;
  2593. exports.Buf16 = Array;
  2594. exports.Buf32 = Array;
  2595. exports.assign(exports, fnUntyped)
  2596. }
  2597. };
  2598. exports.setTyped(TYPED_OK)
  2599. }, {}],
  2600. 3: [function(_dereq_, module, exports) {
  2601. "use strict";
  2602. var utils = _dereq_("./common");
  2603. var STR_APPLY_OK = true;
  2604. var STR_APPLY_UIA_OK = true;
  2605. try {
  2606. String.fromCharCode.apply(null, [0])
  2607. } catch (__) {
  2608. STR_APPLY_OK = false
  2609. }
  2610. try {
  2611. String.fromCharCode.apply(null, new Uint8Array(1))
  2612. } catch (__) {
  2613. STR_APPLY_UIA_OK = false
  2614. }
  2615. var _utf8len = new utils.Buf8(256);
  2616. for (var i = 0; i < 256; i++) {
  2617. _utf8len[i] = i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1
  2618. }
  2619. _utf8len[254] = _utf8len[254] = 1;
  2620. exports.string2buf = function(str) {
  2621. var buf, c, c2, m_pos, i, str_len = str.length,
  2622. buf_len = 0;
  2623. for (m_pos = 0; m_pos < str_len; m_pos++) {
  2624. c = str.charCodeAt(m_pos);
  2625. if ((c & 64512) === 55296 && m_pos + 1 < str_len) {
  2626. c2 = str.charCodeAt(m_pos + 1);
  2627. if ((c2 & 64512) === 56320) {
  2628. c = 65536 + (c - 55296 << 10) + (c2 - 56320);
  2629. m_pos++
  2630. }
  2631. }
  2632. buf_len += c < 128 ? 1 : c < 2048 ? 2 : c < 65536 ? 3 : 4
  2633. }
  2634. buf = new utils.Buf8(buf_len);
  2635. for (i = 0, m_pos = 0; i < buf_len; m_pos++) {
  2636. c = str.charCodeAt(m_pos);
  2637. if ((c & 64512) === 55296 && m_pos + 1 < str_len) {
  2638. c2 = str.charCodeAt(m_pos + 1);
  2639. if ((c2 & 64512) === 56320) {
  2640. c = 65536 + (c - 55296 << 10) + (c2 - 56320);
  2641. m_pos++
  2642. }
  2643. }
  2644. if (c < 128) {
  2645. buf[i++] = c
  2646. } else if (c < 2048) {
  2647. buf[i++] = 192 | c >>> 6;
  2648. buf[i++] = 128 | c & 63
  2649. } else if (c < 65536) {
  2650. buf[i++] = 224 | c >>> 12;
  2651. buf[i++] = 128 | c >>> 6 & 63;
  2652. buf[i++] = 128 | c & 63
  2653. } else {
  2654. buf[i++] = 240 | c >>> 18;
  2655. buf[i++] = 128 | c >>> 12 & 63;
  2656. buf[i++] = 128 | c >>> 6 & 63;
  2657. buf[i++] = 128 | c & 63
  2658. }
  2659. }
  2660. return buf
  2661. };
  2662.  
  2663. function buf2binstring(buf, len) {
  2664. if (len < 65537) {
  2665. if (buf.subarray && STR_APPLY_UIA_OK || !buf.subarray && STR_APPLY_OK) {
  2666. return String.fromCharCode.apply(null, utils.shrinkBuf(buf, len))
  2667. }
  2668. }
  2669. var result = "";
  2670. for (var i = 0; i < len; i++) {
  2671. result += String.fromCharCode(buf[i])
  2672. }
  2673. return result
  2674. }
  2675. exports.buf2binstring = function(buf) {
  2676. return buf2binstring(buf, buf.length)
  2677. };
  2678. exports.binstring2buf = function(str) {
  2679. var buf = new utils.Buf8(str.length);
  2680. for (var i = 0, len = buf.length; i < len; i++) {
  2681. buf[i] = str.charCodeAt(i)
  2682. }
  2683. return buf
  2684. };
  2685. exports.buf2string = function(buf, max) {
  2686. var i, out, c, c_len;
  2687. var len = max || buf.length;
  2688. var utf16buf = new Array(len * 2);
  2689. for (out = 0, i = 0; i < len;) {
  2690. c = buf[i++];
  2691. if (c < 128) {
  2692. utf16buf[out++] = c;
  2693. continue
  2694. }
  2695. c_len = _utf8len[c];
  2696. if (c_len > 4) {
  2697. utf16buf[out++] = 65533;
  2698. i += c_len - 1;
  2699. continue
  2700. }
  2701. c &= c_len === 2 ? 31 : c_len === 3 ? 15 : 7;
  2702. while (c_len > 1 && i < len) {
  2703. c = c << 6 | buf[i++] & 63;
  2704. c_len--
  2705. }
  2706. if (c_len > 1) {
  2707. utf16buf[out++] = 65533;
  2708. continue
  2709. }
  2710. if (c < 65536) {
  2711. utf16buf[out++] = c
  2712. } else {
  2713. c -= 65536;
  2714. utf16buf[out++] = 55296 | c >> 10 & 1023;
  2715. utf16buf[out++] = 56320 | c & 1023
  2716. }
  2717. }
  2718. return buf2binstring(utf16buf, out)
  2719. };
  2720. exports.utf8border = function(buf, max) {
  2721. var pos;
  2722. max = max || buf.length;
  2723. if (max > buf.length) {
  2724. max = buf.length
  2725. }
  2726. pos = max - 1;
  2727. while (pos >= 0 && (buf[pos] & 192) === 128) {
  2728. pos--
  2729. }
  2730. if (pos < 0) {
  2731. return max
  2732. }
  2733. if (pos === 0) {
  2734. return max
  2735. }
  2736. return pos + _utf8len[buf[pos]] > max ? pos : max
  2737. }
  2738. }, {
  2739. "./common": 2
  2740. }],
  2741. 4: [function(_dereq_, module, exports) {
  2742. "use strict";
  2743.  
  2744. function adler32(adler, buf, len, pos) {
  2745. var s1 = adler & 65535 | 0,
  2746. s2 = adler >>> 16 & 65535 | 0,
  2747. n = 0;
  2748. while (len !== 0) {
  2749. n = len > 2e3 ? 2e3 : len;
  2750. len -= n;
  2751. do {
  2752. s1 = s1 + buf[pos++] | 0;
  2753. s2 = s2 + s1 | 0
  2754. } while (--n);
  2755. s1 %= 65521;
  2756. s2 %= 65521
  2757. }
  2758. return s1 | s2 << 16 | 0
  2759. }
  2760. module.exports = adler32
  2761. }, {}],
  2762. 5: [function(_dereq_, module, exports) {
  2763. module.exports = {
  2764. Z_NO_FLUSH: 0,
  2765. Z_PARTIAL_FLUSH: 1,
  2766. Z_SYNC_FLUSH: 2,
  2767. Z_FULL_FLUSH: 3,
  2768. Z_FINISH: 4,
  2769. Z_BLOCK: 5,
  2770. Z_TREES: 6,
  2771. Z_OK: 0,
  2772. Z_STREAM_END: 1,
  2773. Z_NEED_DICT: 2,
  2774. Z_ERRNO: -1,
  2775. Z_STREAM_ERROR: -2,
  2776. Z_DATA_ERROR: -3,
  2777. Z_BUF_ERROR: -5,
  2778. Z_NO_COMPRESSION: 0,
  2779. Z_BEST_SPEED: 1,
  2780. Z_BEST_COMPRESSION: 9,
  2781. Z_DEFAULT_COMPRESSION: -1,
  2782. Z_FILTERED: 1,
  2783. Z_HUFFMAN_ONLY: 2,
  2784. Z_RLE: 3,
  2785. Z_FIXED: 4,
  2786. Z_DEFAULT_STRATEGY: 0,
  2787. Z_BINARY: 0,
  2788. Z_TEXT: 1,
  2789. Z_UNKNOWN: 2,
  2790. Z_DEFLATED: 8
  2791. }
  2792. }, {}],
  2793. 6: [function(_dereq_, module, exports) {
  2794. "use strict";
  2795.  
  2796. function makeTable() {
  2797. var c, table = [];
  2798. for (var n = 0; n < 256; n++) {
  2799. c = n;
  2800. for (var k = 0; k < 8; k++) {
  2801. c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1
  2802. }
  2803. table[n] = c
  2804. }
  2805. return table
  2806. }
  2807. var crcTable = makeTable();
  2808.  
  2809. function crc32(crc, buf, len, pos) {
  2810. var t = crcTable,
  2811. end = pos + len;
  2812. crc = crc ^ -1;
  2813. for (var i = pos; i < end; i++) {
  2814. crc = crc >>> 8 ^ t[(crc ^ buf[i]) & 255]
  2815. }
  2816. return crc ^ -1
  2817. }
  2818. module.exports = crc32
  2819. }, {}],
  2820. 7: [function(_dereq_, module, exports) {
  2821. "use strict";
  2822.  
  2823. function GZheader() {
  2824. this.text = 0;
  2825. this.time = 0;
  2826. this.xflags = 0;
  2827. this.os = 0;
  2828. this.extra = null;
  2829. this.extra_len = 0;
  2830. this.name = "";
  2831. this.comment = "";
  2832. this.hcrc = 0;
  2833. this.done = false
  2834. }
  2835. module.exports = GZheader
  2836. }, {}],
  2837. 8: [function(_dereq_, module, exports) {
  2838. "use strict";
  2839. var BAD = 30;
  2840. var TYPE = 12;
  2841. module.exports = function inflate_fast(strm, start) {
  2842. var state;
  2843. var _in;
  2844. var last;
  2845. var _out;
  2846. var beg;
  2847. var end;
  2848. var dmax;
  2849. var wsize;
  2850. var whave;
  2851. var wnext;
  2852. var window;
  2853. var hold;
  2854. var bits;
  2855. var lcode;
  2856. var dcode;
  2857. var lmask;
  2858. var dmask;
  2859. var here;
  2860. var op;
  2861. var len;
  2862. var dist;
  2863. var from;
  2864. var from_source;
  2865. var input, output;
  2866. state = strm.state;
  2867. _in = strm.next_in;
  2868. input = strm.input;
  2869. last = _in + (strm.avail_in - 5);
  2870. _out = strm.next_out;
  2871. output = strm.output;
  2872. beg = _out - (start - strm.avail_out);
  2873. end = _out + (strm.avail_out - 257);
  2874. dmax = state.dmax;
  2875. wsize = state.wsize;
  2876. whave = state.whave;
  2877. wnext = state.wnext;
  2878. window = state.window;
  2879. hold = state.hold;
  2880. bits = state.bits;
  2881. lcode = state.lencode;
  2882. dcode = state.distcode;
  2883. lmask = (1 << state.lenbits) - 1;
  2884. dmask = (1 << state.distbits) - 1;
  2885. top: do {
  2886. if (bits < 15) {
  2887. hold += input[_in++] << bits;
  2888. bits += 8;
  2889. hold += input[_in++] << bits;
  2890. bits += 8
  2891. }
  2892. here = lcode[hold & lmask];
  2893. dolen: for (;;) {
  2894. op = here >>> 24;
  2895. hold >>>= op;
  2896. bits -= op;
  2897. op = here >>> 16 & 255;
  2898. if (op === 0) {
  2899. output[_out++] = here & 65535
  2900. } else if (op & 16) {
  2901. len = here & 65535;
  2902. op &= 15;
  2903. if (op) {
  2904. if (bits < op) {
  2905. hold += input[_in++] << bits;
  2906. bits += 8
  2907. }
  2908. len += hold & (1 << op) - 1;
  2909. hold >>>= op;
  2910. bits -= op
  2911. }
  2912. if (bits < 15) {
  2913. hold += input[_in++] << bits;
  2914. bits += 8;
  2915. hold += input[_in++] << bits;
  2916. bits += 8
  2917. }
  2918. here = dcode[hold & dmask];
  2919. dodist: for (;;) {
  2920. op = here >>> 24;
  2921. hold >>>= op;
  2922. bits -= op;
  2923. op = here >>> 16 & 255;
  2924. if (op & 16) {
  2925. dist = here & 65535;
  2926. op &= 15;
  2927. if (bits < op) {
  2928. hold += input[_in++] << bits;
  2929. bits += 8;
  2930. if (bits < op) {
  2931. hold += input[_in++] << bits;
  2932. bits += 8
  2933. }
  2934. }
  2935. dist += hold & (1 << op) - 1;
  2936. if (dist > dmax) {
  2937. strm.msg = "invalid distance too far back";
  2938. state.mode = BAD;
  2939. break top
  2940. }
  2941. hold >>>= op;
  2942. bits -= op;
  2943. op = _out - beg;
  2944. if (dist > op) {
  2945. op = dist - op;
  2946. if (op > whave) {
  2947. if (state.sane) {
  2948. strm.msg = "invalid distance too far back";
  2949. state.mode = BAD;
  2950. break top
  2951. }
  2952. }
  2953. from = 0;
  2954. from_source = window;
  2955. if (wnext === 0) {
  2956. from += wsize - op;
  2957. if (op < len) {
  2958. len -= op;
  2959. do {
  2960. output[_out++] = window[from++]
  2961. } while (--op);
  2962. from = _out - dist;
  2963. from_source = output
  2964. }
  2965. } else if (wnext < op) {
  2966. from += wsize + wnext - op;
  2967. op -= wnext;
  2968. if (op < len) {
  2969. len -= op;
  2970. do {
  2971. output[_out++] = window[from++]
  2972. } while (--op);
  2973. from = 0;
  2974. if (wnext < len) {
  2975. op = wnext;
  2976. len -= op;
  2977. do {
  2978. output[_out++] = window[from++]
  2979. } while (--op);
  2980. from = _out - dist;
  2981. from_source = output
  2982. }
  2983. }
  2984. } else {
  2985. from += wnext - op;
  2986. if (op < len) {
  2987. len -= op;
  2988. do {
  2989. output[_out++] = window[from++]
  2990. } while (--op);
  2991. from = _out - dist;
  2992. from_source = output
  2993. }
  2994. }
  2995. while (len > 2) {
  2996. output[_out++] = from_source[from++];
  2997. output[_out++] = from_source[from++];
  2998. output[_out++] = from_source[from++];
  2999. len -= 3
  3000. }
  3001. if (len) {
  3002. output[_out++] = from_source[from++];
  3003. if (len > 1) {
  3004. output[_out++] = from_source[from++]
  3005. }
  3006. }
  3007. } else {
  3008. from = _out - dist;
  3009. do {
  3010. output[_out++] = output[from++];
  3011. output[_out++] = output[from++];
  3012. output[_out++] = output[from++];
  3013. len -= 3
  3014. } while (len > 2);
  3015. if (len) {
  3016. output[_out++] = output[from++];
  3017. if (len > 1) {
  3018. output[_out++] = output[from++]
  3019. }
  3020. }
  3021. }
  3022. } else if ((op & 64) === 0) {
  3023. here = dcode[(here & 65535) + (hold & (1 << op) - 1)];
  3024. continue dodist
  3025. } else {
  3026. strm.msg = "invalid distance code";
  3027. state.mode = BAD;
  3028. break top
  3029. }
  3030. break
  3031. }
  3032. } else if ((op & 64) === 0) {
  3033. here = lcode[(here & 65535) + (hold & (1 << op) - 1)];
  3034. continue dolen
  3035. } else if (op & 32) {
  3036. state.mode = TYPE;
  3037. break top
  3038. } else {
  3039. strm.msg = "invalid literal/length code";
  3040. state.mode = BAD;
  3041. break top
  3042. }
  3043. break
  3044. }
  3045. } while (_in < last && _out < end);
  3046. len = bits >> 3;
  3047. _in -= len;
  3048. bits -= len << 3;
  3049. hold &= (1 << bits) - 1;
  3050. strm.next_in = _in;
  3051. strm.next_out = _out;
  3052. strm.avail_in = _in < last ? 5 + (last - _in) : 5 - (_in - last);
  3053. strm.avail_out = _out < end ? 257 + (end - _out) : 257 - (_out - end);
  3054. state.hold = hold;
  3055. state.bits = bits;
  3056. return
  3057. }
  3058. }, {}],
  3059. 9: [function(_dereq_, module, exports) {
  3060. "use strict";
  3061. var utils = _dereq_("../utils/common");
  3062. var adler32 = _dereq_("./adler32");
  3063. var crc32 = _dereq_("./crc32");
  3064. var inflate_fast = _dereq_("./inffast");
  3065. var inflate_table = _dereq_("./inftrees");
  3066. var CODES = 0;
  3067. var LENS = 1;
  3068. var DISTS = 2;
  3069. var Z_FINISH = 4;
  3070. var Z_BLOCK = 5;
  3071. var Z_TREES = 6;
  3072. var Z_OK = 0;
  3073. var Z_STREAM_END = 1;
  3074. var Z_NEED_DICT = 2;
  3075. var Z_STREAM_ERROR = -2;
  3076. var Z_DATA_ERROR = -3;
  3077. var Z_MEM_ERROR = -4;
  3078. var Z_BUF_ERROR = -5;
  3079. var Z_DEFLATED = 8;
  3080. var HEAD = 1;
  3081. var FLAGS = 2;
  3082. var TIME = 3;
  3083. var OS = 4;
  3084. var EXLEN = 5;
  3085. var EXTRA = 6;
  3086. var NAME = 7;
  3087. var COMMENT = 8;
  3088. var HCRC = 9;
  3089. var DICTID = 10;
  3090. var DICT = 11;
  3091. var TYPE = 12;
  3092. var TYPEDO = 13;
  3093. var STORED = 14;
  3094. var COPY_ = 15;
  3095. var COPY = 16;
  3096. var TABLE = 17;
  3097. var LENLENS = 18;
  3098. var CODELENS = 19;
  3099. var LEN_ = 20;
  3100. var LEN = 21;
  3101. var LENEXT = 22;
  3102. var DIST = 23;
  3103. var DISTEXT = 24;
  3104. var MATCH = 25;
  3105. var LIT = 26;
  3106. var CHECK = 27;
  3107. var LENGTH = 28;
  3108. var DONE = 29;
  3109. var BAD = 30;
  3110. var MEM = 31;
  3111. var SYNC = 32;
  3112. var ENOUGH_LENS = 852;
  3113. var ENOUGH_DISTS = 592;
  3114. var MAX_WBITS = 15;
  3115. var DEF_WBITS = MAX_WBITS;
  3116.  
  3117. function ZSWAP32(q) {
  3118. return (q >>> 24 & 255) + (q >>> 8 & 65280) + ((q & 65280) << 8) + ((q & 255) << 24)
  3119. }
  3120.  
  3121. function InflateState() {
  3122. this.mode = 0;
  3123. this.last = false;
  3124. this.wrap = 0;
  3125. this.havedict = false;
  3126. this.flags = 0;
  3127. this.dmax = 0;
  3128. this.check = 0;
  3129. this.total = 0;
  3130. this.head = null;
  3131. this.wbits = 0;
  3132. this.wsize = 0;
  3133. this.whave = 0;
  3134. this.wnext = 0;
  3135. this.window = null;
  3136. this.hold = 0;
  3137. this.bits = 0;
  3138. this.length = 0;
  3139. this.offset = 0;
  3140. this.extra = 0;
  3141. this.lencode = null;
  3142. this.distcode = null;
  3143. this.lenbits = 0;
  3144. this.distbits = 0;
  3145. this.ncode = 0;
  3146. this.nlen = 0;
  3147. this.ndist = 0;
  3148. this.have = 0;
  3149. this.next = null;
  3150. this.lens = new utils.Buf16(320);
  3151. this.work = new utils.Buf16(288);
  3152. this.lendyn = null;
  3153. this.distdyn = null;
  3154. this.sane = 0;
  3155. this.back = 0;
  3156. this.was = 0
  3157. }
  3158.  
  3159. function inflateResetKeep(strm) {
  3160. var state;
  3161. if (!strm || !strm.state) {
  3162. return Z_STREAM_ERROR
  3163. }
  3164. state = strm.state;
  3165. strm.total_in = strm.total_out = state.total = 0;
  3166. strm.msg = "";
  3167. if (state.wrap) {
  3168. strm.adler = state.wrap & 1
  3169. }
  3170. state.mode = HEAD;
  3171. state.last = 0;
  3172. state.havedict = 0;
  3173. state.dmax = 32768;
  3174. state.head = null;
  3175. state.hold = 0;
  3176. state.bits = 0;
  3177. state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS);
  3178. state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS);
  3179. state.sane = 1;
  3180. state.back = -1;
  3181. return Z_OK
  3182. }
  3183.  
  3184. function inflateReset(strm) {
  3185. var state;
  3186. if (!strm || !strm.state) {
  3187. return Z_STREAM_ERROR
  3188. }
  3189. state = strm.state;
  3190. state.wsize = 0;
  3191. state.whave = 0;
  3192. state.wnext = 0;
  3193. return inflateResetKeep(strm)
  3194. }
  3195.  
  3196. function inflateReset2(strm, windowBits) {
  3197. var wrap;
  3198. var state;
  3199. if (!strm || !strm.state) {
  3200. return Z_STREAM_ERROR
  3201. }
  3202. state = strm.state;
  3203. if (windowBits < 0) {
  3204. wrap = 0;
  3205. windowBits = -windowBits
  3206. } else {
  3207. wrap = (windowBits >> 4) + 1;
  3208. if (windowBits < 48) {
  3209. windowBits &= 15
  3210. }
  3211. }
  3212. if (windowBits && (windowBits < 8 || windowBits > 15)) {
  3213. return Z_STREAM_ERROR
  3214. }
  3215. if (state.window !== null && state.wbits !== windowBits) {
  3216. state.window = null
  3217. }
  3218. state.wrap = wrap;
  3219. state.wbits = windowBits;
  3220. return inflateReset(strm)
  3221. }
  3222.  
  3223. function inflateInit2(strm, windowBits) {
  3224. var ret;
  3225. var state;
  3226. if (!strm) {
  3227. return Z_STREAM_ERROR
  3228. }
  3229. state = new InflateState;
  3230. strm.state = state;
  3231. state.window = null;
  3232. ret = inflateReset2(strm, windowBits);
  3233. if (ret !== Z_OK) {
  3234. strm.state = null
  3235. }
  3236. return ret
  3237. }
  3238.  
  3239. function inflateInit(strm) {
  3240. return inflateInit2(strm, DEF_WBITS)
  3241. }
  3242. var virgin = true;
  3243. var lenfix, distfix;
  3244.  
  3245. function fixedtables(state) {
  3246. if (virgin) {
  3247. var sym;
  3248. lenfix = new utils.Buf32(512);
  3249. distfix = new utils.Buf32(32);
  3250. sym = 0;
  3251. while (sym < 144) {
  3252. state.lens[sym++] = 8
  3253. }
  3254. while (sym < 256) {
  3255. state.lens[sym++] = 9
  3256. }
  3257. while (sym < 280) {
  3258. state.lens[sym++] = 7
  3259. }
  3260. while (sym < 288) {
  3261. state.lens[sym++] = 8
  3262. }
  3263. inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, {
  3264. bits: 9
  3265. });
  3266. sym = 0;
  3267. while (sym < 32) {
  3268. state.lens[sym++] = 5
  3269. }
  3270. inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, {
  3271. bits: 5
  3272. });
  3273. virgin = false
  3274. }
  3275. state.lencode = lenfix;
  3276. state.lenbits = 9;
  3277. state.distcode = distfix;
  3278. state.distbits = 5
  3279. }
  3280.  
  3281. function updatewindow(strm, src, end, copy) {
  3282. var dist;
  3283. var state = strm.state;
  3284. if (state.window === null) {
  3285. state.wsize = 1 << state.wbits;
  3286. state.wnext = 0;
  3287. state.whave = 0;
  3288. state.window = new utils.Buf8(state.wsize)
  3289. }
  3290. if (copy >= state.wsize) {
  3291. utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0);
  3292. state.wnext = 0;
  3293. state.whave = state.wsize
  3294. } else {
  3295. dist = state.wsize - state.wnext;
  3296. if (dist > copy) {
  3297. dist = copy
  3298. }
  3299. utils.arraySet(state.window, src, end - copy, dist, state.wnext);
  3300. copy -= dist;
  3301. if (copy) {
  3302. utils.arraySet(state.window, src, end - copy, copy, 0);
  3303. state.wnext = copy;
  3304. state.whave = state.wsize
  3305. } else {
  3306. state.wnext += dist;
  3307. if (state.wnext === state.wsize) {
  3308. state.wnext = 0
  3309. }
  3310. if (state.whave < state.wsize) {
  3311. state.whave += dist
  3312. }
  3313. }
  3314. }
  3315. return 0
  3316. }
  3317.  
  3318. function inflate(strm, flush) {
  3319. var state;
  3320. var input, output;
  3321. var next;
  3322. var put;
  3323. var have, left;
  3324. var hold;
  3325. var bits;
  3326. var _in, _out;
  3327. var copy;
  3328. var from;
  3329. var from_source;
  3330. var here = 0;
  3331. var here_bits, here_op, here_val;
  3332. var last_bits, last_op, last_val;
  3333. var len;
  3334. var ret;
  3335. var hbuf = new utils.Buf8(4);
  3336. var opts;
  3337. var n;
  3338. var order = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
  3339. if (!strm || !strm.state || !strm.output || !strm.input && strm.avail_in !== 0) {
  3340. return Z_STREAM_ERROR
  3341. }
  3342. state = strm.state;
  3343. if (state.mode === TYPE) {
  3344. state.mode = TYPEDO
  3345. }
  3346. put = strm.next_out;
  3347. output = strm.output;
  3348. left = strm.avail_out;
  3349. next = strm.next_in;
  3350. input = strm.input;
  3351. have = strm.avail_in;
  3352. hold = state.hold;
  3353. bits = state.bits;
  3354. _in = have;
  3355. _out = left;
  3356. ret = Z_OK;
  3357. inf_leave: for (;;) {
  3358. switch (state.mode) {
  3359. case HEAD:
  3360. if (state.wrap === 0) {
  3361. state.mode = TYPEDO;
  3362. break
  3363. }
  3364. while (bits < 16) {
  3365. if (have === 0) {
  3366. break inf_leave
  3367. }
  3368. have--;
  3369. hold += input[next++] << bits;
  3370. bits += 8
  3371. }
  3372. if (state.wrap & 2 && hold === 35615) {
  3373. state.check = 0;
  3374. hbuf[0] = hold & 255;
  3375. hbuf[1] = hold >>> 8 & 255;
  3376. state.check = crc32(state.check, hbuf, 2, 0);
  3377. hold = 0;
  3378. bits = 0;
  3379. state.mode = FLAGS;
  3380. break
  3381. }
  3382. state.flags = 0;
  3383. if (state.head) {
  3384. state.head.done = false
  3385. }
  3386. if (!(state.wrap & 1) || (((hold & 255) << 8) + (hold >> 8)) % 31) {
  3387. strm.msg = "incorrect header check";
  3388. state.mode = BAD;
  3389. break
  3390. }
  3391. if ((hold & 15) !== Z_DEFLATED) {
  3392. strm.msg = "unknown compression method";
  3393. state.mode = BAD;
  3394. break
  3395. }
  3396. hold >>>= 4;
  3397. bits -= 4;
  3398. len = (hold & 15) + 8;
  3399. if (state.wbits === 0) {
  3400. state.wbits = len
  3401. } else if (len > state.wbits) {
  3402. strm.msg = "invalid window size";
  3403. state.mode = BAD;
  3404. break
  3405. }
  3406. state.dmax = 1 << len;
  3407. strm.adler = state.check = 1;
  3408. state.mode = hold & 512 ? DICTID : TYPE;
  3409. hold = 0;
  3410. bits = 0;
  3411. break;
  3412. case FLAGS:
  3413. while (bits < 16) {
  3414. if (have === 0) {
  3415. break inf_leave
  3416. }
  3417. have--;
  3418. hold += input[next++] << bits;
  3419. bits += 8
  3420. }
  3421. state.flags = hold;
  3422. if ((state.flags & 255) !== Z_DEFLATED) {
  3423. strm.msg = "unknown compression method";
  3424. state.mode = BAD;
  3425. break
  3426. }
  3427. if (state.flags & 57344) {
  3428. strm.msg = "unknown header flags set";
  3429. state.mode = BAD;
  3430. break
  3431. }
  3432. if (state.head) {
  3433. state.head.text = hold >> 8 & 1
  3434. }
  3435. if (state.flags & 512) {
  3436. hbuf[0] = hold & 255;
  3437. hbuf[1] = hold >>> 8 & 255;
  3438. state.check = crc32(state.check, hbuf, 2, 0)
  3439. }
  3440. hold = 0;
  3441. bits = 0;
  3442. state.mode = TIME;
  3443. case TIME:
  3444. while (bits < 32) {
  3445. if (have === 0) {
  3446. break inf_leave
  3447. }
  3448. have--;
  3449. hold += input[next++] << bits;
  3450. bits += 8
  3451. }
  3452. if (state.head) {
  3453. state.head.time = hold
  3454. }
  3455. if (state.flags & 512) {
  3456. hbuf[0] = hold & 255;
  3457. hbuf[1] = hold >>> 8 & 255;
  3458. hbuf[2] = hold >>> 16 & 255;
  3459. hbuf[3] = hold >>> 24 & 255;
  3460. state.check = crc32(state.check, hbuf, 4, 0)
  3461. }
  3462. hold = 0;
  3463. bits = 0;
  3464. state.mode = OS;
  3465. case OS:
  3466. while (bits < 16) {
  3467. if (have === 0) {
  3468. break inf_leave
  3469. }
  3470. have--;
  3471. hold += input[next++] << bits;
  3472. bits += 8
  3473. }
  3474. if (state.head) {
  3475. state.head.xflags = hold & 255;
  3476. state.head.os = hold >> 8
  3477. }
  3478. if (state.flags & 512) {
  3479. hbuf[0] = hold & 255;
  3480. hbuf[1] = hold >>> 8 & 255;
  3481. state.check = crc32(state.check, hbuf, 2, 0)
  3482. }
  3483. hold = 0;
  3484. bits = 0;
  3485. state.mode = EXLEN;
  3486. case EXLEN:
  3487. if (state.flags & 1024) {
  3488. while (bits < 16) {
  3489. if (have === 0) {
  3490. break inf_leave
  3491. }
  3492. have--;
  3493. hold += input[next++] << bits;
  3494. bits += 8
  3495. }
  3496. state.length = hold;
  3497. if (state.head) {
  3498. state.head.extra_len = hold
  3499. }
  3500. if (state.flags & 512) {
  3501. hbuf[0] = hold & 255;
  3502. hbuf[1] = hold >>> 8 & 255;
  3503. state.check = crc32(state.check, hbuf, 2, 0)
  3504. }
  3505. hold = 0;
  3506. bits = 0
  3507. } else if (state.head) {
  3508. state.head.extra = null
  3509. }
  3510. state.mode = EXTRA;
  3511. case EXTRA:
  3512. if (state.flags & 1024) {
  3513. copy = state.length;
  3514. if (copy > have) {
  3515. copy = have
  3516. }
  3517. if (copy) {
  3518. if (state.head) {
  3519. len = state.head.extra_len - state.length;
  3520. if (!state.head.extra) {
  3521. state.head.extra = new Array(state.head.extra_len)
  3522. }
  3523. utils.arraySet(state.head.extra, input, next, copy, len)
  3524. }
  3525. if (state.flags & 512) {
  3526. state.check = crc32(state.check, input, copy, next)
  3527. }
  3528. have -= copy;
  3529. next += copy;
  3530. state.length -= copy
  3531. }
  3532. if (state.length) {
  3533. break inf_leave
  3534. }
  3535. }
  3536. state.length = 0;
  3537. state.mode = NAME;
  3538. case NAME:
  3539. if (state.flags & 2048) {
  3540. if (have === 0) {
  3541. break inf_leave
  3542. }
  3543. copy = 0;
  3544. do {
  3545. len = input[next + copy++];
  3546. if (state.head && len && state.length < 65536) {
  3547. state.head.name += String.fromCharCode(len)
  3548. }
  3549. } while (len && copy < have);
  3550. if (state.flags & 512) {
  3551. state.check = crc32(state.check, input, copy, next)
  3552. }
  3553. have -= copy;
  3554. next += copy;
  3555. if (len) {
  3556. break inf_leave
  3557. }
  3558. } else if (state.head) {
  3559. state.head.name = null
  3560. }
  3561. state.length = 0;
  3562. state.mode = COMMENT;
  3563. case COMMENT:
  3564. if (state.flags & 4096) {
  3565. if (have === 0) {
  3566. break inf_leave
  3567. }
  3568. copy = 0;
  3569. do {
  3570. len = input[next + copy++];
  3571. if (state.head && len && state.length < 65536) {
  3572. state.head.comment += String.fromCharCode(len)
  3573. }
  3574. } while (len && copy < have);
  3575. if (state.flags & 512) {
  3576. state.check = crc32(state.check, input, copy, next)
  3577. }
  3578. have -= copy;
  3579. next += copy;
  3580. if (len) {
  3581. break inf_leave
  3582. }
  3583. } else if (state.head) {
  3584. state.head.comment = null
  3585. }
  3586. state.mode = HCRC;
  3587. case HCRC:
  3588. if (state.flags & 512) {
  3589. while (bits < 16) {
  3590. if (have === 0) {
  3591. break inf_leave
  3592. }
  3593. have--;
  3594. hold += input[next++] << bits;
  3595. bits += 8
  3596. }
  3597. if (hold !== (state.check & 65535)) {
  3598. strm.msg = "header crc mismatch";
  3599. state.mode = BAD;
  3600. break
  3601. }
  3602. hold = 0;
  3603. bits = 0
  3604. }
  3605. if (state.head) {
  3606. state.head.hcrc = state.flags >> 9 & 1;
  3607. state.head.done = true
  3608. }
  3609. strm.adler = state.check = 0;
  3610. state.mode = TYPE;
  3611. break;
  3612. case DICTID:
  3613. while (bits < 32) {
  3614. if (have === 0) {
  3615. break inf_leave
  3616. }
  3617. have--;
  3618. hold += input[next++] << bits;
  3619. bits += 8
  3620. }
  3621. strm.adler = state.check = ZSWAP32(hold);
  3622. hold = 0;
  3623. bits = 0;
  3624. state.mode = DICT;
  3625. case DICT:
  3626. if (state.havedict === 0) {
  3627. strm.next_out = put;
  3628. strm.avail_out = left;
  3629. strm.next_in = next;
  3630. strm.avail_in = have;
  3631. state.hold = hold;
  3632. state.bits = bits;
  3633. return Z_NEED_DICT
  3634. }
  3635. strm.adler = state.check = 1;
  3636. state.mode = TYPE;
  3637. case TYPE:
  3638. if (flush === Z_BLOCK || flush === Z_TREES) {
  3639. break inf_leave
  3640. }
  3641. case TYPEDO:
  3642. if (state.last) {
  3643. hold >>>= bits & 7;
  3644. bits -= bits & 7;
  3645. state.mode = CHECK;
  3646. break
  3647. }
  3648. while (bits < 3) {
  3649. if (have === 0) {
  3650. break inf_leave
  3651. }
  3652. have--;
  3653. hold += input[next++] << bits;
  3654. bits += 8
  3655. }
  3656. state.last = hold & 1;
  3657. hold >>>= 1;
  3658. bits -= 1;
  3659. switch (hold & 3) {
  3660. case 0:
  3661. state.mode = STORED;
  3662. break;
  3663. case 1:
  3664. fixedtables(state);
  3665. state.mode = LEN_;
  3666. if (flush === Z_TREES) {
  3667. hold >>>= 2;
  3668. bits -= 2;
  3669. break inf_leave
  3670. }
  3671. break;
  3672. case 2:
  3673. state.mode = TABLE;
  3674. break;
  3675. case 3:
  3676. strm.msg = "invalid block type";
  3677. state.mode = BAD
  3678. }
  3679. hold >>>= 2;
  3680. bits -= 2;
  3681. break;
  3682. case STORED:
  3683. hold >>>= bits & 7;
  3684. bits -= bits & 7;
  3685. while (bits < 32) {
  3686. if (have === 0) {
  3687. break inf_leave
  3688. }
  3689. have--;
  3690. hold += input[next++] << bits;
  3691. bits += 8
  3692. }
  3693. if ((hold & 65535) !== (hold >>> 16 ^ 65535)) {
  3694. strm.msg = "invalid stored block lengths";
  3695. state.mode = BAD;
  3696. break
  3697. }
  3698. state.length = hold & 65535;
  3699. hold = 0;
  3700. bits = 0;
  3701. state.mode = COPY_;
  3702. if (flush === Z_TREES) {
  3703. break inf_leave
  3704. }
  3705. case COPY_:
  3706. state.mode = COPY;
  3707. case COPY:
  3708. copy = state.length;
  3709. if (copy) {
  3710. if (copy > have) {
  3711. copy = have
  3712. }
  3713. if (copy > left) {
  3714. copy = left
  3715. }
  3716. if (copy === 0) {
  3717. break inf_leave
  3718. }
  3719. utils.arraySet(output, input, next, copy, put);
  3720. have -= copy;
  3721. next += copy;
  3722. left -= copy;
  3723. put += copy;
  3724. state.length -= copy;
  3725. break
  3726. }
  3727. state.mode = TYPE;
  3728. break;
  3729. case TABLE:
  3730. while (bits < 14) {
  3731. if (have === 0) {
  3732. break inf_leave
  3733. }
  3734. have--;
  3735. hold += input[next++] << bits;
  3736. bits += 8
  3737. }
  3738. state.nlen = (hold & 31) + 257;
  3739. hold >>>= 5;
  3740. bits -= 5;
  3741. state.ndist = (hold & 31) + 1;
  3742. hold >>>= 5;
  3743. bits -= 5;
  3744. state.ncode = (hold & 15) + 4;
  3745. hold >>>= 4;
  3746. bits -= 4;
  3747. if (state.nlen > 286 || state.ndist > 30) {
  3748. strm.msg = "too many length or distance symbols";
  3749. state.mode = BAD;
  3750. break
  3751. }
  3752. state.have = 0;
  3753. state.mode = LENLENS;
  3754. case LENLENS:
  3755. while (state.have < state.ncode) {
  3756. while (bits < 3) {
  3757. if (have === 0) {
  3758. break inf_leave
  3759. }
  3760. have--;
  3761. hold += input[next++] << bits;
  3762. bits += 8
  3763. }
  3764. state.lens[order[state.have++]] = hold & 7;
  3765. hold >>>= 3;
  3766. bits -= 3
  3767. }
  3768. while (state.have < 19) {
  3769. state.lens[order[state.have++]] = 0
  3770. }
  3771. state.lencode = state.lendyn;
  3772. state.lenbits = 7;
  3773. opts = {
  3774. bits: state.lenbits
  3775. };
  3776. ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts);
  3777. state.lenbits = opts.bits;
  3778. if (ret) {
  3779. strm.msg = "invalid code lengths set";
  3780. state.mode = BAD;
  3781. break
  3782. }
  3783. state.have = 0;
  3784. state.mode = CODELENS;
  3785. case CODELENS:
  3786. while (state.have < state.nlen + state.ndist) {
  3787. for (;;) {
  3788. here = state.lencode[hold & (1 << state.lenbits) - 1];
  3789. here_bits = here >>> 24;
  3790. here_op = here >>> 16 & 255;
  3791. here_val = here & 65535;
  3792. if (here_bits <= bits) {
  3793. break
  3794. }
  3795. if (have === 0) {
  3796. break inf_leave
  3797. }
  3798. have--;
  3799. hold += input[next++] << bits;
  3800. bits += 8
  3801. }
  3802. if (here_val < 16) {
  3803. hold >>>= here_bits;
  3804. bits -= here_bits;
  3805. state.lens[state.have++] = here_val
  3806. } else {
  3807. if (here_val === 16) {
  3808. n = here_bits + 2;
  3809. while (bits < n) {
  3810. if (have === 0) {
  3811. break inf_leave
  3812. }
  3813. have--;
  3814. hold += input[next++] << bits;
  3815. bits += 8
  3816. }
  3817. hold >>>= here_bits;
  3818. bits -= here_bits;
  3819. if (state.have === 0) {
  3820. strm.msg = "invalid bit length repeat";
  3821. state.mode = BAD;
  3822. break
  3823. }
  3824. len = state.lens[state.have - 1];
  3825. copy = 3 + (hold & 3);
  3826. hold >>>= 2;
  3827. bits -= 2
  3828. } else if (here_val === 17) {
  3829. n = here_bits + 3;
  3830. while (bits < n) {
  3831. if (have === 0) {
  3832. break inf_leave
  3833. }
  3834. have--;
  3835. hold += input[next++] << bits;
  3836. bits += 8
  3837. }
  3838. hold >>>= here_bits;
  3839. bits -= here_bits;
  3840. len = 0;
  3841. copy = 3 + (hold & 7);
  3842. hold >>>= 3;
  3843. bits -= 3
  3844. } else {
  3845. n = here_bits + 7;
  3846. while (bits < n) {
  3847. if (have === 0) {
  3848. break inf_leave
  3849. }
  3850. have--;
  3851. hold += input[next++] << bits;
  3852. bits += 8
  3853. }
  3854. hold >>>= here_bits;
  3855. bits -= here_bits;
  3856. len = 0;
  3857. copy = 11 + (hold & 127);
  3858. hold >>>= 7;
  3859. bits -= 7
  3860. }
  3861. if (state.have + copy > state.nlen + state.ndist) {
  3862. strm.msg = "invalid bit length repeat";
  3863. state.mode = BAD;
  3864. break
  3865. }
  3866. while (copy--) {
  3867. state.lens[state.have++] = len
  3868. }
  3869. }
  3870. }
  3871. if (state.mode === BAD) {
  3872. break
  3873. }
  3874. if (state.lens[256] === 0) {
  3875. strm.msg = "invalid code -- missing end-of-block";
  3876. state.mode = BAD;
  3877. break
  3878. }
  3879. state.lenbits = 9;
  3880. opts = {
  3881. bits: state.lenbits
  3882. };
  3883. ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);
  3884. state.lenbits = opts.bits;
  3885. if (ret) {
  3886. strm.msg = "invalid literal/lengths set";
  3887. state.mode = BAD;
  3888. break
  3889. }
  3890. state.distbits = 6;
  3891. state.distcode = state.distdyn;
  3892. opts = {
  3893. bits: state.distbits
  3894. };
  3895. ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);
  3896. state.distbits = opts.bits;
  3897. if (ret) {
  3898. strm.msg = "invalid distances set";
  3899. state.mode = BAD;
  3900. break
  3901. }
  3902. state.mode = LEN_;
  3903. if (flush === Z_TREES) {
  3904. break inf_leave
  3905. }
  3906. case LEN_:
  3907. state.mode = LEN;
  3908. case LEN:
  3909. if (have >= 6 && left >= 258) {
  3910. strm.next_out = put;
  3911. strm.avail_out = left;
  3912. strm.next_in = next;
  3913. strm.avail_in = have;
  3914. state.hold = hold;
  3915. state.bits = bits;
  3916. inflate_fast(strm, _out);
  3917. put = strm.next_out;
  3918. output = strm.output;
  3919. left = strm.avail_out;
  3920. next = strm.next_in;
  3921. input = strm.input;
  3922. have = strm.avail_in;
  3923. hold = state.hold;
  3924. bits = state.bits;
  3925. if (state.mode === TYPE) {
  3926. state.back = -1
  3927. }
  3928. break
  3929. }
  3930. state.back = 0;
  3931. for (;;) {
  3932. here = state.lencode[hold & (1 << state.lenbits) - 1];
  3933. here_bits = here >>> 24;
  3934. here_op = here >>> 16 & 255;
  3935. here_val = here & 65535;
  3936. if (here_bits <= bits) {
  3937. break
  3938. }
  3939. if (have === 0) {
  3940. break inf_leave
  3941. }
  3942. have--;
  3943. hold += input[next++] << bits;
  3944. bits += 8
  3945. }
  3946. if (here_op && (here_op & 240) === 0) {
  3947. last_bits = here_bits;
  3948. last_op = here_op;
  3949. last_val = here_val;
  3950. for (;;) {
  3951. here = state.lencode[last_val + ((hold & (1 << last_bits + last_op) - 1) >> last_bits)];
  3952. here_bits = here >>> 24;
  3953. here_op = here >>> 16 & 255;
  3954. here_val = here & 65535;
  3955. if (last_bits + here_bits <= bits) {
  3956. break
  3957. }
  3958. if (have === 0) {
  3959. break inf_leave
  3960. }
  3961. have--;
  3962. hold += input[next++] << bits;
  3963. bits += 8
  3964. }
  3965. hold >>>= last_bits;
  3966. bits -= last_bits;
  3967. state.back += last_bits
  3968. }
  3969. hold >>>= here_bits;
  3970. bits -= here_bits;
  3971. state.back += here_bits;
  3972. state.length = here_val;
  3973. if (here_op === 0) {
  3974. state.mode = LIT;
  3975. break
  3976. }
  3977. if (here_op & 32) {
  3978. state.back = -1;
  3979. state.mode = TYPE;
  3980. break
  3981. }
  3982. if (here_op & 64) {
  3983. strm.msg = "invalid literal/length code";
  3984. state.mode = BAD;
  3985. break
  3986. }
  3987. state.extra = here_op & 15;
  3988. state.mode = LENEXT;
  3989. case LENEXT:
  3990. if (state.extra) {
  3991. n = state.extra;
  3992. while (bits < n) {
  3993. if (have === 0) {
  3994. break inf_leave
  3995. }
  3996. have--;
  3997. hold += input[next++] << bits;
  3998. bits += 8
  3999. }
  4000. state.length += hold & (1 << state.extra) - 1;
  4001. hold >>>= state.extra;
  4002. bits -= state.extra;
  4003. state.back += state.extra
  4004. }
  4005. state.was = state.length;
  4006. state.mode = DIST;
  4007. case DIST:
  4008. for (;;) {
  4009. here = state.distcode[hold & (1 << state.distbits) - 1];
  4010. here_bits = here >>> 24;
  4011. here_op = here >>> 16 & 255;
  4012. here_val = here & 65535;
  4013. if (here_bits <= bits) {
  4014. break
  4015. }
  4016. if (have === 0) {
  4017. break inf_leave
  4018. }
  4019. have--;
  4020. hold += input[next++] << bits;
  4021. bits += 8
  4022. }
  4023. if ((here_op & 240) === 0) {
  4024. last_bits = here_bits;
  4025. last_op = here_op;
  4026. last_val = here_val;
  4027. for (;;) {
  4028. here = state.distcode[last_val + ((hold & (1 << last_bits + last_op) - 1) >> last_bits)];
  4029. here_bits = here >>> 24;
  4030. here_op = here >>> 16 & 255;
  4031. here_val = here & 65535;
  4032. if (last_bits + here_bits <= bits) {
  4033. break
  4034. }
  4035. if (have === 0) {
  4036. break inf_leave
  4037. }
  4038. have--;
  4039. hold += input[next++] << bits;
  4040. bits += 8
  4041. }
  4042. hold >>>= last_bits;
  4043. bits -= last_bits;
  4044. state.back += last_bits
  4045. }
  4046. hold >>>= here_bits;
  4047. bits -= here_bits;
  4048. state.back += here_bits;
  4049. if (here_op & 64) {
  4050. strm.msg = "invalid distance code";
  4051. state.mode = BAD;
  4052. break
  4053. }
  4054. state.offset = here_val;
  4055. state.extra = here_op & 15;
  4056. state.mode = DISTEXT;
  4057. case DISTEXT:
  4058. if (state.extra) {
  4059. n = state.extra;
  4060. while (bits < n) {
  4061. if (have === 0) {
  4062. break inf_leave
  4063. }
  4064. have--;
  4065. hold += input[next++] << bits;
  4066. bits += 8
  4067. }
  4068. state.offset += hold & (1 << state.extra) - 1;
  4069. hold >>>= state.extra;
  4070. bits -= state.extra;
  4071. state.back += state.extra
  4072. }
  4073. if (state.offset > state.dmax) {
  4074. strm.msg = "invalid distance too far back";
  4075. state.mode = BAD;
  4076. break
  4077. }
  4078. state.mode = MATCH;
  4079. case MATCH:
  4080. if (left === 0) {
  4081. break inf_leave
  4082. }
  4083. copy = _out - left;
  4084. if (state.offset > copy) {
  4085. copy = state.offset - copy;
  4086. if (copy > state.whave) {
  4087. if (state.sane) {
  4088. strm.msg = "invalid distance too far back";
  4089. state.mode = BAD;
  4090. break
  4091. }
  4092. }
  4093. if (copy > state.wnext) {
  4094. copy -= state.wnext;
  4095. from = state.wsize - copy
  4096. } else {
  4097. from = state.wnext - copy
  4098. }
  4099. if (copy > state.length) {
  4100. copy = state.length
  4101. }
  4102. from_source = state.window
  4103. } else {
  4104. from_source = output;
  4105. from = put - state.offset;
  4106. copy = state.length
  4107. }
  4108. if (copy > left) {
  4109. copy = left
  4110. }
  4111. left -= copy;
  4112. state.length -= copy;
  4113. do {
  4114. output[put++] = from_source[from++]
  4115. } while (--copy);
  4116. if (state.length === 0) {
  4117. state.mode = LEN
  4118. }
  4119. break;
  4120. case LIT:
  4121. if (left === 0) {
  4122. break inf_leave
  4123. }
  4124. output[put++] = state.length;
  4125. left--;
  4126. state.mode = LEN;
  4127. break;
  4128. case CHECK:
  4129. if (state.wrap) {
  4130. while (bits < 32) {
  4131. if (have === 0) {
  4132. break inf_leave
  4133. }
  4134. have--;
  4135. hold |= input[next++] << bits;
  4136. bits += 8
  4137. }
  4138. _out -= left;
  4139. strm.total_out += _out;
  4140. state.total += _out;
  4141. if (_out) {
  4142. strm.adler = state.check = state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out)
  4143. }
  4144. _out = left;
  4145. if ((state.flags ? hold : ZSWAP32(hold)) !== state.check) {
  4146. strm.msg = "incorrect data check";
  4147. state.mode = BAD;
  4148. break
  4149. }
  4150. hold = 0;
  4151. bits = 0
  4152. }
  4153. state.mode = LENGTH;
  4154. case LENGTH:
  4155. if (state.wrap && state.flags) {
  4156. while (bits < 32) {
  4157. if (have === 0) {
  4158. break inf_leave
  4159. }
  4160. have--;
  4161. hold += input[next++] << bits;
  4162. bits += 8
  4163. }
  4164. if (hold !== (state.total & 4294967295)) {
  4165. strm.msg = "incorrect length check";
  4166. state.mode = BAD;
  4167. break
  4168. }
  4169. hold = 0;
  4170. bits = 0
  4171. }
  4172. state.mode = DONE;
  4173. case DONE:
  4174. ret = Z_STREAM_END;
  4175. break inf_leave;
  4176. case BAD:
  4177. ret = Z_DATA_ERROR;
  4178. break inf_leave;
  4179. case MEM:
  4180. return Z_MEM_ERROR;
  4181. case SYNC:
  4182. default:
  4183. return Z_STREAM_ERROR
  4184. }
  4185. }
  4186. strm.next_out = put;
  4187. strm.avail_out = left;
  4188. strm.next_in = next;
  4189. strm.avail_in = have;
  4190. state.hold = hold;
  4191. state.bits = bits;
  4192. if (state.wsize || _out !== strm.avail_out && state.mode < BAD && (state.mode < CHECK || flush !== Z_FINISH)) {
  4193. if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) {
  4194. state.mode = MEM;
  4195. return Z_MEM_ERROR
  4196. }
  4197. }
  4198. _in -= strm.avail_in;
  4199. _out -= strm.avail_out;
  4200. strm.total_in += _in;
  4201. strm.total_out += _out;
  4202. state.total += _out;
  4203. if (state.wrap && _out) {
  4204. strm.adler = state.check = state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out)
  4205. }
  4206. strm.data_type = state.bits + (state.last ? 64 : 0) + (state.mode === TYPE ? 128 : 0) + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);
  4207. if ((_in === 0 && _out === 0 || flush === Z_FINISH) && ret === Z_OK) {
  4208. ret = Z_BUF_ERROR
  4209. }
  4210. return ret
  4211. }
  4212.  
  4213. function inflateEnd(strm) {
  4214. if (!strm || !strm.state) {
  4215. return Z_STREAM_ERROR
  4216. }
  4217. var state = strm.state;
  4218. if (state.window) {
  4219. state.window = null
  4220. }
  4221. strm.state = null;
  4222. return Z_OK
  4223. }
  4224.  
  4225. function inflateGetHeader(strm, head) {
  4226. var state;
  4227. if (!strm || !strm.state) {
  4228. return Z_STREAM_ERROR
  4229. }
  4230. state = strm.state;
  4231. if ((state.wrap & 2) === 0) {
  4232. return Z_STREAM_ERROR
  4233. }
  4234. state.head = head;
  4235. head.done = false;
  4236. return Z_OK
  4237. }
  4238. exports.inflateReset = inflateReset;
  4239. exports.inflateReset2 = inflateReset2;
  4240. exports.inflateResetKeep = inflateResetKeep;
  4241. exports.inflateInit = inflateInit;
  4242. exports.inflateInit2 = inflateInit2;
  4243. exports.inflate = inflate;
  4244. exports.inflateEnd = inflateEnd;
  4245. exports.inflateGetHeader = inflateGetHeader;
  4246. exports.inflateInfo = "pako inflate (from Nodeca project)"
  4247. }, {
  4248. "../utils/common": 2,
  4249. "./adler32": 4,
  4250. "./crc32": 6,
  4251. "./inffast": 8,
  4252. "./inftrees": 10
  4253. }],
  4254. 10: [function(_dereq_, module, exports) {
  4255. "use strict";
  4256. var utils = _dereq_("../utils/common");
  4257. var MAXBITS = 15;
  4258. var ENOUGH_LENS = 852;
  4259. var ENOUGH_DISTS = 592;
  4260. var CODES = 0;
  4261. var LENS = 1;
  4262. var DISTS = 2;
  4263. var lbase = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0];
  4264. var lext = [16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78];
  4265. var dbase = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0];
  4266. var dext = [16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64];
  4267. module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) {
  4268. var bits = opts.bits;
  4269. var len = 0;
  4270. var sym = 0;
  4271. var min = 0,
  4272. max = 0;
  4273. var root = 0;
  4274. var curr = 0;
  4275. var drop = 0;
  4276. var left = 0;
  4277. var used = 0;
  4278. var huff = 0;
  4279. var incr;
  4280. var fill;
  4281. var low;
  4282. var mask;
  4283. var next;
  4284. var base = null;
  4285. var base_index = 0;
  4286. var end;
  4287. var count = new utils.Buf16(MAXBITS + 1);
  4288. var offs = new utils.Buf16(MAXBITS + 1);
  4289. var extra = null;
  4290. var extra_index = 0;
  4291. var here_bits, here_op, here_val;
  4292. for (len = 0; len <= MAXBITS; len++) {
  4293. count[len] = 0
  4294. }
  4295. for (sym = 0; sym < codes; sym++) {
  4296. count[lens[lens_index + sym]]++
  4297. }
  4298. root = bits;
  4299. for (max = MAXBITS; max >= 1; max--) {
  4300. if (count[max] !== 0) {
  4301. break
  4302. }
  4303. }
  4304. if (root > max) {
  4305. root = max
  4306. }
  4307. if (max === 0) {
  4308. table[table_index++] = 1 << 24 | 64 << 16 | 0;
  4309. table[table_index++] = 1 << 24 | 64 << 16 | 0;
  4310. opts.bits = 1;
  4311. return 0
  4312. }
  4313. for (min = 1; min < max; min++) {
  4314. if (count[min] !== 0) {
  4315. break
  4316. }
  4317. }
  4318. if (root < min) {
  4319. root = min
  4320. }
  4321. left = 1;
  4322. for (len = 1; len <= MAXBITS; len++) {
  4323. left <<= 1;
  4324. left -= count[len];
  4325. if (left < 0) {
  4326. return -1
  4327. }
  4328. }
  4329. if (left > 0 && (type === CODES || max !== 1)) {
  4330. return -1
  4331. }
  4332. offs[1] = 0;
  4333. for (len = 1; len < MAXBITS; len++) {
  4334. offs[len + 1] = offs[len] + count[len]
  4335. }
  4336. for (sym = 0; sym < codes; sym++) {
  4337. if (lens[lens_index + sym] !== 0) {
  4338. work[offs[lens[lens_index + sym]]++] = sym
  4339. }
  4340. }
  4341. if (type === CODES) {
  4342. base = extra = work;
  4343. end = 19
  4344. } else if (type === LENS) {
  4345. base = lbase;
  4346. base_index -= 257;
  4347. extra = lext;
  4348. extra_index -= 257;
  4349. end = 256
  4350. } else {
  4351. base = dbase;
  4352. extra = dext;
  4353. end = -1
  4354. }
  4355. huff = 0;
  4356. sym = 0;
  4357. len = min;
  4358. next = table_index;
  4359. curr = root;
  4360. drop = 0;
  4361. low = -1;
  4362. used = 1 << root;
  4363. mask = used - 1;
  4364. if (type === LENS && used > ENOUGH_LENS || type === DISTS && used > ENOUGH_DISTS) {
  4365. return 1
  4366. }
  4367. var i = 0;
  4368. for (;;) {
  4369. i++;
  4370. here_bits = len - drop;
  4371. if (work[sym] < end) {
  4372. here_op = 0;
  4373. here_val = work[sym]
  4374. } else if (work[sym] > end) {
  4375. here_op = extra[extra_index + work[sym]];
  4376. here_val = base[base_index + work[sym]]
  4377. } else {
  4378. here_op = 32 + 64;
  4379. here_val = 0
  4380. }
  4381. incr = 1 << len - drop;
  4382. fill = 1 << curr;
  4383. min = fill;
  4384. do {
  4385. fill -= incr;
  4386. table[next + (huff >> drop) + fill] = here_bits << 24 | here_op << 16 | here_val | 0
  4387. } while (fill !== 0);
  4388. incr = 1 << len - 1;
  4389. while (huff & incr) {
  4390. incr >>= 1
  4391. }
  4392. if (incr !== 0) {
  4393. huff &= incr - 1;
  4394. huff += incr
  4395. } else {
  4396. huff = 0
  4397. }
  4398. sym++;
  4399. if (--count[len] === 0) {
  4400. if (len === max) {
  4401. break
  4402. }
  4403. len = lens[lens_index + work[sym]]
  4404. }
  4405. if (len > root && (huff & mask) !== low) {
  4406. if (drop === 0) {
  4407. drop = root
  4408. }
  4409. next += min;
  4410. curr = len - drop;
  4411. left = 1 << curr;
  4412. while (curr + drop < max) {
  4413. left -= count[curr + drop];
  4414. if (left <= 0) {
  4415. break
  4416. }
  4417. curr++;
  4418. left <<= 1
  4419. }
  4420. used += 1 << curr;
  4421. if (type === LENS && used > ENOUGH_LENS || type === DISTS && used > ENOUGH_DISTS) {
  4422. return 1
  4423. }
  4424. low = huff & mask;
  4425. table[low] = root << 24 | curr << 16 | next - table_index | 0
  4426. }
  4427. }
  4428. if (huff !== 0) {
  4429. table[next + huff] = len - drop << 24 | 64 << 16 | 0
  4430. }
  4431. opts.bits = root;
  4432. return 0
  4433. }
  4434. }, {
  4435. "../utils/common": 2
  4436. }],
  4437. 11: [function(_dereq_, module, exports) {
  4438. "use strict";
  4439. module.exports = {
  4440. 2: "need dictionary",
  4441. 1: "stream end",
  4442. 0: "",
  4443. "-1": "file error",
  4444. "-2": "stream error",
  4445. "-3": "data error",
  4446. "-4": "insufficient memory",
  4447. "-5": "buffer error",
  4448. "-6": "incompatible version"
  4449. }
  4450. }, {}],
  4451. 12: [function(_dereq_, module, exports) {
  4452. "use strict";
  4453.  
  4454. function ZStream() {
  4455. this.input = null;
  4456. this.next_in = 0;
  4457. this.avail_in = 0;
  4458. this.total_in = 0;
  4459. this.output = null;
  4460. this.next_out = 0;
  4461. this.avail_out = 0;
  4462. this.total_out = 0;
  4463. this.msg = "";
  4464. this.state = null;
  4465. this.data_type = 2;
  4466. this.adler = 0
  4467. }
  4468. module.exports = ZStream
  4469. }, {}]
  4470. }, {}, [1])(1)
  4471. });
  4472. var swfobject = function() {
  4473. var D = "undefined",
  4474. r = "object",
  4475. T = "Shockwave Flash",
  4476. Z = "ShockwaveFlash.ShockwaveFlash",
  4477. q = "application/x-shockwave-flash",
  4478. S = "SWFObjectExprInst",
  4479. x = "onreadystatechange",
  4480. Q = window,
  4481. h = document,
  4482. t = navigator,
  4483. V = false,
  4484. X = [],
  4485. o = [],
  4486. P = [],
  4487. K = [],
  4488. I, p, E, B, L = false,
  4489. a = false,
  4490. m, G, j = true,
  4491. l = false,
  4492. O = function() {
  4493. var ad = typeof h.getElementById != D && typeof h.getElementsByTagName != D && typeof h.createElement != D,
  4494. ak = t.userAgent.toLowerCase(),
  4495. ab = t.platform.toLowerCase(),
  4496. ah = ab ? /win/.test(ab) : /win/.test(ak),
  4497. af = ab ? /mac/.test(ab) : /mac/.test(ak),
  4498. ai = /webkit/.test(ak) ? parseFloat(ak.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false,
  4499. aa = t.appName === "Microsoft Internet Explorer",
  4500. aj = [0, 0, 0],
  4501. ae = null;
  4502. if (typeof t.plugins != D && typeof t.plugins[T] == r) {
  4503. ae = t.plugins[T].description;
  4504. if (ae && (typeof t.mimeTypes != D && t.mimeTypes[q] && t.mimeTypes[q].enabledPlugin)) {
  4505. V = true;
  4506. aa = false;
  4507. ae = ae.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
  4508. aj[0] = n(ae.replace(/^(.*)\..*$/, "$1"));
  4509. aj[1] = n(ae.replace(/^.*\.(.*)\s.*$/, "$1"));
  4510. aj[2] = /[a-zA-Z]/.test(ae) ? n(ae.replace(/^.*[a-zA-Z]+(.*)$/, "$1")) : 0
  4511. }
  4512. } else {
  4513. if (typeof Q.ActiveXObject != D) {
  4514. try {
  4515. var ag = new ActiveXObject(Z);
  4516. if (ag) {
  4517. ae = ag.GetVariable("$version");
  4518. if (ae) {
  4519. aa = true;
  4520. ae = ae.split(" ")[1].split(",");
  4521. aj = [n(ae[0]), n(ae[1]), n(ae[2])]
  4522. }
  4523. }
  4524. } catch (ac) {}
  4525. }
  4526. }
  4527. return {
  4528. w3: ad,
  4529. pv: aj,
  4530. wk: ai,
  4531. ie: aa,
  4532. win: ah,
  4533. mac: af
  4534. }
  4535. }(),
  4536. i = function() {
  4537. if (!O.w3) {
  4538. return
  4539. }
  4540. if (typeof h.readyState != D && (h.readyState === "complete" || h.readyState === "interactive") || typeof h.readyState == D && (h.getElementsByTagName("body")[0] || h.body)) {
  4541. f()
  4542. }
  4543. if (!L) {
  4544. if (typeof h.addEventListener != D) {
  4545. h.addEventListener("DOMContentLoaded", f, false)
  4546. }
  4547. if (O.ie) {
  4548. h.attachEvent(x, function aa() {
  4549. if (h.readyState == "complete") {
  4550. h.detachEvent(x, aa);
  4551. f()
  4552. }
  4553. });
  4554. if (Q == top) {
  4555. (function ac() {
  4556. if (L) {
  4557. return
  4558. }
  4559. try {
  4560. h.documentElement.doScroll("left")
  4561. } catch (ad) {
  4562. setTimeout(ac, 0);
  4563. return
  4564. }
  4565. f()
  4566. })()
  4567. }
  4568. }
  4569. if (O.wk) {
  4570. (function ab() {
  4571. if (L) {
  4572. return
  4573. }
  4574. if (!/loaded|complete/.test(h.readyState)) {
  4575. setTimeout(ab, 0);
  4576. return
  4577. }
  4578. f()
  4579. })()
  4580. }
  4581. }
  4582. }();
  4583.  
  4584. function f() {
  4585. if (L || !document.getElementsByTagName("body")[0]) {
  4586. return
  4587. }
  4588. try {
  4589. var ac, ad = C("span");
  4590. ad.style.display = "none";
  4591. ac = h.getElementsByTagName("body")[0].appendChild(ad);
  4592. ac.parentNode.removeChild(ac);
  4593. ac = null;
  4594. ad = null
  4595. } catch (ae) {
  4596. return
  4597. }
  4598. L = true;
  4599. var aa = X.length;
  4600. for (var ab = 0; ab < aa; ab++) {
  4601. X[ab]()
  4602. }
  4603. }
  4604.  
  4605. function M(aa) {
  4606. if (L) {
  4607. aa()
  4608. } else {
  4609. X[X.length] = aa
  4610. }
  4611. }
  4612.  
  4613. function s(ab) {
  4614. if (typeof Q.addEventListener != D) {
  4615. Q.addEventListener("load", ab, false)
  4616. } else {
  4617. if (typeof h.addEventListener != D) {
  4618. h.addEventListener("load", ab, false)
  4619. } else {
  4620. if (typeof Q.attachEvent != D) {
  4621. g(Q, "onload", ab)
  4622. } else {
  4623. if (typeof Q.onload == "function") {
  4624. var aa = Q.onload;
  4625. Q.onload = function() {
  4626. aa();
  4627. ab()
  4628. }
  4629. } else {
  4630. Q.onload = ab
  4631. }
  4632. }
  4633. }
  4634. }
  4635. }
  4636.  
  4637. function Y() {
  4638. var aa = h.getElementsByTagName("body")[0];
  4639. var ae = C(r);
  4640. ae.setAttribute("style", "visibility: hidden;");
  4641. ae.setAttribute("type", q);
  4642. var ad = aa.appendChild(ae);
  4643. if (ad) {
  4644. var ac = 0;
  4645. (function ab() {
  4646. if (typeof ad.GetVariable != D) {
  4647. try {
  4648. var ag = ad.GetVariable("$version");
  4649. if (ag) {
  4650. ag = ag.split(" ")[1].split(",");
  4651. O.pv = [n(ag[0]), n(ag[1]), n(ag[2])]
  4652. }
  4653. } catch (af) {
  4654. O.pv = [8, 0, 0]
  4655. }
  4656. } else {
  4657. if (ac < 10) {
  4658. ac++;
  4659. setTimeout(ab, 10);
  4660. return
  4661. }
  4662. }
  4663. aa.removeChild(ae);
  4664. ad = null;
  4665. H()
  4666. })()
  4667. } else {
  4668. H()
  4669. }
  4670. }
  4671.  
  4672. function H() {
  4673. var aj = o.length;
  4674. if (aj > 0) {
  4675. for (var ai = 0; ai < aj; ai++) {
  4676. var ab = o[ai].id;
  4677. var ae = o[ai].callbackFn;
  4678. var ad = {
  4679. success: false,
  4680. id: ab
  4681. };
  4682. if (O.pv[0] > 0) {
  4683. var ah = c(ab);
  4684. if (ah) {
  4685. if (F(o[ai].swfVersion) && !(O.wk && O.wk < 312)) {
  4686. w(ab, true);
  4687. if (ae) {
  4688. ad.success = true;
  4689. ad.ref = z(ab);
  4690. ad.id = ab;
  4691. ae(ad)
  4692. }
  4693. } else {
  4694. if (o[ai].expressInstall && A()) {
  4695. var al = {};
  4696. al.data = o[ai].expressInstall;
  4697. al.width = ah.getAttribute("width") || "0";
  4698. al.height = ah.getAttribute("height") || "0";
  4699. if (ah.getAttribute("class")) {
  4700. al.styleclass = ah.getAttribute("class")
  4701. }
  4702. if (ah.getAttribute("align")) {
  4703. al.align = ah.getAttribute("align")
  4704. }
  4705. var ak = {};
  4706. var aa = ah.getElementsByTagName("param");
  4707. var af = aa.length;
  4708. for (var ag = 0; ag < af; ag++) {
  4709. if (aa[ag].getAttribute("name").toLowerCase() != "movie") {
  4710. ak[aa[ag].getAttribute("name")] = aa[ag].getAttribute("value")
  4711. }
  4712. }
  4713. R(al, ak, ab, ae)
  4714. } else {
  4715. b(ah);
  4716. if (ae) {
  4717. ae(ad)
  4718. }
  4719. }
  4720. }
  4721. }
  4722. } else {
  4723. w(ab, true);
  4724. if (ae) {
  4725. var ac = z(ab);
  4726. if (ac && typeof ac.SetVariable != D) {
  4727. ad.success = true;
  4728. ad.ref = ac;
  4729. ad.id = ac.id
  4730. }
  4731. ae(ad)
  4732. }
  4733. }
  4734. }
  4735. }
  4736. }
  4737. X[0] = function() {
  4738. if (V) {
  4739. Y()
  4740. } else {
  4741. H()
  4742. }
  4743. };
  4744.  
  4745. function z(ac) {
  4746. var aa = null,
  4747. ab = c(ac);
  4748. if (ab && ab.nodeName.toUpperCase() === "OBJECT") {
  4749. if (typeof ab.SetVariable !== D) {
  4750. aa = ab
  4751. } else {
  4752. aa = ab.getElementsByTagName(r)[0] || ab
  4753. }
  4754. }
  4755. return aa
  4756. }
  4757.  
  4758. function A() {
  4759. return !a && F("6.0.65") && (O.win || O.mac) && !(O.wk && O.wk < 312)
  4760. }
  4761.  
  4762. function R(ad, ae, aa, ac) {
  4763. var ah = c(aa);
  4764. aa = W(aa);
  4765. a = true;
  4766. E = ac || null;
  4767. B = {
  4768. success: false,
  4769. id: aa
  4770. };
  4771. if (ah) {
  4772. if (ah.nodeName.toUpperCase() == "OBJECT") {
  4773. I = J(ah);
  4774. p = null
  4775. } else {
  4776. I = ah;
  4777. p = aa
  4778. }
  4779. ad.id = S;
  4780. if (typeof ad.width == D || !/%$/.test(ad.width) && n(ad.width) < 310) {
  4781. ad.width = "310"
  4782. }
  4783. if (typeof ad.height == D || !/%$/.test(ad.height) && n(ad.height) < 137) {
  4784. ad.height = "137"
  4785. }
  4786. var ag = O.ie ? "ActiveX" : "PlugIn",
  4787. af = "MMredirectURL=" + encodeURIComponent(Q.location.toString().replace(/&/g, "%26")) + "&MMplayerType=" + ag + "&MMdoctitle=" + encodeURIComponent(h.title.slice(0, 47) + " - Flash Player Installation");
  4788. if (typeof ae.flashvars != D) {
  4789. ae.flashvars += "&" + af
  4790. } else {
  4791. ae.flashvars = af
  4792. }
  4793. if (O.ie && ah.readyState != 4) {
  4794. var ab = C("div");
  4795. aa += "SWFObjectNew";
  4796. ab.setAttribute("id", aa);
  4797. ah.parentNode.insertBefore(ab, ah);
  4798. ah.style.display = "none";
  4799. y(ah)
  4800. }
  4801. u(ad, ae, aa)
  4802. }
  4803. }
  4804.  
  4805. function b(ab) {
  4806. if (O.ie && ab.readyState != 4) {
  4807. ab.style.display = "none";
  4808. var aa = C("div");
  4809. ab.parentNode.insertBefore(aa, ab);
  4810. aa.parentNode.replaceChild(J(ab), aa);
  4811. y(ab)
  4812. } else {
  4813. ab.parentNode.replaceChild(J(ab), ab)
  4814. }
  4815. }
  4816.  
  4817. function J(af) {
  4818. var ae = C("div");
  4819. if (O.win && O.ie) {
  4820. ae.innerHTML = af.innerHTML
  4821. } else {
  4822. var ab = af.getElementsByTagName(r)[0];
  4823. if (ab) {
  4824. var ag = ab.childNodes;
  4825. if (ag) {
  4826. var aa = ag.length;
  4827. for (var ad = 0; ad < aa; ad++) {
  4828. if (!(ag[ad].nodeType == 1 && ag[ad].nodeName == "PARAM") && !(ag[ad].nodeType == 8)) {
  4829. ae.appendChild(ag[ad].cloneNode(true))
  4830. }
  4831. }
  4832. }
  4833. }
  4834. }
  4835. return ae
  4836. }
  4837.  
  4838. function k(aa, ab) {
  4839. var ac = C("div");
  4840. ac.innerHTML = "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'><param name='movie' value='" + aa + "'>" + ab + "</object>";
  4841. return ac.firstChild
  4842. }
  4843.  
  4844. function u(ai, ag, ab) {
  4845. var aa, ad = c(ab);
  4846. ab = W(ab);
  4847. if (O.wk && O.wk < 312) {
  4848. return aa
  4849. }
  4850. if (ad) {
  4851. var ac = O.ie ? C("div") : C(r),
  4852. af, ah, ae;
  4853. if (typeof ai.id == D) {
  4854. ai.id = ab
  4855. }
  4856. for (ae in ag) {
  4857. if (ag.hasOwnProperty(ae) && ae.toLowerCase() !== "movie") {
  4858. e(ac, ae, ag[ae])
  4859. }
  4860. }
  4861. if (O.ie) {
  4862. ac = k(ai.data, ac.innerHTML)
  4863. }
  4864. for (af in ai) {
  4865. if (ai.hasOwnProperty(af)) {
  4866. ah = af.toLowerCase();
  4867. if (ah === "styleclass") {
  4868. ac.setAttribute("class", ai[af])
  4869. } else {
  4870. if (ah !== "classid" && ah !== "data") {
  4871. ac.setAttribute(af, ai[af])
  4872. }
  4873. }
  4874. }
  4875. }
  4876. if (O.ie) {
  4877. P[P.length] = ai.id
  4878. } else {
  4879. ac.setAttribute("type", q);
  4880. ac.setAttribute("data", ai.data)
  4881. }
  4882. ad.parentNode.replaceChild(ac, ad);
  4883. aa = ac
  4884. }
  4885. return aa
  4886. }
  4887.  
  4888. function e(ac, aa, ab) {
  4889. var ad = C("param");
  4890. ad.setAttribute("name", aa);
  4891. ad.setAttribute("value", ab);
  4892. ac.appendChild(ad)
  4893. }
  4894.  
  4895. function y(ac) {
  4896. var ab = c(ac);
  4897. if (ab && ab.nodeName.toUpperCase() == "OBJECT") {
  4898. if (O.ie) {
  4899. ab.style.display = "none";
  4900. (function aa() {
  4901. if (ab.readyState == 4) {
  4902. for (var ad in ab) {
  4903. if (typeof ab[ad] == "function") {
  4904. ab[ad] = null
  4905. }
  4906. }
  4907. ab.parentNode.removeChild(ab)
  4908. } else {
  4909. setTimeout(aa, 10)
  4910. }
  4911. })()
  4912. } else {
  4913. ab.parentNode.removeChild(ab)
  4914. }
  4915. }
  4916. }
  4917.  
  4918. function U(aa) {
  4919. return aa && aa.nodeType && aa.nodeType === 1
  4920. }
  4921.  
  4922. function W(aa) {
  4923. return U(aa) ? aa.id : aa
  4924. }
  4925.  
  4926. function c(ac) {
  4927. if (U(ac)) {
  4928. return ac
  4929. }
  4930. var aa = null;
  4931. try {
  4932. aa = h.getElementById(ac)
  4933. } catch (ab) {}
  4934. return aa
  4935. }
  4936.  
  4937. function C(aa) {
  4938. return h.createElement(aa)
  4939. }
  4940.  
  4941. function n(aa) {
  4942. return parseInt(aa, 10)
  4943. }
  4944.  
  4945. function g(ac, aa, ab) {
  4946. ac.attachEvent(aa, ab);
  4947. K[K.length] = [ac, aa, ab]
  4948. }
  4949.  
  4950. function F(ac) {
  4951. ac += "";
  4952. var ab = O.pv,
  4953. aa = ac.split(".");
  4954. aa[0] = n(aa[0]);
  4955. aa[1] = n(aa[1]) || 0;
  4956. aa[2] = n(aa[2]) || 0;
  4957. return ab[0] > aa[0] || ab[0] == aa[0] && ab[1] > aa[1] || ab[0] == aa[0] && ab[1] == aa[1] && ab[2] >= aa[2] ? true : false
  4958. }
  4959.  
  4960. function v(af, ab, ag, ae) {
  4961. var ad = h.getElementsByTagName("head")[0];
  4962. if (!ad) {
  4963. return
  4964. }
  4965. var aa = typeof ag == "string" ? ag : "screen";
  4966. if (ae) {
  4967. m = null;
  4968. G = null
  4969. }
  4970. if (!m || G != aa) {
  4971. var ac = C("style");
  4972. ac.setAttribute("type", "text/css");
  4973. ac.setAttribute("media", aa);
  4974. m = ad.appendChild(ac);
  4975. if (O.ie && typeof h.styleSheets != D && h.styleSheets.length > 0) {
  4976. m = h.styleSheets[h.styleSheets.length - 1]
  4977. }
  4978. G = aa
  4979. }
  4980. if (m) {
  4981. if (typeof m.addRule != D) {
  4982. m.addRule(af, ab)
  4983. } else {
  4984. if (typeof h.createTextNode != D) {
  4985. m.appendChild(h.createTextNode(af + " {" + ab + "}"))
  4986. }
  4987. }
  4988. }
  4989. }
  4990.  
  4991. function w(ad, aa) {
  4992. if (!j) {
  4993. return
  4994. }
  4995. var ab = aa ? "visible" : "hidden",
  4996. ac = c(ad);
  4997. if (L && ac) {
  4998. ac.style.visibility = ab
  4999. } else {
  5000. if (typeof ad === "string") {
  5001. v("#" + ad, "visibility:" + ab)
  5002. }
  5003. }
  5004. }
  5005.  
  5006. function N(ab) {
  5007. var ac = /[\\\"<>\.;]/;
  5008. var aa = ac.exec(ab) != null;
  5009. return aa && typeof encodeURIComponent != D ? encodeURIComponent(ab) : ab
  5010. }
  5011. var d = function() {
  5012. if (O.ie) {
  5013. window.attachEvent("onunload", function() {
  5014. var af = K.length;
  5015. for (var ae = 0; ae < af; ae++) {
  5016. K[ae][0].detachEvent(K[ae][1], K[ae][2])
  5017. }
  5018. var ac = P.length;
  5019. for (var ad = 0; ad < ac; ad++) {
  5020. y(P[ad])
  5021. }
  5022. for (var ab in O) {
  5023. O[ab] = null
  5024. }
  5025. O = null;
  5026. for (var aa in swfobject) {
  5027. swfobject[aa] = null
  5028. }
  5029. swfobject = null
  5030. })
  5031. }
  5032. }();
  5033. return {
  5034. registerObject: function(ae, aa, ad, ac) {
  5035. if (O.w3 && ae && aa) {
  5036. var ab = {};
  5037. ab.id = ae;
  5038. ab.swfVersion = aa;
  5039. ab.expressInstall = ad;
  5040. ab.callbackFn = ac;
  5041. o[o.length] = ab;
  5042. w(ae, false)
  5043. } else {
  5044. if (ac) {
  5045. ac({
  5046. success: false,
  5047. id: ae
  5048. })
  5049. }
  5050. }
  5051. },
  5052. getObjectById: function(aa) {
  5053. if (O.w3) {
  5054. return z(aa)
  5055. }
  5056. },
  5057. embedSWF: function(af, al, ai, ak, ab, ae, ad, ah, aj, ag) {
  5058. var ac = W(al),
  5059. aa = {
  5060. success: false,
  5061. id: ac
  5062. };
  5063. if (O.w3 && !(O.wk && O.wk < 312) && af && al && ai && ak && ab) {
  5064. w(ac, false);
  5065. M(function() {
  5066. ai += "";
  5067. ak += "";
  5068. var an = {};
  5069. if (aj && typeof aj === r) {
  5070. for (var aq in aj) {
  5071. an[aq] = aj[aq]
  5072. }
  5073. }
  5074. an.data = af;
  5075. an.width = ai;
  5076. an.height = ak;
  5077. var ar = {};
  5078. if (ah && typeof ah === r) {
  5079. for (var ao in ah) {
  5080. ar[ao] = ah[ao]
  5081. }
  5082. }
  5083. if (ad && typeof ad === r) {
  5084. for (var am in ad) {
  5085. if (ad.hasOwnProperty(am)) {
  5086. var ap = l ? encodeURIComponent(am) : am,
  5087. at = l ? encodeURIComponent(ad[am]) : ad[am];
  5088. if (typeof ar.flashvars != D) {
  5089. ar.flashvars += "&" + ap + "=" + at
  5090. } else {
  5091. ar.flashvars = ap + "=" + at
  5092. }
  5093. }
  5094. }
  5095. }
  5096. if (F(ab)) {
  5097. var au = u(an, ar, al);
  5098. if (an.id == ac) {
  5099. w(ac, true)
  5100. }
  5101. aa.success = true;
  5102. aa.ref = au;
  5103. aa.id = au.id
  5104. } else {
  5105. if (ae && A()) {
  5106. an.data = ae;
  5107. R(an, ar, al, ag);
  5108. return
  5109. } else {
  5110. w(ac, true)
  5111. }
  5112. }
  5113. if (ag) {
  5114. ag(aa)
  5115. }
  5116. })
  5117. } else {
  5118. if (ag) {
  5119. ag(aa)
  5120. }
  5121. }
  5122. },
  5123. switchOffAutoHideShow: function() {
  5124. j = false
  5125. },
  5126. enableUriEncoding: function(aa) {
  5127. l = typeof aa === D ? true : aa
  5128. },
  5129. ua: O,
  5130. getFlashPlayerVersion: function() {
  5131. return {
  5132. major: O.pv[0],
  5133. minor: O.pv[1],
  5134. release: O.pv[2]
  5135. }
  5136. },
  5137. hasFlashPlayerVersion: F,
  5138. createSWF: function(ac, ab, aa) {
  5139. if (O.w3) {
  5140. return u(ac, ab, aa)
  5141. } else {
  5142. return undefined
  5143. }
  5144. },
  5145. showExpressInstall: function(ac, ad, aa, ab) {
  5146. if (O.w3 && A()) {
  5147. R(ac, ad, aa, ab)
  5148. }
  5149. },
  5150. removeSWF: function(aa) {
  5151. if (O.w3) {
  5152. y(aa)
  5153. }
  5154. },
  5155. createCSS: function(ad, ac, ab, aa) {
  5156. if (O.w3) {
  5157. v(ad, ac, ab, aa)
  5158. }
  5159. },
  5160. addDomLoadEvent: M,
  5161. addLoadEvent: s,
  5162. getQueryParamValue: function(ad) {
  5163. var ac = h.location.search || h.location.hash;
  5164. if (ac) {
  5165. if (/\?/.test(ac)) {
  5166. ac = ac.split("?")[1]
  5167. }
  5168. if (ad == null) {
  5169. return N(ac)
  5170. }
  5171. var ab = ac.split("&");
  5172. for (var aa = 0; aa < ab.length; aa++) {
  5173. if (ab[aa].substring(0, ab[aa].indexOf("=")) == ad) {
  5174. return N(ab[aa].substring(ab[aa].indexOf("=") + 1))
  5175. }
  5176. }
  5177. }
  5178. return ""
  5179. },
  5180. expressInstallCallback: function() {
  5181. if (a) {
  5182. var aa = c(S);
  5183. if (aa && I) {
  5184. aa.parentNode.replaceChild(I, aa);
  5185. if (p) {
  5186. w(p, true);
  5187. if (O.ie) {
  5188. I.style.display = "block"
  5189. }
  5190. }
  5191. if (E) {
  5192. E(B)
  5193. }
  5194. }
  5195. a = false
  5196. }
  5197. },
  5198. version: "2.3"
  5199. }
  5200. }();
  5201. mat4.translation = function(out, vec) {
  5202. mat4.identity(out);
  5203. out[12] = vec[0];
  5204. out[13] = vec[1];
  5205. out[14] = vec[2];
  5206. return out
  5207. };
  5208. mat4.rotationQuat = function(out, q) {
  5209. mat4.identity(out);
  5210. var xx = q[0] * q[0],
  5211. yy = q[1] * q[1],
  5212. zz = q[2] * q[2],
  5213. xy = q[0] * q[1],
  5214. zw = q[2] * q[3],
  5215. zx = q[2] * q[0],
  5216. yw = q[1] * q[3],
  5217. yz = q[1] * q[2],
  5218. xw = q[0] * q[3];
  5219. out[0] = 1 - 2 * (yy + zz);
  5220. out[1] = 2 * (xy + zw);
  5221. out[2] = 2 * (zx - yw);
  5222. out[4] = 2 * (xy - zw);
  5223. out[5] = 1 - 2 * (zz + xx);
  5224. out[6] = 2 * (yz + xw);
  5225. out[8] = 2 * (zx + yw);
  5226. out[9] = 2 * (yz - xw);
  5227. out[10] = 1 - 2 * (yy + xx);
  5228. return out
  5229. };
  5230. mat4.mulSlimDX = function(out, l, r) {
  5231. var left = {
  5232. M11: l[0],
  5233. M12: l[1],
  5234. M13: l[2],
  5235. M14: l[3],
  5236. M21: l[4],
  5237. M22: l[5],
  5238. M23: l[6],
  5239. M24: l[7],
  5240. M31: l[8],
  5241. M32: l[9],
  5242. M33: l[10],
  5243. M34: l[11],
  5244. M41: l[12],
  5245. M42: l[13],
  5246. M43: l[14],
  5247. M44: l[15]
  5248. };
  5249. var right = {
  5250. M11: r[0],
  5251. M12: r[1],
  5252. M13: r[2],
  5253. M14: r[3],
  5254. M21: r[4],
  5255. M22: r[5],
  5256. M23: r[6],
  5257. M24: r[7],
  5258. M31: r[8],
  5259. M32: r[9],
  5260. M33: r[10],
  5261. M34: r[11],
  5262. M41: r[12],
  5263. M42: r[13],
  5264. M43: r[14],
  5265. M44: r[15]
  5266. };
  5267. out[0] = left.M11 * right.M11 + left.M12 * right.M21 + left.M13 * right.M31 + left.M14 * right.M41;
  5268. out[1] = left.M11 * right.M12 + left.M12 * right.M22 + left.M13 * right.M32 + left.M14 * right.M42;
  5269. out[2] = left.M11 * right.M13 + left.M12 * right.M23 + left.M13 * right.M33 + left.M14 * right.M43;
  5270. out[3] = left.M11 * right.M14 + left.M12 * right.M24 + left.M13 * right.M34 + left.M14 * right.M44;
  5271. out[4] = left.M21 * right.M11 + left.M22 * right.M21 + left.M23 * right.M31 + left.M24 * right.M41;
  5272. out[5] = left.M21 * right.M12 + left.M22 * right.M22 + left.M23 * right.M32 + left.M24 * right.M42;
  5273. out[6] = left.M21 * right.M13 + left.M22 * right.M23 + left.M23 * right.M33 + left.M24 * right.M43;
  5274. out[7] = left.M21 * right.M14 + left.M22 * right.M24 + left.M23 * right.M34 + left.M24 * right.M44;
  5275. out[8] = left.M31 * right.M11 + left.M32 * right.M21 + left.M33 * right.M31 + left.M34 * right.M41;
  5276. out[9] = left.M31 * right.M12 + left.M32 * right.M22 + left.M33 * right.M32 + left.M34 * right.M42;
  5277. out[10] = left.M31 * right.M13 + left.M32 * right.M23 + left.M33 * right.M33 + left.M34 * right.M43;
  5278. out[11] = left.M31 * right.M14 + left.M32 * right.M24 + left.M33 * right.M34 + left.M34 * right.M44;
  5279. out[12] = left.M41 * right.M11 + left.M42 * right.M21 + left.M43 * right.M31 + left.M44 * right.M41;
  5280. out[13] = left.M41 * right.M12 + left.M42 * right.M22 + left.M43 * right.M32 + left.M44 * right.M42;
  5281. out[14] = left.M41 * right.M13 + left.M42 * right.M23 + left.M43 * right.M33 + left.M44 * right.M43;
  5282. out[15] = left.M41 * right.M14 + left.M42 * right.M24 + left.M43 * right.M34 + left.M44 * right.M44;
  5283. return out
  5284. };
  5285. mat4.transformVec3 = function(out, v, m) {
  5286. out[0] = v[0] * m[0] + v[1] * m[4] + v[2] * m[8] + m[12];
  5287. out[1] = v[0] * m[1] + v[1] * m[5] + v[2] * m[9] + m[13];
  5288. out[2] = v[0] * m[2] + v[1] * m[6] + v[2] * m[10] + m[14];
  5289. return out
  5290. };
  5291. mat4.transformVec4 = function(out, v, m) {
  5292. out[0] = v[0] * m[0] + v[1] * m[4] + v[2] * m[8] + v[3] * m[12];
  5293. out[1] = v[0] * m[1] + v[1] * m[5] + v[2] * m[9] + v[3] * m[13];
  5294. out[2] = v[0] * m[2] + v[1] * m[6] + v[2] * m[10] + v[3] * m[14];
  5295. out[3] = v[0] * m[3] + v[1] * m[7] + v[2] * m[11] + v[3] * m[15];
  5296. return out
  5297. };
  5298. mat4.extractEulerAngles = function(out, m) {
  5299. out[0] = Math.atan2(m[6], m[10]);
  5300. var c2 = Math.sqrt(m[0] * m[0] + m[1] * m[1]);
  5301. out[1] = Math.atan2(-m[2], c2);
  5302. var s1 = Math.sin(out[0]),
  5303. c1 = Math.cos(out[0]);
  5304. out[2] = Math.atan2(s1 * m[8] - c1 * m[4], c1 * m[5] - s1 * m[9]);
  5305. return out
  5306. };
  5307. mat4.invert2 = function(out, m) {
  5308. var det = m[0] * (m[5] * m[10] - m[6] * m[9]) + m[4] * (m[2] * m[9] - m[1] * m[10]) + m[8] * (m[1] * m[6] - m[2] * m[5]);
  5309. if (det == 0) return null;
  5310. var invDet = 1 / det;
  5311. out[0] = (m[5] * m[10] - m[6] * m[9]) * invDet;
  5312. out[1] = (m[9] * m[2] - m[10] * m[1]) * invDet;
  5313. out[2] = (m[1] * m[6] - m[2] * m[5]) * invDet;
  5314. out[4] = (m[6] * m[8] - m[4] * m[10]) * invDet;
  5315. out[5] = (m[10] * m[0] - m[8] * m[2]) * invDet;
  5316. out[6] = (m[2] * m[4] - m[0] * m[6]) * invDet;
  5317. out[8] = (m[4] * m[9] - m[5] * m[8]) * invDet;
  5318. out[9] = (m[8] * m[1] - m[9] * m[0]) * invDet;
  5319. out[10] = (m[0] * m[5] - m[1] * m[4]) * invDet;
  5320. out[3] = out[0] * -m[3] + out[1] * -m[7] + out[2] * -m[11];
  5321. out[7] = out[4] * -m[3] + out[5] * -m[7] + out[6] * -m[11];
  5322. out[11] = out[8] * -m[3] + out[9] * -m[7] + out[10] * -m[11];
  5323. out[12] = out[13] = out[14] = 0;
  5324. out[15] = 1;
  5325. return out
  5326. };
  5327. window.requestAnimFrame = function() {
  5328. return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback, element) {
  5329. window.setTimeout(callback, 1e3 / 60)
  5330. }
  5331. }();
  5332. jQuery.support.cors = true;
  5333. if ($.ajaxTransport) {
  5334. $.ajaxSetup({
  5335. flatOptions: {
  5336. renderer: true
  5337. }
  5338. });
  5339. $.ajaxTransport("+binary", function(options, originalOptions, jqXHR) {
  5340. if (window.FormData && (options.dataType && options.dataType == "binary" || options.data && (window.ArrayBuffer && options.data instanceof ArrayBuffer || window.Blob && options.data instanceof Blob))) {
  5341. return {
  5342. send: function(_, callback) {
  5343. var xhr = new XMLHttpRequest,
  5344. url = options.url,
  5345. type = options.type,
  5346. dataType = options.responseType || "blob",
  5347. data = options.data || null;
  5348. if (options.renderer) {
  5349. xhr.addEventListener("progress", function(event) {
  5350. if (event.lengthComputable) {
  5351. if (!options.renderer.downloads[this.responseURL]) {
  5352. options.renderer.downloads[this.responseURL] = {
  5353. loaded: event.loaded,
  5354. total: event.total
  5355. }
  5356. } else {
  5357. options.renderer.downloads[this.responseURL].loaded = event.loaded
  5358. }
  5359. options.renderer.updateProgress()
  5360. }
  5361. })
  5362. }
  5363. xhr.addEventListener("load", function() {
  5364. if (options.renderer) {
  5365. delete options.renderer.downloads[this.responseURL];
  5366. options.renderer.updateProgress()
  5367. }
  5368. var data = {};
  5369. data[options.dataType] = xhr.response;
  5370. callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders())
  5371. });
  5372. xhr.open(type, url, true);
  5373. xhr.responseType = dataType;
  5374. xhr.send(data)
  5375. },
  5376. abort: function() {
  5377. jqXHR.abort()
  5378. }
  5379. }
  5380. }
  5381. })
  5382. } else {
  5383. (function() {
  5384. var httpData = $.httpData;
  5385. $.httpData = function(xhr, type, s) {
  5386. if (type == "binary") {
  5387. return xhr.response
  5388. } else {
  5389. return httpData(xhr, type, s)
  5390. }
  5391. }
  5392. })();
  5393. $.ajaxSetup({
  5394. beforeSend: function(xhr, options) {
  5395. if (options.dataType == "binary") {
  5396. xhr.responseType = options.responseType || "arraybuffer";
  5397. xhr.addEventListener("progress", function(event) {
  5398. if (!options.renderer) return;
  5399. if (event.lengthComputable) {
  5400. if (!options.renderer.downloads[this.responseURL]) {
  5401. options.renderer.downloads[this.responseURL] = {
  5402. loaded: event.loaded,
  5403. total: event.total
  5404. }
  5405. } else {
  5406. options.renderer.downloads[this.responseURL].loaded = event.loaded
  5407. }
  5408. options.renderer.updateProgress()
  5409. }
  5410. }, false);
  5411. xhr.addEventListener("load", function() {
  5412. if (!options.renderer) return;
  5413. delete options.renderer.downloads[this.responseURL];
  5414. options.renderer.updateProgress()
  5415. }, false)
  5416. }
  5417. }
  5418. })
  5419. }
  5420. Math.randomInt = function() {
  5421. return Math.randomInt || function(min, max) {
  5422. return Math.floor(Math.random() * (max - min)) + min
  5423. }
  5424. }();
  5425. if (typeof Object.create != "function") {
  5426. Object.create = function() {
  5427. var obj = function() {};
  5428. return function(prototype) {
  5429. if (arguments.length > 1) {
  5430. throw Error("Second argument not supported")
  5431. }
  5432. if (typeof prototype != "object") {
  5433. throw TypeError("Argument must be an object")
  5434. }
  5435. obj.prototype = prototype;
  5436. var result = new obj;
  5437. obj.prototype = null;
  5438. return result
  5439. }
  5440. }()
  5441. }
  5442. window.console = window.console || {
  5443. log: function() {},
  5444. error: function() {},
  5445. warn: function() {}
  5446. };
  5447.  
  5448. function ZamModelViewer(opts) {
  5449. var self = this;
  5450. if (!opts.type || !self.validTypes[opts.type]) throw "Viewer error: Bad viewer type given";
  5451. if (!opts.container) throw "Viewer error: Bad container given";
  5452. if (!opts.aspect) throw "Viewer error: Bad aspect ratio given";
  5453. if (!opts.contentPath) throw "Viewer error: No content path given";
  5454. self.type = opts.type;
  5455. self.container = opts.container;
  5456. self.aspect = parseFloat(opts.aspect);
  5457. self.renderer = null;
  5458. self.options = opts;
  5459. var width = parseInt(self.container.width());
  5460. var height = Math.round(width / self.aspect);
  5461. self.init(width, height)
  5462. }
  5463. ZamModelViewer.WEBGL = 1;
  5464. ZamModelViewer.FLASH = 2;
  5465. ZamModelViewer.TOR = 1;
  5466. ZamModelViewer.WOW = 2;
  5467. ZamModelViewer.LOL = 3;
  5468. ZamModelViewer.GW2 = 4;
  5469. ZamModelViewer.WILDSTAR = 5;
  5470. ZamModelViewer.HEROES = 6;
  5471. ZamModelViewer.DESTINY = 7;
  5472. ZamModelViewer.Models = {};
  5473. ZamModelViewer.prototype = {
  5474. validTypes: {
  5475. 2: "Wowhead",
  5476. 3: "LolKing",
  5477. 6: "HeroKing",
  5478. 7: "DestinyDB"
  5479. },
  5480. destroy: function() {
  5481. var self = this;
  5482. if (self.renderer) self.renderer.destroy();
  5483. self.options = null;
  5484. self.container = null
  5485. },
  5486. init: function(width, height) {
  5487. var self = this,
  5488. glSupport = false;
  5489. if (typeof window["Uint8Array"] !== undefined && typeof window["DataView"] !== undefined) {
  5490. try {
  5491. var canvas = document.createElement("canvas");
  5492. var ctx = canvas.getContext("webgl", {
  5493. alpha: false
  5494. }) || canvas.getContext("experimental-webgl", {
  5495. alpha: false
  5496. });
  5497. if (ctx) glSupport = true
  5498. } catch (e) {}
  5499. }
  5500. if (!self.options.flash && glSupport) {
  5501. self.mode = ZamModelViewer.WEBGL;
  5502. self.renderer = new ZamModelViewer.WebGL(self)
  5503. } else {
  5504. self.mode = ZamModelViewer.FLASH;
  5505. self.renderer = new ZamModelViewer.Flash(self)
  5506. }
  5507. self.renderer.resize(width, height);
  5508. self.renderer.init()
  5509. },
  5510. method: function(name, params) {
  5511. var self = this;
  5512. if (params === undefined) params = [];
  5513. if (self.renderer) return self.renderer.method(name, [].concat(params));
  5514. return null
  5515. },
  5516. option: function(key, val) {
  5517. var self = this;
  5518. if (val !== undefined) {
  5519. self.options[key] = val
  5520. }
  5521. return self.options[key]
  5522. }
  5523. };
  5524. ZamModelViewer.isFullscreen = function() {
  5525. if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) return true;
  5526. return false
  5527. };
  5528. ZamModelViewer.requestFullscreen = function(e) {
  5529. if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) return;
  5530. if (e.requestFullscreen) {
  5531. e.requestFullscreen()
  5532. } else if (e.webkitRequestFullscreen) {
  5533. e.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)
  5534. } else if (e.mozRequestFullScreen) {
  5535. e.mozRequestFullScreen()
  5536. } else if (e.msRequestFullscreen) {
  5537. e.msRequestFullscreen()
  5538. }
  5539. };
  5540. ZamModelViewer.exitFullscreen = function() {
  5541. if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) return;
  5542. if (document.exitFullscreen) {
  5543. document.exitFullscreen()
  5544. } else if (document.webkitExitFullscreen) {
  5545. document.webkitExitFullscreen()
  5546. } else if (document.mozCancelFullScreen) {
  5547. document.mozCancelFullScreen()
  5548. } else if (document.msExitFullscreen) {
  5549. document.msExitFullscreen()
  5550. }
  5551. };
  5552. ZamModelViewer.DataView = function(buffer) {
  5553. this.buffer = new DataView(buffer);
  5554. this.position = 0
  5555. };
  5556. ZamModelViewer.DataView.prototype = {
  5557. getBool: function() {
  5558. var v = this.buffer.getUint8(this.position) != 0;
  5559. this.position += 1;
  5560. return v
  5561. },
  5562. getUint8: function() {
  5563. var v = this.buffer.getUint8(this.position);
  5564. this.position += 1;
  5565. return v
  5566. },
  5567. getInt8: function() {
  5568. var v = this.buffer.getInt8(this.position);
  5569. this.position += 1;
  5570. return v
  5571. },
  5572. getUint16: function() {
  5573. var v = this.buffer.getUint16(this.position, true);
  5574. this.position += 2;
  5575. return v
  5576. },
  5577. getInt16: function() {
  5578. var v = this.buffer.getInt16(this.position, true);
  5579. this.position += 2;
  5580. return v
  5581. },
  5582. getUint32: function() {
  5583. var v = this.buffer.getUint32(this.position, true);
  5584. this.position += 4;
  5585. return v
  5586. },
  5587. getInt32: function() {
  5588. var v = this.buffer.getInt32(this.position, true);
  5589. this.position += 4;
  5590. return v
  5591. },
  5592. getFloat: function() {
  5593. var v = this.buffer.getFloat32(this.position, true);
  5594. this.position += 4;
  5595. return v
  5596. },
  5597. getString: function(len) {
  5598. if (len === undefined) len = this.getUint16();
  5599. var str = "";
  5600. for (var i = 0; i < len; ++i) {
  5601. str += String.fromCharCode(this.getUint8())
  5602. }
  5603. return str
  5604. },
  5605. setBool: function(v) {
  5606. this.buffer.setUint8(this.position, v ? 1 : 0);
  5607. this.position += 1
  5608. },
  5609. setUint8: function(v) {
  5610. this.buffer.setUint8(this.position, v);
  5611. this.position += 1
  5612. },
  5613. setInt8: function(v) {
  5614. this.buffer.setInt8(this.position, v);
  5615. this.position += 1
  5616. },
  5617. setUint16: function(v) {
  5618. this.buffer.setUint16(this.position, v, true);
  5619. this.position += 2
  5620. },
  5621. setInt16: function(v) {
  5622. this.buffer.setInt16(this.position, v, true);
  5623. this.position += 2
  5624. },
  5625. setUint32: function(v) {
  5626. this.buffer.setUint32(this.position, v, true);
  5627. this.position += 4
  5628. },
  5629. setInt32: function(v) {
  5630. this.buffer.setInt32(this.position, v, true);
  5631. this.position += 4
  5632. },
  5633. setFloat: function(v) {
  5634. this.buffer.setFloat32(this.position, v, true);
  5635. this.position += 4
  5636. }
  5637. };
  5638. ZamModelViewer.WebGL = function(viewer) {
  5639. var self = this;
  5640. self.viewer = viewer;
  5641. self.options = viewer.options;
  5642. self.downloads = {};
  5643. self.context = null;
  5644. self.width = 0;
  5645. self.height = 0;
  5646. self.time = 0;
  5647. self.delta = 0;
  5648. self.models = [];
  5649. self.screenshotDataURL = null;
  5650. self.makeDataURL = false;
  5651. self.azimuth = Math.PI * 1.5;
  5652. self.zenith = Math.PI / 2;
  5653. self.distance = 15;
  5654. self.fov = 30;
  5655. self.translation = [0, 0, 0];
  5656. self.target = [0, 0, 0];
  5657. self.eye = [0, 0, 0];
  5658. self.up = [0, 0, 1];
  5659. self.lookDir = vec3.create();
  5660. self.fullscreen = false;
  5661. self.projMatrix = mat4.create();
  5662. self.viewMatrix = mat4.create();
  5663. self.panningMatrix = mat4.create();
  5664. self.viewOffset = vec3.create();
  5665. if (!ZamModelViewer.WebGL.addedCss) {
  5666. ZamModelViewer.WebGL.addedCss = true;
  5667. $("head").append('<link rel="stylesheet" href="//cdn.zamimg.com/zmv/viewer.css" type="text/css" />')
  5668. }
  5669. };
  5670. ZamModelViewer.WebGL.prototype = {
  5671. updateProgress: function() {
  5672. var self = this,
  5673. totalSize = 0,
  5674. totalLoaded = 0;
  5675. for (var url in self.downloads) {
  5676. totalSize += self.downloads[url].total;
  5677. totalLoaded += self.downloads[url].loaded
  5678. }
  5679. if (totalSize <= 0) {
  5680. if (self.progressShown) {
  5681. self.progressBg.hide();
  5682. self.progressBar.hide();
  5683. self.progressShown = false
  5684. }
  5685. } else {
  5686. if (!self.progressShown) {
  5687. self.progressBg.show();
  5688. self.progressBar.show();
  5689. self.progressShown = true
  5690. }
  5691. var pct = totalLoaded / totalSize;
  5692. self.progressBar.width(Math.round(self.width * pct) + "px")
  5693. }
  5694. },
  5695. destroy: function() {
  5696. var self = this;
  5697. self.stop = true;
  5698. if (self.canvas) {
  5699. self.canvas.detach();
  5700. self.progressBg.detach();
  5701. self.progressBar.detach();
  5702. self.canvas.off("mousedown touchstart", self.onMouseDown).off("DOMMouseScroll", self.onMouseScroll).off("mousewheel", self.onMouseWheel).off("dblclick", self.onDoubleClick).off("contextmenu", self.onContextMenu);
  5703. $(window).off("resize", self.onFullscreen);
  5704. $(document).off("mouseup touchend", self.onMouseUp).off("mousemove touchmove", self.onMouseMove);
  5705. self.canvas = self.progressBg = self.progressBar = null
  5706. }
  5707. if (self.context) {
  5708. var gl = self.context;
  5709. if (self.bgTexture) gl.deleteTexture(self.bgTexture);
  5710. self.bgTexture = null;
  5711. if (self.program) gl.deleteProgram(self.program);
  5712. self.program = null;
  5713. if (self.vb) gl.deleteBuffer(self.vb);
  5714. if (self.vs) gl.deleteShader(self.vs);
  5715. if (self.fs) gl.deleteShader(self.fs);
  5716. self.vb = self.vs = self.fs = null
  5717. }
  5718. if (self.bgImg) self.bgImg = null;
  5719. for (var i = 0; i < self.models.length; ++i) {
  5720. self.models[i].destroy();
  5721. self.models[i] = null
  5722. }
  5723. self.models = []
  5724. },
  5725. method: function(name, params) {
  5726. var self = this;
  5727. if (self.models.length > 0 && self.models[0].external && self.models[0].external[name]) {
  5728. return self.models[0].external[name].apply(self.models[0], params)
  5729. } else {
  5730. return null
  5731. }
  5732. },
  5733. getTime: function() {
  5734. if (window.performance && window.performance.now) return window.performance.now();
  5735. else return Date.now()
  5736. },
  5737. draw: function() {
  5738. var self = this,
  5739. gl = self.context,
  5740. i;
  5741. var time = self.getTime();
  5742. self.delta = (time - self.time) * .001;
  5743. self.time = time;
  5744. self.updateCamera();
  5745. gl.viewport(0, 0, self.width, self.height);
  5746. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  5747. if (self.bgTexture && self.program) {
  5748. gl.useProgram(self.program);
  5749. gl.activeTexture(gl.TEXTURE0);
  5750. gl.bindTexture(gl.TEXTURE_2D, self.bgTexture);
  5751. gl.uniform1i(self.uTexture, 0);
  5752. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  5753. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
  5754. gl.enableVertexAttribArray(self.aPosition);
  5755. gl.vertexAttribPointer(self.aPosition, 2, gl.FLOAT, false, 16, 0);
  5756. gl.enableVertexAttribArray(self.aTexCoord);
  5757. gl.vertexAttribPointer(self.aTexCoord, 2, gl.FLOAT, false, 16, 8);
  5758. gl.depthMask(false);
  5759. gl.disable(gl.CULL_FACE);
  5760. gl.blendFunc(gl.ONE, gl.ZERO);
  5761. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  5762. gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
  5763. gl.enable(gl.CULL_FACE);
  5764. gl.depthMask(true);
  5765. gl.disableVertexAttribArray(self.aPosition);
  5766. gl.disableVertexAttribArray(self.aTexCoord)
  5767. }
  5768. for (i = 0; i < self.models.length; ++i) self.models[i].draw()
  5769. },
  5770. updateCamera: function() {
  5771. var self = this;
  5772. var d = self.distance,
  5773. a = self.azimuth,
  5774. z = self.zenith;
  5775. if (self.up[2] == 1) {
  5776. self.eye[0] = -d * Math.sin(z) * Math.cos(a) + self.target[0];
  5777. self.eye[1] = -d * Math.sin(z) * Math.sin(a) + self.target[1];
  5778. self.eye[2] = -d * Math.cos(z) + self.target[2]
  5779. } else {
  5780. self.eye[0] = -d * Math.sin(z) * Math.cos(a) + self.target[0];
  5781. self.eye[1] = -d * Math.cos(z) + self.target[1];
  5782. self.eye[2] = -d * Math.sin(z) * Math.sin(a) + self.target[2]
  5783. }
  5784. vec3.subtract(self.lookDir, self.target, self.eye);
  5785. vec3.normalize(self.lookDir, self.lookDir);
  5786. mat4.lookAt(self.viewMatrix, self.eye, self.target, self.up);
  5787. mat4.identity(self.panningMatrix);
  5788. if (self.up[2] == 1) {
  5789. vec3.set(self.viewOffset, self.translation[0], -self.translation[1], 0)
  5790. } else {
  5791. vec3.set(self.viewOffset, self.translation[0], 0, self.translation[1])
  5792. }
  5793. mat4.translate(self.panningMatrix, self.panningMatrix, self.viewOffset);
  5794. mat4.multiply(self.viewMatrix, self.panningMatrix, self.viewMatrix)
  5795. },
  5796. init: function() {
  5797. var self = this,
  5798. gl = self.context,
  5799. i;
  5800. mat4.perspective(self.projMatrix, self.fov * .0174532925, self.viewer.aspect, .1, 5e3);
  5801. self.updateCamera();
  5802. gl.clearColor(0, 0, 0, 1);
  5803. gl.enable(gl.DEPTH_TEST);
  5804. gl.depthFunc(gl.LEQUAL);
  5805. gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
  5806. gl.enable(gl.BLEND);
  5807. if ((self.options.models || self.options.items) && ZamModelViewer.Models[self.viewer.type]) {
  5808. var Model = ZamModelViewer.Models[self.viewer.type];
  5809. var models = [].concat(self.options.models);
  5810. if (models.length > 0) {
  5811. for (i = 0; i < models.length; ++i) {
  5812. self.models.push(new Model(self, self.viewer, models[i], i))
  5813. }
  5814. } else if (self.viewer.type == ZamModelViewer.DESTINY && self.options.items) {
  5815. self.models.push(new Model(self, self.viewer))
  5816. }
  5817. }
  5818.  
  5819. function tick() {
  5820. if (self.stop) return;
  5821. requestAnimFrame(tick);
  5822. self.draw();
  5823. if (self.makeDataURL !== false) {
  5824. if (self.canvas[0].toDataURL) {
  5825. if (!Array.isArray(self.makeDataURL)) {
  5826. self.makeDataURL = []
  5827. }
  5828. self.screenshotDataURL = self.canvas[0].toDataURL.apply(self.canvas[0], self.makeDataURL)
  5829. }
  5830. self.makeDataURL = false
  5831. }
  5832. }
  5833. tick()
  5834. },
  5835. resize: function(width, height) {
  5836. var self = this;
  5837. if (self.width === width) return;
  5838. if (!self.fullscreen) {
  5839. self.viewer.container.css({
  5840. height: height + "px",
  5841. position: "relative"
  5842. })
  5843. }
  5844. self.width = width;
  5845. self.height = height;
  5846. if (!self.canvas) {
  5847. self.canvas = $("<canvas/>");
  5848. self.canvas.attr({
  5849. width: width,
  5850. height: height
  5851. });
  5852. self.viewer.container.append(self.canvas);
  5853. self.context = self.canvas[0].getContext("webgl", {
  5854. alpha: false
  5855. }) || self.canvas[0].getContext("experimental-webgl", {
  5856. alpha: false
  5857. });
  5858. self.progressBg = $("<div/>", {
  5859. css: {
  5860. display: "none",
  5861. position: "absolute",
  5862. bottom: 0,
  5863. left: 0,
  5864. right: 0,
  5865. height: "10px",
  5866. backgroundColor: "#000"
  5867. }
  5868. });
  5869. self.progressBar = $("<div/>", {
  5870. css: {
  5871. display: "none",
  5872. position: "absolute",
  5873. bottom: 0,
  5874. left: 0,
  5875. width: 0,
  5876. height: "10px",
  5877. backgroundColor: "#ccc"
  5878. }
  5879. });
  5880. self.viewer.container.append(self.progressBg);
  5881. self.viewer.container.append(self.progressBar);
  5882. if (!self.context) {
  5883. alert("No WebGL support, sorry! You should totally use Chrome.");
  5884. self.canvas.detach();
  5885. self.canvas = null;
  5886. return
  5887. }
  5888. self.toggleSize = function(event) {
  5889. if (!self.resized) {
  5890. self.restoreWidth = self.width;
  5891. self.restoreHeight = self.height;
  5892. self.resized = true;
  5893. self.resize(640, 480);
  5894. mat4.perspective(self.projMatrix, self.fov * .0174532925, 640 / 480, .1, 5e3)
  5895. } else {
  5896. self.resized = false;
  5897. self.resize(self.restoreWidth, self.restoreHeight);
  5898. mat4.perspective(self.projMatrix, self.fov * .0174532925, self.viewer.aspect, .1, 5e3)
  5899. }
  5900. };
  5901. self.onDoubleClick = function(event) {
  5902. if (ZamModelViewer.isFullscreen()) {
  5903. ZamModelViewer.exitFullscreen()
  5904. } else {
  5905. ZamModelViewer.requestFullscreen(self.canvas[0])
  5906. }
  5907. };
  5908. self.onFullscreen = function(event) {
  5909. if (!self.fullscreen && ZamModelViewer.isFullscreen()) {
  5910. self.restoreWidth = self.width;
  5911. self.restoreHeight = self.height;
  5912. self.fullscreen = true;
  5913. var $window = $(window);
  5914. self.resize($window.width(), $window.height());
  5915. mat4.perspective(self.projMatrix, self.fov * .0174532925, $window.width() / $window.height(), .1, 5e3)
  5916. } else if (self.fullscreen && !ZamModelViewer.isFullscreen()) {
  5917. self.fullscreen = false;
  5918. self.resize(self.restoreWidth, self.restoreHeight);
  5919. mat4.perspective(self.projMatrix, self.fov * .0174532925, self.viewer.aspect, .1, 5e3)
  5920. }
  5921. };
  5922. self.onMouseDown = function(event) {
  5923. if (event.which == 3 || event.ctrlKey) {
  5924. self.rightMouseDown = true
  5925. } else {
  5926. self.mouseDown = true
  5927. }
  5928. if (event.type == "touchstart") {
  5929. self.mouseX = event.originalEvent.touches[0].clientX;
  5930. self.mouseY = event.originalEvent.touches[0].clientY
  5931. } else {
  5932. self.mouseX = event.clientX;
  5933. self.mouseY = event.clientY
  5934. }
  5935. $("body").addClass("unselectable")
  5936. };
  5937. self.onMouseScroll = function(event) {
  5938. if (event.originalEvent.detail > 0) {
  5939. self.distance *= 1.25
  5940. } else {
  5941. self.distance *= .75
  5942. }
  5943. event.preventDefault();
  5944. return false
  5945. };
  5946. self.onMouseWheel = function(event) {
  5947. if (event.originalEvent.wheelDelta < 0) {
  5948. self.distance *= 1.25
  5949. } else {
  5950. self.distance *= .75
  5951. }
  5952. event.preventDefault();
  5953. return false
  5954. };
  5955. self.onMouseUp = function(event) {
  5956. if (self.mouseDown || self.rightMouseDown) {
  5957. $("body").removeClass("unselectable");
  5958. self.mouseDown = false;
  5959. self.rightMouseDown = false
  5960. }
  5961. };
  5962. self.onMouseMove = function(event) {
  5963. if (!self.mouseDown && !self.rightMouseDown || self.mouseX === undefined) return;
  5964. var x, y;
  5965. if (event.type == "touchmove") {
  5966. event.preventDefault();
  5967. x = event.originalEvent.touches[0].clientX;
  5968. y = event.originalEvent.touches[0].clientY
  5969. } else {
  5970. x = event.clientX;
  5971. y = event.clientY
  5972. }
  5973. var dx = (x - self.mouseX) / self.width * Math.PI * 2;
  5974. var dy = (y - self.mouseY) / self.width * Math.PI * 2;
  5975. if (self.mouseDown) {
  5976. if (self.up[2] == 1) {
  5977. self.azimuth -= dx
  5978. } else {
  5979. self.azimuth += dx
  5980. }
  5981. self.zenith += dy;
  5982. var pi2 = Math.PI * 2;
  5983. while (self.azimuth < 0) self.azimuth += pi2;
  5984. while (self.azimuth > pi2) self.azimuth -= pi2;
  5985. if (self.zenith < 1e-4) self.zenith = 1e-4;
  5986. if (self.zenith >= Math.PI) self.zenith = Math.PI - 1e-4
  5987. } else {
  5988. self.translation[0] += dx;
  5989. self.translation[1] += dy
  5990. }
  5991. self.mouseX = x;
  5992. self.mouseY = y
  5993. };
  5994. self.onContextMenu = function(event) {
  5995. return false
  5996. };
  5997. self.canvas.on("mousedown touchstart", self.onMouseDown).on("DOMMouseScroll", self.onMouseScroll).on("mousewheel", self.onMouseWheel).on("dblclick", self.onDoubleClick).on("contextmenu", self.onContextMenu);
  5998. $(window).on("resize", self.onFullscreen);
  5999. $(document).on("mouseup touchend", self.onMouseUp).on("mousemove touchmove", self.onMouseMove)
  6000. } else {
  6001. self.canvas.attr({
  6002. width: width,
  6003. height: height
  6004. });
  6005. self.canvas.css({
  6006. width: width + "px",
  6007. height: height + "px"
  6008. });
  6009. self.context.viewport(0, 0, self.drawingBufferWidth, self.drawingBufferHeight)
  6010. }
  6011. if (self.options.background) {
  6012. self.loadBackground()
  6013. }
  6014. },
  6015. loadBackground: function() {
  6016. var self = this,
  6017. gl = self.context;
  6018. var initVb = function() {
  6019. self.vb = gl.createBuffer();
  6020. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  6021. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(16), gl.DYNAMIC_DRAW);
  6022. var vs = self.compileShader(gl.VERTEX_SHADER, self.vertShader);
  6023. var fs = self.compileShader(gl.FRAGMENT_SHADER, self.fragShader);
  6024. var program = gl.createProgram();
  6025. gl.attachShader(program, vs);
  6026. gl.attachShader(program, fs);
  6027. gl.linkProgram(program);
  6028. if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
  6029. console.error("Error linking shaders");
  6030. return
  6031. }
  6032. self.vs = vs;
  6033. self.fs = fs;
  6034. self.program = program;
  6035. self.uTexture = gl.getUniformLocation(program, "uTexture");
  6036. self.aPosition = gl.getAttribLocation(program, "aPosition");
  6037. self.aTexCoord = gl.getAttribLocation(program, "aTexCoord")
  6038. };
  6039. var updateVb = function() {
  6040. var u = self.width / self.bgImg.width,
  6041. v = self.height / self.bgImg.height;
  6042. var vbData = [-1, -1, 0, v, 1, -1, u, v, -1, 1, 0, 0, 1, 1, u, 0];
  6043. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  6044. gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(vbData))
  6045. };
  6046. if (!self.bgImg) {
  6047. self.bgImg = new Image;
  6048. self.bgImg.crossOrigin = "";
  6049. self.bgImg.onload = function() {
  6050. self.bgImg.loaded = true;
  6051. self.bgTexture = gl.createTexture();
  6052. gl.bindTexture(gl.TEXTURE_2D, self.bgTexture);
  6053. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, self.bgImg);
  6054. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  6055. if (!self.vb) initVb();
  6056. updateVb()
  6057. };
  6058. self.bgImg.onerror = function() {
  6059. self.bgImg = null
  6060. };
  6061. self.bgImg.src = self.options.contentPath + self.options.background
  6062. } else if (self.bgImg.loaded) {
  6063. if (!self.vb) initVb();
  6064. updateVb()
  6065. }
  6066. },
  6067. vertShader: " attribute vec2 aPosition; attribute vec2 aTexCoord; varying vec2 vTexCoord; void main(void) { vTexCoord = aTexCoord; gl_Position = vec4(aPosition, 0, 1); } ",
  6068. fragShader: " precision mediump float; varying vec2 vTexCoord; uniform sampler2D uTexture; void main(void) { gl_FragColor = texture2D(uTexture, vTexCoord); } ",
  6069. compileShader: function(type, source) {
  6070. var self = this,
  6071. gl = self.context;
  6072. var shader = gl.createShader(type);
  6073. gl.shaderSource(shader, source);
  6074. gl.compileShader(shader);
  6075. if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
  6076. throw "Shader compile error: " + gl.getShaderInfoLog(shader)
  6077. }
  6078. return shader
  6079. }
  6080. };
  6081. ZamModelViewer.Flash = function(viewer) {
  6082. var self = this;
  6083. self.viewer = viewer;
  6084. self.options = viewer.options;
  6085. self.width = 0;
  6086. self.height = 0;
  6087. self.div = null;
  6088. self.object = null;
  6089. self.divId = "sjfdlkjsfesl32"
  6090. };
  6091. ZamModelViewer.Flash.prototype = {
  6092. destroy: function() {
  6093. var self = this;
  6094. if (self.div) {
  6095. self.div.detach();
  6096. self.div = null
  6097. }
  6098. if (self.object) {
  6099. self.object.detach();
  6100. self.object = null
  6101. }
  6102. },
  6103. method: function(name, params) {
  6104. var self = this,
  6105. object = $("#" + self.divId);
  6106. if (object.length > 0) {
  6107. return object[0][name].apply(object[0], params)
  6108. } else {
  6109. return null
  6110. }
  6111. },
  6112. resize: function(width, height) {
  6113. var self = this;
  6114. if (self.width === width) return;
  6115. self.viewer.container.css({
  6116. height: height + "px"
  6117. });
  6118. self.width = width;
  6119. self.height = height;
  6120. if (!self.div) {
  6121. self.div = $("<div/>", {
  6122. id: self.divId
  6123. });
  6124. self.viewer.container.append(self.div)
  6125. }
  6126. },
  6127. init: function() {
  6128. var self = this,
  6129. opts = self.options;
  6130. var model = opts.models;
  6131. var flashVars = {
  6132. modelType: model.type,
  6133. model: model.id,
  6134. container: self.divId,
  6135. contentPath: opts.contentPath
  6136. };
  6137. var params = {
  6138. quality: "high",
  6139. allowscriptaccess: "always",
  6140. allowfullscreen: true,
  6141. menu: false,
  6142. bgcolor: "#181818",
  6143. wmode: "direct"
  6144. };
  6145. if (opts.background) flashVars.background = opts.background;
  6146. if (opts.cls !== undefined) flashVars.cls = opts.cls;
  6147. if (opts.hd !== undefined) flashVars.hd = opts.hd;
  6148. if (opts.sk !== undefined) flashVars.sk = opts.sk;
  6149. if (opts.ha !== undefined) flashVars.ha = opts.ha;
  6150. if (opts.hc !== undefined) flashVars.hc = opts.hc;
  6151. if (opts.fa !== undefined) flashVars.fa = opts.fa;
  6152. if (opts.fc !== undefined) flashVars.fc = opts.fc;
  6153. if (opts.fh !== undefined) flashVars.fh = opts.fh;
  6154. if (opts.items) {
  6155. var items = opts.items;
  6156. var equipList = [];
  6157. if ($.isArray(items)) {
  6158. for (var i = 0; i < items.length; ++i) {
  6159. equipList.push(items[i][0]);
  6160. equipList.push(items[i][1])
  6161. }
  6162. } else {
  6163. for (var slot in items) {
  6164. equipList.push(slot);
  6165. equipList.push(items[slot])
  6166. }
  6167. }
  6168. flashVars.equipList = equipList.join(",")
  6169. }
  6170. self.object = $("#" + self.divId);
  6171. self.object.html("<b>WebGL not supported by your browser, please go to https://get.webgl.org/ for support.</b>")
  6172. }
  6173. };
  6174. ZamModelViewer.Wow = function() {};
  6175. ZamModelViewer.Wow.Model = function(renderer, viewer, model, index, skipLoad) {
  6176. var self = this;
  6177. self.Texture = ZamModelViewer.Wow.Texture;
  6178. self.renderer = renderer;
  6179. self.viewer = viewer;
  6180. self.model = model;
  6181. self.modelIndex = index;
  6182. self.modelPath = null;
  6183. self.loaded = false;
  6184. self.opts = self.viewer.options;
  6185. self.mount = null;
  6186. self.isMount = self.opts.mount && self.opts.mount.type == ZamModelViewer.Wow.Types.NPC && self.opts.mount.id == self.model.id;
  6187. if (self.model.type == ZamModelViewer.Wow.Types.CHARACTER) {
  6188. if (self.opts.mount && self.opts.mount.type == ZamModelViewer.Wow.Types.NPC && self.opts.mount.id) {
  6189. self.opts.mount.parent = self;
  6190. self.mount = new ZamModelViewer.Wow.Model(renderer, viewer, self.opts.mount, 0)
  6191. }
  6192. }
  6193. self.race = -1;
  6194. self.gender = -1;
  6195. self.class = self.opts.cls ? parseInt(self.opts.cls) : -1;
  6196. self.meta = null;
  6197. self.skinIndex = 0;
  6198. self.hairIndex = 0;
  6199. self.hairColorIndex = 0;
  6200. self.faceIndex = 0;
  6201. self.faceFeatureIndex = 0;
  6202. self.faceColorIndex = 0;
  6203. self.HornsIndex = 0;
  6204. self.EyePatchIndex = 0;
  6205. self.TattoosIndex = 0;
  6206. self.hairVis = true;
  6207. self.faceVis = true;
  6208. self.hairMesh = null;
  6209. self.parent = self.model.parent || null;
  6210. self.items = {};
  6211. self.needsCompositing = false;
  6212. self.textureOverrides = {};
  6213. self.compositeImage = null;
  6214. self.compositeTexture = null;
  6215. self.npcTexture = null;
  6216. self.specialTextures = {};
  6217. self.bakedTextures = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}];
  6218. self.isHD = false;
  6219. self.sheathMain = -1;
  6220. self.sheathOff = -1;
  6221. self.numGeosets = 26;
  6222. self.geosets = new Array(self.numGeosets);
  6223. self.time = 0;
  6224. self.frame = 0;
  6225. self.animationList = null;
  6226. self.currentAnimation = null;
  6227. self.animStartTime = 0;
  6228. self.slotAttachments = {};
  6229. self.matrix = mat4.create();
  6230. self.vbData = null;
  6231. self.vb = null;
  6232. self.ib = null;
  6233. self.shaderReady = false;
  6234. self.vs = null;
  6235. self.fs = null;
  6236. self.program = null;
  6237. self.uniforms = null;
  6238. self.attribs = null;
  6239. self.ambientColor = [.35, .35, .35, 1];
  6240. self.primaryColor = [1, 1, 1, 1];
  6241. self.secondaryColor = [.35, .35, .35, 1];
  6242. self.lightDir1 = vec3.create();
  6243. self.lightDir2 = vec3.create();
  6244. self.lightDir3 = vec3.create();
  6245. vec3.normalize(self.lightDir1, [5, -3, 3]);
  6246. vec3.normalize(self.lightDir2, [5, 5, 5]);
  6247. vec3.normalize(self.lightDir3, [-5, -5, -5]);
  6248. self.boundsSet = false;
  6249. self.animBounds = false;
  6250. self.boundsMin = [0, 0, 0];
  6251. self.boundsMax = [0, 0, 0];
  6252. self.boundsCenter = [0, 0, 0];
  6253. self.boundsSize = [0, 0, 0];
  6254. self.vertices = null;
  6255. self.indices = null;
  6256. self.animations = null;
  6257. self.animLookup = null;
  6258. self.bones = null;
  6259. self.boneLookup = null;
  6260. self.keyBoneLookup = null;
  6261. self.meshes = null;
  6262. self.texUnits = null;
  6263. self.texUnitLookup = null;
  6264. self.renderFlags = null;
  6265. self.materials = null;
  6266. self.materialLookup = null;
  6267. self.textureAnims = null;
  6268. self.textureAnimLookup = null;
  6269. self.textureReplacements = null;
  6270. self.attachments = null;
  6271. self.attachmentLookup = null;
  6272. self.colors = null;
  6273. self.alphas = null;
  6274. self.alphaLookup = null;
  6275. self.particleEmitters = null;
  6276. self.ribbonEmitters = null;
  6277. self.skins = null;
  6278. self.faces = null;
  6279. self.hairs = null;
  6280. self.tmpMat = mat4.create();
  6281. self.tmpVec = vec3.create();
  6282. self.tmpVec3 = vec3.create();
  6283. self.tmpVec4 = vec4.create();
  6284. self.mountMat = mat4.create();
  6285. if (!skipLoad) {
  6286. self.load()
  6287. }
  6288. };
  6289. ZamModelViewer.Models[ZamModelViewer.WOW] = ZamModelViewer.Wow.Model;
  6290. ZamModelViewer.Wow.Model.prototype = {
  6291. external: {
  6292. getNumAnimations: function() {
  6293. var model = this.mount ? this.mount : this;
  6294. return model.animations ? model.animations.length : 0
  6295. },
  6296. getAnimation: function(idx) {
  6297. var model = this.mount ? this.mount : this;
  6298. if (model.animations && idx > -1 && idx < model.animations.length) {
  6299. return model.animations[idx].name
  6300. } else {
  6301. return ""
  6302. }
  6303. },
  6304. setAnimation: function(name) {
  6305. var model = this.mount ? this.mount : this;
  6306. model.setAnimation(name)
  6307. },
  6308. resetAnimation: function() {
  6309. var model = this.mount ? this.mount : this;
  6310. model.setAnimation("Stand")
  6311. },
  6312. attachList: function(list) {
  6313. var equip = list.split(",");
  6314. var items = [];
  6315. for (var i = 0; i < equip.length; i += 2) {
  6316. items.push([equip[i], equip[i + 1]])
  6317. }
  6318. for (var i in items) {
  6319. var item = [parseInt(items[i][0]), parseInt(items[i][1])];
  6320. this.opts.items.push(item)
  6321. }
  6322. this.loadItems(items);
  6323. this.needsCompositing = true;
  6324. if (this.dhmodel) {
  6325. this.dhmodel.destroy();
  6326. this.dhloaded = 0;
  6327. this.loadDH(this.meta.DHGeosetsHDModel)
  6328. }
  6329. this.setup()
  6330. },
  6331. clearSlots: function(list) {
  6332. var slots = list.split(",");
  6333. for (var i = 0; i < slots.length; ++i) {
  6334. this.removeSlot(slots[i]);
  6335. var items = [];
  6336. for (var i in this.opts.items) {
  6337. if (this.opts.items[i].indexOf(parseInt(slots[i])) != 0) items.push(this.opts.items[i])
  6338. }
  6339. this.opts.items = items
  6340. }
  6341. this.needsCompositing = true;
  6342. if (this.dhmodel) {
  6343. this.dhmodel.destroy();
  6344. this.dhloaded = 0;
  6345. this.loadDH(this.meta.DHGeosetsHDModel)
  6346. }
  6347. this.setup()
  6348. },
  6349. setAppearance: function(hairStyle, hairColor, faceType, skinColor, features, featuresColor, horns, eyepatch, tattoos, sheathMain, sheathOff) {
  6350. this.skinIndex = skinColor;
  6351. this.hairIndex = hairStyle;
  6352. this.hairColorIndex = hairColor;
  6353. this.faceIndex = faceType;
  6354. this.faceFeatureIndex = features;
  6355. this.faceColorIndex = featuresColor;
  6356. this.HornsIndex = horns;
  6357. this.EyePatchIndex = eyepatch;
  6358. this.TattoosIndex = tattoos;
  6359. var Region = ZamModelViewer.Wow.Regions;
  6360. var destroyTexture = function(array, key) {
  6361. array[key].destroy();
  6362. delete array[key]
  6363. };
  6364. if (this.specialTextures[1]) destroyTexture(this.specialTextures, 1);
  6365. if (this.specialTextures[6]) destroyTexture(this.specialTextures, 6);
  6366. if (this.specialTextures[8]) destroyTexture(this.specialTextures, 8);
  6367. if (this.bakedTextures[Region.LegUpper][1]) destroyTexture(this.bakedTextures[Region.LegUpper], 1);
  6368. if (this.bakedTextures[Region.TorsoUpper][1]) destroyTexture(this.bakedTextures[Region.TorsoUpper], 1);
  6369. if (this.bakedTextures[Region.FaceLower][1]) destroyTexture(this.bakedTextures[Region.FaceLower], 1);
  6370. if (this.bakedTextures[Region.FaceUpper][1]) destroyTexture(this.bakedTextures[Region.FaceUpper], 1);
  6371. if (this.bakedTextures[Region.FaceLower][2]) destroyTexture(this.bakedTextures[Region.FaceLower], 2);
  6372. if (this.bakedTextures[Region.FaceUpper][2]) destroyTexture(this.bakedTextures[Region.FaceUpper], 2);
  6373. if (this.bakedTextures[Region.FaceLower][3]) destroyTexture(this.bakedTextures[Region.FaceLower], 3);
  6374. if (this.bakedTextures[Region.FaceUpper][3]) destroyTexture(this.bakedTextures[Region.FaceUpper], 3);
  6375. if (this.bakedTextures[Region.Base][1]) destroyTexture(this.bakedTextures[Region.Base], 1);
  6376. this.sheathMain = sheathMain;
  6377. this.sheathOff = sheathOff;
  6378. this.updateSlotMap();
  6379. this.needsCompositing = true;
  6380. if (this.dhmodel) {
  6381. this.dhmodel.destroy();
  6382. this.dhloaded = 0;
  6383. this.loadDH(this.meta.DHGeosetsHDModel)
  6384. }
  6385. this.setup()
  6386. },
  6387. isLoaded: function() {
  6388. if (this.mount) {
  6389. return this.mount.loaded && this.loaded
  6390. } else {
  6391. return this.loaded
  6392. }
  6393. }
  6394. },
  6395. setMatrix: function(parent, bone, attach, extra) {
  6396. var self = this;
  6397. mat4.copy(self.matrix, parent);
  6398. mat4.multiply(self.matrix, self.matrix, bone);
  6399. if (attach) mat4.translate(self.matrix, self.matrix, attach);
  6400. if (extra) mat4.multiply(self.matrix, self.matrix, extra)
  6401. },
  6402. setAnimation: function(name) {
  6403. var self = this,
  6404. anim, Wow = ZamModelViewer.Wow;
  6405. self.animationList = [];
  6406. for (var i = 0; i < self.animations.length; ++i) {
  6407. anim = self.animations[i];
  6408. if (!anim.name) continue;
  6409. if (anim.name == name && name == "Stand") {
  6410. if (self.race == Wow.Races.PANDAREN && self.gender == Wow.Genders.MALE && anim.length == 11900) continue;
  6411. self.animationList.push(anim)
  6412. } else if (anim.name == name) {
  6413. self.animationList.push(anim)
  6414. }
  6415. }
  6416. self.animStartTime = 0;
  6417. self.currentAnimation = self.animationList.length > 0 ? self.animationList[0] : null;
  6418. if (name != "Stand" && !self.currentAnimation) {
  6419. self.setAnimation("Stand")
  6420. }
  6421. },
  6422. updateBuffers: function(fillVb) {
  6423. var self = this,
  6424. i, j, vertLength = 8,
  6425. gl = self.renderer.context;
  6426. if (!self.vertices || !self.indices) return;
  6427. var vbLength = self.vertices.length * vertLength;
  6428. if (!self.vbData) self.vbData = new Float32Array(vbLength);
  6429. if (fillVb) {
  6430. var vbData = self.vbData,
  6431. verts = self.vertices;
  6432. for (i = 0, j = 0; i < vbLength; ++j) {
  6433. vbData[i + 0] = verts[j].transPosition[0];
  6434. vbData[i + 1] = verts[j].transPosition[1];
  6435. vbData[i + 2] = verts[j].transPosition[2];
  6436. vbData[i + 3] = verts[j].transNormal[0];
  6437. vbData[i + 4] = verts[j].transNormal[1];
  6438. vbData[i + 5] = verts[j].transNormal[2];
  6439. vbData[i + 6] = verts[j].u;
  6440. vbData[i + 7] = verts[j].v;
  6441. i += 8
  6442. }
  6443. }
  6444. if (!self.vb) {
  6445. self.vb = gl.createBuffer();
  6446. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  6447. gl.bufferData(gl.ARRAY_BUFFER, self.vbData, gl.DYNAMIC_DRAW);
  6448. self.ib = gl.createBuffer();
  6449. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.ib);
  6450. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(self.indices), gl.STATIC_DRAW)
  6451. } else {
  6452. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  6453. gl.bufferSubData(gl.ARRAY_BUFFER, 0, self.vbData)
  6454. }
  6455. },
  6456. updateBounds: function() {
  6457. var self = this,
  6458. t, m, color = [1, 1, 1, 1],
  6459. Wow = ZamModelViewer.Wow;
  6460. var min = self.boundsMin,
  6461. max = self.boundsMax,
  6462. pos, tmp = self.tmpVec;
  6463. vec3.set(min, 9999, 9999, 999);
  6464. vec3.set(max, -9999, -9999, -9999);
  6465. if (!self.texUnits) {
  6466. mat4.identity(self.matrix);
  6467. self.renderer.distance = 1;
  6468. return false
  6469. }
  6470. for (var i = 0; i < self.texUnits.length; ++i) {
  6471. t = self.texUnits[i];
  6472. if (!t.show) continue;
  6473. color[0] = color[1] = color[2] = color[3] = 1;
  6474. if (self.currentAnimation) {
  6475. if (t.color) t.color.getValue(self.currentAnimation.index, self.time, color);
  6476. if (t.alpha) color[3] *= t.alpha.getValue(self.currentAnimation.index, self.time)
  6477. }
  6478. if (color[3] < .01) continue;
  6479. m = t.mesh;
  6480. for (var j = 0; j < m.indexCount; ++j) {
  6481. pos = self.vertices[self.indices[m.indexStart + j]].transPosition;
  6482. vec3.min(min, min, pos);
  6483. vec3.max(max, max, pos)
  6484. }
  6485. }
  6486. if (self.mount && self.mount.loaded) {
  6487. if (self.mount.updateBounds()) {
  6488. vec3.copy(min, vec3.scale(min, self.mount.boundsMin, 1.1));
  6489. vec3.copy(max, vec3.scale(max, self.mount.boundsMax, 1.1));
  6490. max[2] *= 1.75
  6491. }
  6492. }
  6493. if (self.model.type == Wow.Types.NPC) {
  6494. vec3.scale(min, min, self.meta.Scale);
  6495. vec3.scale(max, max, self.meta.Scale)
  6496. }
  6497. vec3.subtract(self.boundsSize, max, min);
  6498. vec3.scaleAndAdd(self.boundsCenter, min, self.boundsSize, .5);
  6499. var hSize = self.boundsSize[2],
  6500. wSize, dSize, scale = self.meta ? self.meta.Scale : 1;
  6501. if (self.model.type != Wow.Types.ITEM) {
  6502. wSize = self.boundsSize[1];
  6503. dSize = self.boundsSize[0]
  6504. } else {
  6505. wSize = self.boundsSize[0];
  6506. dSize = self.boundsSize[1]
  6507. }
  6508. if (!self.parent) {
  6509. var ratio = self.renderer.width / self.renderer.height;
  6510. var hTan = 2 * Math.tan(self.renderer.fov / 2 * .0174532925);
  6511. var wTan = hTan * ratio;
  6512. var hDist = hSize * 1.2 / hTan;
  6513. var wDist = wSize * 1.2 / wTan;
  6514. self.renderer.distance = Math.max(Math.max(hDist, wDist), dSize * 2)
  6515. }
  6516. mat4.identity(self.matrix);
  6517. if (self.model.type != Wow.Types.ITEM) {
  6518. mat4.rotateZ(self.matrix, self.matrix, Math.PI / 2)
  6519. }
  6520. mat4.translate(self.matrix, self.matrix, vec3.negate(tmp, self.boundsCenter));
  6521. vec3.set(self.tmpVec, scale, scale, scale);
  6522. mat4.scale(self.matrix, self.matrix, self.tmpVec);
  6523. return true
  6524. },
  6525. disabledMeshes: {
  6526. 146273: {
  6527. 1: true
  6528. },
  6529. 319730: {
  6530. 1: true
  6531. }
  6532. },
  6533. setup: function() {
  6534. var self = this,
  6535. i, Wow = ZamModelViewer.Wow;
  6536. if (self.model.type != Wow.Types.CHARACTER && self.model.type != Wow.Types.NPC && self.model.type != Wow.Types.HUMANOIDNPC || self.race < 1) {
  6537. if (self.texUnits) {
  6538. if (self.modelPath == 1276975 || self.modelPath == 1276976 || self.modelPath == 1276977 || self.modelPath == 1276978) {
  6539. if (self.parent.dhloaded == 0) {
  6540. self.slot = 6;
  6541. var HASPANTS = false;
  6542. for (var i in self.parent.opts.items) {
  6543. if (self.parent.opts.items[i].indexOf(7) == 0) HASPANTS = true
  6544. }
  6545. for (i = 0; i < self.texUnits.length; ++i) {
  6546. if (self.texUnits[i].meshId == 1401 && !HASPANTS) self.texUnits[i].show = true;
  6547. else self.texUnits[i].show = false
  6548. }
  6549. }
  6550. if (self.parent.dhloaded == 1) {
  6551. self.slot = 1;
  6552. for (i = 0; i < self.texUnits.length; ++i) {
  6553. if (self.parent.HornsIndex > 0 && self.texUnits[i].meshId == 2400 + self.parent.HornsIndex) self.texUnits[i].show = true;
  6554. else self.texUnits[i].show = false
  6555. }
  6556. }
  6557. if (self.parent.dhloaded == 2) {
  6558. self.slot = 1;
  6559. for (i = 0; i < self.texUnits.length; ++i) {
  6560. if (self.parent.EyePatchIndex > 0 && self.texUnits[i].meshId == 2500 + self.parent.EyePatchIndex) self.texUnits[i].show = true;
  6561. else self.texUnits[i].show = false
  6562. }
  6563. }
  6564. if (self.parent.dhloaded == 3) {
  6565. self.slot = 25;
  6566. for (i = 0; i < self.texUnits.length; ++i) {
  6567. if (self.texUnits[i].meshId == 2301) self.texUnits[i].show = true;
  6568. else self.texUnits[i].show = false
  6569. }
  6570. }
  6571. self.parent.dhloaded = self.parent.dhloaded + 1
  6572. } else if (self.modelPath == 982557) {
  6573. for (i = 0; i < self.texUnits.length; ++i) {
  6574. self.texUnits[i].show = self.texUnits[i].meshId == 0
  6575. }
  6576. } else if (self.disabledMeshes[self.modelPath] !== undefined) {
  6577. var mesh = self.disabledMeshes[self.modelPath];
  6578. for (i = 0; i < self.texUnits.length; ++i) {
  6579. self.texUnits[i].show = mesh[i] === undefined
  6580. }
  6581. } else {
  6582. for (i = 0; i < self.texUnits.length; ++i) {
  6583. self.texUnits[i].show = true
  6584. }
  6585. }
  6586. }
  6587. return
  6588. }
  6589. if ((self.race == Wow.Races.BROKEN || self.race == Wow.Races.TUSKARR) && self.hairIndex == 0) {
  6590. self.hairIndex = 1
  6591. }
  6592. if (self.model.type == Wow.Types.CHARACTER && self.race == Wow.Races.DWARF && self.opts.fh == undefined) {
  6593. self.faceFeatureIndex = 3
  6594. }
  6595. var skin, face, features, featureTexture, hair, hairTexture, dk = self.class == Wow.Classes.DEATHKNIGHT;
  6596. var skins, faces, textures, tattoo;
  6597. skins = self.skins;
  6598. if (skins) {
  6599. if (self.skinIndex >= skins.length) self.skinIndex = 0;
  6600. if (self.skinIndex < skins.length) skin = skins[self.skinIndex];
  6601. if (skin) {
  6602. if (false && dk) {
  6603. faces = Wow.Skin.GetFaces(skin.faces, true, dk, skin.skinFlags);
  6604. if (self.faceIndex >= faces.length) self.faceIndex = 0;
  6605. if (self.faceIndex < faces.length) face = faces[self.faceIndex]
  6606. } else if (self.faceIndex < skins.length) {
  6607. faces = Wow.Skin.GetFaces(skins[self.faceIndex].faces, true, dk, 0);
  6608. var index = self.skinIndex;
  6609. if (index >= faces.length) index = faces.length - 1;
  6610. if (index < faces.length) face = faces[index]
  6611. }
  6612. }
  6613. }
  6614. if (self.faces) {
  6615. if (self.faceFeatureIndex >= self.faces.length) self.faceFeatureIndex = faces.length - 1;
  6616. if (self.faceFeatureIndex < self.faces.length) features = self.faces[self.faceFeatureIndex];
  6617. if (features) {
  6618. if (self.class == Wow.Classes.DEMONHUNTER) textures = features.textures;
  6619. else textures = Wow.Face.GetTextures(features.textures, true, dk);
  6620. if (self.faceColorIndex >= textures.length) self.faceColorIndex = textures.length - 1;
  6621. if (self.faceColorIndex < textures.length) featureTexture = textures[self.faceColorIndex]
  6622. }
  6623. }
  6624. if (self.hairs) {
  6625. if (self.hairIndex >= self.hairs.length) self.hairIndex = 0;
  6626. if (self.hairIndex < self.hairs.length) hair = self.hairs[self.hairIndex];
  6627. if (hair) {
  6628. if (self.class == Wow.Classes.DEMONHUNTER) textures = hair.textures;
  6629. else textures = Wow.Hair.GetTextures(hair.textures, true, dk);
  6630. if (self.hairColorIndex >= textures.length) self.hairColorIndex = 0;
  6631. if (self.hairColorIndex < textures.length) hairTexture = textures[self.hairColorIndex]
  6632. }
  6633. }
  6634. if (self.tattoos && self.class == Wow.Classes.DEMONHUNTER) {
  6635. if (self.TattoosIndex >= self.tattoos.length) self.TattoosIndex = 0;
  6636. if (self.TattoosIndex < self.tattoos.length) tattoo = self.tattoos[self.TattoosIndex]
  6637. }
  6638. var Region = ZamModelViewer.Wow.Regions;
  6639. if (!self.npcTexture) {
  6640. self.needsCompositing = true;
  6641. if (skin) {
  6642. if (skin.base && !self.specialTextures[1]) self.specialTextures[1] = new self.Texture(self, 1, skin.base);
  6643. if (skin.panties && !self.bakedTextures[Region.LegUpper][1]) self.bakedTextures[Region.LegUpper][1] = new self.Texture(self, Region.LegUpper, skin.panties);
  6644. if (skin.bra && !self.bakedTextures[Region.TorsoUpper][1]) self.bakedTextures[Region.TorsoUpper][1] = new self.Texture(self, Region.TorsoUpper, skin.bra);
  6645. if (tattoo && !self.bakedTextures[Region.Base][1] && tattoo.texture != 0) {
  6646. self.bakedTextures[Region.Base][1] = new self.Texture(self, Region.FaceLower, tattoo.texture)
  6647. }
  6648. }
  6649. if (face) {
  6650. if (face.lower && !self.bakedTextures[Region.FaceLower][1]) self.bakedTextures[Region.FaceLower][1] = new self.Texture(self, Region.FaceLower, face.lower);
  6651. if (face.upper && !self.bakedTextures[Region.FaceUpper][1]) self.bakedTextures[Region.FaceUpper][1] = new self.Texture(self, Region.FaceUpper, face.upper)
  6652. }
  6653. if (featureTexture) {
  6654. if (featureTexture.lower && !self.bakedTextures[Region.FaceLower][2]) self.bakedTextures[Region.FaceLower][2] = new self.Texture(self, Region.FaceLower, featureTexture.lower);
  6655. if (featureTexture.upper && !self.bakedTextures[Region.FaceUpper][2]) self.bakedTextures[Region.FaceUpper][2] = new self.Texture(self, Region.FaceUpper, featureTexture.upper)
  6656. }
  6657. if (hairTexture) {
  6658. if (hairTexture.lower && !self.bakedTextures[Region.FaceLower][3]) self.bakedTextures[Region.FaceLower][3] = new self.Texture(self, Region.FaceLower, hairTexture.lower);
  6659. if (hairTexture.upper && !self.bakedTextures[Region.FaceUpper][3]) self.bakedTextures[Region.FaceUpper][3] = new self.Texture(self, Region.FaceUpper, hairTexture.upper)
  6660. }
  6661. }
  6662. if (skin && skin.fur && !self.specialTextures[8]) self.specialTextures[8] = new self.Texture(self, 8, skin.fur);
  6663. if (hairTexture && hairTexture.texture && !self.specialTextures[6]) self.specialTextures[6] = new self.Texture(self, 6, hairTexture.texture);
  6664. else if (hairTexture && !hairTexture.texture && !self.specialTextures[6] && self.hairIndex == 0 && self.hairs.length > 1) {
  6665. hair = self.hairs[1];
  6666. if (self.hairColorIndex >= hair.textures.length) self.hairColorIndex = 0;
  6667. if (self.hairColorIndex < hair.textures.length) {
  6668. hairTexture = hair.textures[self.hairColorIndex];
  6669. if (hairTexture.texture) self.specialTextures[6] = new self.Texture(self, 6, hairTexture.texture)
  6670. }
  6671. }
  6672. self.updateMeshes()
  6673. },
  6674. updateMeshes: function() {
  6675. var self = this,
  6676. i, j, u, Wow = ZamModelViewer.Wow,
  6677. Races = Wow.Races,
  6678. Genders = Wow.Genders,
  6679. Slots = Wow.Slots;
  6680. if (!self.texUnits || self.texUnits.length == 0) return;
  6681. var showHair = true;
  6682. if (self.hairMesh) showHair = self.hairMesh.show;
  6683. for (i = 0; i < self.texUnits.length; ++i) {
  6684. self.texUnits[i].show = self.texUnits[i].meshId == 0
  6685. }
  6686. for (i = 0; i < self.numGeosets; ++i) {
  6687. self.geosets[i] = 1
  6688. }
  6689. self.geosets[7] = 2;
  6690. if (self.faceVis) {
  6691. if (self.faces && self.faceFeatureIndex < self.faces.length) {
  6692. var face = self.faces[self.faceFeatureIndex];
  6693. self.geosets[1] = face.geoset1;
  6694. self.geosets[2] = face.geoset2;
  6695. self.geosets[3] = face.geoset3
  6696. }
  6697. }
  6698. if (self.race == Races.GOBLIN) {
  6699. if (self.geosets[1] == 1) self.geosets[1] = 2;
  6700. if (self.geosets[2] == 1) self.geosets[2] = 2;
  6701. if (self.geosets[3] == 1) self.geosets[3] = 2
  6702. }
  6703. var slot, item, hasRobe = false,
  6704. hasBoots = false,
  6705. hasHelm = false;
  6706. for (slot in self.items) {
  6707. item = self.items[slot];
  6708. if (item.slot == Slots.ROBE) hasRobe = true;
  6709. else if (item.slot == Slots.BOOTS) hasBoots = true;
  6710. else if (item.slot == Slots.HEAD) hasHelm = true;
  6711. if (!item.geosets) continue;
  6712. for (j = 0; j < item.geosets.length; ++j) {
  6713. self.geosets[item.geosets[j].index] = item.geosets[j].value
  6714. }
  6715. if (self.geosets[13] == 1) self.geosets[13] += item.geoC;
  6716. if (item.slot == Slots.BELT) self.geosets[18] = 1 + item.geoA;
  6717. if (self.race == Races.PANDAREN && item.slot == Slots.PANTS) self.geosets[14] = 0
  6718. }
  6719. if (self.geosets[13] == 2) self.geosets[5] = self.geosets[12] = 0;
  6720. if (self.geosets[4] > 1) self.geosets[8] = 0;
  6721. if (self.isHD && hasBoots) self.geosets[20] = 2;
  6722. if (!hasHelm) {
  6723. showHair = true;
  6724. self.hairVis = self.faceVis = true
  6725. } else {
  6726. showHair = self.hairVis
  6727. }
  6728. if (showHair && self.hairs && self.hairIndex < self.hairs.length) {
  6729. self.hairMesh = null;
  6730. var hair = self.hairs[self.hairIndex];
  6731. for (i = 0; i < self.texUnits.length; ++i) {
  6732. u = self.texUnits[i];
  6733. if (u.meshId != 0 && u.meshId == hair.geoset) {
  6734. u.show = true;
  6735. self.hairMesh = u
  6736. }
  6737. }
  6738. }
  6739. var a, b;
  6740. for (i = 0; i < self.texUnits.length; ++i) {
  6741. u = self.texUnits[i];
  6742. if (self.race != Races.HUMAN && !((self.race == Races.DRAENEI || self.race == Races.SCOURGE) && self.gender == Genders.FEMALE) && u.meshId == 0 && u.mesh.indexCount < 36) {
  6743. u.show = false;
  6744. continue
  6745. }
  6746. if (u.meshId == 1 && (!self.hairVis || self.gender == Genders.MALE && self.hairIndex == 0 && (self.race == Races.HUMAN || self.race == Races.GNOME || self.race == Races.TROLL))) {
  6747. u.show = true
  6748. }
  6749. for (j = 1; j < self.numGeosets; ++j) {
  6750. a = j * 100;
  6751. b = (j + 1) * 100;
  6752. if (u.meshId > a && u.meshId < b) u.show = u.meshId == a + self.geosets[j]
  6753. }
  6754. if (self.race == Races.SCOURGE && !self.isHD) {
  6755. if (self.gender == Genders.FEMALE) {
  6756. if (u.mesh == 49 || u.mesh == 51) u.show = true
  6757. } else {
  6758. if (u.mesh == 62) u.show = true
  6759. }
  6760. } else if (self.race == Races.GOBLIN) {
  6761. if (self.gender == Genders.FEMALE && u.mesh == 0 || self.gender == Genders.MALE && u.mesh == 3) u.show = false
  6762. } else if (self.race == Races.WORGEN) {
  6763. if (self.gender == Genders.MALE) {
  6764. if (u.mesh == 5 || u.mesh == 3 || u.mesh >= 36 && u.mesh <= 47) u.show = false
  6765. } else {
  6766. if (u.mesh == 2 || u.mesh == 3 || u.mesh >= 58 && u.mesh <= 69) u.show = false
  6767. }
  6768. } else if (self.race == Races.PANDAREN) {
  6769. if (self.gender == Genders.FEMALE) {
  6770. if (hasRobe && u.meshId == 1401) u.show = false
  6771. }
  6772. } else if (self.race == Races.NIGHTELF) {
  6773. if (self.class != Wow.Classes.DEATHKNIGHT && u.meshId == 1702) u.show = true
  6774. }
  6775. if (self.race == Races.BLOODELF || self.race == Races.NIGHTELF) {
  6776. if (u.meshId == 2301) u.show = true
  6777. }
  6778. if (self.class == Wow.Classes.DEATHKNIGHT) {
  6779. if (u.meshId == 1703) u.show = true
  6780. }
  6781. }
  6782. var attach;
  6783. if (self.dhmodel) {
  6784. var dhmodel = self.dhmodel;
  6785. if (dhmodel.models) {
  6786. for (i = 0; i < dhmodel.models.length; ++i) {
  6787. if (self.slotAttachments[dhmodel.models[i].model.slot]) {
  6788. attach = self.attachments[self.slotAttachments[dhmodel.models[i].model.slot]];
  6789. var newattach = JSON.parse(JSON.stringify(attach));
  6790. dhmodel.models[i].bone = newattach.bone;
  6791. dhmodel.models[i].attachment = newattach;
  6792. if (self.gender == Genders.MALE && self.race == Races.NIGHTELF && self.isHD) dhmodel.models[i].attachment.position = [.012, 0, .018];
  6793. else {
  6794. if (dhmodel.models[i].model.slot == 6 && self.gender == Genders.FEMALE && self.race == Races.BLOODELF) dhmodel.models[i].attachment.position = [-.032, 0, -.65];
  6795. else if (dhmodel.models[i].model.slot == 6 && self.gender == Genders.MALE && self.race == Races.NIGHTELF && !self.isHD) dhmodel.models[i].attachment.position = [-.015, 0, -.18];
  6796. else if (dhmodel.models[i].model.slot == 6) dhmodel.models[i].attachment.position = [-.032, 0, -.4];
  6797. else dhmodel.models[i].attachment.position = [0, 0, 0]
  6798. }
  6799. }
  6800. }
  6801. }
  6802. }
  6803. var attach;
  6804. for (slot in self.items) {
  6805. item = self.items[slot];
  6806. if (!item.models) continue;
  6807. for (i = 0; i < item.models.length; ++i) {
  6808. if (self.slotAttachments[item.slot] && self.slotAttachments[item.slot].length > i) {
  6809. attach = self.attachments[self.slotAttachments[item.slot][i]];
  6810. item.models[i].bone = attach.bone;
  6811. item.models[i].attachment = attach
  6812. }
  6813. }
  6814. }
  6815. if (self.hairMesh) self.hairMesh.show = showHair && self.hairVis
  6816. },
  6817. compositeTextures: function() {
  6818. var self = this,
  6819. i, j, Region = ZamModelViewer.Wow.Regions,
  6820. Classes = ZamModelViewer.Wow.Classes,
  6821. Slots = ZamModelViewer.Wow.Slots,
  6822. Races = ZamModelViewer.Wow.Races,
  6823. item, t;
  6824. for (i = 0; i < 11; ++i) {
  6825. for (j in self.bakedTextures[i]) {
  6826. if (!self.bakedTextures[i][j].ready()) return
  6827. }
  6828. }
  6829. for (i in self.items) {
  6830. item = self.items[i];
  6831. if (!item.loaded) {
  6832. return
  6833. } else if (item.textures) {
  6834. for (j = 0; j < item.textures.length; ++j) {
  6835. if (item.textures[j].texture && !item.textures[j].texture.ready()) return
  6836. }
  6837. }
  6838. }
  6839. for (var i in self.specialTextures) {
  6840. if (self.specialTextures[i] && !self.specialTextures[i].ready()) return
  6841. }
  6842. if (!self.compositeImage) {
  6843. self.compositeImage = document.createElement("canvas");
  6844. self.compositeImage.width = self.specialTextures[1].mergedImg.width;
  6845. self.compositeImage.height = self.specialTextures[1].mergedImg.height
  6846. }
  6847. var ctx = self.compositeImage.getContext("2d");
  6848. ctx.drawImage(self.specialTextures[1].mergedImg, 0, 0, self.compositeImage.width, self.compositeImage.height);
  6849. var w = self.compositeImage.width,
  6850. h = self.compositeImage.height,
  6851. regions = Region.old,
  6852. r;
  6853. if (w != h) regions = Region.new;
  6854. for (i = 1; i <= 3; ++i) {
  6855. if (self.bakedTextures[Region.FaceLower][i]) {
  6856. if (!self.bakedTextures[Region.FaceLower][i].ready()) return;
  6857. r = regions[Region.FaceLower];
  6858. ctx.drawImage(self.bakedTextures[Region.FaceLower][i].mergedImg, w * r.x, h * r.y, w * r.w, h * r.h)
  6859. }
  6860. if (self.bakedTextures[Region.FaceUpper][i]) {
  6861. if (!self.bakedTextures[Region.FaceUpper][i].ready()) return;
  6862. r = regions[Region.FaceUpper];
  6863. ctx.drawImage(self.bakedTextures[Region.FaceUpper][i].mergedImg, w * r.x, h * r.y, w * r.w, h * r.h)
  6864. }
  6865. }
  6866. if (self.isHD) {
  6867. for (i = 2; i <= 3; ++i) {
  6868. if (self.bakedTextures[Region.FaceLower][i]) {
  6869. if (!self.bakedTextures[Region.FaceLower][i].ready()) return;
  6870. r = regions[Region.FaceLower2];
  6871. if (r) ctx.drawImage(self.bakedTextures[Region.FaceLower][i].mergedImg, w * r.x, h * r.y, w * r.w, h * r.h)
  6872. }
  6873. }
  6874. }
  6875. var drawBra = true,
  6876. drawPanties = true,
  6877. uniqueSlot;
  6878. for (i in self.items) {
  6879. uniqueSlot = self.items[i].uniqueSlot;
  6880. if (uniqueSlot == Slots.SHIRT || uniqueSlot == Slots.CHEST || uniqueSlot == Slots.TABARD) drawBra = false;
  6881. if (uniqueSlot == Slots.PANTS) drawPanties = false
  6882. }
  6883. if (drawBra && self.bakedTextures[Region.TorsoUpper][1]) {
  6884. if (!self.bakedTextures[Region.TorsoUpper][1].ready()) return;
  6885. r = regions[Region.TorsoUpper];
  6886. ctx.drawImage(self.bakedTextures[Region.TorsoUpper][1].mergedImg, w * r.x, h * r.y, w * r.w, h * r.h)
  6887. }
  6888. if (drawPanties && self.bakedTextures[Region.LegUpper][1]) {
  6889. if (!self.bakedTextures[Region.LegUpper][1].ready()) return;
  6890. r = regions[Region.LegUpper];
  6891. ctx.drawImage(self.bakedTextures[Region.LegUpper][1].mergedImg, w * r.x, h * r.y, w * r.w, h * r.h)
  6892. }
  6893. if (self.TattoosIndex > 0 && self.class == Classes.DEMONHUNTER) {
  6894. if (self.bakedTextures[Region.Base][1]) {
  6895. if (!self.bakedTextures[Region.Base][1].ready()) return;
  6896. r = regions[Region.Base];
  6897. ctx.drawImage(self.bakedTextures[Region.Base][1].mergedImg, w * r.x, h * r.y, w * r.w, h * r.h)
  6898. }
  6899. }
  6900. var items = [];
  6901. for (i in self.items) {
  6902. items.push(self.items[i])
  6903. }
  6904. if (self.dhmodel) items.push(self.dhmodel);
  6905. items.sort(function(a, b) {
  6906. return a.sortValue - b.sortValue
  6907. });
  6908. for (i = 0; i < items.length; ++i) {
  6909. item = items[i];
  6910. if (!item.textures) continue;
  6911. for (j = 0; j < item.textures.length; ++j) {
  6912. t = item.textures[j];
  6913. if (t.gender != self.gender || !t.texture || !t.texture.ready()) continue;
  6914. if (t.region > 0) {
  6915. if ((self.race == Races.TAUREN || self.race == Races.TROLL || self.race == Races.DRAENEI || self.race == Races.BROKEN || self.race == Races.WORGEN) && t.region == Region.Foot) continue;
  6916. r = regions[t.region];
  6917. ctx.drawImage(t.texture.mergedImg, w * r.x, h * r.y, w * r.w, h * r.h)
  6918. }
  6919. }
  6920. }
  6921. var gl = self.renderer.context;
  6922. if (self.compositeTexture) gl.deleteTexture(self.compositeTexture);
  6923. self.compositeTexture = gl.createTexture();
  6924. gl.bindTexture(gl.TEXTURE_2D, self.compositeTexture);
  6925. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, self.compositeImage);
  6926. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  6927. self.needsCompositing = false
  6928. },
  6929. loadItems: function(items) {
  6930. var self = this;
  6931. if ($.isArray(items)) {
  6932. for (var i = 0; i < items.length; ++i) {
  6933. self.addItem(items[i][0], items[i][1])
  6934. }
  6935. } else {
  6936. for (var slot in items) {
  6937. self.addItem(parseInt(slot), items[slot])
  6938. }
  6939. }
  6940. },
  6941. loadDH: function(model) {
  6942. var self = this,
  6943. Wow = ZamModelViewer.Wow;
  6944. self.dhloaded = 0;
  6945. self.dhmodel = new Wow.HornModel(self, 23, model, self.race, self.gender)
  6946. },
  6947. addItem: function(slot, id) {
  6948. var self = this,
  6949. Wow = ZamModelViewer.Wow;
  6950. var item = new Wow.Item(self, slot, id, self.race, self.gender);
  6951. var uniqueSlot = item.uniqueSlot;
  6952. var altSlot = Wow.SlotAlternate[slot];
  6953. if (!self.items[uniqueSlot] || altSlot == 0) {
  6954. self.items[uniqueSlot] = item
  6955. } else {
  6956. item.uniqueSlot = altSlot;
  6957. self.items[altSlot] = item
  6958. }
  6959. },
  6960. removeSlot: function(slot) {
  6961. var self = this;
  6962. if (self.items[slot]) {
  6963. if (self.items[slot].models) {
  6964. for (var i = 0; i < self.items[slot].models.length; ++i) {
  6965. if (self.items[slot].models[i].model) self.items[slot].models[i].model.destroy()
  6966. }
  6967. }
  6968. self.items[slot] = null;
  6969. delete self.items[slot]
  6970. }
  6971. },
  6972. updateSlotMap: function() {
  6973. var self = this,
  6974. i;
  6975. self.slotAttachments = {};
  6976. if (self.attachments && self.attachmentLookup) {
  6977. var slotMap = {
  6978. 1: [11],
  6979. 3: [6, 5],
  6980. 22: [2],
  6981. 21: [1],
  6982. 17: [1],
  6983. 15: [2],
  6984. 25: [1],
  6985. 13: [1],
  6986. 14: [0],
  6987. 23: [2],
  6988. 6: [53],
  6989. 26: [1]
  6990. };
  6991. var sheathStandardOverrides = {
  6992. 21: 26,
  6993. 22: 27,
  6994. 15: 28,
  6995. 17: 26,
  6996. 25: 32,
  6997. 13: 32,
  6998. 23: 33,
  6999. 14: 28,
  7000. 26: 26
  7001. };
  7002. var SheathWeaponOverrides = {
  7003. 0: {
  7004. 21: 26,
  7005. 22: 27
  7006. },
  7007. 1: {
  7008. 21: 26,
  7009. 22: 27
  7010. },
  7011. 2: {
  7012. 21: 30,
  7013. 22: 31
  7014. },
  7015. 3: {
  7016. 21: 33,
  7017. 22: 32
  7018. },
  7019. 4: {
  7020. 21: 26,
  7021. 22: 27,
  7022. 15: 28
  7023. },
  7024. 5: {
  7025. 21: 26
  7026. },
  7027. 6: {
  7028. 21: 26,
  7029. 22: 27
  7030. },
  7031. 7: {
  7032. 21: 26,
  7033. 22: 27
  7034. },
  7035. 8: {
  7036. 21: 26,
  7037. 22: 27
  7038. }
  7039. };
  7040. for (var slot in slotMap) {
  7041. for (i = 0; i < slotMap[slot].length; ++i) {
  7042. var att = slotMap[slot][i];
  7043. if ((self.sheathMain >= 0 || self.sheathOff >= 0 || self.mount) && sheathStandardOverrides[slot]) att = sheathStandardOverrides[slot];
  7044. if (self.sheathMain >= 0 && slot == 21 && SheathWeaponOverrides[self.sheathMain][slot]) att = SheathWeaponOverrides[self.sheathMain][slot];
  7045. if (self.sheathOff >= 0 && slot == 22 && SheathWeaponOverrides[self.sheathOff][slot]) att = SheathWeaponOverrides[self.sheathOff][slot];
  7046. if (att >= self.attachmentLookup.length || self.attachmentLookup[att] == -1) continue;
  7047. if (!self.slotAttachments[slot]) self.slotAttachments[slot] = [];
  7048. self.slotAttachments[slot].push(self.attachmentLookup[att])
  7049. }
  7050. }
  7051. }
  7052. },
  7053. onLoaded: function() {
  7054. var self = this,
  7055. i;
  7056. if (self.texUnits) {
  7057. for (i = 0; i < self.texUnits.length; ++i) self.texUnits[i].setup(self);
  7058. self.sortedTexUnits = self.texUnits.concat();
  7059. self.sortedTexUnits.sort(function(a, b) {
  7060. if (a.meshId == b.meshId) return a.meshIndex - b.meshIndex;
  7061. else return a.meshId - b.meshId
  7062. })
  7063. }
  7064. self.updateSlotMap();
  7065. if (self.modelPath == 982557) {
  7066. self.setAnimation("StealthStand")
  7067. } else if (self.mount) {
  7068. if (ZamModelViewer.Wow.StandingMounts[self.mount.model.id]) {
  7069. self.setAnimation("StealthStand")
  7070. } else {
  7071. self.setAnimation("Mount")
  7072. }
  7073. } else {
  7074. self.setAnimation("Stand")
  7075. }
  7076. self.updateBuffers(true);
  7077. self.updateBounds();
  7078. self.setup();
  7079. self.loaded = true;
  7080. if (self.isMount && self.parent.loaded) {
  7081. self.parent.updateBounds()
  7082. }
  7083. if (self.parent && self.parent.loaded) {
  7084. self.parent.updateMeshes()
  7085. }
  7086. }
  7087. };
  7088. ZamModelViewer.Wow.ReversedModels = {
  7089. 147259: true
  7090. };
  7091. ZamModelViewer.Wow.ReversedItems = {
  7092. 139260: true,
  7093. 45146: true
  7094. };
  7095. ZamModelViewer.Wow.StandingMounts = {
  7096. 28060: true,
  7097. 28063: true,
  7098. 28082: true,
  7099. 41903: true,
  7100. 42147: true,
  7101. 44808: true,
  7102. 45271: true
  7103. };
  7104. ZamModelViewer.Wow.Types = {
  7105. ITEM: 1,
  7106. HELM: 2,
  7107. SHOULDER: 4,
  7108. NPC: 8,
  7109. CHARACTER: 16,
  7110. HUMANOIDNPC: 32,
  7111. OBJECT: 64,
  7112. ARMOR: 128,
  7113. PATH: 256
  7114. };
  7115. ZamModelViewer.Wow.Classes = {
  7116. WARRIOR: 1,
  7117. PALADIN: 2,
  7118. HUNTER: 3,
  7119. ROGUE: 4,
  7120. PRIEST: 5,
  7121. DEATHKNIGHT: 6,
  7122. SHAMAN: 7,
  7123. MAGE: 8,
  7124. WARLOCK: 9,
  7125. MONK: 10,
  7126. DRUID: 11,
  7127. DEMONHUNTER: 12
  7128. };
  7129. ZamModelViewer.Wow.Genders = {
  7130. MALE: 0,
  7131. FEMALE: 1,
  7132. 0: "male",
  7133. 1: "female"
  7134. };
  7135. ZamModelViewer.Wow.Races = {
  7136. HUMAN: 1,
  7137. ORC: 2,
  7138. DWARF: 3,
  7139. NIGHTELF: 4,
  7140. SCOURGE: 5,
  7141. TAUREN: 6,
  7142. GNOME: 7,
  7143. TROLL: 8,
  7144. GOBLIN: 9,
  7145. BLOODELF: 10,
  7146. DRAENEI: 11,
  7147. FELORC: 12,
  7148. NAGA: 13,
  7149. BROKEN: 14,
  7150. SKELETON: 15,
  7151. VRYKUL: 16,
  7152. TUSKARR: 17,
  7153. FORESTTROLL: 18,
  7154. TAUNKA: 19,
  7155. NORTHRENDSKELETON: 20,
  7156. ICETROLL: 21,
  7157. WORGEN: 22,
  7158. WORGENHUMAN: 23,
  7159. PANDAREN: 24,
  7160. 1: "human",
  7161. 2: "orc",
  7162. 3: "dwarf",
  7163. 4: "nightelf",
  7164. 5: "scourge",
  7165. 6: "tauren",
  7166. 7: "gnome",
  7167. 8: "troll",
  7168. 9: "goblin",
  7169. 10: "bloodelf",
  7170. 11: "draenei",
  7171. 12: "felorc",
  7172. 13: "naga_",
  7173. 14: "broken",
  7174. 15: "skeleton",
  7175. 16: "vrykul",
  7176. 17: "tuskarr",
  7177. 18: "foresttroll",
  7178. 19: "taunka",
  7179. 20: "northrendskeleton",
  7180. 21: "icetroll",
  7181. 22: "worgen",
  7182. 23: "human",
  7183. 24: "pandaren",
  7184. 25: "pandaren",
  7185. 26: "pandaren"
  7186. };
  7187. ZamModelViewer.Wow.UniqueSlots = [0, 1, 0, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 21, 22, 22, 16, 21, 0, 19, 5, 21, 22, 22, 0, 21, 21];
  7188. ZamModelViewer.Wow.SlotOrder = [0, 16, 0, 15, 1, 8, 10, 5, 6, 6, 7, 0, 0, 17, 18, 19, 14, 20, 0, 9, 8, 21, 22, 23, 0, 24, 25];
  7189. ZamModelViewer.Wow.SlotAlternate = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0];
  7190. ZamModelViewer.Wow.SlotType = [0, 2, 0, 4, 128, 128, 128, 128, 128, 128, 128, 0, 0, 1, 1, 1, 128, 1, 0, 128, 128, 1, 1, 1, 0, 1, 1];
  7191. ZamModelViewer.Wow.Slots = {
  7192. HEAD: 1,
  7193. SHOULDER: 3,
  7194. SHIRT: 4,
  7195. CHEST: 5,
  7196. BELT: 6,
  7197. PANTS: 7,
  7198. BOOTS: 8,
  7199. BRACERS: 9,
  7200. HANDS: 10,
  7201. ONEHAND: 13,
  7202. SHIELD: 14,
  7203. BOW: 15,
  7204. CAPE: 16,
  7205. TWOHAND: 17,
  7206. TABARD: 19,
  7207. ROBE: 20,
  7208. RIGHTHAND: 21,
  7209. LEFTHAND: 22,
  7210. OFFHAND: 23,
  7211. THROWN: 25,
  7212. RANGED: 26
  7213. };
  7214. ZamModelViewer.Wow.Regions = {
  7215. Base: 0,
  7216. ArmUpper: 1,
  7217. ArmLower: 2,
  7218. Hand: 3,
  7219. FaceUpper: 4,
  7220. FaceLower: 5,
  7221. TorsoUpper: 6,
  7222. TorsoLower: 7,
  7223. LegUpper: 8,
  7224. LegLower: 9,
  7225. Foot: 10,
  7226. FaceLower2: 11,
  7227. old: [{
  7228. x: 0,
  7229. y: 0,
  7230. w: 1,
  7231. h: 1
  7232. }, {
  7233. x: 0,
  7234. y: 0,
  7235. w: .5,
  7236. h: .25
  7237. }, {
  7238. x: 0,
  7239. y: .25,
  7240. w: .5,
  7241. h: .25
  7242. }, {
  7243. x: 0,
  7244. y: .5,
  7245. w: .5,
  7246. h: .125
  7247. }, {
  7248. x: 0,
  7249. y: .625,
  7250. w: .5,
  7251. h: .125
  7252. }, {
  7253. x: 0,
  7254. y: .75,
  7255. w: .5,
  7256. h: .25
  7257. }, {
  7258. x: .5,
  7259. y: 0,
  7260. w: .5,
  7261. h: .25
  7262. }, {
  7263. x: .5,
  7264. y: .25,
  7265. w: .5,
  7266. h: .125
  7267. }, {
  7268. x: .5,
  7269. y: .375,
  7270. w: .5,
  7271. h: .25
  7272. }, {
  7273. x: .5,
  7274. y: .625,
  7275. w: .5,
  7276. h: .25
  7277. }, {
  7278. x: .5,
  7279. y: .875,
  7280. w: .5,
  7281. h: .125
  7282. }],
  7283. "new": [{
  7284. x: 0,
  7285. y: 0,
  7286. w: .5,
  7287. h: 1
  7288. }, {
  7289. x: 0,
  7290. y: 0,
  7291. w: .25,
  7292. h: .25
  7293. }, {
  7294. x: 0,
  7295. y: .25,
  7296. w: .25,
  7297. h: .25
  7298. }, {
  7299. x: 0,
  7300. y: .5,
  7301. w: .25,
  7302. h: .125
  7303. }, {
  7304. x: .5,
  7305. y: 0,
  7306. w: .5,
  7307. h: 1
  7308. }, {
  7309. x: 0,
  7310. y: .75,
  7311. w: .25,
  7312. h: .25
  7313. }, {
  7314. x: .25,
  7315. y: 0,
  7316. w: .25,
  7317. h: .25
  7318. }, {
  7319. x: .25,
  7320. y: .25,
  7321. w: .25,
  7322. h: .125
  7323. }, {
  7324. x: .25,
  7325. y: .375,
  7326. w: .25,
  7327. h: .25
  7328. }, {
  7329. x: .25,
  7330. y: .625,
  7331. w: .25,
  7332. h: .25
  7333. }, {
  7334. x: .25,
  7335. y: .875,
  7336. w: .25,
  7337. h: .125
  7338. }, {
  7339. x: .5,
  7340. y: 0,
  7341. w: .5,
  7342. h: 1
  7343. }]
  7344. };
  7345. ZamModelViewer.Wow.Model.prototype.load = function() {
  7346. var self = this,
  7347. Type = ZamModelViewer.Wow.Types;
  7348. if (!self.model || !self.model.type || !self.model.id) return;
  7349. self._load(self.model.type, self.model.id)
  7350. };
  7351. ZamModelViewer.Wow.Model.prototype._load = function(type, id) {
  7352. var self = this,
  7353. Type = ZamModelViewer.Wow.Types,
  7354. url = null;
  7355. if (type == Type.ITEM) url = "meta/item/";
  7356. else if (type == Type.HELM) url = "meta/armor/1/";
  7357. else if (type == Type.SHOULDER) url = "meta/armor/3/";
  7358. else if (type == Type.NPC || type == Type.HUMANOIDNPC) url = "meta/npc/";
  7359. else if (type == Type.OBJECT) url = "meta/object/";
  7360. else if (type == Type.CHARACTER) url = "meta/character/";
  7361. if (url) {
  7362. url = self.opts.contentPath + url + id + ".json";
  7363. (function(type) {
  7364. $.getJSON(url, function(data) {
  7365. self.loadMeta(data, type)
  7366. })
  7367. })(type)
  7368. } else if (type == Type.PATH) {
  7369. self.modelPath = id;
  7370. if (!self.meta) self.meta = {};
  7371. url = self.opts.contentPath + "mo3/" + id + ".mo3";
  7372. $.ajax({
  7373. url: url,
  7374. type: "GET",
  7375. dataType: "binary",
  7376. responseType: "arraybuffer",
  7377. processData: false,
  7378. renderer: self.renderer,
  7379. success: function(buffer) {
  7380. self.loadMo3(buffer)
  7381. },
  7382. error: function(xhr, status, error) {
  7383. console.log(error)
  7384. }
  7385. })
  7386. }
  7387. };
  7388. ZamModelViewer.Wow.Model.prototype.loadMeta = function(meta, type) {
  7389. var self = this,
  7390. Type = ZamModelViewer.Wow.Types,
  7391. model, i;
  7392. if (!type) type = self.model.type;
  7393. if (!self.meta) self.meta = meta;
  7394. if (type == Type.CHARACTER) {
  7395. model = meta.Model;
  7396. if (self.opts.hd && meta.HDModel) {
  7397. model = meta.HDModel;
  7398. self.isHD = true
  7399. }
  7400. if (self.opts.sheathMain) self.sheathMain = self.opts.sheathMain;
  7401. if (self.opts.sheathOff) self.sheathOff = self.opts.sheathOff;
  7402. if (self.isHD && self.meta.HDTexture) {
  7403. self.npcTexture = new self.Texture(self, -1, self.meta.HDTexture)
  7404. } else if (self.meta.Texture) {
  7405. self.npcTexture = new self.Texture(self, -1, self.meta.Texture)
  7406. }
  7407. self.race = meta.Race;
  7408. self.gender = meta.Gender;
  7409. self._load(Type.PATH, model);
  7410. if (self.opts.cls) self.class = parseInt(self.opts.cls);
  7411. if (self.meta.DHGeosetsHDModel && self.class == 12) {
  7412. self.loadDH(self.meta.DHGeosetsHDModel)
  7413. }
  7414. if (self.meta.Equipment) {
  7415. self.loadItems(self.meta.Equipment)
  7416. }
  7417. if (self.opts.items) {
  7418. self.loadItems(self.opts.items)
  7419. }
  7420. if (self.model.type != Type.CHARACTER && self.meta.Race > 0) {
  7421. self.skinIndex = parseInt(self.meta.SkinColor);
  7422. self.hairIndex = parseInt(self.meta.HairStyle);
  7423. self.hairColorIndex = parseInt(self.meta.HairColor);
  7424. self.faceIndex = parseInt(self.meta.FaceType);
  7425. self.faceFeatureIndex = parseInt(self.meta.FacialHair);
  7426. self.faceColorIndex = self.hairColorIndex;
  7427. self.HornsIndex = 0;
  7428. self.EyePatchIndex = 0;
  7429. self.TattoosIndex = 0
  7430. } else {
  7431. if (self.opts.sk) self.skinIndex = parseInt(self.opts.sk);
  7432. if (self.opts.ha) self.hairIndex = parseInt(self.opts.ha);
  7433. if (self.opts.hc) self.hairColorIndex = parseInt(self.opts.hc);
  7434. if (self.opts.fa) self.faceIndex = parseInt(self.opts.fa);
  7435. if (self.opts.fh) self.faceFeatureIndex = parseInt(self.opts.fh);
  7436. if (self.opts.fc) self.faceColorIndex = parseInt(self.opts.fc);
  7437. if (self.opts.ho) self.HornsIndex = parseInt(self.opts.ho);
  7438. if (self.opts.ep) self.EyePatchIndex = parseInt(self.opts.ep);
  7439. if (self.opts.ta) self.TattoosIndex = parseInt(self.opts.ta)
  7440. }
  7441. } else if (type == Type.HELM) {
  7442. var race = 1;
  7443. var gender = 0;
  7444. if (self.parent) {
  7445. race = self.parent.race;
  7446. gender = self.parent.gender;
  7447. self.parent.hairVis = meta.ShowHair == 0;
  7448. self.parent.faceVis = meta.ShowFacial1 == 0
  7449. }
  7450. if (meta.RaceModels[gender] && meta.RaceModels[gender][race]) {
  7451. self._load(Type.PATH, meta.RaceModels[gender][race])
  7452. }
  7453. if (meta.Textures) {
  7454. for (i in meta.Textures) {
  7455. self.textureOverrides[i] = new self.Texture(self, parseInt(i), meta.Textures[i])
  7456. }
  7457. }
  7458. } else if (type == Type.SHOULDER) {
  7459. if (self.model.shoulder == 1 || self.model.shoulder === undefined && meta.Model) {
  7460. if (meta.Model) self._load(Type.PATH, meta.Model);
  7461. if (meta.Textures) {
  7462. for (i in meta.Textures) {
  7463. self.textureOverrides[i] = new self.Texture(self, parseInt(i), meta.Textures[i])
  7464. }
  7465. }
  7466. } else if (self.model.shoulder == 2 || self.model.shoulder === undefined && meta.Model2) {
  7467. if (meta.Model2) self._load(Type.PATH, meta.Model2);
  7468. if (meta.Textures2) {
  7469. for (i in meta.Textures2) {
  7470. self.textureOverrides[i] = new self.Texture(self, parseInt(i), meta.Textures2[i])
  7471. }
  7472. }
  7473. }
  7474. } else {
  7475. if (meta.Textures) {
  7476. for (i in meta.Textures) {
  7477. self.textureOverrides[i] = new self.Texture(self, parseInt(i), meta.Textures[i])
  7478. }
  7479. } else if (meta.GenderTextures && self.parent) {
  7480. var g = self.parent.gender;
  7481. for (i in meta.GenderTextures[g]) {
  7482. self.textureOverrides[i] = new self.Texture(self, parseInt(i), meta.GenderTextures[g][i])
  7483. }
  7484. }
  7485. if (self.opts.hd && meta.HDModel) {
  7486. self._load(Type.PATH, meta.HDModel)
  7487. } else if (meta.Model) {
  7488. self._load(Type.PATH, meta.Model)
  7489. } else if (meta.GenderModels && self.parent && meta.GenderModels[self.parent.gender]) {
  7490. self._load(Type.PATH, meta.GenderModels[self.parent.gender])
  7491. } else if (meta.Race > 0) {
  7492. model = ZamModelViewer.Wow.Races[meta.Race] + ZamModelViewer.Wow.Genders[meta.Gender];
  7493. self.race = meta.Race;
  7494. self.gender = meta.Gender;
  7495. self._load(Type.CHARACTER, model)
  7496. }
  7497. }
  7498. };
  7499. ZamModelViewer.Wow.Model.prototype.loadMo3 = function(buffer) {
  7500. if (!buffer) {
  7501. console.error("Bad buffer for DataView");
  7502. return
  7503. }
  7504. var self = this,
  7505. r = new ZamModelViewer.DataView(buffer),
  7506. i, Wow = ZamModelViewer.Wow;
  7507. var magic = r.getUint32();
  7508. if (magic != 604210112) {
  7509. console.log("Bad magic value");
  7510. return
  7511. }
  7512. var version = r.getUint32();
  7513. if (version < 2e3) {
  7514. console.log("Bad version");
  7515. return
  7516. }
  7517. var ofsVertices = r.getUint32();
  7518. var ofsIndices = r.getUint32();
  7519. var ofsSequences = r.getUint32();
  7520. var ofsAnimations = r.getUint32();
  7521. var ofsAnimLookup = r.getUint32();
  7522. var ofsBones = r.getUint32();
  7523. var ofsBoneLookup = r.getUint32();
  7524. var ofsKeyBoneLookup = r.getUint32();
  7525. var ofsMeshes = r.getUint32();
  7526. var ofsTexUnits = r.getUint32();
  7527. var ofsTexUnitLookup = r.getUint32();
  7528. var ofsRenderFlags = r.getUint32();
  7529. var ofsMaterials = r.getUint32();
  7530. var ofsMaterialLookup = r.getUint32();
  7531. var ofsTextureAnims = r.getUint32();
  7532. var ofsTexAnimLookup = r.getUint32();
  7533. var ofsTexReplacements = r.getUint32();
  7534. var ofsAttachments = r.getUint32();
  7535. var ofsAttachmentLookup = r.getUint32();
  7536. var ofsColors = r.getUint32();
  7537. var ofsAlphas = r.getUint32();
  7538. var ofsAlphaLookup = r.getUint32();
  7539. var ofsParticleEmitters = r.getUint32();
  7540. var ofsRibbonEmitters = r.getUint32();
  7541. var hasCharData = r.getBool();
  7542. var ofsSkinColors = r.getUint32();
  7543. var ofsFaceTypes = r.getUint32();
  7544. var ofsFacialStyles = r.getUint32();
  7545. var ofsFacialColors = r.getUint32();
  7546. var ofsHairStyles = r.getUint32();
  7547. var ofsHairColors = r.getUint32();
  7548. var ofsHornStyles = r.getUint32();
  7549. var ofsBlindfolds = r.getUint32();
  7550. var ofsColoredHands = r.getUint32();
  7551. var ofsTattoos = r.getUint32();
  7552. var uncompressedSize = r.getUint32();
  7553. var compressedData = new Uint8Array(buffer, r.position);
  7554. var data = null;
  7555. try {
  7556. data = pako.inflate(compressedData)
  7557. } catch (err) {
  7558. console.log("Decompression error: " + err);
  7559. return
  7560. }
  7561. if (data.length < uncompressedSize) {
  7562. console.log("Unexpected data size", data.length, uncompressedSize);
  7563. return
  7564. }
  7565. r = new ZamModelViewer.DataView(data.buffer);
  7566. r.position = ofsVertices;
  7567. var numVertices = r.getInt32();
  7568. if (numVertices > 0) {
  7569. self.vertices = new Array(numVertices);
  7570. for (i = 0; i < numVertices; ++i) {
  7571. self.vertices[i] = new Wow.Vertex(r)
  7572. }
  7573. }
  7574. r.position = ofsIndices;
  7575. var numIndices = r.getInt32();
  7576. if (numIndices > 0) {
  7577. self.indices = new Array(numIndices);
  7578. for (i = 0; i < numIndices; ++i) {
  7579. self.indices[i] = r.getUint16()
  7580. }
  7581. }
  7582. r.position = ofsAnimations;
  7583. var numAnims = r.getInt32();
  7584. if (numAnims > 0) {
  7585. self.animations = new Array(numAnims);
  7586. for (i = 0; i < numAnims; ++i) {
  7587. self.animations[i] = new Wow.Animation(r)
  7588. }
  7589. }
  7590. r.position = ofsAnimLookup;
  7591. var numAnimLookup = r.getInt32();
  7592. if (numAnimLookup > 0) {
  7593. self.animLookup = new Array(numAnimLookup);
  7594. for (i = 0; i < numAnimLookup; ++i) {
  7595. self.animLookup[i] = r.getInt16()
  7596. }
  7597. }
  7598. r.position = ofsBones;
  7599. var numBones = r.getInt32();
  7600. if (numBones > 0) {
  7601. self.bones = new Array(numBones);
  7602. for (i = 0; i < numBones; ++i) {
  7603. self.bones[i] = new Wow.Bone(self, i, r)
  7604. }
  7605. }
  7606. r.position = ofsBoneLookup;
  7607. var numBoneLookup = r.getInt32();
  7608. if (numBoneLookup > 0) {
  7609. self.boneLookup = new Array(numBoneLookup);
  7610. for (i = 0; i < numBoneLookup; ++i) {
  7611. self.boneLookup[i] = r.getInt16()
  7612. }
  7613. }
  7614. r.position = ofsKeyBoneLookup;
  7615. var numKeyBoneLookup = r.getInt32();
  7616. if (numKeyBoneLookup > 0) {
  7617. self.keyBoneLookup = new Array(numKeyBoneLookup);
  7618. for (i = 0; i < numKeyBoneLookup; ++i) {
  7619. self.keyBoneLookup[i] = r.getInt16()
  7620. }
  7621. }
  7622. r.position = ofsMeshes;
  7623. var numMeshes = r.getInt32();
  7624. if (numMeshes > 0) {
  7625. self.meshes = new Array(numMeshes);
  7626. for (i = 0; i < numMeshes; ++i) {
  7627. self.meshes[i] = new Wow.Mesh(r)
  7628. }
  7629. }
  7630. r.position = ofsTexUnits;
  7631. var numTexUnits = r.getInt32();
  7632. if (numTexUnits > 0) {
  7633. self.texUnits = new Array(numTexUnits);
  7634. for (i = 0; i < numTexUnits; ++i) {
  7635. self.texUnits[i] = new Wow.TexUnit(r)
  7636. }
  7637. }
  7638. r.position = ofsTexUnitLookup;
  7639. var numTexUnitLookup = r.getInt32();
  7640. if (numTexUnitLookup > 0) {
  7641. self.texUnitLookup = new Array(numTexUnitLookup);
  7642. for (i = 0; i < numTexUnitLookup; ++i) {
  7643. self.texUnitLookup[i] = r.getInt16()
  7644. }
  7645. }
  7646. r.position = ofsRenderFlags;
  7647. var numRenderFlags = r.getInt32();
  7648. if (numRenderFlags > 0) {
  7649. self.renderFlags = new Array(numRenderFlags);
  7650. for (i = 0; i < numRenderFlags; ++i) {
  7651. self.renderFlags[i] = new Wow.RenderFlag(r)
  7652. }
  7653. }
  7654. r.position = ofsMaterials;
  7655. var numMaterials = r.getInt32();
  7656. if (numMaterials > 0) {
  7657. self.materials = new Array(numMaterials);
  7658. for (i = 0; i < numMaterials; ++i) {
  7659. self.materials[i] = new Wow.Material(self, i, r)
  7660. }
  7661. }
  7662. r.position = ofsMaterialLookup;
  7663. var numMaterialLookup = r.getInt32();
  7664. if (numMaterialLookup > 0) {
  7665. self.materialLookup = new Array(numMaterialLookup);
  7666. for (i = 0; i < numMaterialLookup; ++i) {
  7667. self.materialLookup[i] = r.getInt16()
  7668. }
  7669. }
  7670. r.position = ofsTextureAnims;
  7671. var numTextureAnims = r.getInt32();
  7672. if (numTextureAnims > 0) {
  7673. self.textureAnims = new Array(numTextureAnims);
  7674. for (i = 0; i < numTextureAnims; ++i) {
  7675. self.textureAnims[i] = new Wow.TextureAnimation(r)
  7676. }
  7677. }
  7678. r.position = ofsTexAnimLookup;
  7679. var numTexAnimLookup = r.getInt32();
  7680. if (numTexAnimLookup > 0) {
  7681. self.textureAnimLookup = new Array(numTexAnimLookup);
  7682. for (i = 0; i < numTexAnimLookup; ++i) {
  7683. self.textureAnimLookup[i] = r.getInt16()
  7684. }
  7685. }
  7686. r.position = ofsTexReplacements;
  7687. var numTexReplacements = r.getInt32();
  7688. if (numTexReplacements > 0) {
  7689. self.textureReplacements = new Array(numTexReplacements);
  7690. for (i = 0; i < numTexReplacements; ++i) {
  7691. self.textureReplacements[i] = r.getInt16()
  7692. }
  7693. }
  7694. r.position = ofsAttachments;
  7695. var numAttachments = r.getInt32();
  7696. if (numAttachments > 0) {
  7697. self.attachments = new Array(numAttachments);
  7698. for (i = 0; i < numAttachments; ++i) {
  7699. self.attachments[i] = new Wow.Attachment(r)
  7700. }
  7701. }
  7702. r.position = ofsAttachmentLookup;
  7703. var numAttachmentLookup = r.getInt32();
  7704. if (numAttachmentLookup > 0) {
  7705. self.attachmentLookup = new Array(numAttachmentLookup);
  7706. for (i = 0; i < numAttachmentLookup; ++i) {
  7707. self.attachmentLookup[i] = r.getInt16()
  7708. }
  7709. }
  7710. r.position = ofsColors;
  7711. var numColors = r.getInt32();
  7712. if (numColors > 0) {
  7713. self.colors = new Array(numColors);
  7714. for (i = 0; i < numColors; ++i) {
  7715. self.colors[i] = new Wow.Color(r)
  7716. }
  7717. }
  7718. r.position = ofsAlphas;
  7719. var numAlphas = r.getInt32();
  7720. if (numAlphas > 0) {
  7721. self.alphas = new Array(numAlphas);
  7722. for (i = 0; i < numAlphas; ++i) {
  7723. self.alphas[i] = new Wow.Alpha(r)
  7724. }
  7725. }
  7726. r.position = ofsAlphaLookup;
  7727. var numAlphaLookup = r.getInt32();
  7728. if (numAlphaLookup > 0) {
  7729. self.alphaLookup = new Array(numAlphaLookup);
  7730. for (i = 0; i < numAlphaLookup; ++i) {
  7731. self.alphaLookup[i] = r.getInt16()
  7732. }
  7733. }
  7734. r.position = ofsParticleEmitters;
  7735. var numParticleEmitters = r.getInt32();
  7736. if (numParticleEmitters > 0) {
  7737. self.particleEmitters = new Array(numParticleEmitters);
  7738. for (i = 0; i < numParticleEmitters; ++i) {
  7739. self.particleEmitters[i] = new Wow.ParticleEmitter(self, r)
  7740. }
  7741. }
  7742. r.position = ofsRibbonEmitters;
  7743. var numRibbonEmitters = r.getInt32();
  7744. if (numRibbonEmitters > 0) {
  7745. self.ribbonEmitters = new Array(numRibbonEmitters);
  7746. for (i = 0; i < numRibbonEmitters; ++i) {
  7747. self.ribbonEmitters[i] = new Wow.RibbonEmitter(self, r)
  7748. }
  7749. }
  7750. if (hasCharData) {
  7751. r.position = ofsSkinColors;
  7752. var numSkinColors = r.getInt32();
  7753. if (numSkinColors > 0) {
  7754. self.skins = new Array(numSkinColors);
  7755. for (i = 0; i < numSkinColors; ++i) {
  7756. self.skins[i] = new Wow.Skin(r, version)
  7757. }
  7758. r.position = ofsFaceTypes;
  7759. for (i = 0; i < numSkinColors; ++i) {
  7760. self.skins[i].readFaces(r, version)
  7761. }
  7762. }
  7763. r.position = ofsFacialStyles;
  7764. var numFaceStyles = r.getInt32();
  7765. if (numFaceStyles > 0) {
  7766. self.faces = new Array(numFaceStyles);
  7767. for (i = 0; i < numFaceStyles; ++i) {
  7768. self.faces[i] = new Wow.Face(r)
  7769. }
  7770. data.position = ofsFacialColors;
  7771. for (i = 0; i < numFaceStyles; ++i) {
  7772. self.faces[i].readTextures(r, version)
  7773. }
  7774. }
  7775. r.position = ofsHairStyles;
  7776. var numHairStyles = r.getInt32();
  7777. if (numHairStyles > 0) {
  7778. self.hairs = new Array(numHairStyles);
  7779. for (i = 0; i < numHairStyles; ++i) {
  7780. self.hairs[i] = new Wow.Hair(r)
  7781. }
  7782. data.position = ofsHairColors;
  7783. for (i = 0; i < numHairStyles; ++i) {
  7784. self.hairs[i].readTextures(r, version)
  7785. }
  7786. }
  7787. r.position = ofsHornStyles;
  7788. var numHorns = r.getInt32();
  7789. if (numHorns > 0) {
  7790. self.horns = new Array(numHorns);
  7791. for (i = 0; i < numHorns; ++i) {
  7792. self.horns[i] = new Wow.Horns(r)
  7793. }
  7794. }
  7795. r.position = ofsBlindfolds;
  7796. var numBlindfolds = r.getInt32();
  7797. if (numBlindfolds > 0) {
  7798. self.blindFolds = new Array(numBlindfolds);
  7799. for (i = 0; i < numBlindfolds; ++i) {
  7800. self.blindFolds[i] = new Wow.Blindfolds(r)
  7801. }
  7802. }
  7803. r.position = ofsColoredHands;
  7804. var numColoredHands = r.getInt32();
  7805. if (numColoredHands > 0) {
  7806. self.coloredHands = new Array(numColoredHands);
  7807. for (i = 0; i < numColoredHands; ++i) {
  7808. self.coloredHands[i] = new Wow.ColoredHands(r)
  7809. }
  7810. }
  7811. r.position = ofsTattoos;
  7812. var numTattoos = r.getInt32();
  7813. if (numTattoos > 0) {
  7814. self.tattoos = new Array(numTattoos);
  7815. for (i = 0; i < numTattoos; ++i) {
  7816. self.tattoos[i] = new Wow.Tattoos(r)
  7817. }
  7818. }
  7819. }
  7820. self.onLoaded()
  7821. };
  7822. ZamModelViewer.Wow.Model.prototype.update = function() {
  7823. var self = this,
  7824. i, j;
  7825. if (!self.loaded || !self.texUnits) return;
  7826. self.frame++;
  7827. self.time = self.renderer.time;
  7828. if (self.animationList && self.animationList.length > 0) {
  7829. if (self.animStartTime == 0) self.animStartTime = self.time;
  7830. if (self.time - self.animStartTime >= self.currentAnimation.length) {
  7831. var nextAnim = Math.max(0, Math.randomInt(0, self.animationList.length + 3) - 3);
  7832. self.currentAnimation = self.animationList[nextAnim];
  7833. self.animStartTime = self.time
  7834. }
  7835. }
  7836. var numUnits = self.texUnits.length,
  7837. count, start, u;
  7838. for (i = 0; i < numUnits; ++i) {
  7839. u = self.texUnits[i];
  7840. if (!u.show) continue;
  7841. count = u.mesh.indexCount;
  7842. start = u.mesh.indexStart;
  7843. for (j = 0; j < count; ++j) self.vertices[self.indices[start + j]].frame = self.frame
  7844. }
  7845. var numBones = self.bones.length,
  7846. animTime = self.time - self.animStartTime,
  7847. vb = self.vbData;
  7848. if (self.bones && self.animations) {
  7849. for (i = 0; i < numBones; ++i) self.bones[i].updated = false;
  7850. for (i = 0; i < numBones; ++i) self.bones[i].update(animTime);
  7851. if (self.vertices) {
  7852. var numVerts = self.vertices.length,
  7853. v, b, w, idx, tmpVec3 = self.tmpVec3,
  7854. tmpVec4 = self.tmpVec4;
  7855. for (i = 0; i < numVerts; ++i) {
  7856. v = self.vertices[i];
  7857. if (v.frame != self.frame) continue;
  7858. idx = i * 8;
  7859. vb[idx] = vb[idx + 1] = vb[idx + 2] = vb[idx + 3] = vb[idx + 4] = vb[idx + 5] = 0;
  7860. for (j = 0; j < 4; ++j) {
  7861. w = v.weights[j] / 255;
  7862. if (w > 0) {
  7863. b = self.bones[v.bones[j]];
  7864. vec3.transformMat4(tmpVec3, v.position, b.matrix);
  7865. vec4.transformMat4(tmpVec4, v.normal, b.matrix);
  7866. vb[idx + 0] += tmpVec3[0] * w;
  7867. vb[idx + 1] += tmpVec3[1] * w;
  7868. vb[idx + 2] += tmpVec3[2] * w;
  7869. vb[idx + 3] += tmpVec4[0] * w;
  7870. vb[idx + 4] += tmpVec4[1] * w;
  7871. vb[idx + 5] += tmpVec4[2] * w
  7872. }
  7873. }
  7874. v.transPosition[0] = vb[idx + 0];
  7875. v.transPosition[1] = vb[idx + 1];
  7876. v.transPosition[2] = vb[idx + 2];
  7877. v.transNormal[0] = vb[idx + 3];
  7878. v.transNormal[1] = vb[idx + 4];
  7879. v.transNormal[2] = vb[idx + 5]
  7880. }
  7881. self.updateBuffers(false);
  7882. if (!self.animBounds) {
  7883. self.animBounds = true;
  7884. self.updateBounds()
  7885. }
  7886. }
  7887. }
  7888. };
  7889. ZamModelViewer.Wow.Model.prototype.draw = function(flipWinding) {
  7890. var self = this,
  7891. gl = self.renderer.context,
  7892. i, Wow = ZamModelViewer.Wow,
  7893. Races = Wow.Races,
  7894. Genders = Wow.Genders;
  7895. if (self.mount) {
  7896. self.mount.draw();
  7897. if (self.mount.loaded) {
  7898. var attach = self.mount.attachments[self.mount.attachmentLookup[0]];
  7899. var scale = 1 / self.mount.meta.Scale;
  7900. vec3.set(self.tmpVec, scale, scale, scale);
  7901. mat4.identity(self.tmpMat);
  7902. mat4.scale(self.tmpMat, self.tmpMat, self.tmpVec);
  7903. self.setMatrix(self.mount.matrix, self.mount.bones[attach.bone].matrix, attach.position, self.tmpMat)
  7904. }
  7905. }
  7906. var upsideDown = Wow.ReversedModels[self.model.id];
  7907. if (upsideDown && !self.parent) {
  7908. mat4.identity(self.matrix);
  7909. vec3.set(self.tmpVec, 1, 1, -1);
  7910. mat4.scale(self.matrix, self.matrix, self.tmpVec);
  7911. flipWinding = true
  7912. }
  7913. if (self.meta && self.meta.ItemClass == 2 && (self.meta.ItemSubClass == 13 || self.meta.ItemSubClass == 9) && !self.parent) {
  7914. mat4.identity(self.matrix);
  7915. vec3.set(self.tmpVec, 1, -1, 1);
  7916. mat4.scale(self.matrix, self.matrix, self.tmpVec);
  7917. flipWinding = true
  7918. }
  7919. if (!self.loaded || !self.texUnits) return;
  7920. self.update();
  7921. if (!self.shaderReady) self.initShader();
  7922. if (!self.program) return;
  7923. if (self.needsCompositing) self.compositeTextures();
  7924. gl.useProgram(self.program);
  7925. gl.uniformMatrix4fv(self.uniforms.vModelMatrix, false, self.matrix);
  7926. gl.uniformMatrix4fv(self.uniforms.vViewMatrix, false, self.renderer.viewMatrix);
  7927. gl.uniformMatrix4fv(self.uniforms.vProjMatrix, false, self.renderer.projMatrix);
  7928. gl.uniform3fv(self.uniforms.vCameraPos, self.renderer.eye);
  7929. gl.uniform4fv(self.uniforms.fAmbientColor, self.ambientColor);
  7930. gl.uniform4fv(self.uniforms.fPrimaryColor, self.primaryColor);
  7931. gl.uniform4fv(self.uniforms.fSecondaryColor, self.secondaryColor);
  7932. gl.uniform3fv(self.uniforms.fLightDir1, self.lightDir1);
  7933. gl.uniform3fv(self.uniforms.fLightDir2, self.lightDir2);
  7934. gl.uniform3fv(self.uniforms.fLightDir3, self.lightDir3);
  7935. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  7936. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.ib);
  7937. for (i in self.attribs) {
  7938. var a = self.attribs[i];
  7939. gl.enableVertexAttribArray(a.loc);
  7940. gl.vertexAttribPointer(a.loc, a.size, a.type, false, a.stride, a.offset)
  7941. }
  7942. if (flipWinding) gl.frontFace(gl.CW);
  7943. for (i = 0; i < self.sortedTexUnits.length; ++i) {
  7944. if (!self.sortedTexUnits[i].show) continue;
  7945. self.sortedTexUnits[i].draw()
  7946. }
  7947. if (flipWinding) gl.frontFace(gl.CCW);
  7948. if (self.dhmodel) {
  7949. var item = self.dhmodel;
  7950. if (item.models) {
  7951. for (var j = 0; j < item.models.length; ++j) {
  7952. if (item.models[j].model && item.models[j].bone > -1 && item.models[j].bone < self.bones.length) {
  7953. mat4.identity(self.tmpMat);
  7954. if (self.dhmodel.models[j].model.slot == 6 && !(self.gender == Genders.MALE && self.race == Races.NIGHTELF && self.isHD)) {
  7955. mat4.identity(self.tmpMat);
  7956. if (self.gender == Genders.FEMALE && self.race == Races.NIGHTELF) vec3.set(self.tmpVec, 1.3, 1.3, 1.3);
  7957. if (self.gender == Genders.FEMALE && self.race == Races.BLOODELF) vec3.set(self.tmpVec, 1.55, 1.55, 1.55);
  7958. if (self.gender == Genders.MALE && self.race == Races.BLOODELF) vec3.set(self.tmpVec, 1.3, 1.3, 1.3);
  7959. if (self.gender == Genders.MALE && self.race == Races.NIGHTELF) vec3.set(self.tmpVec, 1.15, 1.15, 1.15);
  7960. mat4.scale(self.tmpMat, self.tmpMat, self.tmpVec)
  7961. }
  7962. item.models[j].model.setMatrix(self.matrix, self.bones[item.models[j].bone].matrix, item.models[j].attachment.position, self.tmpMat);
  7963. item.models[j].model.update();
  7964. item.models[j].model.draw(winding)
  7965. }
  7966. }
  7967. }
  7968. }
  7969. for (i in self.items) {
  7970. var item = self.items[i];
  7971. if (!item.models) continue;
  7972. for (var j = 0; j < item.models.length; ++j) {
  7973. if (item.models[j].model && item.models[j].bone > -1 && item.models[j].bone < self.bones.length) {
  7974. var winding = false,
  7975. reversed = item.models[j].model.model.type == Wow.Types.ITEM && Wow.ReversedItems[item.models[j].model.model.id];
  7976. var upsideDown = Wow.ReversedModels[item.models[j].model.model.id];
  7977. if (j == 1 && item.models[j].model.model.type == Wow.Types.SHOULDER) reversed = true;
  7978. if (upsideDown) {
  7979. mat4.identity(self.tmpMat);
  7980. vec3.set(self.tmpVec, 1, 1, -1);
  7981. mat4.scale(self.tmpMat, self.tmpMat, self.tmpVec);
  7982. winding = true
  7983. } else if (reversed && item.slot != Wow.Slots.LEFTHAND || !reversed && item.slot == Wow.Slots.LEFTHAND) {
  7984. mat4.identity(self.tmpMat);
  7985. vec3.set(self.tmpVec, 1, -1, 1);
  7986. mat4.scale(self.tmpMat, self.tmpMat, self.tmpVec);
  7987. winding = true
  7988. } else {
  7989. mat4.identity(self.tmpMat)
  7990. }
  7991. item.models[j].model.setMatrix(self.matrix, self.bones[item.models[j].bone].matrix, item.models[j].attachment.position, self.tmpMat);
  7992. item.models[j].model.update();
  7993. item.models[j].model.draw(winding)
  7994. }
  7995. }
  7996. }
  7997. if (self.particleEmitters) {
  7998. for (i = 0; i < self.particleEmitters.length; ++i) {
  7999. self.particleEmitters[i].update(self.currentAnimation.index, self.time, self.renderer.delta);
  8000. self.particleEmitters[i].draw()
  8001. }
  8002. }
  8003. if (self.ribbonEmitters) {
  8004. for (i = 0; i < self.ribbonEmitters.length; ++i) {
  8005. self.ribbonEmitters[i].update(self.currentAnimation.index, self.time);
  8006. self.ribbonEmitters[i].draw()
  8007. }
  8008. }
  8009. for (i in self.attribs) {
  8010. gl.disableVertexAttribArray(self.attribs[i].loc)
  8011. }
  8012. };
  8013. ZamModelViewer.Wow.Model.prototype.initShader = function() {
  8014. var self = this,
  8015. gl = self.renderer.context;
  8016. self.shaderReady = true;
  8017. var vs = self.renderer.compileShader(gl.VERTEX_SHADER, self.vertShader);
  8018. var fs = self.renderer.compileShader(gl.FRAGMENT_SHADER, self.fragShader);
  8019. var program = gl.createProgram();
  8020. gl.attachShader(program, vs);
  8021. gl.attachShader(program, fs);
  8022. gl.linkProgram(program);
  8023. if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
  8024. console.error("Error linking shaders");
  8025. return
  8026. }
  8027. self.vs = vs;
  8028. self.fs = fs;
  8029. self.program = program;
  8030. self.uniforms = {
  8031. vModelMatrix: gl.getUniformLocation(program, "uModelMatrix"),
  8032. vViewMatrix: gl.getUniformLocation(program, "uViewMatrix"),
  8033. vProjMatrix: gl.getUniformLocation(program, "uProjMatrix"),
  8034. vCameraPos: gl.getUniformLocation(program, "uCameraPos"),
  8035. vTextureMatrix: gl.getUniformLocation(program, "uTextureMatrix"),
  8036. vTextureMatrix2: gl.getUniformLocation(program, "uTextureMatrix2"),
  8037. vTextureMatrix3: gl.getUniformLocation(program, "uTextureMatrix3"),
  8038. vTextureMatrix3: gl.getUniformLocation(program, "uTextureMatrix4"),
  8039. fHasTexture: gl.getUniformLocation(program, "uHasTexture"),
  8040. fHasTexture2: gl.getUniformLocation(program, "uHasTexture2"),
  8041. fHasTexture3: gl.getUniformLocation(program, "uHasTexture3"),
  8042. fHasTexture3: gl.getUniformLocation(program, "uHasTexture4"),
  8043. fHasAlpha: gl.getUniformLocation(program, "uHasAlpha"),
  8044. fBlendMode: gl.getUniformLocation(program, "uBlendMode"),
  8045. fUnlit: gl.getUniformLocation(program, "uUnlit"),
  8046. fColor: gl.getUniformLocation(program, "uColor"),
  8047. fAmbientColor: gl.getUniformLocation(program, "uAmbientColor"),
  8048. fPrimaryColor: gl.getUniformLocation(program, "uPrimaryColor"),
  8049. fSecondaryColor: gl.getUniformLocation(program, "uSecondaryColor"),
  8050. fLightDir1: gl.getUniformLocation(program, "uLightDir1"),
  8051. fLightDir2: gl.getUniformLocation(program, "uLightDir2"),
  8052. fLightDir3: gl.getUniformLocation(program, "uLightDir3"),
  8053. fTexture: gl.getUniformLocation(program, "uTexture"),
  8054. fTexture2: gl.getUniformLocation(program, "uTexture2"),
  8055. fTexture3: gl.getUniformLocation(program, "uTexture3"),
  8056. fTexture3: gl.getUniformLocation(program, "uTexture4"),
  8057. fAlpha: gl.getUniformLocation(program, "uAlpha")
  8058. };
  8059. self.attribs = {
  8060. position: {
  8061. loc: gl.getAttribLocation(program, "aPosition"),
  8062. type: gl.FLOAT,
  8063. size: 3,
  8064. offset: 0,
  8065. stride: 32
  8066. },
  8067. normal: {
  8068. loc: gl.getAttribLocation(program, "aNormal"),
  8069. type: gl.FLOAT,
  8070. size: 3,
  8071. offset: 12,
  8072. stride: 32
  8073. },
  8074. texcoord: {
  8075. loc: gl.getAttribLocation(program, "aTexCoord"),
  8076. type: gl.FLOAT,
  8077. size: 2,
  8078. offset: 24,
  8079. stride: 32
  8080. }
  8081. }
  8082. };
  8083. ZamModelViewer.Wow.Model.prototype.vertShader = " attribute vec3 aPosition; attribute vec3 aNormal; attribute vec2 aTexCoord; varying vec3 vNormal; varying vec2 vTexCoord; varying vec2 vTexCoord2; varying vec2 vTexCoord3; varying vec2 vTexCoord4; uniform mat4 uModelMatrix; uniform mat4 uPanningMatrix; uniform mat4 uViewMatrix; uniform mat4 uProjMatrix; uniform mat4 uTextureMatrix; uniform mat4 uTextureMatrix2; uniform mat4 uTextureMatrix3; uniform mat4 uTextureMatrix4; uniform vec3 uCameraPos; uniform bool uHasTexture; uniform bool uHasTexture2; uniform bool uHasTexture3; uniform bool uHasTexture4; void main(void) { gl_Position = uProjMatrix * uViewMatrix * uModelMatrix * vec4(aPosition, 1); if(uHasTexture) vTexCoord = (uTextureMatrix * vec4(aTexCoord, 0, 1)).st; if(uHasTexture2) vTexCoord2 = (uTextureMatrix2 * vec4(aTexCoord, 0, 1)).st; if(uHasTexture3) vTexCoord3 = (uTextureMatrix3 * vec4(aTexCoord, 0, 1)).st; if(uHasTexture4) vTexCoord4 = (uTextureMatrix4 * vec4(aTexCoord, 0, 1)).st; vNormal = mat3(uViewMatrix * uModelMatrix) * aNormal; }";
  8084. ZamModelViewer.Wow.Model.prototype.fragShader = " precision mediump float; varying vec3 vNormal; varying vec2 vTexCoord; varying vec2 vTexCoord2; varying vec2 vTexCoord3; varying vec2 vTexCoord4; uniform bool uHasTexture; uniform bool uHasTexture2; uniform bool uHasTexture3; uniform bool uHasTexture4; uniform bool uHasAlpha; uniform int uBlendMode; uniform bool uUnlit; uniform vec4 uColor; uniform vec4 uAmbientColor; uniform vec4 uPrimaryColor; uniform vec4 uSecondaryColor; uniform vec3 uLightDir1; uniform vec3 uLightDir2; uniform vec3 uLightDir3; uniform sampler2D uTexture; uniform sampler2D uTexture2; uniform sampler2D uTexture3; uniform sampler2D uTexture4; uniform sampler2D uAlpha; void main(void) { vec4 color = vec4(1, 1, 1, 1); if (uHasTexture) { color = texture2D(uTexture, vTexCoord.st); } if (uHasTexture2) { color *= texture2D(uTexture2, vTexCoord2.st); } if (uHasTexture3) { color *= texture2D(uTexture3, vTexCoord3.st); } if (uHasTexture4) { color *= texture2D(uTexture4, vTexCoord4.st); } if (uBlendMode == 7) { vec4 color2 = vec4(4, 4, 4, 4); color *= color2; } if ((uBlendMode == 1 || uBlendMode == 2 || uBlendMode == 4 || uBlendMode == 7) && uHasAlpha) { color.a = texture2D(uAlpha, vTexCoord.st).a; } color *= uColor; if (uBlendMode == 1) { if (color.a < 0.7) { discard; } } if (!uUnlit) { vec4 litColor = uAmbientColor; vec3 normal = normalize(vNormal); float dp = max(0.0, dot(normal, uLightDir1)); litColor += uPrimaryColor * dp; dp = max(0.0, dot(normal, uLightDir2)); litColor += uSecondaryColor * dp; dp = max(0.0, dot(normal, uLightDir3)); litColor += uSecondaryColor * dp; litColor = clamp(litColor, vec4(0,0,0,0), vec4(1,1,1,1)); color *= litColor; } gl_FragColor = color; }";
  8085. ZamModelViewer.Wow.Model.prototype.destroy = function() {
  8086. var self = this;
  8087. if (!self.renderer) return;
  8088. var gl = self.renderer.context,
  8089. i, j;
  8090. if (self.program) gl.deleteProgram(self.program);
  8091. if (self.vs) gl.deleteShader(self.vs);
  8092. if (self.fs) gl.deleteShader(self.fs);
  8093. if (self.vb) gl.deleteBuffer(self.vb);
  8094. if (self.ib) gl.deleteBuffer(self.ib);
  8095. self.program = null;
  8096. self.vs = null;
  8097. self.fs = null;
  8098. self.vb = null;
  8099. self.ib = null;
  8100. self.vbData = null;
  8101. self.uniforms = null;
  8102. self.attribs = null;
  8103. if (self.compositeTexture) gl.deleteTexture(self.compositeTexture);
  8104. if (self.npcTexture) self.npcTexture.destroy();
  8105. if (self.bakedTextures) {
  8106. for (i = 0; i < 11; ++i) {
  8107. for (j in self.bakedTextures[i]) {
  8108. self.bakedTextures[i][j].destroy()
  8109. }
  8110. }
  8111. }
  8112. if (self.specialTextures) {
  8113. for (i in self.specialTextures) {
  8114. self.specialTextures[i].destroy()
  8115. }
  8116. }
  8117. if (self.textureOverrides) {
  8118. for (i in self.textureOverrides) {
  8119. self.textureOverrides[i].destroy()
  8120. }
  8121. }
  8122. if (self.indices) self.indices = null;
  8123. if (self.animLookup) self.animLookup = null;
  8124. if (self.boneLookup) self.boneLookup = null;
  8125. if (self.keyBoneLookup) self.keyBoneLookup = null;
  8126. if (self.texUnitLookup) self.texUnitLookup = null;
  8127. if (self.materialLookup) self.materialLookup = null;
  8128. if (self.textureAnimLookup) self.textureAnimLookup = null;
  8129. if (self.textureReplacements) self.textureReplacements = null;
  8130. if (self.attachmentLookup) self.attachmentLookup = null;
  8131. if (self.alphaLookup) self.alphaLookup = null;
  8132. if (self.renderFlags)
  8133. for (i = 0; i < self.renderFlags.length; ++i) self.renderFlags[i] = null;
  8134. self.renderFlags = null;
  8135. var destroyArray = function(key) {
  8136. if (self[key]) {
  8137. var arr = self[key];
  8138. for (var i = 0; i < arr.length; ++i) {
  8139. if (arr[i] && arr[i].destroy) arr[i].destroy();
  8140. arr[i] = null
  8141. }
  8142. self[key] = null
  8143. }
  8144. };
  8145. destroyArray("vertices");
  8146. destroyArray("animations");
  8147. destroyArray("bones");
  8148. destroyArray("meshes");
  8149. destroyArray("texUnits");
  8150. destroyArray("materials");
  8151. destroyArray("textureAnims");
  8152. destroyArray("attachments");
  8153. destroyArray("colors");
  8154. destroyArray("alphas");
  8155. destroyArray("particleEmitters");
  8156. destroyArray("ribbonEmitters");
  8157. destroyArray("skins");
  8158. destroyArray("faces");
  8159. destroyArray("hairs");
  8160. if (self.items) {
  8161. for (i in self.items) {
  8162. self.items[i].destroy();
  8163. self.items[i] = null
  8164. }
  8165. }
  8166. if (self.dhmodel) {
  8167. self.dhmodel.destroy();
  8168. self.dhmodel = null
  8169. }
  8170. if (self.mount) self.mount.destroy();
  8171. self.mount = null;
  8172. self.renderer = null;
  8173. self.viewer = null;
  8174. self.model = null;
  8175. self.items = null;
  8176. self.textureOverrides = null;
  8177. self.specialTextures = null;
  8178. self.bakedTextures = null;
  8179. self.geosets = null;
  8180. self.slotAttachments = null;
  8181. self.matrix = null;
  8182. self.ambientColor = null;
  8183. self.primaryColor = null;
  8184. self.secondaryColor = null;
  8185. self.lightDir1 = null;
  8186. self.lightDir2 = null;
  8187. self.lightDir3 = null;
  8188. self.boundsMin = null;
  8189. self.boundsMax = null;
  8190. self.boundsCenter = null;
  8191. self.boundsSize = null;
  8192. self.tmpMat = null;
  8193. self.tmpVec = null;
  8194. self.tmpVec2 = null;
  8195. self.tmpVec3 = null;
  8196. self.tmpVec4 = null;
  8197. self.mountMat = null
  8198. };
  8199. (function() {
  8200. ZamModelViewer.Wow.Animated = function() {};
  8201. ZamModelViewer.Wow.Animated.prototype = {
  8202. destroy: function() {
  8203. var self = this;
  8204. if (self.data)
  8205. for (var i = 0; i < self.data.length; ++i) self.data[i] = null;
  8206. self.times = null;
  8207. self.data = null;
  8208. return null
  8209. },
  8210. createValue: function() {
  8211. return this.defaultValue
  8212. },
  8213. defaultValue: 0,
  8214. setDefault: function(v) {
  8215. this.defaultValue = v
  8216. },
  8217. interpolate: function(v1, v2, r, result) {
  8218. result = v1 + (v2 - v1) * r;
  8219. return result
  8220. },
  8221. set: function(result, value) {
  8222. result = value;
  8223. return result
  8224. },
  8225. getDefault: function(r) {
  8226. r = this.defaultValue;
  8227. return r
  8228. },
  8229. readValue: function(r) {
  8230. return r.getInt32()
  8231. },
  8232. getValue: function(time, result) {
  8233. var self = this;
  8234. if (result === undefined) result = self.createValue();
  8235. else result = self.getDefault(result);
  8236. if (self.type != 0 || self.data.length > 1) {
  8237. if (self.times.length > 1) {
  8238. var maxTime = self.times[self.times.length - 1];
  8239. if (maxTime > 0 && time > maxTime) time %= maxTime;
  8240. var idx = 0,
  8241. numTimes = self.times.length;
  8242. for (var i = 0; i < numTimes; ++i) {
  8243. if (time >= self.times[i] && time < self.times[i + 1]) {
  8244. idx = i;
  8245. break
  8246. }
  8247. }
  8248. var t1 = self.times[idx],
  8249. t2 = self.times[idx + 1],
  8250. r = 0;
  8251. if (t1 != t2) r = (time - t1) / (t2 - t1);
  8252. if (self.type == 1) return self.interpolate(self.data[idx], self.data[idx + 1], r, result);
  8253. else {
  8254. result = self.set(result, self.data[idx]);
  8255. return result
  8256. }
  8257. } else if (self.data.length > 0) {
  8258. result = self.set(result, self.data[0]);
  8259. return result
  8260. } else {
  8261. return result
  8262. }
  8263. } else {
  8264. if (self.data.length == 0) return result;
  8265. else {
  8266. result = self.set(result, self.data[0]);
  8267. return result
  8268. }
  8269. }
  8270. },
  8271. read: function(r) {
  8272. var self = this,
  8273. i;
  8274. self.type = r.getInt16();
  8275. self.seq = r.getInt16();
  8276. self.used = r.getBool();
  8277. var numTimes = r.getInt32();
  8278. self.times = new Array(numTimes);
  8279. for (i = 0; i < numTimes; ++i) {
  8280. self.times[i] = r.getInt32()
  8281. }
  8282. var numData = r.getInt32();
  8283. self.data = new Array(numData);
  8284. for (i = 0; i < numData; ++i) {
  8285. self.data[i] = self.readValue(r)
  8286. }
  8287. }
  8288. };
  8289. ZamModelViewer.Wow.Animated.destroySet = function(dataset) {
  8290. if (!dataset || dataset.length == 0) return;
  8291. for (var i = 0; i < dataset.length; ++i) {
  8292. dataset[i].destroy();
  8293. dataset[i] = null
  8294. }
  8295. return null
  8296. };
  8297. ZamModelViewer.Wow.Animated.getValue = function(type, dataset, anim, time, result) {
  8298. if (!result) result = type.createValue();
  8299. else result = type.getDefault(result);
  8300. if (!dataset || dataset.length == 0) return result;
  8301. if (anim >= dataset.length) anim = 0;
  8302. return dataset[anim].getValue(time, result)
  8303. };
  8304. ZamModelViewer.Wow.Animated.isUsed = function(dataset, anim) {
  8305. if (!dataset || dataset.length == 0) return false;
  8306. if (anim >= dataset.length) anim = 0;
  8307. return dataset[anim].used
  8308. };
  8309. ZamModelViewer.Wow.AnimatedVec3 = function(r) {
  8310. var self = this;
  8311. self.read(r)
  8312. };
  8313. ZamModelViewer.Wow.AnimatedVec3.prototype = new ZamModelViewer.Wow.Animated;
  8314. ZamModelViewer.Wow.AnimatedVec3.prototype.constructor = ZamModelViewer.Wow.AnimatedVec3;
  8315. ZamModelViewer.Wow.AnimatedVec3.prototype.createValue = function() {
  8316. return vec3.clone(this.defaultValue)
  8317. };
  8318. ZamModelViewer.Wow.AnimatedVec3.prototype.defaultValue = vec3.create();
  8319. ZamModelViewer.Wow.AnimatedVec3.prototype.getDefault = function(result) {
  8320. vec3.copy(result, this.defaultValue);
  8321. return result
  8322. };
  8323. ZamModelViewer.Wow.AnimatedVec3.prototype.interpolate = function(v1, v2, r, result) {
  8324. return vec3.lerp(result, v1, v2, r)
  8325. };
  8326. ZamModelViewer.Wow.AnimatedVec3.prototype.set = function(result, value) {
  8327. result[0] = value[0];
  8328. result[1] = value[1];
  8329. result[2] = value[2]
  8330. };
  8331. ZamModelViewer.Wow.AnimatedVec3.prototype.readValue = function(r) {
  8332. return vec3.set(vec3.create(), r.getFloat(), r.getFloat(), r.getFloat())
  8333. };
  8334. ZamModelViewer.Wow.AnimatedVec3.getValue = function(dataset, anim, time, result) {
  8335. return ZamModelViewer.Wow.Animated.getValue(ZamModelViewer.Wow.AnimatedVec3.prototype, dataset, anim, time, result)
  8336. };
  8337. ZamModelViewer.Wow.AnimatedVec3.readSet = function(r) {
  8338. var count = r.getInt32();
  8339. var data = new Array(count);
  8340. for (var i = 0; i < count; ++i) data[i] = new ZamModelViewer.Wow.AnimatedVec3(r);
  8341. return data
  8342. };
  8343. ZamModelViewer.Wow.AnimatedQuat = function(r) {
  8344. var self = this;
  8345. self.read(r)
  8346. };
  8347. ZamModelViewer.Wow.AnimatedQuat.prototype = new ZamModelViewer.Wow.Animated;
  8348. ZamModelViewer.Wow.AnimatedQuat.prototype.constructor = ZamModelViewer.Wow.AnimatedQuat;
  8349. ZamModelViewer.Wow.AnimatedQuat.prototype.createValue = function() {
  8350. return quat.clone(this.defaultValue)
  8351. };
  8352. ZamModelViewer.Wow.AnimatedQuat.prototype.defaultValue = quat.create();
  8353. ZamModelViewer.Wow.AnimatedQuat.prototype.getDefault = function(result) {
  8354. quat.copy(result, this.defaultValue);
  8355. return result
  8356. };
  8357. ZamModelViewer.Wow.AnimatedQuat.prototype.interpolate = function(v1, v2, r, result) {
  8358. return quat.slerp(result, v1, v2, r)
  8359. };
  8360. ZamModelViewer.Wow.AnimatedQuat.prototype.set = function(result, value) {
  8361. result[0] = value[0];
  8362. result[1] = value[1];
  8363. result[2] = value[2];
  8364. result[3] = value[3]
  8365. };
  8366. ZamModelViewer.Wow.AnimatedQuat.prototype.readValue = function(r) {
  8367. return quat.set(quat.create(), r.getFloat(), r.getFloat(), r.getFloat(), r.getFloat())
  8368. };
  8369. ZamModelViewer.Wow.AnimatedQuat.getValue = function(dataset, anim, time, result) {
  8370. return ZamModelViewer.Wow.Animated.getValue(ZamModelViewer.Wow.AnimatedQuat.prototype, dataset, anim, time, result)
  8371. };
  8372. ZamModelViewer.Wow.AnimatedUint16 = function(r) {
  8373. var self = this;
  8374. self.read(r)
  8375. };
  8376. ZamModelViewer.Wow.AnimatedUint16.prototype = new ZamModelViewer.Wow.Animated;
  8377. ZamModelViewer.Wow.AnimatedUint16.prototype.constructor = ZamModelViewer.Wow.AnimatedUint16;
  8378. ZamModelViewer.Wow.AnimatedUint16.prototype.readValue = function(r) {
  8379. return r.getUint16()
  8380. };
  8381. ZamModelViewer.Wow.AnimatedUint16.getValue = function(dataset, anim, time, result) {
  8382. return ZamModelViewer.Wow.Animated.getValue(ZamModelViewer.Wow.AnimatedUint16.prototype, dataset, anim, time, result)
  8383. };
  8384. ZamModelViewer.Wow.AnimatedUint16.readSet = function(r) {
  8385. var count = r.getInt32();
  8386. var data = new Array(count);
  8387. for (var i = 0; i < count; ++i) data[i] = new ZamModelViewer.Wow.AnimatedUint16(r);
  8388. return data
  8389. };
  8390. ZamModelViewer.Wow.AnimatedFloat = function(r) {
  8391. var self = this;
  8392. self.read(r)
  8393. };
  8394. ZamModelViewer.Wow.AnimatedFloat.prototype = new ZamModelViewer.Wow.Animated;
  8395. ZamModelViewer.Wow.AnimatedFloat.prototype.constructor = ZamModelViewer.Wow.AnimatedFloat;
  8396. ZamModelViewer.Wow.AnimatedFloat.prototype.readValue = function(r) {
  8397. return r.getFloat()
  8398. };
  8399. ZamModelViewer.Wow.AnimatedFloat.getValue = function(dataset, anim, time, result) {
  8400. return ZamModelViewer.Wow.Animated.getValue(ZamModelViewer.Wow.AnimatedFloat.prototype, dataset, anim, time, result)
  8401. };
  8402. ZamModelViewer.Wow.AnimatedFloat.readSet = function(r) {
  8403. var count = r.getInt32();
  8404. var data = new Array(count);
  8405. for (var i = 0; i < count; ++i) data[i] = new ZamModelViewer.Wow.AnimatedFloat(r);
  8406. return data
  8407. };
  8408. ZamModelViewer.Wow.AnimatedUint8 = function(r) {
  8409. var self = this;
  8410. self.read(r)
  8411. };
  8412. ZamModelViewer.Wow.AnimatedUint8.prototype = new ZamModelViewer.Wow.Animated;
  8413. ZamModelViewer.Wow.AnimatedUint8.prototype.constructor = ZamModelViewer.Wow.AnimatedUint8;
  8414. ZamModelViewer.Wow.AnimatedUint8.prototype.readValue = function(r) {
  8415. return r.getUint8()
  8416. };
  8417. ZamModelViewer.Wow.AnimatedUint8.getValue = function(dataset, anim, time, result) {
  8418. return ZamModelViewer.Wow.Animated.getValue(ZamModelViewer.Wow.AnimatedUint8.prototype, dataset, anim, time, result)
  8419. };
  8420. ZamModelViewer.Wow.AnimatedUint8.readSet = function(r) {
  8421. var count = r.getInt32();
  8422. var data = new Array(count);
  8423. for (var i = 0; i < count; ++i) data[i] = new ZamModelViewer.Wow.AnimatedUint8(r);
  8424. return data
  8425. };
  8426. ZamModelViewer.Wow.SAnimated = function() {};
  8427. ZamModelViewer.Wow.SAnimated.prototype = {
  8428. destroy: function() {
  8429. var self = this;
  8430. for (var i = 0; i < self.data.length; ++i) self.data[i] = null;
  8431. self.times = null;
  8432. self.data = null;
  8433. return null
  8434. },
  8435. createValue: function() {
  8436. return this.defaultValue
  8437. },
  8438. defaultValue: 0,
  8439. setDefault: function(v) {
  8440. this.defaultValue = v
  8441. },
  8442. interpolate: function(v1, v2, r, result) {
  8443. result = v1 + (v2 - v1) * r;
  8444. return result
  8445. },
  8446. set: function(result, value) {
  8447. result = value;
  8448. return result
  8449. },
  8450. getDefault: function(r) {
  8451. r = this.defaultValue;
  8452. return r
  8453. },
  8454. readValue: function(r) {
  8455. return r.getInt32()
  8456. },
  8457. getValue: function(time, result) {
  8458. var self = this;
  8459. if (result === undefined) result = self.createValue();
  8460. else result = self.getDefault(result);
  8461. if (self.data.length > 1 && self.times.length > 1) {
  8462. var maxTime = self.times[self.times.length - 1];
  8463. if (maxTime > 0 && time > maxTime) time %= maxTime;
  8464. var idx = 0,
  8465. numTimes = self.times.length;
  8466. for (var i = 0; i < numTimes; ++i) {
  8467. if (time >= self.times[i] && time < self.times[i + 1]) {
  8468. idx = i;
  8469. break
  8470. }
  8471. }
  8472. var t1 = self.times[idx],
  8473. t2 = self.times[idx + 1],
  8474. r = 0;
  8475. if (t1 != t2) r = (time - t1) / (t2 - t1);
  8476. return self.interpolate(self.data[idx], self.data[idx + 1], r, result)
  8477. } else if (self.data.length > 0) {
  8478. result = self.set(result, self.data[0]);
  8479. return result
  8480. } else {
  8481. return result
  8482. }
  8483. },
  8484. read: function(r) {
  8485. var self = this,
  8486. i;
  8487. var numTimes = r.getInt32();
  8488. self.times = new Array(numTimes);
  8489. for (i = 0; i < numTimes; ++i) {
  8490. self.times[i] = r.getUint32()
  8491. }
  8492. var numData = r.getInt32();
  8493. self.data = new Array(numData);
  8494. for (i = 0; i < numData; ++i) {
  8495. self.data[i] = self.readValue(r)
  8496. }
  8497. }
  8498. };
  8499. ZamModelViewer.Wow.SAnimatedVec2 = function(r) {
  8500. var self = this;
  8501. self.read(r)
  8502. };
  8503. ZamModelViewer.Wow.SAnimatedVec2.prototype = new ZamModelViewer.Wow.SAnimated;
  8504. ZamModelViewer.Wow.SAnimatedVec2.prototype.constructor = ZamModelViewer.Wow.SAnimatedVec2;
  8505. ZamModelViewer.Wow.SAnimatedVec2.prototype.createValue = function() {
  8506. return vec2.clone(this.defaultValue)
  8507. };
  8508. ZamModelViewer.Wow.SAnimatedVec2.prototype.defaultValue = vec2.create();
  8509. ZamModelViewer.Wow.SAnimatedVec2.prototype.getDefault = function(result) {
  8510. vec2.copy(result, this.defaultValue);
  8511. return result
  8512. };
  8513. ZamModelViewer.Wow.SAnimatedVec2.prototype.interpolate = function(v1, v2, r, result) {
  8514. return vec2.lerp(result, v1, v2, r)
  8515. };
  8516. ZamModelViewer.Wow.SAnimatedVec2.prototype.set = function(result, value) {
  8517. result[0] = value[0];
  8518. result[1] = value[1];
  8519. result[2] = value[2]
  8520. };
  8521. ZamModelViewer.Wow.SAnimatedVec2.prototype.readValue = function(r) {
  8522. return vec2.set(vec2.create(), r.getFloat(), r.getFloat())
  8523. };
  8524. ZamModelViewer.Wow.SAnimatedVec2.getValue = function(dataset, anim, time, result) {
  8525. return ZamModelViewer.Wow.Animated.getValue(ZamModelViewer.Wow.SAnimatedVec2.prototype, dataset, anim, time, result)
  8526. };
  8527. ZamModelViewer.Wow.SAnimatedVec3 = function(r) {
  8528. var self = this;
  8529. self.read(r)
  8530. };
  8531. ZamModelViewer.Wow.SAnimatedVec3.prototype = new ZamModelViewer.Wow.SAnimated;
  8532. ZamModelViewer.Wow.SAnimatedVec3.prototype.constructor = ZamModelViewer.Wow.SAnimatedVec3;
  8533. ZamModelViewer.Wow.SAnimatedVec3.prototype.createValue = function() {
  8534. return vec3.clone(this.defaultValue)
  8535. };
  8536. ZamModelViewer.Wow.SAnimatedVec3.prototype.defaultValue = vec3.create();
  8537. ZamModelViewer.Wow.SAnimatedVec3.prototype.getDefault = function(result) {
  8538. vec3.copy(result, this.defaultValue);
  8539. return result
  8540. };
  8541. ZamModelViewer.Wow.SAnimatedVec3.prototype.interpolate = function(v1, v2, r, result) {
  8542. return vec3.lerp(result, v1, v2, r)
  8543. };
  8544. ZamModelViewer.Wow.SAnimatedVec3.prototype.set = function(result, value) {
  8545. result[0] = value[0];
  8546. result[1] = value[1];
  8547. result[2] = value[2]
  8548. };
  8549. ZamModelViewer.Wow.SAnimatedVec3.prototype.readValue = function(r) {
  8550. return vec3.set(vec3.create(), r.getFloat(), r.getFloat(), r.getFloat())
  8551. };
  8552. ZamModelViewer.Wow.SAnimatedVec3.getValue = function(dataset, anim, time, result) {
  8553. return ZamModelViewer.Wow.Animated.getValue(ZamModelViewer.Wow.SAnimatedVec3.prototype, dataset, anim, time, result)
  8554. };
  8555. ZamModelViewer.Wow.SAnimatedUint16 = function(r) {
  8556. var self = this;
  8557. self.read(r)
  8558. };
  8559. ZamModelViewer.Wow.SAnimatedUint16.prototype = new ZamModelViewer.Wow.SAnimated;
  8560. ZamModelViewer.Wow.SAnimatedUint16.prototype.constructor = ZamModelViewer.Wow.SAnimatedUint16;
  8561. ZamModelViewer.Wow.SAnimatedUint16.prototype.readValue = function(r) {
  8562. return r.getUint16()
  8563. };
  8564. ZamModelViewer.Wow.SAnimatedUint16.getValue = function(dataset, anim, time, result) {
  8565. return ZamModelViewer.Wow.SAnimated.getValue(ZamModelViewer.Wow.SAnimatedUint16.prototype, dataset, anim, time, result)
  8566. }
  8567. })();
  8568. ZamModelViewer.Wow.Texture = function(model, index, file) {
  8569. var self = this,
  8570. gl = model.renderer.context;
  8571. self.model = model;
  8572. self.index = index;
  8573. self.url = model.opts.contentPath + "textures/" + file + ".png";
  8574. self.texture = null;
  8575. self.alphaTexture = null;
  8576. self.img = self.alphaImg = self.mergedImg = null;
  8577. self.loaded = false;
  8578. (function(self, gl) {
  8579. self.mergedImg = new Image;
  8580. self.mergedImg.crossOrigin = "";
  8581. self.mergedImg.onload = function() {
  8582. self.splitImages()
  8583. };
  8584. self.mergedImg.onerror = function() {
  8585. self.mergedImg = null
  8586. };
  8587. self.mergedImg.src = self.url
  8588. })(self, gl)
  8589. };
  8590. ZamModelViewer.Wow.Texture.prototype = {
  8591. ready: function() {
  8592. return this.loaded
  8593. },
  8594. destroy: function() {
  8595. var self = this;
  8596. if (!self.model) return;
  8597. var gl = self.model.renderer.context;
  8598. if (self.texture) gl.deleteTexture(self.texture);
  8599. if (self.alphaTexture) gl.deleteTexture(self.alphaTexture);
  8600. self.texture = null;
  8601. self.alphaTexture = null;
  8602. self.img = self.alphaImg = self.mergedImg = null;
  8603. self.model = null
  8604. },
  8605. splitImages: function() {
  8606. var self = this,
  8607. gl = self.model.renderer.context;
  8608. var width = self.mergedImg.width,
  8609. height = self.mergedImg.height;
  8610. var canvas = document.createElement("canvas");
  8611. canvas.width = width;
  8612. canvas.height = height;
  8613. var ctx = canvas.getContext("2d");
  8614. ctx.drawImage(self.mergedImg, 0, 0, width, height);
  8615. var rgba = ctx.getImageData(0, 0, width, height),
  8616. p = rgba.data;
  8617. var hasAlpha = false,
  8618. alphaVal, i;
  8619. for (i = 0; i < p.length; i += 4) {
  8620. alphaVal = p[i + 3];
  8621. if (!hasAlpha && alphaVal != 255) hasAlpha = true
  8622. }
  8623. self.texture = gl.createTexture();
  8624. gl.bindTexture(gl.TEXTURE_2D, self.texture);
  8625. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, self.mergedImg);
  8626. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  8627. if (hasAlpha) {
  8628. self.alphaTexture = gl.createTexture();
  8629. gl.bindTexture(gl.TEXTURE_2D, self.alphaTexture);
  8630. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, self.mergedImg);
  8631. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
  8632. }
  8633. self.loaded = true
  8634. }
  8635. };
  8636. ZamModelViewer.Wow.Item = function(model, slot, id, race, gender) {
  8637. var self = this;
  8638. self.model = model;
  8639. self.slot = slot;
  8640. self.uniqueSlot = ZamModelViewer.Wow.UniqueSlots[slot];
  8641. self.sortValue = ZamModelViewer.Wow.SlotOrder[slot];
  8642. self.models = null;
  8643. self.geosets = null;
  8644. self.textures = null;
  8645. self.geoA = 0;
  8646. self.geoB = 0;
  8647. self.geoC = 0;
  8648. self.loaded = false;
  8649. if (id) {
  8650. self.load(id, race, gender)
  8651. }
  8652. };
  8653. ZamModelViewer.Wow.Item.prototype = {
  8654. destroy: function() {
  8655. var self = this,
  8656. i;
  8657. self.model = null;
  8658. if (self.models) {
  8659. for (i = 0; i < self.models.length; ++i) {
  8660. if (self.models[i].model) self.models[i].model.destroy();
  8661. self.models[i].model = null;
  8662. self.models[i].attachment = null;
  8663. self.models[i] = null
  8664. }
  8665. self.models = null
  8666. }
  8667. if (self.textures) {
  8668. for (i = 0; i < self.textures; ++i) {
  8669. if (self.textures[i].texture) self.textures[i].texture.destroy();
  8670. self.textures[i].texture = null;
  8671. self.textures[i] = null
  8672. }
  8673. self.textures = null
  8674. }
  8675. self.geosets = null
  8676. },
  8677. load: function(id, race, gender) {
  8678. var self = this,
  8679. Wow = ZamModelViewer.Wow;
  8680. self.id = id;
  8681. if (self.slot == Wow.Slots.SHOULDER) {
  8682. self.models = new Array(2)
  8683. } else if (Wow.SlotType[self.slot] != Wow.Types.ARMOR) {
  8684. self.models = new Array(1)
  8685. }
  8686. if (self.models) {
  8687. for (var i = 0; i < self.models.length; ++i) {
  8688. self.models[i] = {
  8689. race: race,
  8690. gender: gender,
  8691. bone: -1,
  8692. attachment: null,
  8693. model: null
  8694. };
  8695. var modelInfo = {
  8696. type: Wow.SlotType[self.slot],
  8697. id: self.id,
  8698. parent: self.model
  8699. };
  8700. if (self.slot == Wow.Slots.SHOULDER) {
  8701. modelInfo.shoulder = i + 1
  8702. }
  8703. self.models[i].model = new Wow.Model(self.model.renderer, self.model.viewer, modelInfo, i)
  8704. }
  8705. self.loaded = true
  8706. } else {
  8707. var url = self.model.opts.contentPath + "meta/armor/" + self.slot + "/" + self.id + ".json";
  8708. $.getJSON(url, function(data) {
  8709. self.loadMeta(data)
  8710. })
  8711. }
  8712. },
  8713. loadMeta: function(meta) {
  8714. var self = this,
  8715. Wow = ZamModelViewer.Wow;
  8716. self.slot = parseInt(meta.Slot);
  8717. if (meta.Geosets) {
  8718. self.geosets = [];
  8719. for (var idx in meta.Geosets) {
  8720. self.geosets.push({
  8721. index: parseInt(idx),
  8722. value: meta.Geosets[idx]
  8723. })
  8724. }
  8725. }
  8726. if (meta.GenderTextures) {
  8727. self.textures = [];
  8728. for (var g in meta.GenderTextures) {
  8729. var gender = parseInt(g);
  8730. if (g != self.model.gender) {
  8731. var textures = meta.GenderTextures[g];
  8732. for (var r in textures) {
  8733. var region = parseInt(r);
  8734. var texture = {
  8735. region: region,
  8736. gender: self.model.gender,
  8737. file: textures[r],
  8738. texture: null
  8739. };
  8740. if (region > 0) {
  8741. texture.texture = new Wow.Texture(self.model, r, textures[r])
  8742. } else if (self.slot == Wow.Slots.CAPE) {
  8743. self.model.textureOverrides[2] = new Wow.Texture(self.model, 2, textures[r])
  8744. }
  8745. self.textures.push(texture)
  8746. }
  8747. }
  8748. }
  8749. }
  8750. self.geoA = meta.GeosetA;
  8751. self.geoB = meta.GeosetB;
  8752. self.geoC = meta.GeosetC;
  8753. if (self.slot == Wow.Slots.HEAD) {
  8754. self.model.hairVis = meta.ShowHair == 0;
  8755. self.model.faceVis = meta.ShowFacial1 == 0
  8756. } else if (self.slot == Wow.Slots.BELT && meta.GenderModels && meta.GenderModels[self.model.gender]) {
  8757. var model = {
  8758. race: 0,
  8759. gender: 0,
  8760. bone: -1,
  8761. attachment: null,
  8762. model: null
  8763. };
  8764. var modelInfo = {
  8765. type: Wow.SlotType[self.slot],
  8766. id: self.id,
  8767. parent: self.model
  8768. };
  8769. model.model = new Wow.Model(self.model.renderer, self.model.viewer, modelInfo, 0, true);
  8770. model.model.loadMeta(meta, Wow.Types.ARMOR);
  8771. self.models = [model]
  8772. } else if (self.slot == Wow.Slots.PANTS && self.geoC > 0) {
  8773. self.sortValue += 2
  8774. } else if (self.slot == Wow.Slots.HANDS && self.geoA > 0) {
  8775. self.sortValue += 2
  8776. }
  8777. self.loaded = true;
  8778. self.model.updateMeshes()
  8779. }
  8780. };
  8781. ZamModelViewer.Wow.Vertex = function(r) {
  8782. var self = this;
  8783. self.position = [r.getFloat(), r.getFloat(), r.getFloat()];
  8784. self.normal = [r.getFloat(), r.getFloat(), r.getFloat(), 0];
  8785. self.u = r.getFloat();
  8786. self.v = r.getFloat();
  8787. self.weights = [r.getUint8(), r.getUint8(), r.getUint8(), r.getUint8()];
  8788. self.bones = [r.getUint8(), r.getUint8(), r.getUint8(), r.getUint8()];
  8789. self.transPosition = vec3.clone(self.position);
  8790. self.transNormal = vec4.clone(self.normal)
  8791. };
  8792. ZamModelViewer.Wow.Vertex.prototype = {
  8793. destroy: function() {
  8794. var self = this;
  8795. self.position = null;
  8796. self.normal = null;
  8797. self.weights = null;
  8798. self.bones = null;
  8799. self.transPosition = null;
  8800. self.transNormal = null
  8801. }
  8802. };
  8803. ZamModelViewer.Wow.Animation = function(r) {
  8804. var self = this,
  8805. Wow = ZamModelViewer.Wow;
  8806. self.id = r.getUint16();
  8807. self.subId = r.getUint16();
  8808. self.flags = r.getUint32();
  8809. self.length = r.getUint32();
  8810. self.speed = r.getFloat();
  8811. self.next = r.getInt16();
  8812. self.index = r.getUint16();
  8813. self.available = r.getBool();
  8814. if (self.available) {
  8815. self.dbcFlags = r.getUint32();
  8816. self.name = r.getString();
  8817. var numData = r.getInt32();
  8818. if (numData > 0) {
  8819. self.translation = new Array(numData);
  8820. self.rotation = new Array(numData);
  8821. self.scale = new Array(numData);
  8822. for (var i = 0; i < numData; ++i) {
  8823. self.translation[i] = new Wow.AnimatedVec3(r);
  8824. self.rotation[i] = new Wow.AnimatedQuat(r);
  8825. self.scale[i] = new Wow.AnimatedVec3(r)
  8826. }
  8827. }
  8828. }
  8829. };
  8830. ZamModelViewer.Wow.Animation.prototype = {
  8831. destroy: function() {
  8832. var self = this;
  8833. if (!self.translation) return;
  8834. for (var i = 0; i < self.translation.length; ++i) {
  8835. self.translation[i].destroy();
  8836. self.translation[i] = null;
  8837. self.rotation[i].destroy();
  8838. self.rotation[i] = null;
  8839. self.scale[i].destroy();
  8840. self.scale[i] = null
  8841. }
  8842. self.translation = null;
  8843. self.rotation = null;
  8844. self.scale = null
  8845. }
  8846. };
  8847. ZamModelViewer.Wow.Bone = function(model, index, r) {
  8848. var self = this;
  8849. self.model = model;
  8850. self.index = index;
  8851. self.keyId = r.getInt32();
  8852. self.parent = r.getInt16();
  8853. self.mesh = r.getUint16();
  8854. self.flags = r.getUint32();
  8855. self.pivot = [r.getFloat(), r.getFloat(), r.getFloat()];
  8856. self.transformedPivot = vec3.create();
  8857. self.matrix = mat4.create();
  8858. self.tmpVec = vec3.create();
  8859. self.tmpQuat = quat.create();
  8860. self.tmpMat = mat4.create();
  8861. self.hidden = false;
  8862. self.updated = false
  8863. };
  8864. ZamModelViewer.Wow.Bone.prototype = {
  8865. destroy: function() {
  8866. var self = this;
  8867. self.model = null;
  8868. self.pivot = null;
  8869. self.transformedPivot = null;
  8870. self.matrix = null;
  8871. self.tmpVec = null;
  8872. self.tmpQuat = null;
  8873. self.tmpMat = null
  8874. },
  8875. hide: function() {
  8876. var self = this;
  8877. self.hidden = true;
  8878. for (var i = 0; i < 16; ++i) self.matrix[i] = 0
  8879. },
  8880. update: function(time) {
  8881. var self = this,
  8882. Wow = ZamModelViewer.Wow;
  8883. if (self.hidden) {
  8884. self.hide();
  8885. return
  8886. }
  8887. if (self.model.model.type == Wow.Types.CHARACTER && !self.model.isHD) {
  8888. if (self.model.race == Wow.Races.HUMAN && self.model.gender == Wow.Genders.MALE && self.index == 24) {
  8889. self.hide()
  8890. }
  8891. }
  8892. if (self.updated) return;
  8893. self.updated = true;
  8894. if (!self.model || !self.model.animations) return;
  8895. mat4.identity(self.matrix);
  8896. var anim = self.model.currentAnimation;
  8897. if (!anim || !anim.translation || !anim.rotation || !anim.scale) return;
  8898. var billboard = (self.flags & 8) > 0;
  8899. if (anim.translation[self.index].used || anim.rotation[self.index].used || anim.scale[self.index].used || billboard) {
  8900. mat4.translate(self.matrix, self.matrix, self.pivot);
  8901. if (anim.translation[self.index].used) {
  8902. anim.translation[self.index].getValue(time, self.tmpVec);
  8903. mat4.translate(self.matrix, self.matrix, self.tmpVec)
  8904. }
  8905. if (anim.rotation[self.index].used) {
  8906. anim.rotation[self.index].getValue(time, self.tmpQuat);
  8907. mat4.fromQuat(self.tmpMat, self.tmpQuat);
  8908. mat4.transpose(self.tmpMat, self.tmpMat);
  8909. mat4.multiply(self.matrix, self.matrix, self.tmpMat)
  8910. }
  8911. if (anim.scale[self.index].used) {
  8912. anim.scale[self.index].getValue(time, self.tmpVec);
  8913. if (self.tmpVec[0] > 10 || Math.abs(self.tmpVec[0]) < 1e-4) self.tmpVec[0] = 1;
  8914. if (self.tmpVec[1] > 10 || Math.abs(self.tmpVec[1]) < 1e-4) self.tmpVec[1] = 1;
  8915. if (self.tmpVec[2] > 10 || Math.abs(self.tmpVec[2]) < 1e-4) self.tmpVec[2] = 1;
  8916. mat4.scale(self.matrix, self.matrix, self.tmpVec)
  8917. }
  8918. if (billboard) {
  8919. var yRot = -self.model.renderer.zenith + Math.PI / 2;
  8920. var zRot;
  8921. if (self.model.model.type == Wow.Types.ITEM) {
  8922. zRot = self.model.renderer.azimuth - Math.PI
  8923. } else {
  8924. zRot = self.model.renderer.azimuth - Math.PI * 1.5
  8925. }
  8926. mat4.identity(self.matrix);
  8927. mat4.translate(self.matrix, self.matrix, self.pivot);
  8928. mat4.rotateZ(self.matrix, self.matrix, zRot);
  8929. mat4.rotateY(self.matrix, self.matrix, yRot)
  8930. }
  8931. mat4.translate(self.matrix, self.matrix, vec3.negate(self.tmpVec, self.pivot))
  8932. }
  8933. if (self.parent > -1) {
  8934. self.model.bones[self.parent].update(time);
  8935. mat4.multiply(self.matrix, self.model.bones[self.parent].matrix, self.matrix)
  8936. }
  8937. vec3.transformMat4(self.transformedPivot, self.pivot, self.matrix)
  8938. }
  8939. };
  8940. ZamModelViewer.Wow.Mesh = function(r) {
  8941. var self = this;
  8942. self.id = r.getUint16();
  8943. self.indexWrap = r.getUint16();
  8944. self.vertexStart = r.getUint16();
  8945. self.vertexCount = r.getUint16();
  8946. self.indexStart = r.getUint16() + self.indexWrap * 65536;
  8947. self.indexCount = r.getUint16();
  8948. self.centerOfMass = [r.getFloat(), r.getFloat(), r.getFloat()];
  8949. self.centerBounds = [r.getFloat(), r.getFloat(), r.getFloat()];
  8950. self.radius = r.getFloat()
  8951. };
  8952. ZamModelViewer.Wow.Mesh.prototype = {
  8953. destroy: function() {
  8954. var self = this;
  8955. self.centerOfMass = null;
  8956. self.centerBounds = null
  8957. }
  8958. };
  8959. ZamModelViewer.Wow.TexUnit = function(r) {
  8960. var self = this;
  8961. self.flags = r.getUint8();
  8962. self.flags2 = r.getUint8();
  8963. self.shading = r.getUint16();
  8964. self.meshIndex = r.getUint16();
  8965. self.colorIndex = r.getInt16();
  8966. self.renderFlagIndex = r.getUint16();
  8967. self.opcount = r.getUint16();
  8968. self.materialIndex = r.getInt16();
  8969. self.texUnitIndex = r.getUint16();
  8970. self.alphaIndex = r.getInt16();
  8971. self.textureAnimIndex = r.getInt16();
  8972. self.show = true;
  8973. self.model = null;
  8974. self.mesh = null;
  8975. self.meshId = 0;
  8976. self.renderFlag = null;
  8977. self.material = [];
  8978. self.textureAnim = [];
  8979. self.color = null;
  8980. self.alpha = null;
  8981. self.unlit = false;
  8982. self.cull = false;
  8983. self.noZWrite = false;
  8984. self.tmpColor = vec4.create();
  8985. self.tmpVec = vec3.create();
  8986. self.tmpQuat = quat.create()
  8987. };
  8988. ZamModelViewer.Wow.TexUnit.prototype = {
  8989. destroy: function() {
  8990. var self = this;
  8991. self.model = null;
  8992. self.mesh = null;
  8993. self.renderFlag = null;
  8994. self.material = null;
  8995. self.textureAnim = null;
  8996. self.color = null;
  8997. self.alpha = null;
  8998. self.tmpColor = null;
  8999. self.textureMatrix = null;
  9000. self.tmpVec = null;
  9001. self.tmpQuat = null
  9002. },
  9003. draw: function() {
  9004. var self = this,
  9005. gl = self.model.renderer.context,
  9006. anim = self.model.currentAnimation.index,
  9007. time = self.model.time;
  9008. self.tmpColor[0] = self.tmpColor[1] = self.tmpColor[2] = self.tmpColor[3] = 1;
  9009. if (self.color) {
  9010. self.color.getValue(anim, time, self.tmpColor)
  9011. }
  9012. if (self.alpha) {
  9013. self.tmpColor[3] *= self.alpha.getValue(anim, time)
  9014. }
  9015. if (self.tmpColor[3] <= .001) return;
  9016. var blend = self.renderFlag.blend;
  9017. if (self.meshId > 1500 && self.meshId < 1600) blend = 0;
  9018. gl.uniform4fv(self.model.uniforms.fColor, self.tmpColor);
  9019. gl.uniform1i(self.model.uniforms.fBlendMode, blend);
  9020. gl.uniform1i(self.model.uniforms.fUnlit, self.unlit);
  9021. var count = 0;
  9022. var texture2 = null;
  9023. var texture3 = null;
  9024. var texture4 = null;
  9025. var texture1 = null,
  9026. aTex = null;
  9027. for (var i in self.material) {
  9028. var alphaTexture = null;
  9029. var texture = null;
  9030. if (self.material[i]) {
  9031. if (self.material[i].type == 1) {
  9032. if (self.model.npcTexture) {
  9033. texture = self.model.npcTexture.texture;
  9034. alphaTexture = self.model.npcTexture.alphaTexture
  9035. } else if (self.model.compositeTexture) {
  9036. texture = self.model.compositeTexture
  9037. }
  9038. } else if (self.material[i].texture) {
  9039. texture = self.material[i].texture.texture;
  9040. alphaTexture = self.material[i].texture.alphaTexture
  9041. } else if (((self.model.model.type < 8 || self.model.model.type > 32) && self.material[i].type == 2 || self.material[i].type >= 11) && self.model.textureOverrides[self.material[i].index]) {
  9042. texture = self.model.textureOverrides[self.material[i].index].texture;
  9043. alphaTexture = self.model.textureOverrides[self.material[i].index].alphaTexture
  9044. } else if (self.material[i].type != -1 && self.model.textureOverrides[self.material[i].type]) {
  9045. texture = self.model.textureOverrides[self.material[i].type].texture;
  9046. alphaTexture = self.model.textureOverrides[self.material[i].type].alphaTexture
  9047. } else if (self.material[i].type != -1 && self.model.specialTextures[self.material[i].type]) {
  9048. texture = self.model.specialTextures[self.material[i].type].texture;
  9049. alphaTexture = self.model.specialTextures[self.material[i].type].alphaTexture
  9050. } else if (!self.material[i].filename) {
  9051. var mat = self.model.materials[self.materialIndex + count];
  9052. if (mat.texture) {
  9053. texture = mat.texture.texture;
  9054. alphaTexture = mat.texture.alphaTexture
  9055. }
  9056. }
  9057. }
  9058. if (i == 0) {
  9059. texture1 = texture;
  9060. aTex = alphaTexture
  9061. }
  9062. if (i == 1) texture2 = texture;
  9063. if (i == 2) texture3 = texture;
  9064. if (i == 3) texture4 = texture;
  9065. count++
  9066. }
  9067. if (texture1) {
  9068. gl.activeTexture(gl.TEXTURE0);
  9069. gl.bindTexture(gl.TEXTURE_2D, texture1);
  9070. gl.uniform1i(self.model.uniforms.fTexture, 0)
  9071. }
  9072. if (texture2) {
  9073. gl.activeTexture(gl.TEXTURE0);
  9074. gl.bindTexture(gl.TEXTURE_2D, texture2);
  9075. gl.uniform1i(self.model.uniforms.fTexture2, 0)
  9076. }
  9077. if (texture3) {
  9078. gl.activeTexture(gl.TEXTURE0);
  9079. gl.bindTexture(gl.TEXTURE_2D, texture3);
  9080. gl.uniform1i(self.model.uniforms.fTexture3, 0)
  9081. }
  9082. if (texture4) {
  9083. gl.activeTexture(gl.TEXTURE0);
  9084. gl.bindTexture(gl.TEXTURE_2D, texture4);
  9085. gl.uniform1i(self.model.uniforms.fTexture4, 0)
  9086. }
  9087. if (aTex) {
  9088. gl.activeTexture(gl.TEXTURE1);
  9089. gl.bindTexture(gl.TEXTURE_2D, aTex);
  9090. gl.uniform1i(self.model.uniforms.fAlpha, 1)
  9091. }
  9092. gl.uniform1i(self.model.uniforms.fHasTexture, texture ? 1 : 0);
  9093. gl.uniform1i(self.model.uniforms.fHasTexture2, texture2 ? 1 : 0);
  9094. gl.uniform1i(self.model.uniforms.fHasTexture3, texture3 ? 1 : 0);
  9095. gl.uniform1i(self.model.uniforms.fHasTexture4, texture4 ? 1 : 0);
  9096. gl.uniform1i(self.model.uniforms.fHasAlpha, aTex ? 1 : 0);
  9097. for (var i in self.textureAnim) {
  9098. self.textureMatrix = mat4.create();
  9099. mat4.identity(self.textureMatrix);
  9100. if (self.textureAnim[i]) {
  9101. var rotTrans = false;
  9102. if (self.textureAnim[i].translation) {
  9103. ZamModelViewer.Wow.AnimatedVec3.getValue(self.textureAnim[i].translation, anim, time, self.tmpVec);
  9104. rotTrans = true
  9105. } else {
  9106. vec3.set(self.tmpVec, 0, 0, 0)
  9107. }
  9108. if (self.textureAnim[i].rotation) {
  9109. ZamModelViewer.Wow.AnimatedQuat.getValue(self.textureAnim[i].rotation, anim, time, self.tmpQuat);
  9110. rotTrans = true
  9111. } else {
  9112. quat.set(self.tmpQuat, 0, 0, 0, 1)
  9113. }
  9114. if (rotTrans) mat4.fromRotationTranslation(self.textureMatrix, self.tmpQuat, self.tmpVec);
  9115. if (self.textureAnim[i].scale && ZamModelViewer.Wow.Animated.isUsed(self.textureAnim[i].scale, anim)) {
  9116. ZamModelViewer.Wow.AnimatedVec3.getValue(self.textureAnim[i].scale, anim, time, self.tmpVec);
  9117. mat4.scale(self.textureMatrix, self.textureMatrix, self.tmpVec)
  9118. }
  9119. }
  9120. if (i == 0) gl.uniformMatrix4fv(self.model.uniforms.vTextureMatrix, false, self.textureMatrix);
  9121. if (i == 1) gl.uniformMatrix4fv(self.model.uniforms.vTextureMatrix2, false, self.textureMatrix);
  9122. if (i == 2) gl.uniformMatrix4fv(self.model.uniforms.vTextureMatrix3, false, self.textureMatrix);
  9123. if (i == 3) gl.uniformMatrix4fv(self.model.uniforms.vTextureMatrix4, false, self.textureMatrix)
  9124. }
  9125. if (blend == 0 || blend == 1) {
  9126. gl.blendFunc(gl.ONE, gl.ZERO)
  9127. } else if (blend == 2) {
  9128. if (self.flags == 130 && self.flags2 > 2 && self.flags2 < 6) gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
  9129. else if (self.flags == 130) gl.blendFunc(gl.ONE, gl.ONE);
  9130. else if (self.flags == 146) gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
  9131. else gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
  9132. } else if (blend == 3) {
  9133. gl.blendFunc(gl.SRC_COLOR, gl.ONE)
  9134. } else if (blend == 4) {
  9135. if (self.opcount == 1 || self.opcount == 2) {
  9136. if (self.flags == 144 && self.flags2 == 0) gl.blendFunc(gl.ONE, gl.ONE);
  9137. else gl.blendFunc(gl.SRC_ALPHA, gl.ONE)
  9138. } else {
  9139. gl.blendFunc(gl.DST_COLOR, gl.SRC_ALPHA)
  9140. }
  9141. } else if (blend == 5) {
  9142. if (self.opcount == 1) {
  9143. gl.blendFunc(gl.ZERO, gl.SRC_COLOR)
  9144. } else {
  9145. gl.blendFunc(gl.DST_COLOR, gl.SRC_COLOR)
  9146. }
  9147. } else if (blend == 6) {
  9148. gl.blendFunc(gl.DST_COLOR, gl.SRC_COLOR)
  9149. } else {
  9150. gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
  9151. }
  9152. if (self.cull) {
  9153. gl.enable(gl.CULL_FACE)
  9154. } else {
  9155. gl.disable(gl.CULL_FACE)
  9156. }
  9157. if (self.noZWrite) {
  9158. gl.depthMask(false)
  9159. } else {
  9160. gl.depthMask(true)
  9161. }
  9162. gl.drawElements(gl.TRIANGLES, self.mesh.indexCount, gl.UNSIGNED_SHORT, self.mesh.indexStart * 2)
  9163. },
  9164. setup: function(model) {
  9165. var self = this;
  9166. self.model = model;
  9167. self.mesh = model.meshes[self.meshIndex];
  9168. self.meshId = self.mesh.id;
  9169. if (model.renderFlags && self.renderFlagIndex < model.renderFlags.length) {
  9170. self.renderFlag = model.renderFlags[self.renderFlagIndex]
  9171. } else self.renderFlag = {
  9172. flags: 0,
  9173. blend: 0
  9174. };
  9175. self.unlit = (self.renderFlag.flags & 1) > 0;
  9176. self.cull = (self.renderFlag.flags & 4) == 0;
  9177. self.noZWrite = self.renderFlag.flags >= 16 && self.renderFlag.blend != 7 && self.renderFlag.flags != 17 || (self.flags2 == 10 || self.flags2 == 20) || self.renderFlag.flags == 17 && self.flags2 == 0 || self.renderFlag.flags == 21 && self.flags == 128 && self.flags2 == 0 && self.renderFlag.blend == 7;
  9178. self.flip = self.renderFlag.flags == 16 && self.flags == 128 && self.flags2 < 10 || self.renderFlag.flags != 16 && self.flags == 128 && self.flags2 < 10 && self.flags2 != 0 || self.flags == 130 || self.renderFlag.flags == 21 && self.flags == 128 && self.flags2 == 0 && self.renderFlag.blend == 7;
  9179. self.multiTexture = self.renderFlag.flags >= 16;
  9180. if (self.flags == 128 && self.flags2 == 1 && self.renderFlag.flags == 17 && self.renderFlag.blend == 2) {
  9181. self.noZWrite = true
  9182. }
  9183. if (self.flags == 128 && self.flags2 == 3) {
  9184. self.flip = false;
  9185. self.noZWrite = true
  9186. }
  9187. if (self.flags == 128 && self.flags2 == 4) {
  9188. self.flip = false;
  9189. self.noZWrite = true
  9190. }
  9191. if (self.renderFlag.flags == 21 && self.renderFlag.blend == 2 && self.flags == 128 && self.flags2 == 1) {
  9192. self.flip = false
  9193. }
  9194. for (var i = 0; i < self.opcount; i++) {
  9195. if (self.multiTexture || i == 0) {
  9196. if (self.materialIndex > -1 && self.materialIndex < model.materialLookup.length) {
  9197. var matIdx = model.materialLookup[self.materialIndex + i];
  9198. if (matIdx > -1 && matIdx < model.materials.length) {
  9199. self.material.splice(i, 0, model.materials[matIdx])
  9200. }
  9201. }
  9202. if (self.textureAnimIndex > -1 && self.textureAnimIndex < model.textureAnimLookup.length) {
  9203. var animIdx = model.textureAnimLookup[self.textureAnimIndex + i];
  9204. if (animIdx > -1 && model.textureAnims && animIdx < model.textureAnims.length) {
  9205. self.textureAnim.splice(i, 0, model.textureAnims[animIdx])
  9206. } else self.textureAnim.splice(i, 0, null)
  9207. }
  9208. }
  9209. }
  9210. if (self.flip) {
  9211. self.material = self.material.reverse();
  9212. self.textureAnim = self.textureAnim.reverse()
  9213. }
  9214. if (model.colors && self.colorIndex > -1 && self.colorIndex < model.colors.length) {
  9215. self.color = model.colors[self.colorIndex]
  9216. }
  9217. if (self.alphaIndex > -1 && self.alphaIndex < model.alphaLookup.length) {
  9218. var alphaIdx = model.alphaLookup[self.alphaIndex];
  9219. if (alphaIdx > -1 && alphaIdx < model.alphas.length) {
  9220. self.alpha = model.alphas[alphaIdx]
  9221. }
  9222. }
  9223. }
  9224. };
  9225. ZamModelViewer.Wow.RenderFlag = function(r) {
  9226. var self = this;
  9227. self.flags = r.getUint16();
  9228. self.blend = r.getUint16()
  9229. };
  9230. ZamModelViewer.Wow.Material = function(model, index, r) {
  9231. var self = this;
  9232. self.model = model;
  9233. self.index = index;
  9234. self.type = r.getInt32();
  9235. self.flags = r.getUint32();
  9236. self.filename = r.getUint32();
  9237. self.texture = null;
  9238. self.load()
  9239. };
  9240. ZamModelViewer.Wow.Material.prototype = {
  9241. destroy: function() {
  9242. var self = this;
  9243. self.model = null;
  9244. if (self.texture) self.texture.destroy();
  9245. self.texture = null
  9246. },
  9247. load: function() {
  9248. var self = this;
  9249. if (self.filename == 0) return;
  9250. self.texture = new ZamModelViewer.Wow.Texture(self.model, 0, self.filename)
  9251. }
  9252. };
  9253. ZamModelViewer.Wow.TextureAnimation = function(r) {
  9254. var Wow = ZamModelViewer.Wow;
  9255. var self = this,
  9256. i;
  9257. var numTrans = r.getInt32();
  9258. if (numTrans > 0) {
  9259. self.translation = new Array(numTrans);
  9260. for (i = 0; i < numTrans; ++i) self.translation[i] = new Wow.AnimatedVec3(r)
  9261. } else self.translation = null;
  9262. var numRot = r.getInt32();
  9263. if (numRot > 0) {
  9264. self.rotation = new Array(numRot);
  9265. for (i = 0; i < numRot; ++i) self.rotation[i] = new Wow.AnimatedQuat(r)
  9266. } else self.rotation = null;
  9267. var numScale = r.getInt32();
  9268. if (numScale > 0) {
  9269. self.scale = new Array(numScale);
  9270. for (i = 0; i < numScale; ++i) self.scale[i] = new Wow.AnimatedVec3(r)
  9271. } else self.scale = null
  9272. };
  9273. ZamModelViewer.Wow.TextureAnimation.prototype = {
  9274. destroy: function() {
  9275. var self = this,
  9276. i;
  9277. if (self.translation) {
  9278. for (i = 0; i < self.translation.length; ++i) self.translation[i] = self.translation[i].destroy();
  9279. self.translation = null
  9280. }
  9281. if (self.rotation) {
  9282. for (i = 0; i < self.rotation.length; ++i) self.rotation[i] = self.rotation[i].destroy();
  9283. self.rotation = null
  9284. }
  9285. if (self.scale) {
  9286. for (i = 0; i < self.scale.length; ++i) self.scale[i] = self.scale[i].destroy();
  9287. self.scale = null
  9288. }
  9289. }
  9290. };
  9291. ZamModelViewer.Wow.Attachment = function(r) {
  9292. var self = this;
  9293. self.id = r.getInt32();
  9294. self.bone = r.getInt32();
  9295. self.position = [r.getFloat(), r.getFloat(), r.getFloat()];
  9296. self.slot = -1
  9297. };
  9298. ZamModelViewer.Wow.Attachment.prototype = {
  9299. destroy: function() {
  9300. var self = this;
  9301. self.position = null
  9302. }
  9303. };
  9304. ZamModelViewer.Wow.Color = function(r) {
  9305. var Wow = ZamModelViewer.Wow;
  9306. var self = this,
  9307. i;
  9308. var numRgb = r.getInt32();
  9309. if (numRgb > 0) {
  9310. self.rgb = new Array(numRgb);
  9311. for (i = 0; i < numRgb; ++i) {
  9312. self.rgb[i] = new Wow.AnimatedVec3(r)
  9313. }
  9314. }
  9315. var numAlpha = r.getInt32();
  9316. if (numAlpha > 0) {
  9317. self.alpha = new Array(numAlpha);
  9318. for (i = 0; i < numAlpha; ++i) {
  9319. self.alpha[i] = new Wow.AnimatedUint16(r)
  9320. }
  9321. }
  9322. };
  9323. ZamModelViewer.Wow.Color.prototype = {
  9324. destroy: function() {
  9325. var self = this,
  9326. i;
  9327. if (self.rgb) {
  9328. for (i = 0; i < self.rgb.length; ++i) self.rgb[i] = self.rgb[i].destroy();
  9329. self.rgb = null
  9330. }
  9331. if (self.alpha) {
  9332. for (i = 0; i < self.alpha.length; ++i) self.alpha[i] = self.alpha[i].destroy();
  9333. self.alpha = null
  9334. }
  9335. },
  9336. rgbUsed: function(anim) {
  9337. var self = this;
  9338. if (!self.rgb) return false;
  9339. if (anim < self.rgb.length) return self.rgb[anim].used;
  9340. else return self.rgb[0].used
  9341. },
  9342. alphaUsed: function(anim) {
  9343. var self = this;
  9344. if (!self.alpha) return false;
  9345. if (anim < self.alpha.length) return self.alpha[anim].used;
  9346. else return self.alpha[0].used
  9347. },
  9348. used: function(anim) {
  9349. var self = this;
  9350. return self.rgbUsed(anim) || self.alphaUsed(anim)
  9351. },
  9352. getValue: function(anim, time, result) {
  9353. var self = this;
  9354. if (!result) result = [1, 1, 1, 1];
  9355. else result[0] = result[1] = result[2] = result[3] = 1;
  9356. if (self.rgbUsed(anim)) ZamModelViewer.Wow.AnimatedVec3.getValue(self.rgb, anim, time, result);
  9357. if (self.alphaUsed(anim)) result[3] = ZamModelViewer.Wow.AnimatedUint16.getValue(self.alpha, anim, time, result[3]) / 32767;
  9358. return result
  9359. }
  9360. };
  9361. ZamModelViewer.Wow.Alpha = function(r) {
  9362. var self = this;
  9363. var count = r.getInt32();
  9364. self.data = new Array(count);
  9365. for (var i = 0; i < count; ++i) {
  9366. self.data[i] = new ZamModelViewer.Wow.AnimatedUint16(r)
  9367. }
  9368. };
  9369. ZamModelViewer.Wow.Alpha.prototype = {
  9370. destroy: function() {
  9371. var self = this;
  9372. for (var i = 0; i < self.data.length; ++i) self.data[i] = self.data[i].destroy();
  9373. self.data = null
  9374. },
  9375. used: function(anim) {
  9376. var self = this;
  9377. if (self.data.length == 0) return false;
  9378. if (anim < self.data.length) return self.data[anim].used;
  9379. else return self.data[0].used
  9380. },
  9381. getValue: function(anim, time) {
  9382. var self = this,
  9383. a = 1;
  9384. if (self.used(anim)) {
  9385. var val = ZamModelViewer.Wow.AnimatedUint16.getValue(self.data, anim, time, a);
  9386. a = val / 32767
  9387. }
  9388. if (a > 1) a = 1;
  9389. else if (a < 0) a = 0;
  9390. return a
  9391. }
  9392. };
  9393. ZamModelViewer.Wow.ParticleEmitter = function(model, r) {
  9394. var self = this,
  9395. Wow = ZamModelViewer.Wow;
  9396. self.model = model;
  9397. self.id = r.getInt32();
  9398. self.flags = r.getUint32();
  9399. self.colorIndex = r.getUint16();
  9400. self.position = [r.getFloat(), r.getFloat(), r.getFloat()];
  9401. self.boneId = r.getInt16();
  9402. self.textureId = r.getInt16();
  9403. if ((self.flags & 268435456) != 0) {
  9404. self.textureIds = [0, 0, 0];
  9405. self.textureIds[0] = self.textureId & 31;
  9406. self.textureIds[1] = self.textureId >> 5 & 31;
  9407. self.textureIds[2] = self.textureId >> 10 & 31
  9408. }
  9409. self.blendMode = r.getUint8();
  9410. self.emitterType = r.getUint8();
  9411. self.particleType = r.getUint8() & 3;
  9412. self.headTail = r.getUint8();
  9413. self.tileRotation = r.getUint16();
  9414. self.tileRows = r.getUint16();
  9415. self.tileColumns = r.getUint16();
  9416. self.scale = [r.getFloat(), r.getFloat(), r.getFloat()];
  9417. self.slowdown = r.getFloat();
  9418. self.rotation = [r.getFloat(), r.getFloat(), r.getFloat()];
  9419. self.modelRot1 = [r.getFloat(), r.getFloat(), r.getFloat()];
  9420. self.modelRot2 = [r.getFloat(), r.getFloat(), r.getFloat()];
  9421. self.modelTranslation = [r.getFloat(), r.getFloat(), r.getFloat()];
  9422. self.modelPath = r.getString();
  9423. self.particlePath = r.getString();
  9424. self.emissionSpeed = Wow.AnimatedFloat.readSet(r);
  9425. self.speedVariation = Wow.AnimatedFloat.readSet(r);
  9426. self.verticalRange = Wow.AnimatedFloat.readSet(r);
  9427. self.horizontalRange = Wow.AnimatedFloat.readSet(r);
  9428. self.gravity = Wow.AnimatedFloat.readSet(r);
  9429. self.lifespan = Wow.AnimatedFloat.readSet(r);
  9430. self.emissionRate = Wow.AnimatedFloat.readSet(r);
  9431. self.areaLength = Wow.AnimatedFloat.readSet(r);
  9432. self.areaWidth = Wow.AnimatedFloat.readSet(r);
  9433. self.gravity2 = Wow.AnimatedFloat.readSet(r);
  9434. self.color = new Wow.SAnimatedVec3(r);
  9435. self.alpha = new Wow.SAnimatedUint16(r);
  9436. self.size = new Wow.SAnimatedVec2(r);
  9437. self.intensity = new Wow.SAnimatedUint16(r);
  9438. self.enabled = Wow.AnimatedUint8.readSet(r);
  9439. self.bone = self.model.bones[self.boneId];
  9440. self.maxParticles = 500;
  9441. self.particles = new Array(self.maxParticles);
  9442. self.unusedParticles = new Array(self.maxParticles);
  9443. for (var i = self.maxParticles - 1, j = 0; i >= 0; --i, ++j) self.unusedParticles[i] = j;
  9444. self.nextParticle = self.maxParticles - 1;
  9445. self.numParticles = 0;
  9446. self.spawnRemainder = 0;
  9447. self.tmpColors = [vec4.create(), vec4.create(), vec4.create()];
  9448. self.spreadMat = mat4.create();
  9449. self.tmpMat = mat4.create();
  9450. self.init()
  9451. };
  9452. ZamModelViewer.Wow.ParticleEmitter.prototype = {
  9453. destroy: function() {
  9454. var self = this,
  9455. gl = self.model.renderer.context,
  9456. Animated = ZamModelViewer.Wow.Animated;
  9457. if (self.program) gl.deleteProgram(self.program);
  9458. if (self.vs) gl.deleteShader(self.vs);
  9459. if (self.fs) gl.deleteShader(self.fs);
  9460. if (self.vb) gl.deleteBuffer(self.vb);
  9461. if (self.ib) gl.deleteBuffer(self.ib);
  9462. self.program = null;
  9463. self.vs = null;
  9464. self.fs = null;
  9465. self.vb = null;
  9466. self.ib = null;
  9467. self.vbData = null;
  9468. self.texture = null;
  9469. self.attribs = null;
  9470. self.uniforms = null;
  9471. self.model = null;
  9472. self.bone = null;
  9473. self.position = null;
  9474. self.scale = null;
  9475. self.rotation = null;
  9476. self.modelRot1 = null;
  9477. self.modelRot2 = null;
  9478. self.modelTranslation = null;
  9479. self.emissionSpeed = Animated.destroySet(self.emissionSpeed);
  9480. self.speedVariation = Animated.destroySet(self.speedVariation);
  9481. self.verticalRange = Animated.destroySet(self.verticalRange);
  9482. self.horizontalRange = Animated.destroySet(self.horizontalRange);
  9483. self.gravity = Animated.destroySet(self.gravity);
  9484. self.lifespan = Animated.destroySet(self.lifespan);
  9485. self.emissionRate = Animated.destroySet(self.emissionRate);
  9486. self.areaLength = Animated.destroySet(self.areaLength);
  9487. self.areaWidth = Animated.destroySet(self.areaWidth);
  9488. self.gravity2 = Animated.destroySet(self.gravity2);
  9489. self.enabled = Animated.destroySet(self.enabled);
  9490. self.color = self.color.destroy();
  9491. self.alpha = self.alpha.destroy();
  9492. self.size = self.size.destroy();
  9493. self.intensity = self.intensity.destroy();
  9494. self.particles = null;
  9495. self.unusedParticles = null;
  9496. self.tmpColors[0] = self.tmpColors[1] = self.tmpColors[2] = null;
  9497. self.tmpColors = null;
  9498. self.spreadMat = null;
  9499. self.tmpMat = null
  9500. },
  9501. updateBuffers: function() {
  9502. var self = this,
  9503. gl = self.model.renderer.context,
  9504. i, j;
  9505. if (!self.vbData) {
  9506. self.vbData = new Float32Array(self.maxParticles * 11);
  9507. var ibData = new Uint16Array(self.maxParticles * 6);
  9508. var vert = 0;
  9509. for (i = 0; i < self.maxParticles; ++i) {
  9510. ibData[i * 6 + 0] = vert;
  9511. ibData[i * 6 + 1] = vert + 1;
  9512. ibData[i * 6 + 2] = vert + 2;
  9513. ibData[i * 6 + 3] = vert + 2;
  9514. ibData[i * 6 + 4] = vert + 1;
  9515. ibData[i * 6 + 5] = vert + 3;
  9516. vert += 4
  9517. }
  9518. self.ib = gl.createBuffer();
  9519. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.ib);
  9520. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, ibData, gl.STATIC_DRAW)
  9521. }
  9522. self.numParticles = 0;
  9523. var p, idx = 0,
  9524. tc, vbData = self.vbData;
  9525. if (self.particleType == 0 || self.particleType == 2) {
  9526. for (i = 0; i < self.maxParticles; ++i) {
  9527. p = self.particles[i];
  9528. if (!p || p.maxLife == 0) continue;
  9529. tc = self.textureCoords[p.tile];
  9530. for (j = 0; j < 4; ++j) {
  9531. vbData[idx + 0] = p.position[0];
  9532. vbData[idx + 1] = p.position[1];
  9533. vbData[idx + 2] = p.position[2];
  9534. vbData[idx + 3] = p.color[0];
  9535. vbData[idx + 4] = p.color[1];
  9536. vbData[idx + 5] = p.color[2];
  9537. vbData[idx + 6] = p.color[3];
  9538. vbData[idx + 7] = tc[j].x;
  9539. vbData[idx + 8] = tc[j].y;
  9540. vbData[idx + 9] = tc[j].z * p.size[0];
  9541. vbData[idx + 10] = tc[j].w * p.size[1];
  9542. idx += 11
  9543. }
  9544. self.numParticles++
  9545. }
  9546. } else {
  9547. for (i = 0; i < self.maxParticles; ++i) {
  9548. p = self.particles[i];
  9549. if (!p || p.maxLife == 0) continue;
  9550. tc = self.textureCoords[p.tile];
  9551. vbData[idx + 0] = p.position[0];
  9552. vbData[idx + 1] = p.position[1];
  9553. vbData[idx + 2] = p.position[2];
  9554. vbData[idx + 11] = p.position[0];
  9555. vbData[idx + 12] = p.position[1];
  9556. vbData[idx + 13] = p.position[2];
  9557. vbData[idx + 22] = p.origin[0];
  9558. vbData[idx + 23] = p.origin[1];
  9559. vbData[idx + 24] = p.origin[2];
  9560. vbData[idx + 33] = p.origin[0];
  9561. vbData[idx + 34] = p.origin[1];
  9562. vbData[idx + 35] = p.origin[2];
  9563. for (j = 0; j < 4; ++j) {
  9564. vbData[idx + 3] = p.color[0];
  9565. vbData[idx + 4] = p.color[1];
  9566. vbData[idx + 5] = p.color[2];
  9567. vbData[idx + 6] = p.color[3];
  9568. vbData[idx + 7] = tc[j].x;
  9569. vbData[idx + 8] = tc[j].y;
  9570. vbData[idx + 9] = tc[j].z * p.size[0];
  9571. vbData[idx + 10] = tc[j].w * p.size[1];
  9572. idx += 11
  9573. }
  9574. self.numParticles++
  9575. }
  9576. }
  9577. if (!self.vb) {
  9578. self.vb = gl.createBuffer();
  9579. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  9580. gl.bufferData(gl.ARRAY_BUFFER, self.vbData, gl.DYNAMIC_DRAW)
  9581. } else {
  9582. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  9583. gl.bufferSubData(gl.ARRAY_BUFFER, 0, self.vbData)
  9584. }
  9585. },
  9586. draw: function() {
  9587. var self = this,
  9588. gl = self.model.renderer.context,
  9589. i;
  9590. if (self.numParticles == 0) return;
  9591. if (!self.shaderReady) self.initShader();
  9592. if (!self.program) return;
  9593. if (!self.texture) {
  9594. if ((self.flags & 268435456) != 0) {
  9595. for (i = 0; i < self.textureIds.length; i++) {
  9596. var textureId = self.textureIds[i];
  9597. if (textureId > -1 && textureId < self.model.materials.length) {
  9598. var mat = self.model.materials[textureId];
  9599. if (mat && mat.texture && mat.texture.texture && (!mat.texture.alphaImg || mat.texture.alphaTexture)) {
  9600. if (i == 0) self.texture = mat.texture;
  9601. else if (i == 1) self.texture2 = mat.texture;
  9602. else self.texture3 = mat.texture
  9603. }
  9604. }
  9605. }
  9606. } else if (self.textureId > -1 && self.textureId < self.model.materials.length) {
  9607. var mat = self.model.materials[self.textureId];
  9608. if (mat.texture && mat.texture.texture && (!mat.texture.alphaImg || mat.texture.alphaTexture)) {
  9609. self.texture = mat.texture
  9610. }
  9611. }
  9612. }
  9613. if (!self.texture) return;
  9614. gl.useProgram(self.program);
  9615. gl.uniformMatrix4fv(self.uniforms.vModelMatrix, false, self.model.matrix);
  9616. gl.uniformMatrix4fv(self.uniforms.vViewMatrix, false, self.model.renderer.viewMatrix);
  9617. gl.uniformMatrix4fv(self.uniforms.vProjMatrix, false, self.model.renderer.projMatrix);
  9618. gl.uniform1i(self.uniforms.fBlendMode, self.blendMode);
  9619. if (self.texture) {
  9620. gl.activeTexture(gl.TEXTURE0);
  9621. gl.bindTexture(gl.TEXTURE_2D, self.texture.texture);
  9622. gl.uniform1i(self.uniforms.fTexture, 0)
  9623. }
  9624. if (self.texture && self.texture.alphaTexture) {
  9625. gl.activeTexture(gl.TEXTURE1);
  9626. gl.bindTexture(gl.TEXTURE_2D, self.texture.alphaTexture);
  9627. gl.uniform1i(self.uniforms.fAlpha, 1)
  9628. }
  9629. if (self.texture2) {
  9630. gl.activeTexture(gl.TEXTURE2);
  9631. gl.bindTexture(gl.TEXTURE_2D, self.texture2.texture);
  9632. gl.uniform1i(self.uniforms.fTexture2, 2)
  9633. }
  9634. if (self.texture3) {
  9635. gl.activeTexture(gl.TEXTURE3);
  9636. gl.bindTexture(gl.TEXTURE_2D, self.texture3.texture);
  9637. gl.uniform1i(self.uniforms.fTexture3, 3)
  9638. }
  9639. gl.uniform1i(self.uniforms.fHasTexture, self.texture ? 1 : 0);
  9640. gl.uniform1i(self.uniforms.fHasTexture2, self.texture2 ? 1 : 0);
  9641. gl.uniform1i(self.uniforms.fHasTexture3, self.texture3 ? 1 : 0);
  9642. gl.uniform1i(self.uniforms.fHasAlpha, self.texture && self.texture.alphaTexture ? 1 : 0);
  9643. var blend = self.blendMode;
  9644. if (blend == 0 || blend == 1) {
  9645. gl.blendFunc(gl.ONE, gl.ZERO)
  9646. } else if (blend == 2) {
  9647. gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
  9648. } else if (blend == 3) {
  9649. gl.blendFunc(gl.SRC_COLOR, gl.ONE)
  9650. } else if (blend == 4) {
  9651. gl.blendFunc(gl.SRC_ALPHA, gl.ONE)
  9652. } else if (blend == 5 || blend == 6) {
  9653. gl.blendFunc(gl.DST_COLOR, gl.SRC_COLOR)
  9654. } else {
  9655. gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
  9656. }
  9657. gl.disable(gl.CULL_FACE);
  9658. gl.depthMask(false);
  9659. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  9660. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.ib);
  9661. for (i in self.attribs) {
  9662. var a = self.attribs[i];
  9663. gl.enableVertexAttribArray(a.loc);
  9664. gl.vertexAttribPointer(a.loc, a.size, a.type, false, a.stride, a.offset)
  9665. }
  9666. gl.drawElements(gl.TRIANGLES, self.numParticles * 6, gl.UNSIGNED_SHORT, 0);
  9667. for (i in self.attribs) {
  9668. gl.disableVertexAttribArray(self.attribs[i].loc)
  9669. }
  9670. },
  9671. initShader: function() {
  9672. var self = this,
  9673. gl = self.model.renderer.context;
  9674. self.shaderReady = true;
  9675. var vs = self.model.renderer.compileShader(gl.VERTEX_SHADER, self.vertShader);
  9676. var fs = self.model.renderer.compileShader(gl.FRAGMENT_SHADER, self.fragShader);
  9677. var program = gl.createProgram();
  9678. gl.attachShader(program, vs);
  9679. gl.attachShader(program, fs);
  9680. gl.linkProgram(program);
  9681. if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
  9682. console.error("Error linking shaders");
  9683. return
  9684. }
  9685. self.vs = vs;
  9686. self.fs = fs;
  9687. self.program = program;
  9688. self.uniforms = {
  9689. vModelMatrix: gl.getUniformLocation(program, "uModelMatrix"),
  9690. vViewMatrix: gl.getUniformLocation(program, "uViewMatrix"),
  9691. vProjMatrix: gl.getUniformLocation(program, "uProjMatrix"),
  9692. fHasTexture: gl.getUniformLocation(program, "uHasTexture"),
  9693. fHasTexture2: gl.getUniformLocation(program, "uHasTexture2"),
  9694. fHasTexture3: gl.getUniformLocation(program, "uHasTexture3"),
  9695. fHasAlpha: gl.getUniformLocation(program, "uHasAlpha"),
  9696. fBlendMode: gl.getUniformLocation(program, "uBlendMode"),
  9697. fTexture: gl.getUniformLocation(program, "uTexture"),
  9698. fTexture2: gl.getUniformLocation(program, "uTexture2"),
  9699. fTexture3: gl.getUniformLocation(program, "uTexture3"),
  9700. fAlpha: gl.getUniformLocation(program, "uAlpha")
  9701. };
  9702. self.attribs = {
  9703. position: {
  9704. loc: gl.getAttribLocation(program, "aPosition"),
  9705. type: gl.FLOAT,
  9706. size: 3,
  9707. offset: 0,
  9708. stride: 44
  9709. },
  9710. normal: {
  9711. loc: gl.getAttribLocation(program, "aColor"),
  9712. type: gl.FLOAT,
  9713. size: 4,
  9714. offset: 12,
  9715. stride: 44
  9716. },
  9717. texcoord: {
  9718. loc: gl.getAttribLocation(program, "aTexCoord"),
  9719. type: gl.FLOAT,
  9720. size: 4,
  9721. offset: 28,
  9722. stride: 44
  9723. }
  9724. }
  9725. },
  9726. vertShader: " attribute vec3 aPosition; attribute vec4 aColor; attribute vec4 aTexCoord; varying vec4 vColor; varying vec2 vTexCoord; uniform mat4 uModelMatrix; uniform mat4 uViewMatrix; uniform mat4 uProjMatrix; void main(void) { vec4 pos = uViewMatrix * uModelMatrix * vec4(aPosition, 1); pos.xy += aTexCoord.zw; gl_Position = uProjMatrix * pos; vTexCoord = aTexCoord.xy; vColor = aColor; } ",
  9727. fragShader: " precision mediump float; varying vec4 vColor; varying vec2 vTexCoord; uniform bool uHasTexture; uniform bool uHasTexture2; uniform bool uHasTexture3; uniform bool uHasAlpha; uniform int uBlendMode; uniform sampler2D uTexture; uniform sampler2D uTexture2; uniform sampler2D uTexture3; uniform sampler2D uAlpha; void main(void) { vec4 color = vec4(1, 1, 1, 1); if (uHasTexture) { color = texture2D(uTexture, vTexCoord.st); } if (uHasTexture2) { color *= texture2D(uTexture2, vTexCoord.st); } if (uHasTexture3) { color *= texture2D(uTexture3, vTexCoord.st); } if (uBlendMode == 7) { vec4 color2 = vec4(4, 4, 4, 4); color *= color2; } if ((uBlendMode == 1 || uBlendMode == 2 || uBlendMode == 4 || uBlendMode == 7) && uHasAlpha) { color.a = texture2D(uAlpha, vTexCoord.st).a; } color *= vColor; if (uBlendMode == 1) { if (color.a < 0.7) { discard; } } gl_FragColor = color; } ",
  9728. update: function(anim, time, delta) {
  9729. var self = this,
  9730. Wow = ZamModelViewer.Wow;
  9731. var grav = Wow.AnimatedFloat.getValue(self.gravity, anim, time);
  9732. var deaccel = Wow.AnimatedFloat.getValue(self.gravity2, anim, time);
  9733. var speed, i, j;
  9734. if (self.emitterType == 1 || self.emitterType == 2) {
  9735. var rate = Wow.AnimatedFloat.getValue(self.emissionRate, anim, time);
  9736. var life = Wow.AnimatedFloat.getValue(self.lifespan, anim, time);
  9737. var toSpawn = 0;
  9738. if (life != 0) toSpawn = delta * rate / life + self.spawnRemainder;
  9739. else toSpawn = self.spawnRemainder;
  9740. if (toSpawn < 1) {
  9741. self.spawnRemainder = toSpawn;
  9742. if (self.spawnRemainder < 0) self.spawnRemainder = 0
  9743. } else {
  9744. var count = Math.min(Math.floor(toSpawn), self.nextParticle + 1);
  9745. self.spawnRemainder = toSpawn - count;
  9746. var en = true;
  9747. if (Wow.Animated.isUsed(self.enabled, anim)) en = Wow.AnimatedUint8.getValue(self.enabled, anim, time) != 0;
  9748. if (en && count > 0) {
  9749. var w = Wow.AnimatedFloat.getValue(self.areaWidth, anim, time) * .5;
  9750. var l = Wow.AnimatedFloat.getValue(self.areaLength, anim, time) * .5;
  9751. speed = Wow.AnimatedFloat.getValue(self.emissionSpeed, anim, time);
  9752. var vary = Wow.AnimatedFloat.getValue(self.speedVariation, anim, time);
  9753. if (self.emitterType == 1) {
  9754. for (i = 0; i < count; ++i) self.spawnPlaneParticle(w, l, speed, vary, life)
  9755. } else {
  9756. var vSpread = Wow.AnimatedFloat.getValue(self.verticalRange, anim, time);
  9757. var hSpread = Wow.AnimatedFloat.getValue(self.horizontalRange, anim, time);
  9758. for (i = 0; i < count; ++i) self.spawnSphereParticle(w, l, speed, vary, vSpread, hSpread)
  9759. }
  9760. }
  9761. }
  9762. if (isNaN(self.spawnRemainder)) self.spawnRemainder = 0
  9763. }
  9764. speed = 1;
  9765. var gravDelta = grav * delta;
  9766. var deaccelDelta = deaccel * delta;
  9767. var speedDelta = speed * delta;
  9768. var p, lifePos, limit, v, s1, s2, s3;
  9769. s1 = self.size.data[0];
  9770. if (self.size.data.length > 2) {
  9771. s2 = self.size.data[1];
  9772. s3 = self.size.data[2]
  9773. } else if (self.size.data.length > 1) {
  9774. s2 = self.size.data[1];
  9775. s3 = s2
  9776. } else {
  9777. s3 = s2 = s1
  9778. }
  9779. for (i = 0; i < self.maxParticles; ++i) {
  9780. p = self.particles[i];
  9781. if (!p || p.maxLife == 0) continue;
  9782. p.life += delta;
  9783. lifePos = p.life / p.maxLife;
  9784. if (lifePos >= 1) {
  9785. p.maxLife = 0;
  9786. self.nextParticle++;
  9787. self.unusedParticles[self.nextParticle] = p.index;
  9788. continue
  9789. }
  9790. vec3.scaleAndAdd(p.speed, p.speed, p.down, gravDelta);
  9791. vec3.scaleAndAdd(p.speed, p.speed, p.direction, -deaccelDelta);
  9792. if (self.slowdown > 0) {
  9793. speed = Math.exp(-1 * self.slowdown * p.life);
  9794. speedDelta = speed * delta
  9795. }
  9796. vec3.scaleAndAdd(p.position, p.position, p.speed, speedDelta);
  9797. if (lifePos <= .5) {
  9798. vec2.lerp(p.size, s1, s2, lifePos / .5)
  9799. } else {
  9800. vec2.lerp(p.size, s2, s3, (lifePos - .5) / .5)
  9801. }
  9802. vec2.multiply(p.size, p.size, self.scale);
  9803. limit = Math.min(3, self.color.data.length);
  9804. for (j = 0; j < limit; ++j) {
  9805. v = self.color.data[j];
  9806. vec4.set(self.tmpColors[j], v[0] / 255, v[1] / 255, v[2] / 255, self.alpha.data[j] / 32767)
  9807. }
  9808. if (limit < 3) {
  9809. v = self.color.data[limit - 1];
  9810. for (j = limit; j < 3; ++j) vec4.set(self.tmpColors[j], v[0] / 255, v[1] / 255, v[2] / 255, self.alpha.data[j] / 32767)
  9811. }
  9812. if (lifePos <= .5) {
  9813. vec4.lerp(p.color, self.tmpColors[0], self.tmpColors[1], lifePos / .5)
  9814. } else {
  9815. vec4.lerp(p.color, self.tmpColors[1], self.tmpColors[2], (lifePos - .5) / .5)
  9816. }
  9817. }
  9818. self.updateBuffers()
  9819. },
  9820. getNextParticle: function() {
  9821. var self = this;
  9822. if (self.nextParticle < 0) return null;
  9823. var index = self.unusedParticles[self.nextParticle];
  9824. if (!self.particles[index]) {
  9825. self.particles[index] = {
  9826. index: index,
  9827. position: vec3.create(),
  9828. origin: vec3.create(),
  9829. speed: vec4.create(),
  9830. direction: vec4.create(),
  9831. down: vec3.create(),
  9832. color: vec4.create(),
  9833. size: vec2.create(),
  9834. life: 0,
  9835. maxLife: 0,
  9836. tile: 0
  9837. }
  9838. }
  9839. self.nextParticle--;
  9840. return self.particles[index]
  9841. },
  9842. spawnPlaneParticle: function(width, height, speed, vary, life) {
  9843. var self = this,
  9844. p = self.getNextParticle();
  9845. if (!p) return null;
  9846. vec3.copy(p.position, self.position);
  9847. p.position[0] += -width / 2 + width * Math.random();
  9848. p.position[1] += -height / 2 + height * Math.random();
  9849. vec3.transformMat4(p.position, p.position, self.bone.matrix);
  9850. vec4.set(p.direction, 0, 0, 1, 0);
  9851. vec4.transformMat4(p.direction, p.direction, self.bone.matrix);
  9852. vec3.normalize(p.direction, p.direction);
  9853. vec4.copy(p.speed, p.direction);
  9854. var v1 = speed - speed * vary,
  9855. v2 = speed + speed * vary;
  9856. vec4.scale(p.speed, p.speed, v1 + (v2 - v1) * Math.random());
  9857. vec3.set(p.down, 0, 0, -1);
  9858. p.life = 0;
  9859. p.maxLife = life;
  9860. if (!p.maxLife) p.maxLife = 1;
  9861. vec3.copy(p.origin, p.position);
  9862. p.tile = Math.floor(Math.random() * self.tileRows * self.tileColumns);
  9863. vec4.set(p.color, 1, 1, 1, 1);
  9864. return p
  9865. },
  9866. spawnSphereParticle: function(width, height, speed, vary, spread, spread2, life) {
  9867. var self = this,
  9868. p = self.getNextParticle();
  9869. if (!p) return null;
  9870. var radius = Math.random(),
  9871. t = 0;
  9872. if (spread == 0) {
  9873. t = Math.random() * Math.PI * 2 - Math.PI
  9874. } else {
  9875. t = Math.random() * spread * 2 - spread
  9876. }
  9877. self.calcSpread(spread * 2, spread * 2, width, height);
  9878. if ((self.flags & 57) == 57 || (self.flags & 313) == 313) {
  9879. vec3.copy(p.position, self.position);
  9880. vec4.set(p.direction, width * Math.cos(t) * 1.6, height * Math.sin(t) * 1.6, 0, 0);
  9881. vec3.add(p.position, p.position, p.direction);
  9882. vec3.transformMat4(p.position, p.position, self.bone.matrix);
  9883. if (vec3.squaredLength(p.direction) == 0) {
  9884. vec4.set(p.speed, 0, 0, 0, 0)
  9885. } else {
  9886. vec4.transformMat4(p.direction, p.direction, self.bone.matrix);
  9887. vec3.normalize(p.direction, p.direction);
  9888. vec3.copy(p.speed, p.direction);
  9889. vec3.scale(p.speed, p.speed, speed * (1 + Math.random() * vary * 2 - vary))
  9890. }
  9891. } else {
  9892. vec4.set(p.direction, 0, 0, 1, 0);
  9893. vec4.transformMat4(p.direction, p.direction, self.spreadMat);
  9894. vec3.scale(p.direction, p.direction, radius);
  9895. vec3.copy(p.position, self.position);
  9896. vec3.add(p.position, p.position, p.direction);
  9897. vec3.transformMat4(p.position, p.position, self.bone.matrix);
  9898. if (vec3.squaredLength(p.direction) == 0 && (self.flags & 256) == 0) {
  9899. vec4.set(p.speed, 0, 0, 0, 0);
  9900. vec4.set(p.direction, 0, 0, 1, 0);
  9901. vec4.transformMat4(p.direction, p.direction, self.bone.matrix);
  9902. vec3.normalize(p.direction, p.direction)
  9903. } else {
  9904. if ((self.flags & 256) > 0) {
  9905. vec4.set(p.direction, 0, 0, 1, 0);
  9906. vec4.transformMat4(p.direction, p.direction, self.bone.matrix)
  9907. }
  9908. vec3.normalize(p.direction, p.direction);
  9909. vec4.copy(p.speed, p.direction);
  9910. vec3.scale(p.speed, p.speed, speed * (1 + Math.random() * vary * 2 - vary))
  9911. }
  9912. }
  9913. vec3.set(p.down, 0, 0, -1);
  9914. p.life = 0;
  9915. p.maxLife = life;
  9916. if (!p.maxLife) p.maxLife = 1;
  9917. vec3.copy(p.origin, p.position);
  9918. p.tile = Math.floor(Math.random() * self.tileRows * self.tileColumns);
  9919. vec4.set(p.color, 1, 1, 1, 1);
  9920. return p
  9921. },
  9922. calcSpread: function(spread1, spread2, width, height) {
  9923. var self = this,
  9924. mat = this.spreadMat,
  9925. tmpMat = this.tmpMat;
  9926. var a0 = (Math.random() * (spread1 * 2) - spread1) / 2,
  9927. a1 = (Math.random() * (spread2 * 2) - spread2) / 2;
  9928. var c0 = Math.cos(a0),
  9929. c1 = Math.cos(a1),
  9930. s0 = Math.sin(a0),
  9931. s1 = Math.sin(a1);
  9932. mat4.identity(mat);
  9933. mat4.identity(tmpMat);
  9934. tmpMat[5] = tmpMat[10] = c0;
  9935. tmpMat[9] = s0;
  9936. tmpMat[6] = -s0;
  9937. mat4.multiply(mat, mat, tmpMat);
  9938. mat4.identity(tmpMat);
  9939. tmpMat[0] = tmpMat[10] = c1;
  9940. tmpMat[2] = s1;
  9941. tmpMat[8] = -s1;
  9942. mat4.multiply(mat, mat, tmpMat);
  9943. var size = Math.abs(c0) * height * Math.abs(s0) * width;
  9944. mat[0] *= size;
  9945. mat[1] *= size;
  9946. mat[2] *= size;
  9947. mat[4] *= size;
  9948. mat[5] *= size;
  9949. mat[6] *= size;
  9950. mat[8] *= size;
  9951. mat[9] *= size;
  9952. mat[10] *= size;
  9953. mat4.multiply(mat, self.bone.matrix, mat);
  9954. return mat
  9955. },
  9956. init: function() {
  9957. var self = this;
  9958. if (self.scale.z == 519) self.scale.z = 1.5;
  9959. var numTiles = self.tileRows * self.tileColumns;
  9960. self.textureCoords = new Array(numTiles);
  9961. var a = {
  9962. x: 0,
  9963. y: 0
  9964. },
  9965. b = {
  9966. x: 0,
  9967. y: 0
  9968. };
  9969. var i, x, y;
  9970. for (i = 0; i < numTiles; ++i) {
  9971. x = i % self.tileColumns;
  9972. y = Math.floor(i / self.tileColumns);
  9973. a.x = x * (1 / self.tileColumns);
  9974. b.x = (x + 1) * (1 / self.tileColumns);
  9975. a.y = y * (1 / self.tileRows);
  9976. b.y = (y + 1) * (1 / self.tileRows);
  9977. self.textureCoords[i] = [{
  9978. x: a.x,
  9979. y: a.y,
  9980. z: -1,
  9981. w: 1
  9982. }, {
  9983. x: b.x,
  9984. y: a.y,
  9985. z: 1,
  9986. w: 1
  9987. }, {
  9988. x: a.x,
  9989. y: b.y,
  9990. z: -1,
  9991. w: -1
  9992. }, {
  9993. x: b.x,
  9994. y: b.y,
  9995. z: 1,
  9996. w: -1
  9997. }]
  9998. }
  9999. }
  10000. };
  10001. ZamModelViewer.Wow.RibbonEmitter = function(model, r) {
  10002. var self = this,
  10003. Wow = ZamModelViewer.Wow,
  10004. i;
  10005. self.model = model;
  10006. self.id = r.getInt32();
  10007. self.boneId = r.getInt32();
  10008. self.position = [r.getFloat(), r.getFloat(), r.getFloat()];
  10009. self.resolution = r.getFloat();
  10010. self.length = r.getFloat();
  10011. self.emissionAngle = r.getFloat();
  10012. self.s1 = r.getInt16();
  10013. self.s2 = r.getInt16();
  10014. var count = r.getInt32();
  10015. if (count > 0) {
  10016. self.textureIds = new Array(count);
  10017. for (i = 0; i < count; ++i) {
  10018. self.textureIds[i] = r.getInt32()
  10019. }
  10020. }
  10021. self.color = Wow.AnimatedVec3.readSet(r);
  10022. self.alpha = Wow.AnimatedUint16.readSet(r);
  10023. self.above = Wow.AnimatedFloat.readSet(r);
  10024. self.below = Wow.AnimatedFloat.readSet(r);
  10025. self.bone = self.model.bones[self.boneId];
  10026. self.maxSegments = 50;
  10027. self.segments = new Array(self.maxSegments);
  10028. for (i = 0; i < self.maxSegments; ++i) {
  10029. self.segments[i] = {
  10030. position: vec3.create(),
  10031. start: vec3.create(),
  10032. up: vec4.create(),
  10033. length: 0
  10034. }
  10035. }
  10036. self.currentSegment = 0;
  10037. self.numSegments = 0;
  10038. self.totalLength = self.resolution / self.length;
  10039. self.currentPosition = vec3.clone(self.position);
  10040. self.currentColor = vec4.create();
  10041. self.currentAbove = 0;
  10042. self.currentBelow = 0;
  10043. self.currentLength = 0;
  10044. self.tmpPosition = vec3.create();
  10045. self.tmpUp = vec4.create();
  10046. self.tmpVec = vec4.create()
  10047. };
  10048. ZamModelViewer.Wow.RibbonEmitter.prototype = {
  10049. destroy: function() {
  10050. var self = this,
  10051. gl = self.model.renderer.context,
  10052. Animated = ZamModelViewer.Wow.Animated;
  10053. if (self.program) gl.deleteProgram(self.program);
  10054. if (self.vs) gl.deleteShader(self.vs);
  10055. if (self.fs) gl.deleteShader(self.fs);
  10056. if (self.vb) gl.deleteBuffer(self.vb);
  10057. if (self.ib) gl.deleteBuffer(self.ib);
  10058. self.program = null;
  10059. self.vs = null;
  10060. self.fs = null;
  10061. self.vb = null;
  10062. self.ib = null;
  10063. self.vbData = null;
  10064. self.uniforms = null;
  10065. self.attribs = null;
  10066. self.texture = null;
  10067. self.model = null;
  10068. self.bone = null;
  10069. self.position = null;
  10070. self.textureIds = null;
  10071. for (var i = 0; i < self.maxSegments; ++i) {
  10072. self.segments[i].position = null;
  10073. self.segments[i].start = null;
  10074. self.segments[i].up = null;
  10075. self.segments[i] = null
  10076. }
  10077. self.segments = null;
  10078. self.currentPosition = null;
  10079. self.currentColor = null;
  10080. self.tmpPosition = null;
  10081. self.tmpUp = null;
  10082. self.tmpVec = null;
  10083. self.color = Animated.destroySet(self.color);
  10084. self.alpha = Animated.destroySet(self.alpha);
  10085. self.above = Animated.destroySet(self.above);
  10086. self.below = Animated.destroySet(self.below)
  10087. },
  10088. updateBuffers: function() {
  10089. var self = this,
  10090. gl = self.model.renderer.context,
  10091. i, j;
  10092. if (!self.vbData) {
  10093. self.vbData = new Float32Array((self.maxSegments * 2 + 2) * 5);
  10094. var ibData = new Uint16Array(self.maxSegments * 6);
  10095. var vert = 0;
  10096. for (i = 0; i < self.maxSegments; ++i) {
  10097. ibData[i * 6 + 0] = vert;
  10098. ibData[i * 6 + 1] = vert + 1;
  10099. ibData[i * 6 + 2] = vert + 2;
  10100. ibData[i * 6 + 3] = vert + 2;
  10101. ibData[i * 6 + 4] = vert + 1;
  10102. ibData[i * 6 + 5] = vert + 3;
  10103. vert += 2
  10104. }
  10105. self.ib = gl.createBuffer();
  10106. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.ib);
  10107. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, ibData, gl.STATIC_DRAW)
  10108. }
  10109. if (self.numSegments == 0) return;
  10110. var s = self.segments[self.currentSegment],
  10111. n = 0,
  10112. u, u2, l = 0,
  10113. vbData = self.vbData;
  10114. var above = self.currentAbove,
  10115. below = self.currentBelow;
  10116. vbData[n] = s.start[0] + s.up[0] * above;
  10117. vbData[n + 1] = s.start[1] + s.up[1] * above;
  10118. vbData[n + 2] = s.start[2] + s.up[2] * above;
  10119. vbData[n + 3] = 1;
  10120. vbData[n + 4] = 0;
  10121. n += 5;
  10122. vbData[n] = s.start[0] - s.up[0] * below;
  10123. vbData[n + 1] = s.start[1] - s.up[1] * below;
  10124. vbData[n + 2] = s.start[2] - s.up[2] * below;
  10125. vbData[n + 3] = 1;
  10126. vbData[n + 4] = 1;
  10127. n += 5;
  10128. for (i = 0; i < self.numSegments; ++i) {
  10129. s = self.segments[(self.currentSegment + i) % self.maxSegments];
  10130. u = 1 - (self.currentLength != 0 ? l / self.currentLength : 0);
  10131. u2 = 1 - (self.currentLength != 0 ? (l + s.length) / self.currentLength : 1);
  10132. vbData[n] = s.position[0] + s.up[0] * above;
  10133. vbData[n + 1] = s.position[1] + s.up[1] * above;
  10134. vbData[n + 2] = s.position[2] + s.up[2] * above;
  10135. vbData[n + 3] = u2;
  10136. vbData[n + 4] = 0;
  10137. n += 5;
  10138. vbData[n] = s.position[0] - s.up[0] * below;
  10139. vbData[n + 1] = s.position[1] - s.up[1] * below;
  10140. vbData[n + 2] = s.position[2] - s.up[2] * below;
  10141. vbData[n + 3] = u2;
  10142. vbData[n + 4] = 1;
  10143. n += 5;
  10144. l += s.length
  10145. }
  10146. if (!self.vb) {
  10147. self.vb = gl.createBuffer();
  10148. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  10149. gl.bufferData(gl.ARRAY_BUFFER, self.vbData, gl.DYNAMIC_DRAW)
  10150. } else {
  10151. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  10152. gl.bufferSubData(gl.ARRAY_BUFFER, 0, self.vbData)
  10153. }
  10154. },
  10155. draw: function() {
  10156. var self = this,
  10157. gl = self.model.renderer.context,
  10158. i;
  10159. if (self.numSegments == 0) return;
  10160. if (!self.shaderReady) self.initShader();
  10161. if (!self.program) return;
  10162. if (!self.texture && self.textureIds[0] > -1 && self.textureIds[0] < self.model.materials.length) {
  10163. var mat = self.model.materials[self.textureIds[0]];
  10164. if (mat.texture && mat.texture.texture && (!mat.texture.alphaImg || mat.texture.alphaTexture)) {
  10165. self.texture = mat.texture
  10166. }
  10167. }
  10168. if (!self.texture) return;
  10169. gl.useProgram(self.program);
  10170. gl.uniformMatrix4fv(self.uniforms.vModelMatrix, false, self.model.matrix);
  10171. gl.uniformMatrix4fv(self.uniforms.vViewMatrix, false, self.model.renderer.viewMatrix);
  10172. gl.uniformMatrix4fv(self.uniforms.vProjMatrix, false, self.model.renderer.projMatrix);
  10173. gl.uniform4fv(self.uniforms.fColor, self.currentColor);
  10174. if (self.texture) {
  10175. gl.activeTexture(gl.TEXTURE0);
  10176. gl.bindTexture(gl.TEXTURE_2D, self.texture.texture);
  10177. gl.uniform1i(self.uniforms.fTexture, 0)
  10178. }
  10179. if (self.texture && self.texture.alphaTexture) {
  10180. gl.activeTexture(gl.TEXTURE1);
  10181. gl.bindTexture(gl.TEXTURE_2D, self.texture.alphaTexture);
  10182. gl.uniform1i(self.uniforms.fAlpha, 1)
  10183. }
  10184. gl.uniform1i(self.uniforms.fHasTexture, self.texture ? 1 : 0);
  10185. gl.uniform1i(self.uniforms.fHasAlpha, self.texture && self.texture.alphaTexture ? 1 : 0);
  10186. gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
  10187. gl.disable(gl.CULL_FACE);
  10188. gl.depthMask(false);
  10189. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  10190. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.ib);
  10191. for (i in self.attribs) {
  10192. var a = self.attribs[i];
  10193. gl.enableVertexAttribArray(a.loc);
  10194. gl.vertexAttribPointer(a.loc, a.size, a.type, false, a.stride, a.offset)
  10195. }
  10196. gl.drawElements(gl.TRIANGLES, self.numSegments * 6, gl.UNSIGNED_SHORT, 0);
  10197. for (i in self.attribs) {
  10198. gl.disableVertexAttribArray(self.attribs[i].loc)
  10199. }
  10200. },
  10201. initShader: function() {
  10202. var self = this,
  10203. gl = self.model.renderer.context;
  10204. self.shaderReady = true;
  10205. var vs = self.model.renderer.compileShader(gl.VERTEX_SHADER, self.vertShader);
  10206. var fs = self.model.renderer.compileShader(gl.FRAGMENT_SHADER, self.fragShader);
  10207. var program = gl.createProgram();
  10208. gl.attachShader(program, vs);
  10209. gl.attachShader(program, fs);
  10210. gl.linkProgram(program);
  10211. if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
  10212. console.error("Error linking shaders");
  10213. return
  10214. }
  10215. self.vs = vs;
  10216. self.fs = fs;
  10217. self.program = program;
  10218. self.uniforms = {
  10219. vModelMatrix: gl.getUniformLocation(program, "uModelMatrix"),
  10220. vViewMatrix: gl.getUniformLocation(program, "uViewMatrix"),
  10221. vProjMatrix: gl.getUniformLocation(program, "uProjMatrix"),
  10222. fHasTexture: gl.getUniformLocation(program, "uHasTexture"),
  10223. fHasAlpha: gl.getUniformLocation(program, "uHasAlpha"),
  10224. fTexture: gl.getUniformLocation(program, "uTexture"),
  10225. fAlpha: gl.getUniformLocation(program, "uAlpha"),
  10226. fColor: gl.getUniformLocation(program, "uColor")
  10227. };
  10228. self.attribs = {
  10229. position: {
  10230. loc: gl.getAttribLocation(program, "aPosition"),
  10231. type: gl.FLOAT,
  10232. size: 3,
  10233. offset: 0,
  10234. stride: 20
  10235. },
  10236. texcoord: {
  10237. loc: gl.getAttribLocation(program, "aTexCoord"),
  10238. type: gl.FLOAT,
  10239. size: 2,
  10240. offset: 12,
  10241. stride: 20
  10242. }
  10243. }
  10244. },
  10245. vertShader: " attribute vec3 aPosition; attribute vec2 aTexCoord; varying vec2 vTexCoord; uniform mat4 uModelMatrix; uniform mat4 uViewMatrix; uniform mat4 uProjMatrix; void main(void) { gl_Position = uProjMatrix * uViewMatrix * uModelMatrix * vec4(aPosition, 1); vTexCoord = aTexCoord; } ",
  10246. fragShader: " precision mediump float; varying vec2 vTexCoord; uniform bool uHasTexture; uniform bool uHasAlpha; uniform sampler2D uTexture; uniform sampler2D uAlpha; uniform vec4 uColor; void main(void) { vec4 color = vec4(1, 1, 1, 1); if (uHasTexture) { color = texture2D(uTexture, vTexCoord.st); } if (uHasAlpha) { color.a = texture2D(uAlpha, vTexCoord.st).a; } gl_FragColor = color * uColor; } ",
  10247. update: function(anim, time) {
  10248. var self = this,
  10249. Wow = ZamModelViewer.Wow,
  10250. i, s;
  10251. vec3.transformMat4(self.tmpPosition, self.position, self.bone.matrix);
  10252. vec4.set(self.tmpUp, 0, 0, 1, 0);
  10253. vec4.transformMat4(self.tmpUp, self.tmpUp, self.bone.matrix);
  10254. vec3.normalize(self.tmpUp, self.tmpUp);
  10255. if (self.numSegments == 0) {
  10256. s = self.pushSegment();
  10257. vec3.copy(s.start, self.tmpPosition);
  10258. vec3.copy(s.position, self.tmpPosition);
  10259. vec4.copy(s.up, self.tmpUp);
  10260. s.length = 0
  10261. } else {
  10262. var currIdx = (self.currentSegment + self.numSegments - 1) % self.maxSegments;
  10263. s = self.segments[currIdx];
  10264. vec3.copy(s.position, self.tmpPosition);
  10265. vec4.copy(s.up, self.tmpUp);
  10266. vec3.subtract(self.tmpVec, s.position, self.currentPosition);
  10267. s.length += vec3.length(self.tmpVec);
  10268. if (s.length >= self.length) {
  10269. s = self.pushSegment();
  10270. vec3.copy(s.start, self.tmpPosition);
  10271. vec3.copy(s.position, self.tmpPosition);
  10272. vec4.copy(s.up, self.tmpUp);
  10273. s.length = 0
  10274. }
  10275. }
  10276. self.currentLength = 0;
  10277. var idx;
  10278. for (i = 0; i < self.numSegments; ++i) {
  10279. idx = (self.currentSegment + i) % self.maxSegments;
  10280. self.currentLength += self.segments[idx].length
  10281. }
  10282. if (self.currentLength > self.totalLength + .1) {
  10283. self.currentLength -= self.segments[self.currentSegment].length;
  10284. self.shiftSegment()
  10285. }
  10286. vec3.copy(self.currentPosition, self.tmpPosition);
  10287. Wow.AnimatedVec3.getValue(self.color, anim, time, self.currentColor);
  10288. self.currentColor[3] = Wow.AnimatedUint16.getValue(self.alpha, anim, time) / 32767;
  10289. self.currentAbove = Wow.AnimatedFloat.getValue(self.above, anim, time);
  10290. self.currentBelow = Wow.AnimatedFloat.getValue(self.below, anim, time);
  10291. self.updateBuffers()
  10292. },
  10293. pushSegment: function() {
  10294. var self = this;
  10295. if (self.numSegments < self.maxSegments) {
  10296. self.numSegments++
  10297. } else {
  10298. self.currentSegment = (self.currentSegment + 1) % self.maxSegments
  10299. }
  10300. return self.segments[self.currentSegment]
  10301. },
  10302. popSegment: function() {
  10303. var self = this;
  10304. self.numSegments--
  10305. },
  10306. shiftSegment: function() {
  10307. var self = this;
  10308. self.currentSegment = (self.currentSegment + 1) % self.maxSegments;
  10309. self.numSegments--
  10310. }
  10311. };
  10312. ZamModelViewer.Wow.Skin = function(r, version) {
  10313. var self = this;
  10314. self.skinFlags = version > 2e3 ? r.getUint32() : 0;
  10315. self.base = r.getUint32();
  10316. self.fur = r.getUint32();
  10317. self.underwearFlags = version > 2e3 ? r.getUint32() : 0;
  10318. self.panties = r.getUint32();
  10319. self.bra = r.getUint32();
  10320. self.faces = null
  10321. };
  10322. ZamModelViewer.Wow.Skin._lastFaces = null;
  10323. ZamModelViewer.Wow.Skin.GetSkins = function(skins, playerOnly, dk) {
  10324. if (!skins) return [];
  10325. var list = [];
  10326. for (var i = 0; i < skins.length; ++i) {
  10327. if (playerOnly && (skins[i].skinFlags & 3) > 0) {
  10328. if ((skins[i].skinFlags & 4) > 0) {
  10329. if (dk) list.push(skins[i])
  10330. } else {
  10331. list.push(skins[i])
  10332. }
  10333. } else if (!playerOnly || skins[i].skinFlags == 0) {
  10334. list.push(skins[i])
  10335. }
  10336. }
  10337. return list
  10338. };
  10339. ZamModelViewer.Wow.Skin.GetFaces = function(faces, playerOnly, dk, skinFlags) {
  10340. if (!faces || dk && (skinFlags & 4) > 0) return [];
  10341. var list = [];
  10342. for (var i = 0; i < faces.length; ++i) {
  10343. if (playerOnly && (faces[i].flags & 3) > 0) {
  10344. if ((faces[i].flags & 4) > 0) {
  10345. if (dk) list.push(faces[i])
  10346. } else {
  10347. list.push(faces[i])
  10348. }
  10349. } else if (!playerOnly || faces[i].flags == 0) {
  10350. list.push(faces[i])
  10351. }
  10352. }
  10353. return list
  10354. };
  10355. ZamModelViewer.Wow.Skin.prototype = {
  10356. destroy: function() {
  10357. var self = this;
  10358. if (self.faces) {
  10359. for (var i = 0; i < self.faces.length; ++i) self.faces[i] = null;
  10360. self.faces = null
  10361. }
  10362. },
  10363. readFaces: function(r, version) {
  10364. var self = this;
  10365. var count = r.getInt32();
  10366. if (count == 0 && ZamModelViewer.Wow.Skin._lastFaces) {
  10367. self.faces = ZamModelViewer.Wow.Skin._lastFaces
  10368. } else if (count > 0) {
  10369. self.faces = new Array(count);
  10370. for (var i = 0; i < count; ++i) {
  10371. self.faces[i] = {
  10372. flags: version > 2e3 ? r.getUint32() : 0,
  10373. lower: r.getUint32(),
  10374. upper: r.getUint32()
  10375. };
  10376. ZamModelViewer.Wow.Skin._lastFaces = self.faces[i]
  10377. }
  10378. }
  10379. }
  10380. };
  10381. ZamModelViewer.Wow.Face = function(r) {
  10382. var self = this;
  10383. self.geoset1 = r.getInt32();
  10384. self.geoset2 = r.getInt32();
  10385. self.geoset3 = r.getInt32();
  10386. self.textures = null
  10387. };
  10388. ZamModelViewer.Wow.Face.GetTextures = function(textures, playerOnly, dk) {
  10389. if (!textures) return [];
  10390. var list = [];
  10391. for (var i = 0; i < textures.length; ++i) {
  10392. if (playerOnly && (textures[i].flags & 3) > 0) {
  10393. if ((textures[i].flags & 4) > 0) {
  10394. if (dk) list.push(textures[i])
  10395. } else {
  10396. list.push(textures[i])
  10397. }
  10398. } else if (!playerOnly || textures[i].flags == 0) {
  10399. list.push(textures[i])
  10400. }
  10401. }
  10402. return list
  10403. };
  10404. ZamModelViewer.Wow.Face.prototype = {
  10405. destroy: function() {
  10406. var self = this;
  10407. if (self.textures) {
  10408. for (var i = 0; i < self.textures.length; ++i) self.textures[i] = null;
  10409. self.textures = null
  10410. }
  10411. },
  10412. readTextures: function(r, version) {
  10413. var self = this;
  10414. var count = r.getInt32();
  10415. if (count > 0) {
  10416. self.textures = new Array(count);
  10417. for (var i = 0; i < count; ++i) {
  10418. self.textures[i] = {
  10419. flags: version > 2e3 ? r.getUint32() : 0,
  10420. lower: r.getUint32(),
  10421. upper: r.getUint32()
  10422. }
  10423. }
  10424. }
  10425. }
  10426. };
  10427. ZamModelViewer.Wow.Hair = function(r) {
  10428. var self = this;
  10429. self.geoset = r.getUint8();
  10430. self.textures = null
  10431. };
  10432. ZamModelViewer.Wow.Hair.GetTextures = function(textures, playerOnly, dk) {
  10433. if (!textures) return [];
  10434. var list = [];
  10435. for (var i = 0; i < textures.length; ++i) {
  10436. if (textures[i].flags != 0) {
  10437. if (playerOnly && (textures[i].flags & 3) > 0) {
  10438. if ((textures[i].flags & 4) > 0) {
  10439. if (dk) list.push(textures[i])
  10440. } else {
  10441. list.push(textures[i])
  10442. }
  10443. } else if (!playerOnly || textures[i].flags == 0) {
  10444. list.push(textures[i])
  10445. }
  10446. }
  10447. }
  10448. return list
  10449. };
  10450. ZamModelViewer.Wow.Hair.prototype = {
  10451. destroy: function() {
  10452. var self = this;
  10453. if (self.textures) {
  10454. for (var i = 0; i < self.textures.length; ++i) self.textures[i] = null;
  10455. self.textures = null
  10456. }
  10457. },
  10458. readTextures: function(r, version) {
  10459. var self = this;
  10460. var count = r.getInt32();
  10461. if (count > 0) {
  10462. self.textures = new Array(count);
  10463. for (var i = 0; i < count; ++i) {
  10464. self.textures[i] = {
  10465. flags: version > 2e3 ? r.getUint32() : 0,
  10466. texture: r.getUint32(),
  10467. lower: r.getUint32(),
  10468. upper: r.getUint32()
  10469. };
  10470. if (self.textures[i].upper > 0 && self.textures[i].lower > 0) {
  10471. var str = ""
  10472. }
  10473. }
  10474. }
  10475. }
  10476. };
  10477. ZamModelViewer.Wow.Horns = function(r) {
  10478. this.geoset = r.getUint8()
  10479. };
  10480. ZamModelViewer.Wow.Horns.prototype = {
  10481. destroy: function() {
  10482. this.geoset = null
  10483. }
  10484. };
  10485. ZamModelViewer.Wow.Blindfolds = function(r) {
  10486. this.geoset = r.getUint8()
  10487. };
  10488. ZamModelViewer.Wow.Blindfolds.prototype = {
  10489. destroy: function() {
  10490. this.geoset = null
  10491. }
  10492. };
  10493. ZamModelViewer.Wow.ColoredHands = function(r) {
  10494. this.colorIndex = r.getUint8()
  10495. };
  10496. ZamModelViewer.Wow.ColoredHands.prototype = {
  10497. destroy: function() {
  10498. this.colorIndex = null
  10499. }
  10500. };
  10501. ZamModelViewer.Wow.Tattoos = function(r) {
  10502. this.texture = r.getInt32()
  10503. };
  10504. ZamModelViewer.Wow.Tattoos.prototype = {
  10505. destroy: function() {
  10506. this.texture = null
  10507. }
  10508. };
  10509. ZamModelViewer.Wow.HornModel = function(model, slot, id, race, gender) {
  10510. var self = this;
  10511. self.model = model;
  10512. self.slot = slot;
  10513. self.uniqueSlot = ZamModelViewer.Wow.UniqueSlots[slot];
  10514. self.sortValue = ZamModelViewer.Wow.SlotOrder[slot];
  10515. self.models = null;
  10516. self.geosets = null;
  10517. self.textures = null;
  10518. self.geoA = 0;
  10519. self.geoB = 0;
  10520. self.geoC = 0;
  10521. self.loaded = false;
  10522. if (id) {
  10523. self.load(id, race, gender)
  10524. }
  10525. };
  10526. ZamModelViewer.Wow.HornModel.prototype = {
  10527. destroy: function() {
  10528. var self = this,
  10529. i;
  10530. self.model = null;
  10531. if (self.models) {
  10532. for (i = 0; i < self.models.length; ++i) {
  10533. if (self.models[i].model) self.models[i].model.destroy();
  10534. self.models[i].model = null;
  10535. self.models[i].attachment = null;
  10536. self.models[i] = null
  10537. }
  10538. self.models = null
  10539. }
  10540. if (self.textures) {
  10541. for (i = 0; i < self.textures; ++i) {
  10542. if (self.textures[i].texture) self.textures[i].texture.destroy();
  10543. self.textures[i].texture = null;
  10544. self.textures[i] = null
  10545. }
  10546. self.textures = null
  10547. }
  10548. self.geosets = null
  10549. },
  10550. load: function(id, race, gender) {
  10551. var self = this,
  10552. Wow = ZamModelViewer.Wow;
  10553. self.id = id;
  10554. self.meta = {};
  10555. self.models = new Array(3);
  10556. var slotMap = {
  10557. 0: 6,
  10558. 1: 1,
  10559. 2: 1,
  10560. 3: 10
  10561. };
  10562. if (self.models) {
  10563. for (var i = 0; i < self.models.length; ++i) {
  10564. self.models[i] = {
  10565. race: race,
  10566. gender: gender,
  10567. bone: -1,
  10568. attachment: null,
  10569. model: null
  10570. };
  10571. var modelInfo = {
  10572. type: 256,
  10573. id: self.id,
  10574. parent: self.model
  10575. };
  10576. modelInfo.shoulder = i + 1;
  10577. self.models[i].model = new Wow.Model(self.model.renderer, self.model.viewer, modelInfo, i);
  10578. self.models[i].slot = slotMap[i]
  10579. }
  10580. self.loaded = true
  10581. }
  10582. }
  10583. };
  10584. ZamModelViewer.Destiny = function() {};
  10585. ZamModelViewer.Destiny.Model = function(renderer, viewer, model, index, parent) {
  10586. var self = this;
  10587. self.renderer = renderer;
  10588. self.viewer = viewer;
  10589. self.model = model;
  10590. self.modelPath = null;
  10591. self.loaded = false;
  10592. self.opts = self.viewer.options;
  10593. self.gender = self.opts.gender ? parseInt(self.opts.gender) : 0;
  10594. self.meta = null;
  10595. self.index = index;
  10596. self.parent = parent || null;
  10597. self.models = null;
  10598. self.textureLookup = {};
  10599. self.textures = null;
  10600. self.geometry = null;
  10601. self.genderGeometry = [null, null];
  10602. self.genderTextures = [null, null];
  10603. self.dyeGeometry = null;
  10604. self.dyeTextures = null;
  10605. self.gear = null;
  10606. self.matrix = mat4.create();
  10607. self.ib = null;
  10608. self.shaderReady = false;
  10609. self.vs = null;
  10610. self.fs = null;
  10611. self.program = null;
  10612. self.uniforms = null;
  10613. self.attribs = null;
  10614. self.ambientColor = [.35, .35, .35, 1];
  10615. self.primaryColor = [1, 1, 1, 1];
  10616. self.secondaryColor = [.35, .35, .35, 1];
  10617. self.lightDir1 = vec3.create();
  10618. self.lightDir2 = vec3.create();
  10619. self.lightDir3 = vec3.create();
  10620. vec3.normalize(self.lightDir1, [-3, -3, -4]);
  10621. vec3.normalize(self.lightDir2, [3, 1, -3]);
  10622. vec3.normalize(self.lightDir3, [-3, -1, -5]);
  10623. self.lightIntensity = vec4.set(vec4.create(), .7, .15, .15, .25);
  10624. self.animBounds = false;
  10625. self.boundsCenter = [0, 0, 0];
  10626. self.boundsSize = [0, 0, 0];
  10627. self.boundsMin = [0, 0, 0];
  10628. self.boundsMax = [0, 0, 0];
  10629. self.tmpMat = mat4.create();
  10630. self.tmpVec = vec3.create();
  10631. self.load()
  10632. };
  10633. ZamModelViewer.Models[ZamModelViewer.DESTINY] = ZamModelViewer.Destiny.Model;
  10634. ZamModelViewer.Destiny.Model.prototype = {
  10635. destroy: function() {
  10636. var self = this,
  10637. gl = self.renderer.context,
  10638. i, j;
  10639. if (self.program) gl.deleteProgram(self.program);
  10640. if (self.vs) gl.deleteShader(self.vs);
  10641. if (self.fs) gl.deleteShader(self.fs);
  10642. if (self.textures) {
  10643. for (i = 0; i < self.textures.length; ++i) {
  10644. self.textures[i].destroy()
  10645. }
  10646. }
  10647. if (self.models) {
  10648. for (i = 0; i < self.models.length; ++i) {
  10649. self.models[i].destroy()
  10650. }
  10651. }
  10652. if (self.geometry) {
  10653. for (i = 0; i < self.geometry.length; ++i) {
  10654. self.geometry[i].destroy()
  10655. }
  10656. }
  10657. },
  10658. update: function() {
  10659. var self = this,
  10660. i;
  10661. var delta = self.renderer.delta;
  10662. if (self.skeleton) self.skeleton.update(delta);
  10663. if (self.models) {
  10664. for (i = 0; i < self.models.length; ++i) {
  10665. self.models[i].update()
  10666. }
  10667. } else if (self.geometry && self.parent && self.parent.skeleton) {
  10668. for (i = 0; i < self.geometry.length; ++i) {
  10669. self.geometry[i].update()
  10670. }
  10671. }
  10672. },
  10673. draw: function() {
  10674. var self = this,
  10675. gl = self.renderer.context,
  10676. i;
  10677. if (!self.loaded) return;
  10678. if (!self.shaderReady) self.initShader();
  10679. if (!self.program) return;
  10680. self.update();
  10681. gl.useProgram(self.program);
  10682. gl.frontFace(gl.CW);
  10683. gl.disable(gl.CULL_FACE);
  10684. if (self.parent) {
  10685. gl.uniformMatrix4fv(self.uniforms.vModelMatrix, false, self.parent.matrix)
  10686. } else {
  10687. gl.uniformMatrix4fv(self.uniforms.vModelMatrix, false, self.matrix)
  10688. }
  10689. gl.uniformMatrix4fv(self.uniforms.vViewMatrix, false, self.renderer.viewMatrix);
  10690. gl.uniformMatrix4fv(self.uniforms.vProjMatrix, false, self.renderer.projMatrix);
  10691. gl.uniform4fv(self.uniforms.fLightIntensity, self.lightIntensity);
  10692. gl.uniform3fv(self.uniforms.fLightDir1, self.lightDir1);
  10693. gl.uniform3fv(self.uniforms.fLightDir2, self.lightDir2);
  10694. gl.uniform3fv(self.uniforms.fLightDir3, self.lightDir3);
  10695. gl.uniform3fv(self.uniforms.fCameraPos, self.renderer.eye);
  10696. gl.uniform1i(self.uniforms.fHasParent, !!self.parent);
  10697. if (self.models) {
  10698. for (i = 0; i < self.models.length; ++i) {
  10699. self.models[i].draw()
  10700. }
  10701. } else if (self.geometry) {
  10702. var delta = self.renderer.delta;
  10703. for (i = 0; i < self.geometry.length; ++i) {
  10704. self.geometry[i].draw(delta)
  10705. }
  10706. }
  10707. },
  10708. updateBounds: function() {
  10709. var self = this,
  10710. i, j, m, g;
  10711. var min = vec3.set(self.boundsMin, 9999, 9999, 9999),
  10712. max = vec3.set(self.boundsMax, -9999, -9999, -9999);
  10713. if (!self.models) {
  10714. for (i = 0; i < self.geometry.length; ++i) {
  10715. g = self.geometry[i];
  10716. for (j = 0; j < g.meshes.length; ++j) {
  10717. m = g.meshes[j];
  10718. min = vec3.min(min, min, m.boundsMin);
  10719. max = vec3.max(max, max, m.boundsMax)
  10720. }
  10721. }
  10722. } else {
  10723. for (i = 0; i < self.models.length; ++i) {
  10724. m = self.models[i];
  10725. if (!m.loaded) continue;
  10726. min = vec3.min(min, min, m.boundsMin);
  10727. max = vec3.max(max, max, m.boundsMax)
  10728. }
  10729. }
  10730. vec3.subtract(self.boundsSize, max, min);
  10731. vec3.scaleAndAdd(self.boundsCenter, min, self.boundsSize, .5);
  10732. var hSize = self.boundsSize[2],
  10733. wSize = self.boundsSize[0],
  10734. dSize = self.boundsSize[1];
  10735. if (!self.parent) {
  10736. if (self.opts.dist) {
  10737. self.renderer.distance = self.opts.dist
  10738. } else {
  10739. var ratio = self.renderer.width / self.renderer.height;
  10740. var hTan = 2 * Math.tan(self.renderer.fov / 2 * .0174532925);
  10741. var wTan = hTan * ratio;
  10742. var hDist = hSize * 1.2 / hTan;
  10743. var wDist = wSize * 1.2 / wTan;
  10744. self.renderer.distance = Math.max(Math.max(hDist, wDist), dSize * 1.25)
  10745. }
  10746. mat4.identity(self.matrix);
  10747. mat4.rotateZ(self.matrix, self.matrix, Math.PI / 2);
  10748. mat4.translate(self.matrix, self.matrix, vec3.negate(self.tmpVec, self.boundsCenter))
  10749. } else {
  10750. self.parent.updateBounds()
  10751. }
  10752. }
  10753. };
  10754. ZamModelViewer.Destiny.Model.prototype.load = function() {
  10755. var self = this;
  10756. if (self.model) {
  10757. self._load(self.model)
  10758. } else if (self.opts.items) {
  10759. var items;
  10760. if ($.isArray(self.opts.items)) {
  10761. items = self.opts.items
  10762. } else {
  10763. items = self.opts.items.split(";")
  10764. }
  10765. var excludeIdx = items.indexOf("4248210736");
  10766. if (excludeIdx > -1) items.splice(excludeIdx, 1);
  10767. $.getJSON(self.opts.contentPath + "skeleton.json", function(data) {
  10768. self.skeleton = new ZamModelViewer.Destiny.Skeleton(self, data)
  10769. });
  10770. self.models = new Array(items.length);
  10771. for (var i = 0; i < items.length; ++i) {
  10772. self.models[i] = new ZamModelViewer.Destiny.Model(self.renderer, self.viewer, items[i], i, self)
  10773. }
  10774. self.loaded = true
  10775. }
  10776. };
  10777. ZamModelViewer.Destiny.Model.prototype._load = function(id) {
  10778. var self = this;
  10779. var url = self.opts.contentPath + "geom/mobile/" + id + ".geom";
  10780. if (self.opts.cacheBuster) {
  10781. url += "?" + self.opts.cacheBuster
  10782. } else {
  10783. url += "?1"
  10784. }
  10785. $.ajax({
  10786. url: url,
  10787. type: "GET",
  10788. dataType: "binary",
  10789. responseType: "arraybuffer",
  10790. processData: false,
  10791. renderer: self.renderer,
  10792. success: function(buffer) {
  10793. self.loadGeom(buffer)
  10794. },
  10795. error: function(xhr, status, error) {
  10796. console.log(error)
  10797. }
  10798. })
  10799. };
  10800. ZamModelViewer.Destiny.Model.prototype.loadGeom = function(buffer) {
  10801. if (!buffer) {
  10802. console.error("Bad buffer for DataView");
  10803. return
  10804. }
  10805. var self = this,
  10806. r = new ZamModelViewer.DataView(buffer),
  10807. D = ZamModelViewer.Destiny,
  10808. i;
  10809. var magic = r.getUint32();
  10810. if (magic != 572728357) {
  10811. console.log("Bad magic value");
  10812. return
  10813. }
  10814. var compressedData = new Uint8Array(buffer, r.position);
  10815. var data = null;
  10816. try {
  10817. data = pako.inflate(compressedData)
  10818. } catch (err) {
  10819. console.log("Decompression error: " + err);
  10820. return
  10821. }
  10822. r = new ZamModelViewer.DataView(data.buffer);
  10823. var numTextures = r.getInt32();
  10824. self.textures = new Array(numTextures);
  10825. for (i = 0; i < numTextures; ++i) {
  10826. var tex = r.getString();
  10827. self.textures[i] = new D.Texture(self, "textures/mobile/" + tex);
  10828. self.textureLookup[tex] = i
  10829. }
  10830. var numGeometry = r.getInt32();
  10831. self.geometry = new Array(numGeometry);
  10832. for (i = 0; i < numGeometry; ++i) {
  10833. self.geometry[i] = new D.Geometry(self, r)
  10834. }
  10835. var numMaleGeom = r.getInt32();
  10836. self.genderGeometry[0] = new Array(numMaleGeom);
  10837. for (i = 0; i < numMaleGeom; ++i) {
  10838. self.genderGeometry[0][i] = r.getInt32()
  10839. }
  10840. var numMaleTextures = r.getInt32();
  10841. self.genderTextures[0] = new Array(numMaleTextures);
  10842. for (i = 0; i < numMaleTextures; ++i) {
  10843. self.genderTextures[0][i] = r.getInt32()
  10844. }
  10845. var numFemaleGeom = r.getInt32();
  10846. self.genderGeometry[1] = new Array(numFemaleGeom);
  10847. for (i = 0; i < numFemaleGeom; ++i) {
  10848. self.genderGeometry[1][i] = r.getInt32()
  10849. }
  10850. var numFemaleTextures = r.getInt32();
  10851. self.genderTextures[1] = new Array(numFemaleTextures);
  10852. for (i = 0; i < numFemaleTextures; ++i) {
  10853. self.genderTextures[1][i] = r.getInt32()
  10854. }
  10855. var numDyeGeom = r.getInt32();
  10856. self.dyeGeometry = new Array(numDyeGeom);
  10857. for (i = 0; i < numDyeGeom; ++i) {
  10858. self.dyeGeometry[i] = r.getInt32()
  10859. }
  10860. var numDyeTextures = r.getInt32();
  10861. self.dyeTextures = new Array(numDyeTextures);
  10862. for (i = 0; i < numDyeTextures; ++i) {
  10863. self.dyeTextures[i] = r.getInt32()
  10864. }
  10865. var gearLen = r.getInt32();
  10866. var gearStr = r.getString(gearLen);
  10867. self.gear = JSON.parse(gearStr);
  10868. if (self.gear) {
  10869. if (self.gear.locked_dyes && self.gear.locked_dyes.length > 0) {
  10870. self.dyeLocked = true;
  10871. self.dyeInfo = self.gear.locked_dyes
  10872. } else if (self.gear.custom_dyes && self.gear.custom_dyes.length > 0) {
  10873. self.dyeInfo = self.gear.custom_dyes;
  10874. if (self.parent) self.parent.dyeInfo = self.dyeInfo
  10875. } else if (self.gear.default_dyes && self.gear.default_dyes.length > 0) {
  10876. self.dyeInfo = self.gear.default_dyes
  10877. }
  10878. }
  10879. if (numGeometry > 0 && numMaleGeom == 0 && numFemaleGeom == 0) {
  10880. for (i = 0; i < numGeometry; ++i) {
  10881. self.geometry[i].show = true
  10882. }
  10883. } else {
  10884. var geom = self.genderGeometry[self.gender];
  10885. for (i = 0; i < geom.length; ++i) {
  10886. self.geometry[geom[i]].show = true
  10887. }
  10888. }
  10889. self.loaded = true;
  10890. self.updateBounds()
  10891. };
  10892. ZamModelViewer.Destiny.Model.prototype.initShader = function() {
  10893. var self = this,
  10894. gl = self.renderer.context;
  10895. self.shaderReady = true;
  10896. var vs = self.renderer.compileShader(gl.VERTEX_SHADER, self.vertShader);
  10897. var fs = self.renderer.compileShader(gl.FRAGMENT_SHADER, self.fragShader);
  10898. var program = gl.createProgram();
  10899. gl.attachShader(program, vs);
  10900. gl.attachShader(program, fs);
  10901. gl.linkProgram(program);
  10902. if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
  10903. console.error("Error linking shaders");
  10904. return
  10905. }
  10906. self.vs = vs;
  10907. self.fs = fs;
  10908. self.program = program;
  10909. self.uniforms = {
  10910. vModelMatrix: gl.getUniformLocation(program, "uModelMatrix"),
  10911. vViewMatrix: gl.getUniformLocation(program, "uViewMatrix"),
  10912. vProjMatrix: gl.getUniformLocation(program, "uProjMatrix"),
  10913. vHasColor: gl.getUniformLocation(program, "uvHasColor"),
  10914. fHasColor: gl.getUniformLocation(program, "ufHasColor"),
  10915. fHasParent: gl.getUniformLocation(program, "uHasParent"),
  10916. fHasDiffuse: gl.getUniformLocation(program, "uHasDiffuse"),
  10917. fHasNormal: gl.getUniformLocation(program, "uHasNormal"),
  10918. fHasStack: gl.getUniformLocation(program, "uHasStack"),
  10919. fLit: gl.getUniformLocation(program, "uLit"),
  10920. fDiffuse: gl.getUniformLocation(program, "uDiffuse"),
  10921. fNormal: gl.getUniformLocation(program, "uNormal"),
  10922. fStack: gl.getUniformLocation(program, "uStack"),
  10923. fColor: gl.getUniformLocation(program, "uColor"),
  10924. fLightIntensity: gl.getUniformLocation(program, "uLightIntensity"),
  10925. fLightDir1: gl.getUniformLocation(program, "uLightDir1"),
  10926. fLightDir2: gl.getUniformLocation(program, "uLightDir2"),
  10927. fLightDir3: gl.getUniformLocation(program, "uLightDir3"),
  10928. fCameraPos: gl.getUniformLocation(program, "uCameraPos")
  10929. };
  10930. self.attribs = {
  10931. position: gl.getAttribLocation(program, "aPosition"),
  10932. normal: gl.getAttribLocation(program, "aNormal"),
  10933. tangent: gl.getAttribLocation(program, "aTangent"),
  10934. color: gl.getAttribLocation(program, "aColor"),
  10935. texcoord: gl.getAttribLocation(program, "aTexCoords")
  10936. }
  10937. };
  10938. ZamModelViewer.Destiny.Model.prototype.vertShader = " attribute vec3 aPosition; attribute vec4 aNormal; attribute vec4 aTangent; attribute vec2 aTexCoords; attribute vec4 aColor; varying vec3 vPosition; varying vec3 vNormal; varying vec3 vTangent; varying vec3 vBinormal; varying vec2 vTexCoords; varying vec4 vColor; uniform mat4 uModelMatrix; uniform mat4 uViewMatrix; uniform mat4 uProjMatrix; uniform bool uvHasColor; void main(void) { gl_Position = uProjMatrix * uViewMatrix * uModelMatrix * vec4(aPosition, 1); vPosition = (uViewMatrix * uModelMatrix * vec4(aPosition, 1)).xyz; vTexCoords = aTexCoords; vec4 normal = normalize(aNormal); vec4 tangent = normalize(aTangent); vec4 binormal = vec4(cross(normal.xyz, tangent.xyz) * tangent.w, 1); vNormal = mat3(uViewMatrix * uModelMatrix) * normal.xyz; vTangent = mat3(uViewMatrix * uModelMatrix) * tangent.xyz; vBinormal = mat3(uViewMatrix * uModelMatrix) * binormal.xyz; if (uvHasColor) { vColor = aColor; } }";
  10939. ZamModelViewer.Destiny.Model.prototype.fragShader = " precision mediump float; varying vec3 vPosition; varying vec3 vNormal; varying vec3 vTangent; varying vec3 vBinormal; varying vec2 vTexCoords; varying vec4 vColor; uniform bool ufHasColor; uniform bool uHasParent; uniform bool uHasDiffuse; uniform bool uHasNormal; uniform bool uHasStack; uniform bool uLit; uniform sampler2D uDiffuse; uniform sampler2D uNormal; uniform sampler2D uStack; uniform vec4 uColor; uniform vec3 uLightDir1; uniform vec3 uLightDir2; uniform vec3 uLightDir3; uniform vec4 uLightIntensity; uniform vec3 uCameraPos; vec3 saturate(vec3 value) { return clamp(value, 0.0, 1.0); } float saturate(float value) { return clamp(value, 0.0, 1.0); } void main(void) { vec4 color = vec4(1, 0, 1, 1); if (uHasDiffuse) { color.rgb = texture2D(uDiffuse, vTexCoords).rgb; } vec3 tintColor = vec3(1.0, 1.0, 1.0); vec3 stackColor = vec3(1.0, 1.0, 1.0); float specExponent = 255.0; vec3 specColor = vec3(0.2, 0.2, 0.2); if (uHasStack) { color.rgb = pow(color.rgb, vec3(2.2, 2.2, 2.2)); stackColor = texture2D(uStack, vTexCoords).rgb; if (uHasParent && stackColor.b < 0.05) { discard; } tintColor = uColor.rgb * saturate(color.rgb * 4.0) + saturate(color.rgb - 0.25); color.rgb = tintColor * stackColor.r + color.rgb * (1.0 - stackColor.r); float invGamma = 1.0 / 2.2; color.rgb = pow(color.rgb, vec3(invGamma, invGamma, invGamma)); specExponent = stackColor.g * 255.0; } if (uHasNormal && uLit) { vec3 normalMap = texture2D(uNormal, vTexCoords).rgb; vec3 tNormal = normalize(vNormal); vec3 tTangent = normalize(vTangent); vec3 tBinormal = normalize(vBinormal); vec3 normal = mat3(tTangent, tBinormal, tNormal) * normalize(normalMap * 2.0 - vec3(1.0, 1.0, 1.0)); vec3 cameraDir = normalize(uCameraPos - vPosition); vec3 litColor = color.rgb * uLightIntensity.a; float facing = -1.0 + 2.0 * float(gl_FrontFacing); float NdotL = saturate(dot(normal, uLightDir1) * facing); float RdotV = max(0.0, dot(normal * NdotL * 2.0 - uLightDir1, cameraDir)); vec3 specular = saturate(specColor * pow(RdotV, specExponent)) * stackColor.g * uLightIntensity.x * NdotL * 0.5; litColor += color.rgb * NdotL * uLightIntensity.x + specular; NdotL = saturate(dot(normal, uLightDir2) * facing); RdotV = max(0.0, dot(normal * NdotL * 2.0 - uLightDir2, cameraDir)); specular = saturate(specColor * pow(RdotV, specExponent)) * stackColor.g * uLightIntensity.y * NdotL * 0.5; litColor += color.rgb * NdotL * uLightIntensity.y + specular; NdotL = saturate(dot(normal, uLightDir3) * facing); RdotV = max(0.0, dot(normal * NdotL * 2.0 - uLightDir3, cameraDir)); specular = saturate(specColor * pow(RdotV, specExponent)) * stackColor.g * uLightIntensity.z * NdotL * 0.5; litColor += color.rgb * NdotL * uLightIntensity.z + specular; color.rgb = saturate(litColor); } gl_FragColor = color; }";
  10940. ZamModelViewer.Destiny.Geometry = function(model, r) {
  10941. var self = this,
  10942. D = ZamModelViewer.Destiny,
  10943. i;
  10944. self.model = model;
  10945. self.name = r.getString();
  10946. var numMeshes = r.getInt32();
  10947. self.meshes = new Array(numMeshes);
  10948. for (i = 0; i < numMeshes; ++i) {
  10949. self.meshes[i] = new D.Mesh(self, r)
  10950. }
  10951. var numPlates = r.getInt32();
  10952. self.plates = new Array(numPlates);
  10953. for (i = 0; i < numPlates; ++i) {
  10954. self.plates[i] = new D.TexturePlate(self, r)
  10955. }
  10956. self.show = false
  10957. };
  10958. ZamModelViewer.Destiny.Geometry.prototype = {
  10959. destroy: function() {
  10960. var self = this,
  10961. i;
  10962. for (i = 0; i < self.meshes.length; ++i) {
  10963. self.meshes[i].destroy()
  10964. }
  10965. for (i = 0; i < self.plates.length; ++i) {
  10966. self.plates[i].destroy()
  10967. }
  10968. },
  10969. update: function() {
  10970. var self = this,
  10971. i;
  10972. if (!self.show) return;
  10973. for (i = 0; i < self.meshes.length; ++i) {
  10974. self.meshes[i].update()
  10975. }
  10976. },
  10977. draw: function(delta) {
  10978. var self = this,
  10979. i;
  10980. if (!self.show) return;
  10981. for (i = 0; i < self.meshes.length; ++i) {
  10982. self.meshes[i].draw(delta, true)
  10983. }
  10984. for (i = 0; i < self.meshes.length; ++i) {
  10985. self.meshes[i].draw(delta)
  10986. }
  10987. },
  10988. load: function() {
  10989. var self = this,
  10990. i;
  10991. for (i = 0; i < self.plates.length; ++i) {
  10992. self.plates[i].load()
  10993. }
  10994. }
  10995. };
  10996. ZamModelViewer.Destiny.Mesh = function(geometry, r) {
  10997. var self = this,
  10998. D = ZamModelViewer.Destiny,
  10999. i, j;
  11000. self.geometry = geometry;
  11001. self.model = self.geometry.model;
  11002. self.renderer = self.model.renderer;
  11003. var gl = self.renderer.context;
  11004. var numVbs = r.getInt32();
  11005. self.vbs = new Array(numVbs);
  11006. for (i = 0; i < numVbs; ++i) {
  11007. self.vbs[i] = new D.VertexBuffer(self.model, r);
  11008. if (!self.posInfo) {
  11009. self.posInfo = self.vbs[i].getTypeData(D.VertexBuffer.Types.Position);
  11010. if (self.posInfo && self.vbs[i].positions) self.positions = self.vbs[i].positions
  11011. }
  11012. if (!self.normInfo) {
  11013. self.normInfo = self.vbs[i].getTypeData(D.VertexBuffer.Types.Normal);
  11014. if (self.normInfo && self.vbs[i].normals) self.normals = self.vbs[i].normals
  11015. }
  11016. if (!self.tanInfo) {
  11017. self.tanInfo = self.vbs[i].getTypeData(D.VertexBuffer.Types.Tangent);
  11018. if (self.tanInfo && self.vbs[i].tangents) self.tangents = self.vbs[i].tangents
  11019. }
  11020. if (self.vbs[i].hasBlendWeights) self.weights = self.vbs[i].weights;
  11021. if (self.vbs[i].hasBlendIndices) self.indices = self.vbs[i].indices
  11022. }
  11023. var numIndices = r.getInt32();
  11024. var indices = new Uint16Array(numIndices);
  11025. for (i = 0; i < numIndices; ++i) {
  11026. indices[i] = r.getUint16()
  11027. }
  11028. self.boundsMin = [r.getFloat(), r.getFloat(), r.getFloat()];
  11029. self.boundsMax = [r.getFloat(), r.getFloat(), r.getFloat()];
  11030. self.offset = [r.getFloat(), r.getFloat(), r.getFloat()];
  11031. self.scale = [r.getFloat(), r.getFloat(), r.getFloat()];
  11032. self.ibData = [];
  11033. var indexStart, indexCount, numTris;
  11034. var numParts = r.getInt32();
  11035. self.parts = new Array(numParts);
  11036. for (i = 0; i < numParts; ++i) {
  11037. self.parts[i] = new D.MeshPart(r);
  11038. numTris = 0;
  11039. indexStart = self.parts[i].indexStart;
  11040. indexCount = self.parts[i].indexCount;
  11041. self.parts[i].firstIndex = self.ibData.length;
  11042. if (self.parts[i].primitive == 5) {
  11043. for (j = 0; j < indexCount; ++j) {
  11044. self.ibData.push(indices[indexStart + j])
  11045. }
  11046. numTris = indexCount
  11047. } else if (self.parts[i].primitive == 3) {
  11048. for (j = 0; j < indexCount; ++j) {
  11049. self.ibData.push(indices[indexStart + j])
  11050. }
  11051. numTris = indexCount / 3
  11052. } else {
  11053. console.error("unhandled primitive type")
  11054. }
  11055. self.parts[i].triangleCount = numTris;
  11056. self.tmpVec = vec4.create()
  11057. }
  11058. self.ib = gl.createBuffer();
  11059. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.ib);
  11060. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(self.ibData), gl.STATIC_DRAW)
  11061. };
  11062. ZamModelViewer.Destiny.Mesh.prototype = {
  11063. destroy: function() {
  11064. var self = this,
  11065. gl = self.renderer.context,
  11066. i;
  11067. if (self.ib) {
  11068. gl.deleteBuffer(self.ib);
  11069. self.ib = null
  11070. }
  11071. for (i = 0; i < self.vbs.length; ++i) {
  11072. self.vbs[i].destroy()
  11073. }
  11074. },
  11075. hasAllTextures: function() {
  11076. var self = this;
  11077. if (!self.texture && (!self.geometry.plates || self.geometry.plates.length > 0)) return false;
  11078. if (!self.normalTexture && (!self.geometry.plates || self.geometry.plates.length > 1)) return false;
  11079. if (!self.stackTexture && (!self.geometry.plates || self.geometry.plates.length > 2)) return false;
  11080. for (var i = 0; i < self.parts.length; ++i) {
  11081. if (self.parts[i].diffuse && !self.parts[i].diffuse.texture) return false;
  11082. if (self.parts[i].normal && !self.parts[i].normal.texture) return false;
  11083. if (self.parts[i].stack && !self.parts[i].stack.texture) return false
  11084. }
  11085. return true
  11086. },
  11087. getSlot: function(type) {
  11088. var self = this,
  11089. o, base = 0;
  11090. for (var i = 0; i < self.vbs.length; ++i) {
  11091. o = self.vbs[i].getSlot(type);
  11092. if (o) {
  11093. for (var idx in o) {
  11094. o[idx] += base
  11095. }
  11096. return 0
  11097. } else {
  11098. base += self.vbs[i].vbSlots
  11099. }
  11100. }
  11101. return null
  11102. },
  11103. update: function() {
  11104. var self = this;
  11105. if (!self.posInfo || !self.model.parent || !self.model.parent.skeleton) return;
  11106. var i, j, w, b, sk = self.model.parent.skeleton,
  11107. tmpVec = self.tmpVec;
  11108. var posStride = self.posInfo.stride,
  11109. posCount = self.posInfo.count,
  11110. posBuffer = self.posInfo.buffer,
  11111. posOfs = self.posInfo.offset;
  11112. var nrmStride = self.normInfo.stride,
  11113. nrmCount = self.normInfo.count,
  11114. nrmBuffer = self.normInfo.buffer,
  11115. nrmOfs = self.normInfo.offset;
  11116. var tanStride = self.tanInfo.stride,
  11117. tanCount = self.tanInfo.count,
  11118. tanBuffer = self.tanInfo.buffer,
  11119. tanOfs = self.tanInfo.offset;
  11120. for (i = 0; i < posCount; ++i, posOfs += posStride, nrmOfs += nrmStride, tanOfs += tanStride) {
  11121. posBuffer[posOfs + 0] = posBuffer[posOfs + 1] = posBuffer[posOfs + 2] = 0;
  11122. nrmBuffer[nrmOfs + 0] = nrmBuffer[nrmOfs + 1] = nrmBuffer[nrmOfs + 2] = 0;
  11123. tanBuffer[tanOfs + 0] = tanBuffer[tanOfs + 1] = tanBuffer[tanOfs + 2] = 0;
  11124. if (self.weights) {
  11125. for (j = 0; j < 4; ++j) {
  11126. b = self.indices[i][j];
  11127. w = self.weights[i][j] / 255;
  11128. if (w == 0) continue;
  11129. vec3.transformMat4(tmpVec, self.positions[i], sk.finalMats[b]);
  11130. posBuffer[posOfs] += tmpVec[0] * w;
  11131. posBuffer[posOfs + 1] += tmpVec[1] * w;
  11132. posBuffer[posOfs + 2] += tmpVec[2] * w;
  11133. vec4.transformMat4(tmpVec, self.normals[i], sk.finalMats[b]);
  11134. nrmBuffer[nrmOfs] += tmpVec[0] * w;
  11135. nrmBuffer[nrmOfs + 1] += tmpVec[1] * w;
  11136. nrmBuffer[nrmOfs + 2] += tmpVec[2] * w;
  11137. vec4.transformMat4(tmpVec, self.tangents[i], sk.finalMats[b]);
  11138. tanBuffer[tanOfs] += tmpVec[0] * w;
  11139. tanBuffer[tanOfs + 1] += tmpVec[1] * w;
  11140. tanBuffer[tanOfs + 2] += tmpVec[2] * w
  11141. }
  11142. } else if (self.indices) {
  11143. for (j = 0; j < 2; ++j) {
  11144. b = self.indices[i][j];
  11145. w = self.indices[i][j + 2] / 255;
  11146. if (w == 0) continue;
  11147. vec3.transformMat4(tmpVec, self.positions[i], sk.finalMats[b]);
  11148. posBuffer[posOfs] += tmpVec[0] * w;
  11149. posBuffer[posOfs + 1] += tmpVec[1] * w;
  11150. posBuffer[posOfs + 2] += tmpVec[2] * w;
  11151. vec4.transformMat4(tmpVec, self.normals[i], sk.finalMats[b]);
  11152. nrmBuffer[nrmOfs] += tmpVec[0] * w;
  11153. nrmBuffer[nrmOfs + 1] += tmpVec[1] * w;
  11154. nrmBuffer[nrmOfs + 2] += tmpVec[2] * w;
  11155. vec4.transformMat4(tmpVec, self.tangents[i], sk.finalMats[b]);
  11156. tanBuffer[tanOfs] += tmpVec[0] * w;
  11157. tanBuffer[tanOfs + 1] += tmpVec[1] * w;
  11158. tanBuffer[tanOfs + 2] += tmpVec[2] * w
  11159. }
  11160. } else {
  11161. b = self.positions[i][3] | 0;
  11162. vec3.transformMat4(tmpVec, self.positions[i], sk.finalMats[b]);
  11163. posBuffer[posOfs] = tmpVec[0];
  11164. posBuffer[posOfs + 1] = tmpVec[1];
  11165. posBuffer[posOfs + 2] = tmpVec[2];
  11166. vec4.transformMat4(tmpVec, self.normals[i], sk.finalMats[b]);
  11167. nrmBuffer[nrmOfs] = tmpVec[0];
  11168. nrmBuffer[nrmOfs + 1] = tmpVec[1];
  11169. nrmBuffer[nrmOfs + 2] = tmpVec[2];
  11170. vec4.transformMat4(tmpVec, self.tangents[i], sk.finalMats[b]);
  11171. tanBuffer[tanOfs] = tmpVec[0];
  11172. tanBuffer[tanOfs + 1] = tmpVec[1];
  11173. tanBuffer[tanOfs + 2] = tmpVec[2]
  11174. }
  11175. }
  11176. self.posInfo.vb.updateBuffers()
  11177. }
  11178. };
  11179. ZamModelViewer.Destiny.Mesh.prototype.draw = function(delta, depthOnly) {
  11180. var self = this,
  11181. gl = self.renderer.context,
  11182. i, p, t;
  11183. if (!self.hasTextures) {
  11184. for (i = 0; i < self.parts.length; ++i) {
  11185. p = self.parts[i];
  11186. if (p.diffuseTexture && !p.diffuse && self.model.textureLookup[p.diffuseTexture] !== undefined) {
  11187. t = self.model.textures[self.model.textureLookup[p.diffuseTexture]];
  11188. if (!t.img && !t.error) t.load();
  11189. p.diffuse = t
  11190. } else if (p.normalTexture && !p.normal && self.model.textureLookup[p.normalTexture] !== undefined) {
  11191. t = self.model.textures[self.model.textureLookup[p.normalTexture]];
  11192. if (!t.img && !t.error) t.load();
  11193. p.normal = t
  11194. } else if (p.stackTexture && !p.stack && self.model.textureLookup[p.stackTexture] !== undefined) {
  11195. t = self.model.textures[self.model.textureLookup[p.stackTexture]];
  11196. if (!t.img && !t.error) t.load();
  11197. p.stack = t
  11198. }
  11199. }
  11200. self.geometry.load();
  11201. if (self.geometry.plates.length > 0) {
  11202. p = self.geometry.plates[0];
  11203. if (!self.texture && p.texture != null && p.texture.texture) self.texture = p.texture;
  11204. p = self.geometry.plates[1];
  11205. if (!self.normalTexture && p.texture != null && p.texture.texture) self.normalTexture = p.texture;
  11206. p = self.geometry.plates[2];
  11207. if (!self.stackTexture && p.texture != null && p.texture.texture) self.stackTexture = p.texture
  11208. }
  11209. if (self.hasAllTextures()) self.hasTextures = true
  11210. }
  11211. for (i = 0; i < self.vbs.length; ++i) {
  11212. self.vbs[i].enable()
  11213. }
  11214. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.ib);
  11215. var hasColor = self.getSlot(ZamModelViewer.Destiny.VertexBuffer.Types.Color) != null;
  11216. gl.uniform1i(self.model.uniforms.vHasColor, hasColor);
  11217. gl.uniform1i(self.model.uniforms.fHasColor, hasColor);
  11218. self.drawParts(depthOnly);
  11219. for (i = 0; i < self.vbs.length; ++i) {
  11220. self.vbs[i].disable()
  11221. }
  11222. };
  11223. ZamModelViewer.Destiny.Mesh.prototype.drawParts = function(depthOnly) {
  11224. var self = this,
  11225. gl = self.renderer.context,
  11226. dyes = self.model.dyeInfo,
  11227. resetBlending = false,
  11228. resetMask = false;
  11229. if (!self.model.dyeLocked && self.model.parent && self.model.parent.dyeInfo) dyes = self.model.parent.dyeInfo;
  11230. var i, j, k, p, alphaHadTexture = false;
  11231. for (i = 0; i < self.parts.length; ++i) {
  11232. p = self.parts[i];
  11233. if (self.geometry.name == "482021716-1" && p.indexCount == 330 && p.flags == 0) continue;
  11234. if (p.lodName.indexOf("0") == -1) continue;
  11235. if (!depthOnly) {
  11236. if ((p.flags & 32) > 0 || (p.flags & 64) > 0) continue
  11237. } else {
  11238. if ((p.flags & 32) == 0) continue
  11239. }
  11240. if ((p.flags & 32) > 0) {
  11241. if (!resetBlending) {
  11242. resetBlending = true;
  11243. gl.blendFunc(gl.SRC_COLOR, gl.ONE);
  11244. gl.depthMask(false)
  11245. }
  11246. if (p.diffuseTexture) alphaHadTexture = true;
  11247. else if (alphaHadTexture) continue
  11248. } else {
  11249. if (resetBlending) {
  11250. resetBlending = false;
  11251. gl.blendFunc(gl.ONE, gl.ZERO);
  11252. gl.depthMask(true)
  11253. }
  11254. if (resetMask) {
  11255. resetMask = false;
  11256. gl.colorMask(true, true, true, true)
  11257. }
  11258. }
  11259. var hasDiffuse = true,
  11260. hasNormal = true,
  11261. hasStack = true;
  11262. gl.activeTexture(gl.TEXTURE0);
  11263. if (p.diffuse) {
  11264. if (p.diffuse.texture) {
  11265. gl.bindTexture(gl.TEXTURE_2D, p.diffuse.texture)
  11266. } else hasDiffuse = false
  11267. } else if (self.texture && self.texture.texture) {
  11268. gl.bindTexture(gl.TEXTURE_2D, self.texture.texture)
  11269. } else hasDiffuse = false;
  11270. gl.activeTexture(gl.TEXTURE1);
  11271. if (p.normal) {
  11272. if (p.normal.texture) {
  11273. gl.bindTexture(gl.TEXTURE_2D, p.normal.texture)
  11274. } else hasNormal = false
  11275. } else if (self.normalTexture && self.normalTexture.texture) {
  11276. gl.bindTexture(gl.TEXTURE_2D, self.normalTexture.texture)
  11277. } else hasNormal = false;
  11278. gl.activeTexture(gl.TEXTURE2);
  11279. if (p.stack) {
  11280. if (p.stack.texture) {
  11281. gl.bindTexture(gl.TEXTURE_2D, p.stack.texture)
  11282. } else hasStack = false
  11283. } else if (self.stackTexture && self.stackTexture.texture) {
  11284. gl.bindTexture(gl.TEXTURE_2D, self.stackTexture.texture)
  11285. } else hasStack = false;
  11286. if (dyes) {
  11287. for (j = 0; j < dyes.length; ++j) {
  11288. if (dyes[j].slot_type_index == p.dyeIndex) {
  11289. var dye = dyes[j].material_properties;
  11290. if (p.usePrimaryColor)
  11291. for (k = 0; k < 4; ++k) self.tmpVec[k] = dye.primary_color[k];
  11292. else
  11293. for (k = 0; k < 4; ++k) self.tmpVec[k] = dye.secondary_color[k];
  11294. break
  11295. }
  11296. }
  11297. }
  11298. if (!hasDiffuse) {
  11299. continue
  11300. }
  11301. gl.uniform1i(self.model.uniforms.fHasDiffuse, hasDiffuse);
  11302. gl.uniform1i(self.model.uniforms.fHasNormal, hasNormal);
  11303. gl.uniform1i(self.model.uniforms.fHasStack, hasStack);
  11304. gl.uniform1i(self.model.uniforms.fLit, (p.flags & 32) == 0);
  11305. if (hasDiffuse) gl.uniform1i(self.model.uniforms.fDiffuse, 0);
  11306. if (hasNormal) gl.uniform1i(self.model.uniforms.fNormal, 1);
  11307. if (hasStack) gl.uniform1i(self.model.uniforms.fStack, 2);
  11308. gl.uniform4fv(self.model.uniforms.fColor, self.tmpVec);
  11309. if (p.primitive == 5) {
  11310. gl.drawElements(gl.TRIANGLE_STRIP, p.triangleCount, gl.UNSIGNED_SHORT, p.firstIndex * 2)
  11311. } else {
  11312. gl.drawElements(gl.TRIANGLES, p.triangleCount * 3, gl.UNSIGNED_SHORT, p.firstIndex * 2)
  11313. }
  11314. }
  11315. if (resetBlending) {
  11316. gl.blendFunc(gl.ONE, gl.ZERO);
  11317. gl.depthMask(true)
  11318. }
  11319. if (resetMask) {
  11320. gl.colorMask(true, true, true, true)
  11321. }
  11322. };
  11323. ZamModelViewer.Destiny.MeshPart = function(r) {
  11324. var self = this,
  11325. i;
  11326. self.indexStart = r.getUint16();
  11327. self.indexCount = r.getUint16();
  11328. self.indexMin = r.getUint16();
  11329. self.indexMax = r.getUint16();
  11330. self.flags = r.getUint32();
  11331. self.primitive = r.getInt32();
  11332. var dyeIndex = r.getInt32();
  11333. self.externalId = r.getUint32();
  11334. self.lod = r.getInt32();
  11335. self.lodName = r.getString();
  11336. self.usePrimaryColor = true;
  11337. switch (dyeIndex) {
  11338. case 0:
  11339. self.dyeIndex = 0;
  11340. break;
  11341. case 1:
  11342. self.dyeIndex = 0;
  11343. self.usePrimaryColor = false;
  11344. break;
  11345. case 2:
  11346. self.dyeIndex = 1;
  11347. break;
  11348. case 3:
  11349. self.dyeIndex = 1;
  11350. self.usePrimaryColor = false;
  11351. break;
  11352. case 4:
  11353. self.dyeIndex = 2;
  11354. break;
  11355. case 5:
  11356. self.dyeIndex = 2;
  11357. self.usePrimaryColor = false;
  11358. break;
  11359. case 6:
  11360. case 7:
  11361. self.dyeIndex = 3;
  11362. break
  11363. }
  11364. var numTextures = r.getInt32();
  11365. self.textures = new Array(numTextures);
  11366. for (i = 0; i < numTextures; ++i) {
  11367. self.textures[i] = r.getString();
  11368. if (self.textures[i].indexOf(".") == -1) self.textures[i] += ".png"
  11369. }
  11370. if (numTextures >= 5) {
  11371. self.diffuseTexture = self.textures[0];
  11372. self.normalTexture = self.textures[2];
  11373. self.stackTexture = self.textures[4]
  11374. } else if (numTextures > 0 && self.textures[0].indexOf("detail") == -1) {
  11375. self.diffuseTexture = self.textures[0]
  11376. }
  11377. };
  11378. ZamModelViewer.Destiny.Texture = function(model, url) {
  11379. var self = this;
  11380. self.model = model;
  11381. self.url = model.opts.contentPath + url;
  11382. if (model.opts.cacheBuster) {
  11383. self.url += "?" + model.opts.cacheBuster
  11384. } else {
  11385. self.url += "?1"
  11386. }
  11387. self.texture = null
  11388. };
  11389. ZamModelViewer.Destiny.Texture.prototype = {
  11390. destroy: function() {
  11391. var self = this,
  11392. gl = self.model.renderer.context;
  11393. if (self.texture) gl.deleteTexture(self.texture);
  11394. self.img = null
  11395. },
  11396. load: function() {
  11397. var self = this,
  11398. gl = self.model.renderer.context;
  11399. (function(self, gl) {
  11400. self.img = new Image;
  11401. self.img.crossOrigin = "";
  11402. self.img.onload = function() {
  11403. self.img.loaded = true;
  11404. self.texture = gl.createTexture();
  11405. gl.bindTexture(gl.TEXTURE_2D, self.texture);
  11406. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, self.img);
  11407. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
  11408. };
  11409. self.img.onerror = function() {
  11410. self.img = null;
  11411. self.error = true
  11412. };
  11413. self.img.src = self.url
  11414. })(self, gl)
  11415. }
  11416. };
  11417. ZamModelViewer.Destiny.TexturePlate = function(geom, r) {
  11418. var self = this,
  11419. D = ZamModelViewer.Destiny;
  11420. self.geometry = geom;
  11421. self.model = geom.model;
  11422. self.name = r.getString();
  11423. self.id = r.getString();
  11424. self.index = r.getInt32();
  11425. self.width = r.getInt16();
  11426. self.height = r.getInt16();
  11427. var numTextures = r.getInt32();
  11428. self.textures = new Array(numTextures);
  11429. for (var i = 0; i < numTextures; ++i) {
  11430. self.textures[i] = new D.TexturePlate.Part(r)
  11431. }
  11432. };
  11433. ZamModelViewer.Destiny.TexturePlate.prototype = {
  11434. destroy: function() {
  11435. var self = this;
  11436. if (self.texture) self.texture.destroy()
  11437. },
  11438. load: function() {
  11439. var self = this,
  11440. D = ZamModelViewer.Destiny;
  11441. if (self.name != "diffuse" && self.name != "gearstack" && self.name != "normal") return;
  11442. if (!self.texture) {
  11443. self.texture = new D.Texture(self.model, "textures/mobile/" + self.id + ".png");
  11444. self.texture.load()
  11445. }
  11446. }
  11447. };
  11448. ZamModelViewer.Destiny.TexturePlate.Part = function(r) {
  11449. var self = this;
  11450. self.name = r.getString();
  11451. self.index = r.getInt32();
  11452. self.width = r.getInt16();
  11453. self.height = r.getInt16();
  11454. self.x = r.getInt16();
  11455. self.y = r.getInt16()
  11456. };
  11457. ZamModelViewer.Destiny.VertexBuffer = function(model, r) {
  11458. var self = this,
  11459. Types = ZamModelViewer.Destiny.VertexBuffer.Types;
  11460. self.model = model;
  11461. self.renderer = model.renderer;
  11462. self.count = r.getInt32();
  11463. self.stride = r.getInt32();
  11464. var numElements = r.getInt32();
  11465. self.elements = new Array(numElements);
  11466. var slot = 0,
  11467. offset = 0,
  11468. i, j;
  11469. for (i = 0; i < numElements; ++i) {
  11470. var type = r.getUint8();
  11471. var obj = {
  11472. type: type,
  11473. slot: slot,
  11474. offset: offset
  11475. };
  11476. if (type >= Types.Position && type <= Types.MaxPosition) {
  11477. self.positions = new Array(numElements);
  11478. self.hasPosition = true;
  11479. obj.name = "position";
  11480. obj.baseType = Types.Position;
  11481. obj.size = 3;
  11482. obj.read = self.readPosition;
  11483. offset += 3
  11484. } else if (type >= Types.TexCoord && type <= Types.MaxTexCoord) {
  11485. obj.name = "texcoord";
  11486. obj.baseType = Types.TexCoord;
  11487. obj.size = 2;
  11488. obj.read = self.readTexCoord;
  11489. offset += 2
  11490. } else if (type >= Types.Normal && type <= Types.MaxNormal) {
  11491. self.normals = new Array(numElements);
  11492. self.hasNormal = true;
  11493. obj.name = "normal";
  11494. obj.baseType = Types.Normal;
  11495. obj.size = 4;
  11496. obj.read = self.readNormal;
  11497. offset += 4
  11498. } else if (type >= Types.Tangent && type <= Types.MaxTangent) {
  11499. self.tangents = new Array(numElements);
  11500. self.hasTangent = true;
  11501. obj.name = "tangent";
  11502. obj.baseType = Types.Tangent;
  11503. obj.size = 4;
  11504. obj.read = self.readTangent;
  11505. offset += 4
  11506. } else if (type >= Types.Color && type <= Types.MaxColor) {
  11507. obj.name = "color";
  11508. obj.baseType = Types.Color;
  11509. obj.size = 4;
  11510. obj.read = self.readColor;
  11511. offset += 4
  11512. } else if (type >= Types.BlendWeight && type <= Types.MaxWeight) {
  11513. self.weights = new Array(numElements);
  11514. self.hasBlendWeights = true;
  11515. obj.baseType = Types.BlendWeight;
  11516. obj.read = self.readBlendWeight;
  11517. obj.discard = true
  11518. } else if (type >= Types.BlendIndex && type <= Types.MaxIndex) {
  11519. self.indices = new Array(numElements);
  11520. self.hasBlendIndices = true;
  11521. obj.baseType = Types.BlendIndex;
  11522. obj.read = self.readBlendIndex;
  11523. obj.discard = true
  11524. } else {
  11525. throw "bad type"
  11526. }
  11527. self.elements[i] = obj;
  11528. if (obj.discard) continue;
  11529. slot++
  11530. }
  11531. self.vbStride = offset;
  11532. self.vbSlots = slot;
  11533. self.vbData = new Float32Array(self.count * self.vbStride);
  11534. var idx = 0;
  11535. for (i = 0; i < self.count; ++i) {
  11536. for (j = 0; j < numElements; ++j) {
  11537. idx = self.elements[j].read.call(this, r, self.vbData, idx, i)
  11538. }
  11539. }
  11540. self.updateBuffers()
  11541. };
  11542. ZamModelViewer.Destiny.VertexBuffer.prototype = {
  11543. destroy: function() {
  11544. var self = this,
  11545. gl = self.renderer.context;
  11546. if (self.buffer) {
  11547. gl.deleteBuffer(self.buffer);
  11548. self.buffer = null
  11549. }
  11550. },
  11551. enable: function() {
  11552. var self = this,
  11553. gl = self.renderer.context,
  11554. i, e;
  11555. gl.bindBuffer(gl.ARRAY_BUFFER, self.buffer);
  11556. for (i = 0; i < self.elements.length; ++i) {
  11557. e = self.elements[i];
  11558. if (e.name && e.type == e.baseType) {
  11559. gl.enableVertexAttribArray(self.model.attribs[e.name]);
  11560. gl.vertexAttribPointer(self.model.attribs[e.name], e.size, gl.FLOAT, false, self.vbStride * 4, e.offset * 4)
  11561. }
  11562. }
  11563. },
  11564. disable: function() {
  11565. var self = this,
  11566. gl = self.renderer.context,
  11567. i, e;
  11568. gl.bindBuffer(gl.ARRAY_BUFFER, self.buffer);
  11569. for (i = 0; i < self.elements.length; ++i) {
  11570. e = self.elements[i];
  11571. if (e.name && e.type == e.baseType) {
  11572. gl.disableVertexAttribArray(self.model.attribs[e.name])
  11573. }
  11574. }
  11575. },
  11576. updateBuffers: function() {
  11577. var self = this,
  11578. gl = self.renderer.context;
  11579. if (self.vbStride > 0) {
  11580. if (!self.buffer) {
  11581. self.buffer = gl.createBuffer();
  11582. gl.bindBuffer(gl.ARRAY_BUFFER, self.buffer);
  11583. gl.bufferData(gl.ARRAY_BUFFER, self.vbData, gl.DYNAMIC_DRAW)
  11584. } else {
  11585. gl.bindBuffer(gl.ARRAY_BUFFER, self.buffer);
  11586. gl.bufferSubData(gl.ARRAY_BUFFER, 0, self.vbData)
  11587. }
  11588. }
  11589. },
  11590. getTypeData: function(type) {
  11591. var self = this,
  11592. e, i;
  11593. for (i = 0; i < self.elements.length; ++i) {
  11594. e = self.elements[i];
  11595. if (e.type == type) {
  11596. return {
  11597. buffer: self.vbData,
  11598. offset: e.offset,
  11599. stride: self.vbStride,
  11600. count: self.count,
  11601. vb: self
  11602. }
  11603. }
  11604. }
  11605. return null
  11606. },
  11607. getSlot: function(type) {
  11608. var self = this,
  11609. obj = {},
  11610. e, i;
  11611. for (i = 0; i < self.elements.length; ++i) {
  11612. e = self.elements[i];
  11613. if (e.discard) continue;
  11614. if (type == e.baseType) {
  11615. var index = e.type - e.baseType;
  11616. obj[index] = e.slot
  11617. }
  11618. }
  11619. var empty = true;
  11620. for (var idx in obj) {
  11621. empty = false;
  11622. break
  11623. }
  11624. if (empty) return null;
  11625. return obj
  11626. },
  11627. readPosition: function(r, vbData, idx, i) {
  11628. var self = this;
  11629. var pos = self.positions[i] = [r.getFloat(), r.getFloat(), r.getFloat(), r.getFloat()];
  11630. vbData[idx++] = pos[0];
  11631. vbData[idx++] = pos[1];
  11632. vbData[idx++] = pos[2];
  11633. return idx
  11634. },
  11635. readTexCoord: function(r, vbData, idx, i) {
  11636. vbData[idx++] = r.getFloat();
  11637. vbData[idx++] = r.getFloat();
  11638. return idx
  11639. },
  11640. readNormal: function(r, vbData, idx, i) {
  11641. var self = this;
  11642. var normal = self.normals[i] = [r.getFloat(), r.getFloat(), r.getFloat(), r.getFloat()];
  11643. vbData[idx++] = normal[0];
  11644. vbData[idx++] = normal[1];
  11645. vbData[idx++] = normal[2];
  11646. vbData[idx++] = normal[3];
  11647. return idx
  11648. },
  11649. readTangent: function(r, vbData, idx, i) {
  11650. var self = this;
  11651. var tangent = self.tangents[i] = [r.getFloat(), r.getFloat(), r.getFloat(), r.getFloat()];
  11652. vbData[idx++] = tangent[0];
  11653. vbData[idx++] = tangent[1];
  11654. vbData[idx++] = tangent[2];
  11655. vbData[idx++] = tangent[3];
  11656. return idx
  11657. },
  11658. readColor: function(r, vbData, idx, i) {
  11659. vbData[idx++] = r.getUint8() / 255;
  11660. vbData[idx++] = r.getUint8() / 255;
  11661. vbData[idx++] = r.getUint8() / 255;
  11662. vbData[idx++] = r.getUint8() / 255;
  11663. return idx
  11664. },
  11665. readBlendWeight: function(r, vbData, idx, i) {
  11666. var self = this;
  11667. self.weights[i] = [r.getUint8(), r.getUint8(), r.getUint8(), r.getUint8()];
  11668. return idx
  11669. },
  11670. readBlendIndex: function(r, vbData, idx, i) {
  11671. var self = this;
  11672. self.indices[i] = [r.getUint8(), r.getUint8(), r.getUint8(), r.getUint8()];
  11673. return idx
  11674. }
  11675. };
  11676. ZamModelViewer.Destiny.VertexBuffer.Types = {
  11677. Position: 1,
  11678. MaxPosition: 3,
  11679. TexCoord: 4,
  11680. MaxTexCoord: 11,
  11681. Normal: 12,
  11682. MaxNormal: 18,
  11683. Tangent: 19,
  11684. MaxTangent: 25,
  11685. Color: 26,
  11686. MaxColor: 32,
  11687. BlendWeight: 33,
  11688. MaxWeight: 39,
  11689. BlendIndex: 40,
  11690. MaxIndex: 47
  11691. };
  11692. ZamModelViewer.Destiny.Skeleton = function(model, data) {
  11693. var self = this,
  11694. i, j;
  11695. if (!data || !data.anim || !data.bones) {
  11696. throw "Invalid skeleton data"
  11697. }
  11698. self.model = model;
  11699. var anim = self.anim = data.anim;
  11700. var bones = self.bones = data.bones;
  11701. self.fps = 30;
  11702. self.frameDuration = 1 / self.fps;
  11703. self.frameTime = 0;
  11704. self.frame = 0;
  11705. self.animFrames = new Array(anim.frame_count);
  11706. var tmpMat = mat4.create();
  11707. var staticBoneData = anim.static_bone_data,
  11708. staticScaleMap = staticBoneData.scale_control_map,
  11709. staticRotationMap = staticBoneData.rotation_control_map,
  11710. staticTranslationMap = staticBoneData.translation_control_map,
  11711. staticFrame = staticBoneData.transform_stream_header.streams.frames[0],
  11712. staticScales = staticFrame.scales,
  11713. staticRotations = staticFrame.rotations,
  11714. staticTranslations = staticFrame.translations,
  11715. animBoneData = anim.animated_bone_data,
  11716. animScaleMap = animBoneData.scale_control_map,
  11717. animRotationMap = animBoneData.rotation_control_map,
  11718. animTranslationMap = animBoneData.translation_control_map,
  11719. animTransformFrames = animBoneData.transform_stream_header.streams.frames;
  11720. for (i = 0; i < anim.frame_count; ++i) {
  11721. var frameMats = new Array(anim.node_count);
  11722. var frame = animTransformFrames[i];
  11723. for (j = 0; j < anim.node_count; ++j) {
  11724. var staticScaleIdx = staticScaleMap.indexOf(j),
  11725. staticRotIdx = staticRotationMap.indexOf(j),
  11726. staticTransIdx = staticTranslationMap.indexOf(j);
  11727. var animScaleIdx = animScaleMap.indexOf(j),
  11728. animRotIdx = animRotationMap.indexOf(j),
  11729. animTransIdx = animTranslationMap.indexOf(j);
  11730. var scale = staticScaleIdx >= 0 ? staticScales[staticScaleIdx] : frame.scales[animScaleIdx];
  11731. var rot = staticRotIdx >= 0 ? staticRotations[staticRotIdx] : frame.rotations[animRotIdx];
  11732. var trans = staticTransIdx >= 0 ? staticTranslations[staticTransIdx] : frame.translations[animTransIdx];
  11733. mat4.fromQuat(tmpMat, rot);
  11734. mat4.scale(tmpMat, tmpMat, [scale, scale, scale]);
  11735. tmpMat[12] = trans[0];
  11736. tmpMat[13] = trans[1];
  11737. tmpMat[14] = trans[2];
  11738. frameMats[j] = mat4.clone(tmpMat)
  11739. }
  11740. self.animFrames[i] = frameMats
  11741. }
  11742. self.frameMats = new Array(anim.node_count);
  11743. self.finalMats = new Array(anim.node_count);
  11744. for (i = 0; i < anim.node_count; ++i) {
  11745. self.frameMats[i] = mat4.create();
  11746. self.finalMats[i] = mat4.create()
  11747. }
  11748. self.parentNodes = new Array(bones.definition.nodes.length);
  11749. self.invMatrices = new Array(bones.definition.default_inverse_object_space_transforms.length);
  11750. for (i = 0; i < bones.definition.nodes.length; ++i) {
  11751. self.parentNodes[i] = bones.definition.nodes[i].parent_node_index
  11752. }
  11753. for (i = 0; i < bones.definition.default_inverse_object_space_transforms.length; ++i) {
  11754. var info = bones.definition.default_inverse_object_space_transforms[i];
  11755. mat4.fromQuat(tmpMat, info.r);
  11756. mat4.scale(tmpMat, tmpMat, [info.ts[3], info.ts[3], info.ts[3]]);
  11757. tmpMat[12] = info.ts[0];
  11758. tmpMat[13] = info.ts[1];
  11759. tmpMat[14] = info.ts[2];
  11760. self.invMatrices[i] = mat4.clone(tmpMat)
  11761. }
  11762. };
  11763. ZamModelViewer.Destiny.Skeleton.prototype = {
  11764. update: function(delta) {
  11765. var self = this;
  11766. self.frameTime += delta;
  11767. while (self.frameTime >= self.frameDuration) {
  11768. self.frameTime -= self.frameDuration;
  11769. self.frame++
  11770. }
  11771. while (self.frame >= self.anim.frame_count) self.frame -= self.anim.frame_count;
  11772. var mat, frameMat, parentId;
  11773. var mats = self.animFrames[self.frame];
  11774. for (var i = 0; i < self.anim.node_count; ++i) {
  11775. mat = mats[i];
  11776. frameMat = self.frameMats[i];
  11777. parentId = self.parentNodes[i];
  11778. if (parentId >= 0) {
  11779. mat4.multiply(frameMat, self.frameMats[parentId], mat)
  11780. } else {
  11781. mat4.copy(frameMat, mat)
  11782. }
  11783. mat4.multiply(self.finalMats[i], frameMat, self.invMatrices[i])
  11784. }
  11785. }
  11786. };
  11787. ZamModelViewer.Lol = function() {};
  11788. ZamModelViewer.Lol.Model = function(renderer, viewer, model, index, parent) {
  11789. var self = this;
  11790. vec3.set(renderer.up, 0, 1, 0);
  11791. self.renderer = renderer;
  11792. self.viewer = viewer;
  11793. self.model = model;
  11794. self.modelIndex = index;
  11795. self.loaded = false;
  11796. self.animsLoaded = false;
  11797. self.opts = self.viewer.options;
  11798. self.meta = null;
  11799. self.parent = parent || null;
  11800. self.texture = null;
  11801. self.meshTextures = {};
  11802. self.animIndex = -1;
  11803. self.animName = null;
  11804. self.baseAnim = null;
  11805. self.meshes = null;
  11806. self.vertices = null;
  11807. self.indices = null;
  11808. self.transforms = null;
  11809. self.bones = null;
  11810. self.boneLookup = {};
  11811. self.matrix = mat4.create();
  11812. self.ib = null;
  11813. self.shaderReady = false;
  11814. self.vs = null;
  11815. self.fs = null;
  11816. self.program = null;
  11817. self.uniforms = null;
  11818. self.attribs = null;
  11819. self.ambientColor = [.35, .35, .35, 1];
  11820. self.primaryColor = [1, 1, 1, 1];
  11821. self.secondaryColor = [.35, .35, .35, 1];
  11822. self.lightDir1 = vec3.create();
  11823. self.lightDir2 = vec3.create();
  11824. self.lightDir3 = vec3.create();
  11825. vec3.normalize(self.lightDir1, [5, 5, -5]);
  11826. vec3.normalize(self.lightDir2, [5, 5, 5]);
  11827. vec3.normalize(self.lightDir3, [-5, -5, -5]);
  11828. self.animBounds = false;
  11829. self.boundsCenter = [0, 0, 0];
  11830. self.boundsSize = [0, 0, 0];
  11831. self.boundsMin = [0, 0, 0];
  11832. self.boundsMax = [0, 0, 0];
  11833. self.modelOffset = 0;
  11834. self.defaultDistance = 0;
  11835. self.newAnimation = false;
  11836. self.tmpMat = mat4.create();
  11837. self.tmpVec = vec4.create();
  11838. self.ANIMATED = true;
  11839. self.hiddenBones = null;
  11840. var hiddenBones = ZamModelViewer.Lol.Model.HiddenBones;
  11841. if (hiddenBones[self.model.champion] !== undefined) {
  11842. if (hiddenBones[self.model.champion][self.model.skin] !== undefined) {
  11843. self.hiddenBones = hiddenBones[self.model.champion][self.model.skin]
  11844. }
  11845. }
  11846. self.load()
  11847. };
  11848. ZamModelViewer.Models[ZamModelViewer.LOL] = ZamModelViewer.Lol.Model;
  11849. ZamModelViewer.Lol.Model.prototype = {
  11850. external: {
  11851. getNumAnimations: function() {
  11852. return this.animations ? this.animations.length : 0
  11853. },
  11854. getAnimation: function(index) {
  11855. if (this.animations && this.animations.length > index && index > -1) {
  11856. return this.animations[index].name
  11857. } else {
  11858. return ""
  11859. }
  11860. },
  11861. setAnimation: function(name) {
  11862. for (i = 0; i < this.renderer.models.length; ++i) {
  11863. this.renderer.models[i].setAnimation(name)
  11864. }
  11865. },
  11866. isLoaded: function() {
  11867. return this.loaded && this.animsLoaded
  11868. }
  11869. },
  11870. destroy: function() {
  11871. var self = this,
  11872. gl = self.renderer.context,
  11873. i, j;
  11874. if (self.program) gl.deleteProgram(self.program);
  11875. if (self.vs) gl.deleteShader(self.vs);
  11876. if (self.fs) gl.deleteShader(self.fs);
  11877. if (self.textures) {
  11878. for (i = 0; i < self.textures.length; ++i) {
  11879. self.textures[i].destroy()
  11880. }
  11881. }
  11882. if (self.models) {
  11883. for (i = 0; i < self.models.length; ++i) {
  11884. self.models[i].destroy()
  11885. }
  11886. }
  11887. if (self.geometry) {
  11888. for (i = 0; i < self.geometry.length; ++i) {
  11889. self.geometry[i].destroy()
  11890. }
  11891. }
  11892. },
  11893. getAnimation: function(name) {
  11894. var self = this,
  11895. i, animIndex = -1;
  11896. if (!self.animations) return animIndex;
  11897. name = name.toLowerCase();
  11898. if (name == "idle" || name == "attack") {
  11899. var anims = [],
  11900. re = new RegExp(name + "[0-9]*");
  11901. for (i = 0; i < self.animations.length; ++i) {
  11902. if (self.animations[i].name.search(re) == 0) anims.push(i)
  11903. }
  11904. if (anims.length > 0) {
  11905. animIndex = anims[Math.randomInt(0, anims.length)]
  11906. }
  11907. } else {
  11908. for (i = 0; i < self.animations.length; ++i) {
  11909. if (self.animations[i].name == name) {
  11910. animIndex = i;
  11911. break
  11912. }
  11913. }
  11914. }
  11915. return animIndex
  11916. },
  11917. setAnimation: function(name) {
  11918. var self = this;
  11919. self.animIndex = self.getAnimation(name);
  11920. if (self.animIndex == -1) {
  11921. if (name == "idle") {
  11922. self.animIndex = 0;
  11923. self.animName = self.animations[0].name
  11924. } else {
  11925. self.setAnimation("idle");
  11926. return
  11927. }
  11928. } else {
  11929. self.animName = name
  11930. }
  11931. var baseAnims = ZamModelViewer.Lol.Model.BaseAnimations;
  11932. if (baseAnims[self.model.champion] !== undefined) {
  11933. if (baseAnims[self.model.champion][self.model.skin] !== undefined) {
  11934. var baseAnim = baseAnims[self.model.champion][self.model.skin],
  11935. baseIndex = -1;
  11936. if (baseAnim[self.animations[self.animIndex].name]) baseIndex = self.getAnimation(baseAnim[self.animations[self.animIndex].name]);
  11937. else if (baseAnim["all"]) baseIndex = self.getAnimation(baseAnim["all"]);
  11938. if (baseIndex > -1) self.baseAnim = self.animations[baseIndex];
  11939. else self.baseAnim = null
  11940. }
  11941. }
  11942. self.animTime = self.renderer.time;
  11943. self.newAnimation = true
  11944. },
  11945. update: function() {
  11946. var self = this,
  11947. i, j, gl = self.renderer.context;
  11948. if (!self.loaded || !self.vertices || !self.animations || self.animations.length == 0) return;
  11949. if (self.animIndex == -1) self.setAnimation("idle");
  11950. var time = self.renderer.time - self.animTime;
  11951. var anim = self.animations[self.animIndex];
  11952. if (time >= anim.duration) {
  11953. self.setAnimation(self.animName);
  11954. anim = self.animations[self.animIndex];
  11955. time = 0
  11956. }
  11957. if (self.ANIMATED) {
  11958. var timePerFrame = 1e3 / anim.fps;
  11959. var frame = Math.floor(time / timePerFrame);
  11960. var r = time % timePerFrame / timePerFrame;
  11961. var hiddenBones = {};
  11962. if (self.hiddenBones) {
  11963. if (self.hiddenBones[anim.name]) hiddenBones = self.hiddenBones[anim.name];
  11964. else if (self.hiddenBones["all"]) hiddenBones = self.hiddenBones["all"]
  11965. }
  11966. var b;
  11967. if (self.version >= 1) {
  11968. for (i = 0; i < self.bones.length; ++i) {
  11969. b = self.bones[i];
  11970. if (hiddenBones[b.name]) {
  11971. mat4.identity(self.tmpMat);
  11972. mat4.scale(self.tmpMat, self.tmpMat, vec3.set(self.tmpVec, 0, 0, 0));
  11973. mat4.copy(self.transforms[i], self.tmpMat)
  11974. } else if (anim.lookup[b.name] !== undefined) {
  11975. anim.bones[anim.lookup[b.name]].update(i, frame, r)
  11976. } else if (self.baseAnim && self.baseAnim.lookup[b.name] !== undefined) {
  11977. self.baseAnim.bones[self.baseAnim.lookup[b.name]].update(i, frame, r)
  11978. } else {
  11979. if (b.parent != -1) {
  11980. mat4.mulSlimDX(self.transforms[i], b.incrMatrix, self.transforms[b.parent])
  11981. } else {
  11982. mat4.copy(self.transforms[i], b.incrMatrix)
  11983. }
  11984. }
  11985. }
  11986. } else {
  11987. for (i = 0; i < anim.bones.length; ++i) {
  11988. b = anim.bones[i];
  11989. if (self.boneLookup[b.bone] !== undefined) {
  11990. b.update(self.boneLookup[b.bone], frame, r)
  11991. } else {
  11992. var parentBone = anim.bones[i - 1];
  11993. if (!parentBone) continue;
  11994. if (parentBone.index + 1 < self.transforms.length) {
  11995. mat4.copy(self.transforms[parentBone.index + 1], self.transforms[parentBone.index])
  11996. }
  11997. b.index = parentBone.index + 1
  11998. }
  11999. }
  12000. }
  12001. var numBones = Math.min(self.transforms.length, self.bones.length);
  12002. for (i = 0; i < numBones; ++i) {
  12003. mat4.mulSlimDX(self.transforms[i], self.bones[i].baseMatrix, self.transforms[i])
  12004. }
  12005. mat4.identity(self.tmpMat);
  12006. var numVerts = self.vertices.length,
  12007. vbData = self.vbData,
  12008. vec = self.tmpVec,
  12009. v, w, m, idx;
  12010. for (i = 0; i < numVerts; ++i) {
  12011. v = self.vertices[i];
  12012. idx = i * 8;
  12013. vbData[idx] = vbData[idx + 1] = vbData[idx + 2] = vbData[idx + 3] = vbData[idx + 4] = vbData[idx + 5] = 0;
  12014. for (j = 0; j < 4; ++j) {
  12015. if (v.weights[j] > 0) {
  12016. w = v.weights[j];
  12017. m = anim.fps == 1 ? self.tmpMat : self.transforms[v.bones[j]];
  12018. vec3.transformMat4(vec, v.position, m);
  12019. vbData[idx] += vec[0] * w;
  12020. vbData[idx + 1] += vec[1] * w;
  12021. vbData[idx + 2] += vec[2] * w;
  12022. vec4.transformMat4(vec, v.normal, m);
  12023. vbData[idx + 3] += vec[0] * w;
  12024. vbData[idx + 4] += vec[1] * w;
  12025. vbData[idx + 5] += vec[2] * w
  12026. }
  12027. }
  12028. }
  12029. if (!self.animBounds) {
  12030. self.updateBounds(true);
  12031. self.animBounds = true
  12032. }
  12033. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  12034. gl.bufferSubData(gl.ARRAY_BUFFER, 0, self.vbData)
  12035. }
  12036. if (self.newAnimation) {
  12037. self.updateBounds(true);
  12038. self.newAnimation = false
  12039. }
  12040. },
  12041. updatePosition: function() {
  12042. var self = this,
  12043. index = self.modelIndex,
  12044. offset = self.renderer.models[0].boundsSize[0] * 1.5;
  12045. if (index > 2) {
  12046. offset += Math.abs(self.renderer.models[index - 2].modelOffset)
  12047. }
  12048. if (self.modelIndex % 2 > 0) offset = -offset;
  12049. self.modelOffset = offset;
  12050. mat4.identity(self.matrix);
  12051. mat4.translate(self.matrix, self.matrix, vec3.negate(self.tmpVec, self.boundsCenter));
  12052. mat4.scale(self.matrix, self.matrix, vec3.set(self.tmpVec, -1, 1, 1));
  12053. vec3.normalize(self.tmpVec, vec3.set(self.tmpVec, 4, 0, -1));
  12054. vec3.scale(self.tmpVec, self.tmpVec, offset);
  12055. if (offset < 0) self.tmpVec[2] = -self.tmpVec[2];
  12056. self.matrix[12] += self.tmpVec[0];
  12057. self.matrix[13] += self.tmpVec[1];
  12058. self.matrix[14] += self.tmpVec[2]
  12059. },
  12060. updateBounds: function(useVb) {
  12061. var self = this,
  12062. i, j, m, idx, verts = self.vertices,
  12063. vbData = self.vbData;
  12064. var min = vec3.set(self.boundsMin, 9999, 9999, 9999),
  12065. max = vec3.set(self.boundsMax, -9999, -9999, -9999),
  12066. pos;
  12067. if (!verts) return;
  12068. if (self.meshes && self.indices) {
  12069. var firstIndex, numIndices, visible;
  12070. for (i = 0; i < self.meshes.length; ++i) {
  12071. m = self.meshes[i];
  12072. visible = !(self.meta && self.meta.meshVis[m.name] === false);
  12073. if (!visible) continue;
  12074. firstIndex = m.iStart;
  12075. numIndices = m.iCount;
  12076. for (j = 0; j < numIndices; ++j) {
  12077. if (useVb) {
  12078. idx = self.indices[firstIndex + j] * 8;
  12079. pos = vec3.set(self.tmpVec, vbData[idx], vbData[idx + 1], vbData[idx + 2])
  12080. } else {
  12081. pos = vec3.copy(self.tmpVec, verts[self.indices[firstIndex + j]].position)
  12082. }
  12083. if (pos[1] < -250) pos[1] = min[1];
  12084. min = vec3.min(min, min, pos);
  12085. max = vec3.max(max, max, pos)
  12086. }
  12087. }
  12088. } else {
  12089. for (i = 0; i < verts.length; ++i) {
  12090. if (useVb) {
  12091. idx = i * 8;
  12092. pos = vec3.set(self.tmpVec, vbData[idx], vbData[idx + 1], vbData[idx + 2])
  12093. } else {
  12094. pos = vec3.copy(self.tmpVec, verts[i].position)
  12095. }
  12096. if (pos[1] < -250) pos[1] = min[1];
  12097. min = vec3.min(min, min, pos);
  12098. max = vec3.max(max, max, pos)
  12099. }
  12100. }
  12101. vec3.subtract(self.boundsSize, max, min);
  12102. vec3.scaleAndAdd(self.boundsCenter, min, self.boundsSize, .5);
  12103. vec3.copy(self.tmpVec, self.boundsCenter);
  12104. self.tmpVec[1] = -self.tmpVec[1];
  12105. mat4.identity(self.matrix);
  12106. mat4.translate(self.matrix, self.matrix, self.tmpVec);
  12107. mat4.scale(self.matrix, self.matrix, vec3.set(self.tmpVec, -1, 1, 1));
  12108. var models = self.renderer.models;
  12109. if (models.length > 1) {
  12110. for (i = 1; i < models.length; ++i) {
  12111. models[i].updatePosition()
  12112. }
  12113. if (self.modelIndex != 0) models[0].updateDistance()
  12114. }
  12115. if (self.modelIndex == 0) {
  12116. self.updateDistance()
  12117. }
  12118. },
  12119. updateDistance: function() {
  12120. var self = this,
  12121. models = self.renderer.models;
  12122. var wSize = self.boundsSize[0],
  12123. hSize = self.boundsSize[1],
  12124. dSize = self.boundsSize[2];
  12125. if (models.length > 1) {
  12126. var width = Math.abs(models[models.length - 1].modelOffset) + models[models.length - 1].boundsSize[0];
  12127. if (models.length > 2) {
  12128. width += Math.abs(models[models.length - 2].modelOffset) + models[models.length - 2].boundsSize[0]
  12129. } else {
  12130. width *= 2
  12131. }
  12132. wSize = Math.max(wSize, width)
  12133. }
  12134. var dist;
  12135. if (self.opts.dist) {
  12136. dist = self.opts.dist
  12137. } else {
  12138. var ratio = self.renderer.width / self.renderer.height;
  12139. var hTan = 2 * Math.tan(self.renderer.fov / 2 * .0174532925);
  12140. var wTan = hTan * ratio;
  12141. var hDist = hSize * 1.2 / hTan;
  12142. var wDist = wSize * 1.2 / wTan;
  12143. dist = Math.max(Math.max(hDist, wDist), dSize * 2)
  12144. }
  12145. if (self.defaultDistance == 0 || self.defaultDistance == self.renderer.distance) {
  12146. self.defaultDistance = self.renderer.distance = dist
  12147. }
  12148. }
  12149. };
  12150. ZamModelViewer.Lol.Model.prototype.load = function() {
  12151. var self = this;
  12152. if (self.model && self.model.champion !== undefined && self.model.skin !== undefined) {
  12153. self._load(self.model.champion, self.model.skin)
  12154. }
  12155. };
  12156. ZamModelViewer.Lol.Model.prototype._load = function(champion, skin) {
  12157. var self = this;
  12158. self.champion = champion;
  12159. self.skin = skin;
  12160. $.getJSON(self.opts.contentPath + "meta/" + champion + "_" + skin + ".json", function(data) {
  12161. self.loadMeta(data)
  12162. });
  12163. var url = self.opts.contentPath + "models/" + champion + "_" + skin + ".lmesh";
  12164. $.ajax({
  12165. url: url,
  12166. type: "GET",
  12167. dataType: "binary",
  12168. responseType: "arraybuffer",
  12169. processData: false,
  12170. renderer: self.renderer,
  12171. success: function(buffer) {
  12172. self.loadMesh(buffer)
  12173. },
  12174. error: function(xhr, status, error) {
  12175. console.log(error)
  12176. }
  12177. })
  12178. };
  12179. ZamModelViewer.Lol.Model.prototype.loadMeta = function(meta) {
  12180. var self = this;
  12181. self.meta = meta;
  12182. if (self.animations) self.updateBounds(self.animBounds);
  12183. for (var t in meta.meshTextures) {
  12184. self.meshTextures[t] = new ZamModelViewer.Lol.Texture(self, self.champion + "/" + meta.meshTextures[t] + ".png")
  12185. }
  12186. };
  12187. ZamModelViewer.Lol.Model.prototype.loadMesh = function(buffer) {
  12188. if (!buffer) {
  12189. console.error("Bad buffer for DataView");
  12190. return
  12191. }
  12192. var self = this,
  12193. r = new ZamModelViewer.DataView(buffer),
  12194. i, v, idx, Lol = ZamModelViewer.Lol;
  12195. var gl = self.renderer.context;
  12196. var magic = r.getUint32();
  12197. if (magic != 604210091) {
  12198. console.log("Bad magic value");
  12199. return
  12200. }
  12201. self.version = r.getUint32();
  12202. var animFile = r.getString();
  12203. var textureFile = r.getString();
  12204. if (animFile && animFile.length > 0) {
  12205. var url = self.opts.contentPath + "models/" + animFile + ".lanim";
  12206. $.ajax({
  12207. url: url,
  12208. type: "GET",
  12209. dataType: "binary",
  12210. responseType: "arraybuffer",
  12211. processData: false,
  12212. renderer: self.renderer,
  12213. success: function(buffer) {
  12214. self.loadAnim(buffer)
  12215. },
  12216. error: function(xhr, status, error) {
  12217. console.log(error)
  12218. }
  12219. })
  12220. }
  12221. if (textureFile && textureFile.length > 0) {
  12222. self.texture = new Lol.Texture(self, self.champion + "/" + textureFile + ".png")
  12223. }
  12224. var numMeshes = r.getUint32();
  12225. if (numMeshes > 0) {
  12226. self.meshes = new Array(numMeshes);
  12227. for (i = 0; i < numMeshes; ++i) {
  12228. var name = r.getString().toLowerCase();
  12229. var vStart = r.getUint32();
  12230. var vCount = r.getUint32();
  12231. var iStart = r.getUint32();
  12232. var iCount = r.getUint32();
  12233. self.meshes[i] = {
  12234. name: name,
  12235. vStart: vStart,
  12236. vCount: vCount,
  12237. iStart: iStart,
  12238. iCount: iCount
  12239. }
  12240. }
  12241. }
  12242. var numVerts = r.getUint32();
  12243. if (numVerts > 0) {
  12244. self.vertices = new Array(numVerts);
  12245. self.vbData = new Float32Array(numVerts * 8);
  12246. for (i = 0; i < numVerts; ++i) {
  12247. idx = i * 8;
  12248. self.vertices[i] = v = new Lol.Vertex(r);
  12249. self.vbData[idx] = v.position[0];
  12250. self.vbData[idx + 1] = v.position[1];
  12251. self.vbData[idx + 2] = v.position[2];
  12252. self.vbData[idx + 3] = v.normal[0];
  12253. self.vbData[idx + 4] = v.normal[1];
  12254. self.vbData[idx + 5] = v.normal[2];
  12255. self.vbData[idx + 6] = v.u;
  12256. self.vbData[idx + 7] = v.v
  12257. }
  12258. }
  12259. var numIndices = r.getUint32();
  12260. if (numIndices > 0) {
  12261. self.indices = new Array(numIndices);
  12262. for (i = 0; i < numIndices; ++i) {
  12263. self.indices[i] = r.getUint16()
  12264. }
  12265. }
  12266. var numBones = r.getUint32();
  12267. if (numBones > 0) {
  12268. self.transforms = new Array(numBones);
  12269. self.bones = new Array(numBones);
  12270. for (i = 0; i < numBones; ++i) {
  12271. self.bones[i] = new Lol.Bone(self, i, r);
  12272. if (self.boneLookup[self.bones[i].name] !== undefined) {
  12273. self.bones[i].name = self.bones[i].name + "2"
  12274. }
  12275. self.boneLookup[self.bones[i].name] = i;
  12276. self.transforms[i] = new mat4.create
  12277. }
  12278. }
  12279. if (self.vbData) {
  12280. self.vb = gl.createBuffer();
  12281. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  12282. gl.bufferData(gl.ARRAY_BUFFER, self.vbData, gl.DYNAMIC_DRAW)
  12283. }
  12284. if (self.indices) {
  12285. self.ib = gl.createBuffer();
  12286. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.ib);
  12287. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(self.indices), gl.STATIC_DRAW)
  12288. }
  12289. self.loaded = true;
  12290. self.updateBounds()
  12291. };
  12292. ZamModelViewer.Lol.Model.prototype.loadAnim = function(buffer) {
  12293. if (!buffer) {
  12294. console.error("Bad buffer for DataView");
  12295. return
  12296. }
  12297. var self = this,
  12298. r = new ZamModelViewer.DataView(buffer),
  12299. i, Lol = ZamModelViewer.Lol;
  12300. var magic = r.getUint32();
  12301. if (magic != 604210092) {
  12302. console.log("Bad magic value");
  12303. return
  12304. }
  12305. var version = r.getUint32();
  12306. if (version >= 2) {
  12307. var compressedData = new Uint8Array(buffer, r.position);
  12308. var data = null;
  12309. try {
  12310. data = pako.inflate(compressedData)
  12311. } catch (err) {
  12312. console.log("Decompression error: " + err);
  12313. return
  12314. }
  12315. r = new ZamModelViewer.DataView(data.buffer)
  12316. }
  12317. var numAnims = r.getUint32();
  12318. if (numAnims > 0) {
  12319. self.animations = new Array(numAnims);
  12320. for (i = 0; i < numAnims; ++i) {
  12321. self.animations[i] = new Lol.Animation(self, r, version)
  12322. }
  12323. }
  12324. self.animsLoaded = true
  12325. };
  12326. ZamModelViewer.Lol.Model.prototype.draw = function() {
  12327. var self = this,
  12328. gl = self.renderer.context,
  12329. i;
  12330. if (!self.loaded) return;
  12331. if (!self.shaderReady) self.initShader();
  12332. if (!self.program) return;
  12333. self.update();
  12334. gl.useProgram(self.program);
  12335. gl.uniformMatrix4fv(self.uniforms.vModelMatrix, false, self.matrix);
  12336. gl.uniformMatrix4fv(self.uniforms.vViewMatrix, false, self.renderer.viewMatrix);
  12337. gl.uniformMatrix4fv(self.uniforms.vProjMatrix, false, self.renderer.projMatrix);
  12338. gl.uniform4fv(self.uniforms.fAmbientColor, self.ambientColor);
  12339. gl.uniform4fv(self.uniforms.fPrimaryColor, self.primaryColor);
  12340. gl.uniform4fv(self.uniforms.fSecondaryColor, self.secondaryColor);
  12341. gl.uniform3fv(self.uniforms.fLightDir1, self.lightDir1);
  12342. gl.uniform3fv(self.uniforms.fLightDir2, self.lightDir2);
  12343. gl.uniform3fv(self.uniforms.fLightDir3, self.lightDir3);
  12344. gl.uniform1i(self.uniforms.fTexture, 0);
  12345. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  12346. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.ib);
  12347. var cull = gl.getParameter(gl.CULL_FACE);
  12348. if (!cull) gl.enable(gl.CULL_FACE);
  12349. var face = gl.getParameter(gl.FRONT_FACE);
  12350. if (face != gl.CW) gl.frontFace(gl.CW);
  12351. for (i in self.attribs) {
  12352. var a = self.attribs[i];
  12353. gl.enableVertexAttribArray(a.loc);
  12354. gl.vertexAttribPointer(a.loc, a.size, a.type, false, a.stride, a.offset)
  12355. }
  12356. if (self.meshes) {
  12357. var m, visible;
  12358. for (i = 0; i < self.meshes.length; ++i) {
  12359. m = self.meshes[i];
  12360. visible = !(self.meta && self.meta.meshVis[m.name] === false);
  12361. if (self.meta && self.meta.animMeshVis[self.animName] !== undefined && self.meta.animMeshVis[self.animName][m.name] !== undefined) visible = self.meta.animMeshVis[self.animName][m.name];
  12362. if (!visible) continue;
  12363. if (self.meshTextures[m.name] !== undefined) {
  12364. if (self.meshTextures[m.name].texture) {
  12365. gl.uniform1i(self.uniforms.fHasTexture, true);
  12366. gl.bindTexture(gl.TEXTURE_2D, self.meshTextures[m.name].texture)
  12367. } else {
  12368. gl.uniform1i(self.uniforms.fHasTexture, false)
  12369. }
  12370. } else if (self.texture && self.texture.texture) {
  12371. gl.uniform1i(self.uniforms.fHasTexture, true);
  12372. gl.bindTexture(gl.TEXTURE_2D, self.texture.texture)
  12373. } else {
  12374. gl.uniform1i(self.uniforms.fHasTexture, false)
  12375. }
  12376. gl.drawElements(gl.TRIANGLES, m.iCount, gl.UNSIGNED_SHORT, m.iStart * 2)
  12377. }
  12378. } else {
  12379. if (self.texture && self.texture.texture) {
  12380. gl.uniform1i(self.uniforms.fHasTexture, true);
  12381. gl.bindTexture(gl.TEXTURE_2D, self.texture.texture)
  12382. } else {
  12383. gl.uniform1i(self.uniforms.fHasTexture, false)
  12384. }
  12385. gl.drawElements(gl.TRIANGLES, self.indices.length, gl.UNSIGNED_SHORT, 0)
  12386. }
  12387. for (i in self.attribs) {
  12388. gl.disableVertexAttribArray(self.attribs[i].loc)
  12389. }
  12390. if (!cull) gl.disable(gl.CULL_FACE);
  12391. if (face == gl.CCW) gl.frontFace(gl.CCW)
  12392. };
  12393. ZamModelViewer.Lol.Model.prototype.initShader = function() {
  12394. var self = this,
  12395. gl = self.renderer.context;
  12396. self.shaderReady = true;
  12397. var vs = self.renderer.compileShader(gl.VERTEX_SHADER, self.vertShader);
  12398. var fs = self.renderer.compileShader(gl.FRAGMENT_SHADER, self.fragShader);
  12399. var program = gl.createProgram();
  12400. gl.attachShader(program, vs);
  12401. gl.attachShader(program, fs);
  12402. gl.linkProgram(program);
  12403. if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
  12404. console.error("Error linking shaders");
  12405. return
  12406. }
  12407. self.vs = vs;
  12408. self.fs = fs;
  12409. self.program = program;
  12410. self.uniforms = {
  12411. vModelMatrix: gl.getUniformLocation(program, "uModelMatrix"),
  12412. vViewMatrix: gl.getUniformLocation(program, "uViewMatrix"),
  12413. vProjMatrix: gl.getUniformLocation(program, "uProjMatrix"),
  12414. fHasTexture: gl.getUniformLocation(program, "uHasTexture"),
  12415. fAmbientColor: gl.getUniformLocation(program, "uAmbientColor"),
  12416. fPrimaryColor: gl.getUniformLocation(program, "uPrimaryColor"),
  12417. fSecondaryColor: gl.getUniformLocation(program, "uSecondaryColor"),
  12418. fLightDir1: gl.getUniformLocation(program, "uLightDir1"),
  12419. fLightDir2: gl.getUniformLocation(program, "uLightDir2"),
  12420. fLightDir3: gl.getUniformLocation(program, "uLightDir3"),
  12421. fTexture: gl.getUniformLocation(program, "uTexture")
  12422. };
  12423. self.attribs = {
  12424. position: {
  12425. loc: gl.getAttribLocation(program, "aPosition"),
  12426. type: gl.FLOAT,
  12427. size: 3,
  12428. offset: 0,
  12429. stride: 32
  12430. },
  12431. normal: {
  12432. loc: gl.getAttribLocation(program, "aNormal"),
  12433. type: gl.FLOAT,
  12434. size: 3,
  12435. offset: 12,
  12436. stride: 32
  12437. },
  12438. texcoord: {
  12439. loc: gl.getAttribLocation(program, "aTexCoord"),
  12440. type: gl.FLOAT,
  12441. size: 2,
  12442. offset: 24,
  12443. stride: 32
  12444. }
  12445. }
  12446. };
  12447. ZamModelViewer.Lol.Model.prototype.vertShader = " attribute vec3 aPosition; attribute vec3 aNormal; attribute vec2 aTexCoord; varying vec3 vNormal; varying vec2 vTexCoord; uniform mat4 uModelMatrix; uniform mat4 uViewMatrix; uniform mat4 uProjMatrix; void main(void) { gl_Position = uProjMatrix * uViewMatrix * uModelMatrix * vec4(aPosition, 1); vNormal = mat3(uViewMatrix * uModelMatrix) * normalize(aNormal); vTexCoord = aTexCoord; }";
  12448. ZamModelViewer.Lol.Model.prototype.fragShader = " precision mediump float; varying vec3 vNormal; varying vec2 vTexCoord; uniform bool uHasTexture; uniform vec4 uAmbientColor; uniform vec4 uPrimaryColor; uniform vec4 uSecondaryColor; uniform vec3 uLightDir1; uniform vec3 uLightDir2; uniform vec3 uLightDir3; uniform sampler2D uTexture; void main(void) { vec4 color = vec4(1, 1, 1, 1); if (uHasTexture) { color = texture2D(uTexture, vTexCoord.st); } else { color = vec4(vTexCoord.st, 0, 1); } vec4 litColor = uAmbientColor; vec3 normal = normalize(vNormal); float dp = max(0.0, dot(normal, uLightDir1)); litColor += uPrimaryColor * dp; dp = max(0.0, dot(normal, uLightDir2)); litColor += uSecondaryColor * dp; dp = max(0.0, dot(normal, uLightDir3)); litColor += uSecondaryColor * dp; litColor = clamp(litColor, vec4(0,0,0,0), vec4(1,1,1,1)); color *= litColor; gl_FragColor = color; }";
  12449. ZamModelViewer.Lol.Texture = function(model, url) {
  12450. var self = this;
  12451. self.model = model;
  12452. self.url = model.opts.contentPath + "textures/" + url;
  12453. self.texture = null;
  12454. self.load()
  12455. };
  12456. ZamModelViewer.Lol.Texture.prototype = {
  12457. destroy: function() {
  12458. var self = this,
  12459. gl = self.model.renderer.context;
  12460. if (self.texture) gl.deleteTexture(self.texture);
  12461. self.img = null
  12462. },
  12463. load: function() {
  12464. var self = this,
  12465. gl = self.model.renderer.context;
  12466. (function(self, gl) {
  12467. self.img = new Image;
  12468. self.img.crossOrigin = "";
  12469. self.img.onload = function() {
  12470. self.img.loaded = true;
  12471. self.texture = gl.createTexture();
  12472. gl.bindTexture(gl.TEXTURE_2D, self.texture);
  12473. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, self.img);
  12474. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
  12475. };
  12476. self.img.onerror = function() {
  12477. self.img = null;
  12478. self.error = true
  12479. };
  12480. self.img.src = self.url
  12481. })(self, gl)
  12482. }
  12483. };
  12484. ZamModelViewer.Lol.Vertex = function(r) {
  12485. var self = this,
  12486. i;
  12487. self.position = [r.getFloat(), r.getFloat(), r.getFloat()];
  12488. self.normal = [r.getFloat(), r.getFloat(), r.getFloat(), 0];
  12489. self.u = r.getFloat();
  12490. self.v = r.getFloat();
  12491. self.bones = new Array(4);
  12492. for (i = 0; i < 4; ++i) self.bones[i] = r.getUint8();
  12493. self.weights = new Array(4);
  12494. for (i = 0; i < 4; ++i) self.weights[i] = r.getFloat()
  12495. };
  12496. ZamModelViewer.Lol.Bone = function(model, index, r) {
  12497. var self = this,
  12498. i;
  12499. self.model = model;
  12500. self.index = index;
  12501. self.name = r.getString().toLowerCase();
  12502. self.parent = r.getInt32();
  12503. self.scale = r.getFloat();
  12504. self.origMatrix = mat4.create();
  12505. for (i = 0; i < 16; ++i) self.origMatrix[i] = r.getFloat();
  12506. self.baseMatrix = mat4.clone(self.origMatrix);
  12507. mat4.transpose(self.baseMatrix, self.baseMatrix);
  12508. mat4.invert(self.baseMatrix, self.baseMatrix);
  12509. mat4.transpose(self.origMatrix, self.origMatrix);
  12510. self.incrMatrix = mat4.create();
  12511. if (model.version >= 2) {
  12512. for (i = 0; i < 16; ++i) self.incrMatrix[i] = r.getFloat();
  12513. mat4.transpose(self.incrMatrix, self.incrMatrix)
  12514. } else {
  12515. mat4.identity(self.incrMatrix)
  12516. }
  12517. };
  12518. ZamModelViewer.Lol.Animation = function(model, r, version) {
  12519. var self = this,
  12520. i, Lol = ZamModelViewer.Lol;
  12521. self.model = model;
  12522. self.meshOverride = {};
  12523. self.name = r.getString().toLowerCase();
  12524. self.fps = r.getInt32();
  12525. var numBones = r.getUint32();
  12526. self.bones = new Array(numBones);
  12527. self.lookup = {};
  12528. for (i = 0; i < numBones; ++i) {
  12529. self.bones[i] = new Lol.AnimationBone(model, self, r, version);
  12530. self.lookup[self.bones[i].bone] = i
  12531. }
  12532. if (numBones == 0 || self.fps <= 1) {
  12533. self.duration = 1e3
  12534. } else {
  12535. self.duration = Math.floor(1e3 * (self.bones[0].frames.length / self.fps))
  12536. }
  12537. };
  12538. ZamModelViewer.Lol.AnimationBone = function(model, anim, r, version) {
  12539. var self = this;
  12540. self.model = model;
  12541. self.anim = anim;
  12542. var numFrames = r.getUint32();
  12543. self.bone = r.getString().toLowerCase();
  12544. self.flags = r.getUint32();
  12545. self.frames = new Array(numFrames);
  12546. var scale = [1, 1, 1];
  12547. for (var i = 0; i < numFrames; ++i) {
  12548. var pos = [r.getFloat(), r.getFloat(), r.getFloat()];
  12549. var rot = [r.getFloat(), r.getFloat(), r.getFloat(), r.getFloat()];
  12550. if (version >= 3) scale = [r.getFloat(), r.getFloat(), r.getFloat()];
  12551. self.frames[i] = {
  12552. pos: pos,
  12553. rot: rot,
  12554. scale: scale
  12555. }
  12556. }
  12557. self.matrix = mat4.create();
  12558. self.tmpMat = mat4.create();
  12559. self.tmpMat2 = mat4.create();
  12560. self.tmpPos = vec3.create();
  12561. self.tmpRot = quat.create();
  12562. self.tmpScale = vec3.create()
  12563. };
  12564. ZamModelViewer.Lol.AnimationBone.prototype.update = function(boneId, frame, r) {
  12565. var self = this;
  12566. self.index = boneId;
  12567. var parent = self.model.bones[boneId].parent;
  12568. var f0 = frame % self.frames.length,
  12569. f1 = (frame + 1) % self.frames.length;
  12570. vec3.lerp(self.tmpPos, self.frames[f0].pos, self.frames[f1].pos, r);
  12571. vec3.lerp(self.tmpScale, self.frames[f0].scale, self.frames[f1].scale, r);
  12572. quat.slerp(self.tmpRot, self.frames[f0].rot, self.frames[f1].rot, r);
  12573. mat4.translation(self.tmpMat2, self.tmpPos);
  12574. mat4.rotationQuat(self.tmpMat, self.tmpRot);
  12575. mat4.mulSlimDX(self.matrix, self.tmpMat, self.tmpMat2);
  12576. if (parent != -1) {
  12577. mat4.mulSlimDX(self.matrix, self.matrix, self.model.transforms[parent])
  12578. }
  12579. mat4.copy(self.model.transforms[boneId], self.matrix)
  12580. };
  12581. ZamModelViewer.Lol.Model.BaseAnimations = {
  12582. 32: {
  12583. 4: {
  12584. all: "idle1_bow",
  12585. idle1_bow: "idle1"
  12586. }
  12587. },
  12588. 55: {
  12589. 7: {
  12590. idle1_candycane_below: "idle1"
  12591. }
  12592. }
  12593. };
  12594. ZamModelViewer.Lol.Model.HiddenBones = {
  12595. 55: {
  12596. 7: {
  12597. recall: {},
  12598. all: {
  12599. xmas_pole: true
  12600. }
  12601. }
  12602. },
  12603. 115: {
  12604. 4: {
  12605. all: {
  12606. sled: true
  12607. },
  12608. satcheljump: {
  12609. bomb: true,
  12610. bomb_b: true
  12611. }
  12612. }
  12613. },
  12614. 201: {
  12615. 3: {
  12616. all: {
  12617. poro: true
  12618. }
  12619. }
  12620. },
  12621. 254: {
  12622. 0: {
  12623. all: {
  12624. teacup: true
  12625. },
  12626. taunt2: {}
  12627. },
  12628. 1: {
  12629. all: {
  12630. teacup: true
  12631. },
  12632. taunt2: {}
  12633. },
  12634. 3: {
  12635. all: {
  12636. teacup: true
  12637. },
  12638. taunt2: {}
  12639. },
  12640. 4: {
  12641. all: {
  12642. teacup: true
  12643. },
  12644. taunt2: {}
  12645. }
  12646. },
  12647. 412: {
  12648. 1: {
  12649. all: {
  12650. coin1: true,
  12651. coin2: true,
  12652. coin3: true,
  12653. coin4: true,
  12654. coin5: true,
  12655. coin6: true,
  12656. coin7: true,
  12657. treasure_chest: true,
  12658. treasure_chest_cover: true,
  12659. tire: true
  12660. },
  12661. recall: {
  12662. tire: true
  12663. },
  12664. undersea_recall_loop: {
  12665. tire: true
  12666. },
  12667. undersea_recall_loop2: {
  12668. coin1: true,
  12669. coin2: true,
  12670. coin3: true,
  12671. coin4: true,
  12672. coin5: true,
  12673. coin6: true,
  12674. coin7: true,
  12675. treasure_chest: true,
  12676. treasure_chest_cover: true
  12677. },
  12678. undersea_recall_windup: {
  12679. tire: true
  12680. },
  12681. undersea_recall_windup2: {
  12682. coin1: true,
  12683. coin2: true,
  12684. coin3: true,
  12685. coin4: true,
  12686. coin5: true,
  12687. coin6: true,
  12688. coin7: true,
  12689. treasure_chest: true,
  12690. treasure_chest_cover: true
  12691. }
  12692. }
  12693. },
  12694. 420: {
  12695. 0: {
  12696. all: {
  12697. c_tentacle1: true
  12698. }
  12699. },
  12700. 1: {
  12701. all: {
  12702. c_tentacle1: true
  12703. }
  12704. }
  12705. }
  12706. };
  12707. ZamModelViewer.Heroes = function() {};
  12708. ZamModelViewer.Heroes.Model = function(renderer, viewer, model, parent) {
  12709. var self = this;
  12710. self.renderer = renderer;
  12711. self.viewer = viewer;
  12712. self.model = model;
  12713. self.modelPath = null;
  12714. self.ready = false;
  12715. self.parent = parent;
  12716. self.opts = self.viewer.options;
  12717. self.meta = null;
  12718. self.vertices = null;
  12719. self.indices = null;
  12720. self.materialLookup = null;
  12721. self.materials = null;
  12722. self.meshes = null;
  12723. self.bones = null;
  12724. self.boneLookup = null;
  12725. self.boneNameLookup = {};
  12726. self.baseMatrices = null;
  12727. self.animations = null;
  12728. self.animData = null;
  12729. self.animDataLookup = null;
  12730. self.anims = null;
  12731. self.textures = {};
  12732. self.matrix = mat4.create();
  12733. self.ib = null;
  12734. self.shaderReady = false;
  12735. self.vs = null;
  12736. self.fs = null;
  12737. self.program = null;
  12738. self.uniforms = null;
  12739. self.attribs = null;
  12740. self.ambientColor = [.35, .35, .35, 1];
  12741. self.primaryColor = [1, 1, 1, 1];
  12742. self.secondaryColor = [.35, .35, .35, 1];
  12743. self.lightDir1 = vec3.create();
  12744. self.lightDir2 = vec3.create();
  12745. self.lightDir3 = vec3.create();
  12746. vec3.normalize(self.lightDir1, [-3, -3, -3]);
  12747. vec3.normalize(self.lightDir2, [3, -1, -3]);
  12748. vec3.normalize(self.lightDir3, [3, 2, 2]);
  12749. self.lightIntensity = vec4.set(vec4.create(), .75, .25, .25, .35);
  12750. self.animBounds = false;
  12751. self.boundsCenter = [0, 0, 0];
  12752. self.boundsSize = [0, 0, 0];
  12753. self.boundsMin = [0, 0, 0];
  12754. self.boundsMax = [0, 0, 0];
  12755. self.animTime = 0;
  12756. self.lastTime = self.renderer.time;
  12757. self.tmpMat = mat4.create();
  12758. self.tmpVec = vec4.create();
  12759. self.tmpVec2 = vec4.create();
  12760. self.tmpQuat = quat.create();
  12761. self.load()
  12762. };
  12763. ZamModelViewer.Models[ZamModelViewer.HEROES] = ZamModelViewer.Heroes.Model;
  12764. ZamModelViewer.Heroes.disabledAnims = {
  12765. herofalstad: true,
  12766. falstaddarkiron: true,
  12767. falstadnordic: true,
  12768. falstadskinultimate: true,
  12769. falstadultimatered: true,
  12770. falstadultimatewhite: true,
  12771. falstadstormlord: true,
  12772. falstadstormlorddarkiron: true,
  12773. falstadstormlordnordic: true,
  12774. tyraelskinseraphimchampion: true,
  12775. tyraelseraphimsand: true,
  12776. tyraelseraphimdark: true
  12777. };
  12778. ZamModelViewer.Heroes.Model.prototype = {
  12779. external: {
  12780. isLoaded: function() {
  12781. return this.ready
  12782. }
  12783. },
  12784. destroy: function() {
  12785. var self = this,
  12786. gl = self.renderer.context,
  12787. i, j;
  12788. if (self.program) gl.deleteProgram(self.program);
  12789. if (self.vs) gl.deleteShader(self.vs);
  12790. if (self.fs) gl.deleteShader(self.fs);
  12791. if (self.vb) gl.deleteBuffer(self.vb);
  12792. if (self.ib) gl.deleteBuffer(self.ib);
  12793. self.program = self.vs = self.fs = self.vb = self.ib = null;
  12794. self.vbData = null
  12795. },
  12796. update: function() {
  12797. var self = this,
  12798. i, j, k;
  12799. self.animTime += self.renderer.time - self.lastTime;
  12800. self.lastTime = self.renderer.time;
  12801. if (!self.ready || !self.vertices) return;
  12802. var vertLength = 10;
  12803. if (self.currentAnim && !ZamModelViewer.Heroes.disabledAnims[self.model]) {
  12804. var numBones = self.bones.length,
  12805. bone, startBone, animBone, anim = self.currentAnim,
  12806. animModel = self.currentAnimModel;
  12807. var hasScale, hasRot, hasTrans;
  12808. for (i = 0; i < numBones; ++i) {
  12809. startBone = bone = self.bones[i];
  12810. mat4.identity(startBone.matrix);
  12811. while (bone) {
  12812. if (animModel.boneNameLookup[bone.name]) {
  12813. animBone = animModel.bones[animModel.boneNameLookup[bone.name]]
  12814. } else {
  12815. animBone = null
  12816. }
  12817. hasScale = hasRot = hasTrans = false;
  12818. if (animBone && animModel.animDataLookup.length > 0) {
  12819. var animDataIndex = animModel.animDataLookup[anim.index].indices[0];
  12820. var animData = animModel.animData[animDataIndex];
  12821. var numIds = animData.animIds.length;
  12822. for (j = 0; j < numIds; ++j) {
  12823. if (animBone.translation.animId == animData.animIds[j]) {
  12824. var transData = animData.translations[animData.animIndices[j].animIndex];
  12825. transData.getValue(self.animTime, self.tmpVec);
  12826. hasTrans = true
  12827. }
  12828. if (animBone.rotation.animId == animData.animIds[j]) {
  12829. var rotData = animData.rotations[animData.animIndices[j].animIndex];
  12830. rotData.getValue(self.animTime, self.tmpQuat);
  12831. hasRot = true
  12832. }
  12833. if (animBone.scale.animId == animData.animIds[j]) {
  12834. var scaleData = animData.translations[animData.animIndices[j].animIndex];
  12835. scaleData.getValue(self.animTime, self.tmpVec2);
  12836. hasScale = true
  12837. }
  12838. }
  12839. }
  12840. if (!hasTrans) vec3.copy(self.tmpVec, bone.translation.value);
  12841. if (!hasRot) quat.copy(self.tmpQuat, bone.rotation.value);
  12842. if (!hasScale) vec3.copy(self.tmpVec2, bone.scale.value);
  12843. mat4.fromQuat(self.tmpMat, self.tmpQuat);
  12844. mat4.scale(self.tmpMat, self.tmpMat, self.tmpVec2);
  12845. self.tmpMat[12] = self.tmpVec[0];
  12846. self.tmpMat[13] = self.tmpVec[1];
  12847. self.tmpMat[14] = self.tmpVec[2];
  12848. bone.scaleLength = self.tmpVec2[0];
  12849. mat4.multiply(startBone.matrix, self.tmpMat, startBone.matrix);
  12850. if (bone.parentId > -1) {
  12851. bone = self.bones[bone.parentId]
  12852. } else {
  12853. bone = null
  12854. }
  12855. }
  12856. if (!startBone.show) mat4.scale(startBone.matrix, startBone.matrix, vec3.set(self.tmpVec, 0, 0, 0));
  12857. if (animModel.boneNameLookup[startBone.name] !== undefined && animModel.baseMatrices.length > animModel.boneNameLookup[startBone.name]) {
  12858. mat4.multiply(startBone.matrix, startBone.matrix, animModel.baseMatrices[animModel.boneNameLookup[startBone.name]])
  12859. } else if (self.baseMatrices && self.baseMatrices.length > i) {
  12860. mat4.multiply(startBone.matrix, startBone.matrix, self.baseMatrices[i])
  12861. }
  12862. }
  12863. var m, v, w, b, boneIndex, vertStart, vertCount, idx, vbData = self.vbData,
  12864. tmpVec = self.tmpVec,
  12865. tmpVec2 = self.tmpVec2;
  12866. for (i = 0; i < self.meshes.length; ++i) {
  12867. m = self.meshes[i];
  12868. if (!m.show) continue;
  12869. boneIndex = m.boneIndex;
  12870. vertStart = m.vStart;
  12871. vertCount = m.vCount;
  12872. for (j = 0; j < vertCount; ++j) {
  12873. v = self.vertices[vertStart + j];
  12874. idx = (j + vertStart) * vertLength;
  12875. vbData[idx] = vbData[idx + 1] = vbData[idx + 2] = vbData[idx + 3] = vbData[idx + 4] = vbData[idx + 5] = 0;
  12876. for (k = 0; k < 4; ++k) {
  12877. if (v.weights[k] == 0) continue;
  12878. w = v.weights[k] / 255;
  12879. b = self.bones[self.boneLookup[boneIndex + v.bones[k]]];
  12880. vec3.transformMat4(tmpVec, v.position, b.matrix);
  12881. vec4.transformMat4(tmpVec2, v.normal, b.matrix);
  12882. vbData[idx] += tmpVec[0] * w;
  12883. vbData[idx + 1] += tmpVec[1] * w;
  12884. vbData[idx + 2] += tmpVec[2] * w;
  12885. vbData[idx + 3] += tmpVec2[0] * w;
  12886. vbData[idx + 4] += tmpVec2[1] * w;
  12887. vbData[idx + 5] += tmpVec2[2] * w
  12888. }
  12889. vec3.set(v.transPosition, vbData[idx], vbData[idx + 1], vbData[idx + 2]);
  12890. vec4.set(v.transNormal, vbData[idx + 3], vbData[idx + 4], vbData[idx + 5], 0)
  12891. }
  12892. }
  12893. self.updateBuffers();
  12894. if (!self.animBounds) {
  12895. self.updateBounds();
  12896. self.animBounds = true
  12897. }
  12898. }
  12899. },
  12900. updateBuffers: function() {
  12901. var self = this,
  12902. gl = self.renderer.context;
  12903. if (!self.vbData) {
  12904. var vertLength = 10;
  12905. var vbLength = self.vertices.length * vertLength;
  12906. self.vbData = new Float32Array(vbLength);
  12907. var v, numVerts = self.vertices.length,
  12908. vbData = self.vbData,
  12909. base;
  12910. for (var i = 0, j = 0; j < numVerts; i += vertLength, ++j) {
  12911. v = self.vertices[j];
  12912. vbData[i] = v.transPosition[0];
  12913. vbData[i + 1] = v.transPosition[1];
  12914. vbData[i + 2] = v.transPosition[2];
  12915. vbData[i + 3] = v.transNormal[0];
  12916. vbData[i + 4] = v.transNormal[1];
  12917. vbData[i + 5] = v.transNormal[2];
  12918. vbData[i + 6] = v.uv1.u;
  12919. vbData[i + 7] = v.uv1.v;
  12920. if (self.hasUv2) {
  12921. vbData[i + 8] = v.uv2.u;
  12922. vbData[i + 9] = v.uv2.v
  12923. } else {
  12924. vbData[i + 8] = vbData[i + 9] = 0
  12925. }
  12926. }
  12927. self.vb = gl.createBuffer();
  12928. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  12929. gl.bufferData(gl.ARRAY_BUFFER, self.vbData, gl.DYNAMIC_DRAW)
  12930. } else {
  12931. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  12932. gl.bufferSubData(gl.ARRAY_BUFFER, 0, self.vbData)
  12933. }
  12934. },
  12935. draw: function() {
  12936. var self = this,
  12937. gl = self.renderer.context,
  12938. i;
  12939. if (!self.ready) return;
  12940. if (!self.shaderReady) self.initShader();
  12941. if (!self.program) return;
  12942. self.update();
  12943. gl.useProgram(self.program);
  12944. gl.frontFace(gl.CCW);
  12945. gl.uniformMatrix4fv(self.uniforms.vModelMatrix, false, self.matrix);
  12946. gl.uniformMatrix4fv(self.uniforms.vViewMatrix, false, self.renderer.viewMatrix);
  12947. gl.uniformMatrix4fv(self.uniforms.vProjMatrix, false, self.renderer.projMatrix);
  12948. gl.uniform4fv(self.uniforms.fLightIntensity, self.lightIntensity);
  12949. gl.uniform3fv(self.uniforms.fLightDir1, self.lightDir1);
  12950. gl.uniform3fv(self.uniforms.fLightDir2, self.lightDir2);
  12951. gl.uniform3fv(self.uniforms.fLightDir3, self.lightDir3);
  12952. gl.uniform3fv(self.uniforms.fCameraPos, self.renderer.eye);
  12953. gl.uniform1i(self.uniforms.vHasUv2, self.hasUv2);
  12954. gl.bindBuffer(gl.ARRAY_BUFFER, self.vb);
  12955. for (i in self.attribs) {
  12956. var a = self.attribs[i];
  12957. gl.enableVertexAttribArray(a.loc);
  12958. gl.vertexAttribPointer(a.loc, a.size, a.type, false, a.stride, a.offset)
  12959. }
  12960. if (self.meshes) {
  12961. for (i = 0; i < self.meshes.length; ++i) {
  12962. if (!self.meshes[i].show) continue;
  12963. self.meshes[i].draw()
  12964. }
  12965. }
  12966. for (i in self.attribs) {
  12967. gl.disableVertexAttribArray(self.attribs[i].loc)
  12968. }
  12969. },
  12970. getMaterial: function(idx) {
  12971. var self = this;
  12972. if (idx >= self.materialLookup.length || self.materialLookup[idx].type != 1) return null;
  12973. return self.materials[self.materialLookup[idx].index]
  12974. },
  12975. setAnimation: function(name) {
  12976. var self = this,
  12977. i, j;
  12978. self.animTime = 0;
  12979. if (self.animations) {
  12980. for (i = 0; i < self.animations.length; ++i) {
  12981. if (self.animations[i].name == name) {
  12982. self.currentAnim = self.animations[i];
  12983. self.currentAnimModel = self;
  12984. return
  12985. }
  12986. }
  12987. }
  12988. if (self.anims) {
  12989. for (i = 0; i < self.anims.length; ++i) {
  12990. if (!self.anims[i].animations) continue;
  12991. for (j = 0; j < self.anims[i].animations.length; ++j) {
  12992. if (self.anims[i].animations[j].name == name) {
  12993. self.currentAnim = self.anims[i].animations[j];
  12994. self.currentAnimModel = self.anims[i];
  12995. return
  12996. }
  12997. }
  12998. }
  12999. }
  13000. if (self.animations.length > 0) {
  13001. self.currentAnim = self.animations[0];
  13002. self.currentAnimModel = self
  13003. } else {
  13004. self.currentAnim = null;
  13005. self.currentAnimModel = null
  13006. }
  13007. },
  13008. onAnimLoaded: function() {
  13009. var self = this;
  13010. if (self.anims) {
  13011. for (var i = 0; i < self.anims.length; ++i) {
  13012. if (!self.anims[i].ready) break
  13013. }
  13014. }
  13015. self.animsLoaded = true;
  13016. self.setAnimation("Stand")
  13017. },
  13018. updateBounds: function(skipSizing) {
  13019. var self = this,
  13020. i, j, m, p;
  13021. var min = self.boundsMin,
  13022. max = self.boundsMax;
  13023. if (!skipSizing) {
  13024. vec3.set(min, 9999, 9999, 9999);
  13025. vec3.set(max, -9999, -9999, -9999);
  13026. for (i = 0; i < self.meshes.length; ++i) {
  13027. m = self.meshes[i];
  13028. if (!m.show) continue;
  13029. for (j = 0; j < m.vCount; ++j) {
  13030. p = self.vertices[m.vStart + j].transPosition;
  13031. if (Math.abs(p[0]) > 15 || Math.abs(p[1]) > 15 || Math.abs(p[2]) > 15) continue;
  13032. min = vec3.min(min, min, p);
  13033. max = vec3.max(max, max, p)
  13034. }
  13035. }
  13036. }
  13037. vec3.subtract(self.boundsSize, max, min);
  13038. vec3.scaleAndAdd(self.boundsCenter, min, self.boundsSize, .5);
  13039. var hSize = self.boundsSize[2],
  13040. wSize = self.boundsSize[0],
  13041. dSize = self.boundsSize[1];
  13042. if (!self.parent) {
  13043. if (self.opts.dist) {
  13044. self.renderer.distance = self.opts.dist
  13045. } else {
  13046. var ratio = self.renderer.width / self.renderer.height;
  13047. var hTan = 2 * Math.tan(self.renderer.fov / 2 * .0174532925);
  13048. var wTan = hTan * ratio;
  13049. var hDist = (dSize * .5 + hSize * 1.2) / hTan;
  13050. var wDist = (dSize * .5 + wSize * 1.2) / wTan;
  13051. self.renderer.distance = Math.max(Math.max(hDist, wDist), dSize * 1.25)
  13052. }
  13053. mat4.identity(self.matrix);
  13054. mat4.rotateZ(self.matrix, self.matrix, Math.PI);
  13055. mat4.translate(self.matrix, self.matrix, vec3.negate(self.tmpVec, self.boundsCenter))
  13056. } else {
  13057. self.parent.updateBounds()
  13058. }
  13059. }
  13060. };
  13061. ZamModelViewer.Heroes.Model.prototype.load = function() {
  13062. var self = this;
  13063. if (!self.model) return;
  13064. self._load(self.model)
  13065. };
  13066. ZamModelViewer.Heroes.Model.prototype._load = function(model) {
  13067. var self = this;
  13068. $.getJSON(self.opts.contentPath + "meta/" + model + ".json?" + (self.opts.cacheBuster || 1), function(data) {
  13069. self.loadMeta(data)
  13070. })
  13071. };
  13072. ZamModelViewer.Heroes.Model.prototype._loadModel = function(model) {
  13073. var self = this;
  13074. var url;
  13075. if (model.indexOf(".mdl") > -1) {
  13076. url = model
  13077. } else {
  13078. url = "models/" + model + ".mdl"
  13079. }
  13080. $.ajax({
  13081. url: self.opts.contentPath + url + "?" + (self.opts.cacheBuster || 1),
  13082. type: "GET",
  13083. dataType: "binary",
  13084. responseType: "arraybuffer",
  13085. processData: false,
  13086. renderer: self.renderer,
  13087. success: function(buffer) {
  13088. self.loadModel(buffer)
  13089. },
  13090. error: function(xhr, status, error) {
  13091. console.log(error)
  13092. }
  13093. })
  13094. };
  13095. ZamModelViewer.Heroes.Model.prototype.loadMeta = function(meta) {
  13096. var self = this;
  13097. self.meta = meta;
  13098. if (meta.Model) {
  13099. self._loadModel(meta.Model)
  13100. }
  13101. };
  13102. ZamModelViewer.Heroes.Model.prototype.loadModel = function(buffer) {
  13103. if (!buffer) {
  13104. console.error("Bad buffer for DataView");
  13105. return
  13106. }
  13107. var self = this,
  13108. r = new ZamModelViewer.DataView(buffer),
  13109. Heroes = ZamModelViewer.Heroes,
  13110. i;
  13111. var version = r.getUint32();
  13112. if (version > 2) {
  13113. console.log("Bad version");
  13114. return
  13115. }
  13116. var numVertices = r.getInt32();
  13117. self.vertices = new Array(numVertices);
  13118. var uv2 = self.hasUv2 = r.getBool();
  13119. var uv3 = self.hasUv3 = r.getBool();
  13120. var uv4 = self.hasUv4 = r.getBool();
  13121. var uv5 = self.hasUv5 = r.getBool();
  13122. for (i = 0; i < numVertices; ++i) {
  13123. self.vertices[i] = new Heroes.Vertex(r, uv2, uv3, uv4, uv5)
  13124. }
  13125. var numIndices = r.getInt32();
  13126. self.indices = new Array(numIndices);
  13127. for (i = 0; i < numIndices; ++i) self.indices[i] = r.getUint16();
  13128. var numMaterialLookup = r.getInt32();
  13129. self.materialLookup = new Array(numMaterialLookup);
  13130. for (i = 0; i < numMaterialLookup; ++i) {
  13131. self.materialLookup[i] = {
  13132. type: r.getUint32(),
  13133. index: r.getUint32()
  13134. }
  13135. }
  13136. var numMaterials = r.getInt32();
  13137. self.materials = new Array(numMaterials);
  13138. for (i = 0; i < numMaterials; ++i) {
  13139. self.materials[i] = new Heroes.Material(self, r)
  13140. }
  13141. var numMeshes = r.getInt32();
  13142. self.meshes = new Array(numMeshes);
  13143. for (i = 0; i < numMeshes; ++i) {
  13144. self.meshes[i] = new Heroes.Mesh(self, r)
  13145. }
  13146. var numBones = r.getInt32();
  13147. self.bones = new Array(numBones);
  13148. for (i = 0; i < numBones; ++i) {
  13149. self.bones[i] = new Heroes.Bone(self, i, r);
  13150. self.boneNameLookup[self.bones[i].name] = i
  13151. }
  13152. var numBoneLookup = r.getInt32();
  13153. self.boneLookup = new Array(numBoneLookup);
  13154. for (i = 0; i < numBoneLookup; ++i) self.boneLookup[i] = r.getUint16();
  13155. var numMatrices = r.getInt32();
  13156. self.baseMatrices = new Array(numMatrices);
  13157. for (i = 0; i < numMatrices; ++i) {
  13158. var mat = mat4.create();
  13159. for (var j = 0; j < 16; ++j) {
  13160. mat[j] = r.getFloat()
  13161. }
  13162. self.baseMatrices[i] = mat
  13163. }
  13164. var numAnimations = r.getInt32();
  13165. self.animations = new Array(numAnimations);
  13166. for (i = 0; i < numAnimations; ++i) {
  13167. self.animations[i] = new Heroes.Animation(i, r)
  13168. }
  13169. var numAnimData = r.getInt32();
  13170. self.animData = new Array(numAnimData);
  13171. for (i = 0; i < numAnimData; ++i) {
  13172. self.animData[i] = new Heroes.AnimData(r)
  13173. }
  13174. var numAnimDataLookup = r.getInt32();
  13175. self.animDataLookup = new Array(numAnimDataLookup);
  13176. for (i = 0; i < numAnimDataLookup; ++i) {
  13177. self.animDataLookup[i] = new Heroes.AnimData.Lookup(r)
  13178. }
  13179. var numAnimFiles = 1,
  13180. animFile;
  13181. if (version > 1) {
  13182. numAnimFiles = r.getInt32();
  13183. self.anims = new Array(numAnimFiles);
  13184. for (i = 0; i < numAnimFiles; ++i) {
  13185. animFile = r.getString();
  13186. self.anims[i] = new Heroes.Model(self.renderer, self.viewer, null, self);
  13187. self.anims[i]._loadModel(animFile)
  13188. }
  13189. } else {
  13190. animFile = r.getString();
  13191. if (animFile && animFile.length > 0) {
  13192. var anim = new Heroes.Model(self.renderer, self.viewer, null, self);
  13193. anim._loadModel(animFile);
  13194. self.anims = [anim]
  13195. }
  13196. }
  13197. self.ready = true;
  13198. if (!self.parent) {
  13199. self.meshes.sort(function(a, b) {
  13200. var m1 = a.material,
  13201. m2 = b.material;
  13202. var p1 = m1 ? m1.priority : 0,
  13203. p2 = m2 ? m2.priority : 0;
  13204. return p1 - p2
  13205. });
  13206. var HM = ZamModelViewer.Heroes.Mesh.hiddenMeshes;
  13207. if (HM[self.model]) {
  13208. for (i = 0; i < self.meshes.length; ++i) {
  13209. if (HM[self.model][i]) self.meshes[i].show = false
  13210. }
  13211. }
  13212. self.updateBuffers();
  13213. self.updateBounds();
  13214. if (!self.anims) {
  13215. self.setAnimation("Stand")
  13216. }
  13217. } else {
  13218. self.parent.onAnimLoaded()
  13219. }
  13220. };
  13221. ZamModelViewer.Heroes.Model.prototype.initShader = function() {
  13222. var self = this,
  13223. gl = self.renderer.context;
  13224. self.shaderReady = true;
  13225. var vs = self.renderer.compileShader(gl.VERTEX_SHADER, self.vertShader);
  13226. var fs = self.renderer.compileShader(gl.FRAGMENT_SHADER, self.fragShader);
  13227. var program = gl.createProgram();
  13228. gl.attachShader(program, vs);
  13229. gl.attachShader(program, fs);
  13230. gl.linkProgram(program);
  13231. if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
  13232. console.error("Error linking shaders");
  13233. return
  13234. }
  13235. self.vs = vs;
  13236. self.fs = fs;
  13237. self.program = program;
  13238. self.uniforms = {
  13239. vModelMatrix: gl.getUniformLocation(program, "uModelMatrix"),
  13240. vViewMatrix: gl.getUniformLocation(program, "uViewMatrix"),
  13241. vProjMatrix: gl.getUniformLocation(program, "uProjMatrix"),
  13242. vHasUv2: gl.getUniformLocation(program, "uHasUv2"),
  13243. fBlendMode: gl.getUniformLocation(program, "uBlendMode"),
  13244. fHasDiffuse: gl.getUniformLocation(program, "uHasDiffuse"),
  13245. fHasDiffuseAlpha: gl.getUniformLocation(program, "uHasDiffuseAlpha"),
  13246. fDiffuse: gl.getUniformLocation(program, "uDiffuse"),
  13247. fDiffuseAlpha: gl.getUniformLocation(program, "uDiffuseAlpha"),
  13248. fLightIntensity: gl.getUniformLocation(program, "uLightIntensity"),
  13249. fLightDir1: gl.getUniformLocation(program, "uLightDir1"),
  13250. fLightDir2: gl.getUniformLocation(program, "uLightDir2"),
  13251. fLightDir3: gl.getUniformLocation(program, "uLightDir3"),
  13252. fCameraPos: gl.getUniformLocation(program, "uCameraPos")
  13253. };
  13254. self.attribs = {
  13255. position: {
  13256. loc: gl.getAttribLocation(program, "aPosition"),
  13257. type: gl.FLOAT,
  13258. size: 3,
  13259. offset: 0,
  13260. stride: 40
  13261. },
  13262. normal: {
  13263. loc: gl.getAttribLocation(program, "aNormal"),
  13264. type: gl.FLOAT,
  13265. size: 3,
  13266. offset: 12,
  13267. stride: 40
  13268. },
  13269. uv1: {
  13270. loc: gl.getAttribLocation(program, "aUv1"),
  13271. type: gl.FLOAT,
  13272. size: 2,
  13273. offset: 24,
  13274. stride: 40
  13275. },
  13276. uv2: {
  13277. loc: gl.getAttribLocation(program, "aUv2"),
  13278. type: gl.FLOAT,
  13279. size: 2,
  13280. offset: 32,
  13281. stride: 40
  13282. }
  13283. }
  13284. };
  13285. ZamModelViewer.Heroes.Model.prototype.vertShader = " attribute vec3 aPosition; attribute vec3 aNormal; attribute vec2 aUv1; attribute vec2 aUv2; attribute vec2 aUv3; attribute vec2 aUv4; attribute vec2 aUv5; varying vec3 vPosition; varying vec3 vNormal; varying vec2 vTexCoord; uniform mat4 uModelMatrix; uniform mat4 uViewMatrix; uniform mat4 uProjMatrix; uniform bool uHasUv2; void main(void) { gl_Position = uProjMatrix * uViewMatrix * uModelMatrix * vec4(aPosition, 1); vPosition = (uViewMatrix * uModelMatrix * vec4(aPosition, 1)).xyz; vNormal = mat3(uViewMatrix * uModelMatrix) * aNormal; if (uHasUv2) { vTexCoord = aUv2; } else { vTexCoord = aUv1; } }";
  13286. ZamModelViewer.Heroes.Model.prototype.fragShader = " precision mediump float; varying vec3 vPosition; varying vec3 vNormal; varying vec2 vTexCoord; uniform int uBlendMode; uniform bool uHasDiffuse; uniform bool uHasDiffuseAlpha; uniform sampler2D uDiffuse; uniform sampler2D uDiffuseAlpha; uniform vec3 uLightDir1; uniform vec3 uLightDir2; uniform vec3 uLightDir3; uniform vec4 uLightIntensity; uniform vec3 uCameraPos; vec3 saturate(vec3 value) { return clamp(value, 0.0, 1.0); } float saturate(float value) { return clamp(value, 0.0, 1.0); } void main(void) { vec4 color = vec4(1, 0, 1, 1); if (uHasDiffuse) { color.rgb = texture2D(uDiffuse, vTexCoord).rgb; } if ((uBlendMode == 1 || uBlendMode == 3 || uBlendMode == 6) && uHasDiffuseAlpha) { color.a = texture2D(uDiffuseAlpha, vTexCoord).r; } vec3 normal = normalize(vNormal); vec3 cameraDir = normalize(uCameraPos - vPosition); vec3 litColor = color.rgb * uLightIntensity.a; float facing = (-1.0 + 2.0 * float(gl_FrontFacing)) * -1.0; float NdotL = saturate(dot(normal, uLightDir1) * facing); litColor += color.rgb * NdotL * uLightIntensity.x; NdotL = saturate(dot(normal, uLightDir2) * facing); litColor += color.rgb * NdotL * uLightIntensity.y; NdotL = saturate(dot(normal, uLightDir3) * facing); litColor += color.rgb * NdotL * uLightIntensity.z; color.rgb = saturate(litColor); gl_FragColor = color; }";
  13287. ZamModelViewer.Heroes.Vertex = function(r, uv2, uv3, uv4, uv5) {
  13288. var self = this;
  13289. self.position = [r.getFloat(), r.getFloat(), r.getFloat()];
  13290. self.weights = [r.getUint8(), r.getUint8(), r.getUint8(), r.getUint8()];
  13291. self.bones = [r.getUint8(), r.getUint8(), r.getUint8(), r.getUint8()];
  13292. self.normal = [r.getFloat(), r.getFloat(), r.getFloat(), r.getFloat()];
  13293. self.tangent = [r.getFloat(), r.getFloat(), r.getFloat(), r.getFloat()];
  13294. self.uv1 = {
  13295. u: r.getFloat(),
  13296. v: r.getFloat()
  13297. };
  13298. if (uv2) self.uv2 = {
  13299. u: r.getFloat(),
  13300. v: r.getFloat()
  13301. };
  13302. if (uv3) self.uv3 = {
  13303. u: r.getFloat(),
  13304. v: r.getFloat()
  13305. };
  13306. if (uv4) self.uv4 = {
  13307. u: r.getFloat(),
  13308. v: r.getFloat()
  13309. };
  13310. if (uv5) self.uv5 = {
  13311. u: r.getFloat(),
  13312. v: r.getFloat()
  13313. };
  13314. self.transPosition = vec3.clone(self.position);
  13315. self.transNormal = vec4.clone(self.normal)
  13316. };
  13317. ZamModelViewer.Heroes.Vertex.prototype = {
  13318. destroy: function() {
  13319. var self = this;
  13320. self.position = null;
  13321. self.weights = null;
  13322. self.bones = null;
  13323. self.normal = null;
  13324. self.tangent = null;
  13325. self.uv1 = self.uv2 = self.uv3 = self.uv4 = self.uv5 = null;
  13326. self.transPosition = null;
  13327. self.transNormal = null
  13328. }
  13329. };
  13330. ZamModelViewer.Heroes.Material = function(model, r) {
  13331. var self = this,
  13332. M = ZamModelViewer.Heroes.Material;
  13333. self.model = model;
  13334. self.name = r.getString();
  13335. self.flags = r.getUint32();
  13336. self.blendMode = r.getUint32();
  13337. self.priority = r.getUint32();
  13338. self.specularity = r.getFloat();
  13339. self.cutoutThreshold = r.getUint32();
  13340. self.specularMultiplier = r.getFloat();
  13341. self.emissiveMultiplier = r.getFloat();
  13342. self.layerBlend = r.getUint32();
  13343. self.emissiveBlend = r.getUint32();
  13344. self.specularType = r.getUint32();
  13345. var numTextures = 0;
  13346. if (model.meta && model.meta.Textures) numTextures = model.meta.Textures.length;
  13347. var numLayers = r.getInt32();
  13348. self.layers = new Array(numLayers);
  13349. for (var i = 0; i < numLayers; ++i) {
  13350. var l = self.layers[i] = new M.Layer(r);
  13351. if (l.path) {
  13352. if (M.overrides[model.model] && M.overrides[model.model][self.name] && M.overrides[model.model][self.name][i]) {
  13353. l.path = M.overrides[model.model][self.name][i];
  13354. if (!model.parent) {
  13355. l.texture = self.getTexture(l.path)
  13356. }
  13357. } else if (i == M.Layer.Diffuse) {
  13358. for (var j = 0; j < numTextures; ++j) {
  13359. if (model.meta.Textures[j].indexOf("_diff") > -1) {
  13360. l.path = model.meta.Textures[j];
  13361. break
  13362. }
  13363. }
  13364. if (!model.parent) {
  13365. l.texture = self.getTexture(l.path)
  13366. }
  13367. }
  13368. }
  13369. }
  13370. };
  13371. ZamModelViewer.Heroes.Material.overrides = {
  13372. novaultimatewhiteteal: {
  13373. Ultimate_Ponytail: {
  13374. 0: "storm_hero_novahairgrid_ultimate_blue_diff"
  13375. }
  13376. },
  13377. novaskinultimate: {
  13378. Ultimate_Ponytail: {
  13379. 0: "storm_hero_novahairgrid_ultimate_red_diff"
  13380. }
  13381. },
  13382. novaultimatewhitepink: {
  13383. Ultimate_Ponytail: {
  13384. 0: "storm_hero_novahairgrid_ultimate_pink_diff"
  13385. }
  13386. }
  13387. };
  13388. ZamModelViewer.Heroes.Material.blends = {
  13389. EyeLens: 6
  13390. };
  13391. ZamModelViewer.Heroes.Material.prototype = {
  13392. destroy: function() {
  13393. var self = this,
  13394. i;
  13395. if (self.layers) {
  13396. for (i = 0; i < self.layers.length; ++i) {
  13397. self.layers[i].destroy();
  13398. self.layers[i] = null
  13399. }
  13400. self.layers = null
  13401. }
  13402. self.model = null
  13403. },
  13404. bind: function(blend) {
  13405. var self = this,
  13406. gl = self.model.renderer.context,
  13407. M = ZamModelViewer.Heroes.Material;
  13408. if (M.blends[self.name]) blend = M.blends[self.name];
  13409. if (blend === null) blend = self.blendMode;
  13410. switch (blend) {
  13411. case 0:
  13412. gl.blendFunc(gl.ONE, gl.ZERO);
  13413. break;
  13414. case 1:
  13415. gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
  13416. break;
  13417. case 2:
  13418. gl.blendFunc(gl.SRC_COLOR, gl.ONE);
  13419. break;
  13420. case 3:
  13421. gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
  13422. break;
  13423. case 4:
  13424. case 5:
  13425. gl.blendFunc(gl.DST_COLOR, gl.SRC_COLOR);
  13426. break;
  13427. case 6:
  13428. gl.blendFunc(gl.ONE_MINUS_SRC_ALPHA, gl.SRC_ALPHA);
  13429. break;
  13430. default:
  13431. gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
  13432. break
  13433. }
  13434. if ((self.flags & 8) > 0) {
  13435. gl.disable(gl.CULL_FACE)
  13436. } else {
  13437. gl.enable(gl.CULL_FACE)
  13438. }
  13439. gl.uniform1i(self.model.uniforms.fBlendMode, blend);
  13440. var t = self.layers[M.Layer.Diffuse].texture;
  13441. if (t) {
  13442. if (t.texture) {
  13443. gl.bindTexture(gl.TEXTURE_2D, t.texture);
  13444. gl.uniform1i(self.model.uniforms.fHasDiffuse, true);
  13445. gl.uniform1i(self.model.uniforms.fDiffuse, 0)
  13446. } else {
  13447. gl.uniform1i(self.model.uniforms.fHasDiffuse, false)
  13448. }
  13449. if (t.alphaTexture) {
  13450. gl.activeTexture(gl.TEXTURE1);
  13451. gl.bindTexture(gl.TEXTURE_2D, t.alphaTexture);
  13452. gl.uniform1i(self.model.uniforms.fHasDiffuseAlpha, true);
  13453. gl.uniform1i(self.model.uniforms.fDiffuseAlpha, 1);
  13454. gl.activeTexture(gl.TEXTURE0)
  13455. } else {
  13456. gl.uniform1i(self.model.uniforms.fHasDiffuseAlpha, false)
  13457. }
  13458. } else {
  13459. gl.uniform1i(self.model.uniforms.fHasDiffuse, false);
  13460. gl.uniform1i(self.model.uniforms.fHasDiffuseAlpha, false)
  13461. }
  13462. },
  13463. getTexture: function(path) {
  13464. var self = this;
  13465. if (!self.model.textures[path]) {
  13466. self.model.textures[path] = new ZamModelViewer.Heroes.Texture(self.model, path + ".png")
  13467. }
  13468. return self.model.textures[path]
  13469. }
  13470. };
  13471. ZamModelViewer.Heroes.Material.Layer = function(r) {
  13472. var self = this;
  13473. self.path = r.getString();
  13474. self.color = r.getUint32();
  13475. self.flags = r.getUint32();
  13476. self.uvChannel = r.getUint32();
  13477. self.alphaFlags = r.getUint32();
  13478. self.uvAngle = [r.getFloat(), r.getFloat(), r.getFloat()];
  13479. self.uvTiling = [r.getFloat(), r.getFloat()];
  13480. self.brightness = r.getFloat();
  13481. self.tintStrenght = r.getFloat();
  13482. self.tintUnk1 = r.getFloat();
  13483. self.tintUnk2 = r.getFloat();
  13484. self.tintUnk3 = r.getFloat()
  13485. };
  13486. ZamModelViewer.Heroes.Material.Layer.Diffuse = 0;
  13487. ZamModelViewer.Heroes.Material.Layer.Emissive = 4;
  13488. ZamModelViewer.Heroes.Material.Layer.Normal = 10;
  13489. ZamModelViewer.Heroes.Material.Layer.prototype = {
  13490. destroy: function() {
  13491. var self = this;
  13492. if (self.texture) self.texture.destroy();
  13493. self.texture = null;
  13494. self.uvAngle = null;
  13495. self.uvTiling = null
  13496. }
  13497. };
  13498. ZamModelViewer.Heroes.Mesh = function(model, r) {
  13499. var self = this,
  13500. M = ZamModelViewer.Heroes.Mesh;
  13501. self.model = model;
  13502. self.materialId = r.getUint16();
  13503. self.vStart = r.getUint32();
  13504. self.vCount = r.getUint32();
  13505. self.iStart = r.getUint32();
  13506. self.iCount = r.getUint32();
  13507. self.numBones = r.getUint16();
  13508. self.boneIndex = r.getUint16();
  13509. self.rootBone = r.getUint16();
  13510. var indices = model.indices;
  13511. self.indices = new Array(self.iCount);
  13512. for (var i = 0; i < self.iCount; ++i) {
  13513. self.indices[i] = indices[self.iStart + i] + self.vStart
  13514. }
  13515. self.show = true;
  13516. self.material = model.getMaterial(self.materialId);
  13517. if (!self.material || (self.material.flags & 32) > 0) self.show = false;
  13518. if (M.blendOverrides[model.model] !== undefined) {
  13519. self.blendOverride = M.blendOverrides[model.model]
  13520. } else {
  13521. self.blendOverride = null
  13522. }
  13523. };
  13524. ZamModelViewer.Heroes.Mesh.blendOverrides = {
  13525. zagaraskininsectoid: 0,
  13526. zagarainsectoidblack: 0,
  13527. zagarainsectoidblue: 0
  13528. };
  13529. ZamModelViewer.Heroes.Mesh.hiddenMeshes = {
  13530. heroarthas: {
  13531. 3: true,
  13532. 4: true
  13533. },
  13534. arthasblue: {
  13535. 3: true,
  13536. 4: true
  13537. },
  13538. arthaswhite: {
  13539. 3: true,
  13540. 4: true
  13541. },
  13542. arthasskindragonbone: {
  13543. 4: true,
  13544. 5: true
  13545. },
  13546. arthasfrostwyrmgreen: {
  13547. 4: true,
  13548. 5: true
  13549. },
  13550. arthasfrostwyrmred: {
  13551. 4: true,
  13552. 5: true
  13553. },
  13554. arthasskinlichprince: {
  13555. 1: true,
  13556. 2: true,
  13557. 5: true
  13558. },
  13559. arthaslichprincegreen: {
  13560. 1: true,
  13561. 2: true,
  13562. 5: true
  13563. },
  13564. arthaslichprincepurple: {
  13565. 1: true,
  13566. 2: true,
  13567. 5: true
  13568. },
  13569. arthasskinultimate: {
  13570. 1: true,
  13571. 3: true,
  13572. 5: true
  13573. },
  13574. arthasultimategreen: {
  13575. 1: true,
  13576. 3: true,
  13577. 5: true
  13578. },
  13579. arthasultimatepink: {
  13580. 1: true,
  13581. 3: true,
  13582. 5: true
  13583. },
  13584. herozeratul: {
  13585. 0: true,
  13586. 4: true
  13587. },
  13588. zeratulargent: {
  13589. 0: true,
  13590. 4: true
  13591. },
  13592. zeratulgreen: {
  13593. 0: true,
  13594. 4: true
  13595. },
  13596. zeratulskinhightemplar: {
  13597. 0: true,
  13598. 3: true
  13599. },
  13600. zeratulhightemplarorange: {
  13601. 0: true,
  13602. 3: true
  13603. },
  13604. zeratulhightemplarwhite: {
  13605. 0: true,
  13606. 3: true
  13607. },
  13608. zeratulskinninja: {
  13609. 3: true,
  13610. 2: true
  13611. },
  13612. zeratulroninteal: {
  13613. 3: true,
  13614. 2: true
  13615. },
  13616. zeratulroninyellow: {
  13617. 3: true,
  13618. 2: true
  13619. },
  13620. zeratulskinultimate: {
  13621. 0: true,
  13622. 3: true
  13623. },
  13624. zeratulultimateblue: {
  13625. 0: true,
  13626. 3: true
  13627. },
  13628. zeratulultimatered: {
  13629. 0: true,
  13630. 3: true
  13631. },
  13632. heromurky: {
  13633. 1: true,
  13634. 2: true
  13635. },
  13636. murkyblue: {
  13637. 1: true,
  13638. 2: true
  13639. },
  13640. murkyorange: {
  13641. 1: true,
  13642. 2: true
  13643. },
  13644. murkyskingrunty: {
  13645. 1: true,
  13646. 4: true
  13647. },
  13648. murkygruntyblack: {
  13649. 1: true,
  13650. 4: true
  13651. },
  13652. murkygruntyred: {
  13653. 1: true,
  13654. 4: true
  13655. },
  13656. murkyskineaster: {
  13657. 1: true,
  13658. 3: true,
  13659. 4: true
  13660. },
  13661. murkyeasterwhite: {
  13662. 1: true,
  13663. 3: true,
  13664. 4: true
  13665. },
  13666. murkyeasterorange: {
  13667. 1: true,
  13668. 3: true,
  13669. 4: true
  13670. },
  13671. murkyskinultimate: {
  13672. 1: true,
  13673. 4: true
  13674. },
  13675. murkyultimateblue: {
  13676. 1: true,
  13677. 4: true
  13678. },
  13679. murkyultimateblack: {
  13680. 1: true,
  13681. 4: true
  13682. },
  13683. heromuradin: {
  13684. 0: true,
  13685. 1: true
  13686. },
  13687. muradiniron: {
  13688. 0: true,
  13689. 1: true
  13690. },
  13691. muradinred: {
  13692. 0: true,
  13693. 1: true
  13694. },
  13695. muradinskinkandyking: {
  13696. 0: true
  13697. },
  13698. muradinkandykingcaramel: {
  13699. 0: true
  13700. },
  13701. muradinkandykinggreen: {
  13702. 0: true
  13703. },
  13704. muradinskinmagni: {
  13705. 3: true
  13706. },
  13707. muradinmagniartic: {
  13708. 3: true
  13709. },
  13710. muradinmagnidarkiron: {
  13711. 3: true
  13712. },
  13713. muradinskinultimate: {
  13714. 1: true
  13715. },
  13716. muradinultimatedarkiron: {
  13717. 1: true
  13718. },
  13719. muradinultimatered: {
  13720. 1: true
  13721. },
  13722. herofalstad: {
  13723. 2: true
  13724. },
  13725. falstaddarkiron: {
  13726. 2: true
  13727. },
  13728. falstadnordic: {
  13729. 2: true
  13730. },
  13731. falstadskinultimate: {
  13732. 3: true
  13733. },
  13734. falstadultimatered: {
  13735. 3: true
  13736. },
  13737. falstadultimatewhite: {
  13738. 3: true
  13739. },
  13740. falstadstormlord: {
  13741. 2: true
  13742. },
  13743. falstadstormlorddarkiron: {
  13744. 2: true
  13745. },
  13746. falstadstormlordnordic: {
  13747. 2: true
  13748. },
  13749. zagaraskininsectoid: {
  13750. 0: true
  13751. },
  13752. zagarainsectoidblack: {
  13753. 0: true
  13754. },
  13755. zagarainsectoidblue: {
  13756. 0: true
  13757. },
  13758. tyrandeskinwarden: {
  13759. 2: true
  13760. },
  13761. tyrandewardenbloodelf: {
  13762. 2: true
  13763. },
  13764. tyrandewardenwhite: {
  13765. 2: true
  13766. },
  13767. herosylvanas: {
  13768. 2: true
  13769. },
  13770. sylvanasblue: {
  13771. 2: true
  13772. },
  13773. sylvanasred: {
  13774. 2: true
  13775. },
  13776. herojaina: {
  13777. 3: true
  13778. },
  13779. jainagreen: {
  13780. 3: true
  13781. },
  13782. jainablue: {
  13783. 3: true
  13784. },
  13785. herojainaskintempest: {
  13786. 4: true
  13787. },
  13788. jainatempestcrimson: {
  13789. 4: true
  13790. },
  13791. jainatempestjade: {
  13792. 4: true
  13793. },
  13794. herojainaskinultimate: {
  13795. 0: true
  13796. },
  13797. jainaultimatered: {
  13798. 0: true
  13799. },
  13800. jainaultimategray: {
  13801. 0: true
  13802. },
  13803. herobarbarian: {
  13804. 4: true
  13805. },
  13806. barbarianred: {
  13807. 4: true
  13808. },
  13809. barbarianblue: {
  13810. 4: true
  13811. },
  13812. barbarianwrathmodelfemale: {
  13813. 0: true
  13814. },
  13815. barbarianwrathfemalered: {
  13816. 0: true
  13817. },
  13818. barbarianwrathfemalepink: {
  13819. 0: true
  13820. },
  13821. herobarbarianultimatesonya: {
  13822. 5: true
  13823. },
  13824. sonyaultimatered: {
  13825. 5: true
  13826. },
  13827. sonyaultimatenordic: {
  13828. 5: true
  13829. },
  13830. tyrandeskinbloodelf: {
  13831. 0: true
  13832. },
  13833. tyrandebloodelfred: {
  13834. 0: true
  13835. },
  13836. tyrandebloodelfblue: {
  13837. 0: true
  13838. }
  13839. };
  13840. ZamModelViewer.Heroes.Mesh.prototype = {
  13841. destroy: function() {
  13842. var self = this,
  13843. gl = self.model.renderer.context;
  13844. if (self.ib) gl.deleteBuffer(self.ib);
  13845. self.ib = null;
  13846. self.indices = null;
  13847. self.model = null;
  13848. self.material = null
  13849. }
  13850. };
  13851. ZamModelViewer.Heroes.Mesh.prototype.draw = function() {
  13852. var self = this,
  13853. gl = self.model.renderer.context;
  13854. if (self.material) self.material.bind(self.blendOverride);
  13855. if (!self.ib) {
  13856. self.ib = gl.createBuffer();
  13857. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.ib);
  13858. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(self.indices), gl.STATIC_DRAW)
  13859. } else {
  13860. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.ib)
  13861. }
  13862. gl.drawElements(gl.TRIANGLES, self.iCount, gl.UNSIGNED_SHORT, 0)
  13863. };
  13864. ZamModelViewer.Heroes.Bone = function(model, index, r) {
  13865. var self = this,
  13866. H = ZamModelViewer.Heroes;
  13867. self.model = model;
  13868. self.index = index;
  13869. self.name = r.getString();
  13870. self.flags = r.getUint32();
  13871. self.parentId = r.getInt16();
  13872. self.translation = new H.AnimVec3(r);
  13873. self.rotation = new H.AnimQuaternion(r);
  13874. self.scale = new H.AnimVec3(r);
  13875. self.matrix = mat4.create();
  13876. self.tmpMat = mat4.create();
  13877. self.tmpVec = vec4.create();
  13878. self.tmpQuat = quat.create();
  13879. self.scaleLength = 0;
  13880. self.updated = false;
  13881. self.show = H.Bone.disabledBones[model.model] && H.Bone.disabledBones[model.model][self.name] ? false : true
  13882. };
  13883. ZamModelViewer.Heroes.Bone.disabledBones = {};
  13884. ZamModelViewer.Heroes.Bone.prototype = {
  13885. destroy: function() {
  13886. var self = this;
  13887. if (self.translation) self.translation.destroy();
  13888. if (self.rotation) self.rotation.destroy();
  13889. if (self.scale) self.scale.destroy();
  13890. self.translation = null;
  13891. self.rotation = null;
  13892. self.scale = null;
  13893. self.matrix = null;
  13894. self.tmpMat = null;
  13895. self.tmpVec = null;
  13896. self.tmpQuat = null;
  13897. self.model = null;
  13898. self.parent = null
  13899. }
  13900. };
  13901. ZamModelViewer.Heroes.Animation = function(index, r) {
  13902. var self = this;
  13903. self.index = index;
  13904. self.name = r.getString();
  13905. self.seqStart = r.getInt32();
  13906. self.seqEnd = r.getInt32();
  13907. self.flags = r.getUint32();
  13908. self.moveSpeed = r.getFloat();
  13909. self.frequency = r.getInt32();
  13910. self.replayStart = r.getInt32();
  13911. self.replayEnd = r.getInt32()
  13912. };
  13913. ZamModelViewer.Heroes.AnimData = function(r) {
  13914. var self = this,
  13915. H = ZamModelViewer.Heroes,
  13916. i;
  13917. self.name = r.getString();
  13918. self.index = r.getUint16();
  13919. self.index2 = r.getUint16();
  13920. var numAnimIds = r.getInt32();
  13921. self.animIds = new Array(numAnimIds);
  13922. for (i = 0; i < numAnimIds; ++i) self.animIds[i] = r.getUint32();
  13923. var numAnimIndices = r.getInt32();
  13924. self.animIndices = new Array(numAnimIndices);
  13925. for (i = 0; i < numAnimIndices; ++i) {
  13926. self.animIndices[i] = new H.AnimData.Index(r)
  13927. }
  13928. var numTranslations = r.getInt32();
  13929. self.translations = new Array(numTranslations);
  13930. for (i = 0; i < numTranslations; ++i) {
  13931. self.translations[i] = new H.AnimData.Vec3(r)
  13932. }
  13933. var numRotations = r.getInt32();
  13934. self.rotations = new Array(numRotations);
  13935. for (i = 0; i < numRotations; ++i) {
  13936. self.rotations[i] = new H.AnimData.Quaternion(r)
  13937. }
  13938. var numColors = r.getInt32();
  13939. self.colors = new Array(numColors);
  13940. for (i = 0; i < numColors; ++i) {
  13941. self.colors[i] = new H.AnimData.Color(r)
  13942. }
  13943. };
  13944. ZamModelViewer.Heroes.AnimData.prototype = {
  13945. destroy: function() {
  13946. var self = this,
  13947. i;
  13948. self.animIds = null;
  13949. if (self.animIndices)
  13950. for (i = 0; i < self.animIndices.length; ++i) self.animIndices[i] = null;
  13951. self.animIndices = null;
  13952. if (self.translations) {
  13953. for (i = 0; i < self.translations.length; ++i) {
  13954. self.translations[i].destroy();
  13955. self.translations[i] = null
  13956. }
  13957. self.translations = null
  13958. }
  13959. if (self.rotations) {
  13960. for (i = 0; i < self.rotations.length; ++i) {
  13961. self.rotations[i].destroy();
  13962. self.rotations[i] = null
  13963. }
  13964. self.rotations = null
  13965. }
  13966. if (self.colors) {
  13967. for (i = 0; i < self.colors.length; ++i) {
  13968. self.colors[i].destroy();
  13969. self.colors[i] = null
  13970. }
  13971. self.colors = null
  13972. }
  13973. }
  13974. };
  13975. ZamModelViewer.Heroes.AnimData.Index = function(r) {
  13976. var self = this;
  13977. self.animIndex = r.getUint16();
  13978. self.dataIndex = r.getUint16()
  13979. };
  13980. ZamModelViewer.Heroes.AnimData.Lookup = function(r) {
  13981. var self = this;
  13982. self.name = r.getString();
  13983. var numIndices = r.getInt32();
  13984. self.indices = new Array(numIndices);
  13985. for (var i = 0; i < numIndices; ++i) {
  13986. self.indices[i] = r.getUint32()
  13987. }
  13988. };
  13989. ZamModelViewer.Heroes.AnimData.Lookup.prototype = {
  13990. destroy: function() {
  13991. this.indices = null
  13992. }
  13993. };
  13994. ZamModelViewer.Heroes.AnimData.Base = function() {};
  13995. ZamModelViewer.Heroes.AnimData.Base.prototype = {
  13996. destroy: function() {
  13997. var self = this,
  13998. i;
  13999. self.timeline = null;
  14000. if (self.values) {
  14001. for (i = 0; i < self.values.length; ++i) {
  14002. self.values[i] = null
  14003. }
  14004. self.values = null
  14005. }
  14006. },
  14007. read: function(r) {
  14008. var self = this,
  14009. i;
  14010. var numTimes = r.getInt32();
  14011. self.timeline = new Array(numTimes);
  14012. for (i = 0; i < numTimes; ++i) {
  14013. self.timeline[i] = r.getInt32()
  14014. }
  14015. self.flags = r.getUint32();
  14016. self.length = r.getUint32();
  14017. var numValues = r.getInt32();
  14018. self.values = new Array(numValues);
  14019. for (i = 0; i < numValues; ++i) {
  14020. self.values[i] = self.readValue(r)
  14021. }
  14022. },
  14023. defaultValue: 0,
  14024. createValue: function() {
  14025. return this.defaultValue
  14026. },
  14027. setDefault: function(v) {
  14028. this.defaultValue = v
  14029. },
  14030. interpolate: function(v1, v2, r, result) {
  14031. result = v1 + (v2 - v1) * r;
  14032. return result
  14033. },
  14034. set: function(result, value) {
  14035. result = value;
  14036. return result
  14037. },
  14038. getDefault: function(r) {
  14039. r = this.defaultValue;
  14040. return r
  14041. },
  14042. readValue: function(r) {
  14043. return null
  14044. },
  14045. getValue: function(time, result) {
  14046. var self = this;
  14047. if (time > self.length) time %= self.length;
  14048. var lastIdx = 0,
  14049. numTimes = self.timeline.length - 1;
  14050. for (var i = 0; i < numTimes; ++i) {
  14051. if (self.timeline[i] < time) lastIdx = i;
  14052. else break
  14053. }
  14054. if (lastIdx < numTimes) {
  14055. var r = (time - self.timeline[lastIdx]) / (self.timeline[lastIdx + 1] - self.timeline[lastIdx]);
  14056. result = self.interpolate(self.values[lastIdx], self.values[lastIdx + 1], r, result)
  14057. } else {
  14058. result = self.set(result, self.values[lastIdx])
  14059. }
  14060. return result
  14061. }
  14062. };
  14063. ZamModelViewer.Heroes.AnimData.Vec3 = function(r) {
  14064. var self = this;
  14065. self.read(r)
  14066. };
  14067. ZamModelViewer.Heroes.AnimData.Vec3.prototype = new ZamModelViewer.Heroes.AnimData.Base;
  14068. ZamModelViewer.Heroes.AnimData.Vec3.prototype.constructor = ZamModelViewer.Heroes.AnimData.Vec3;
  14069. ZamModelViewer.Heroes.AnimData.Vec3.prototype.createValue = function() {
  14070. return vec3.clone(this.defaultValue);
  14071. };
  14072. ZamModelViewer.Heroes.AnimData.Vec3.prototype.defaultValue = vec3.create();
  14073. ZamModelViewer.Heroes.AnimData.Vec3.prototype.getDefault = function(result) {
  14074. vec3.copy(result, this.defaultValue);
  14075. return result
  14076. };
  14077. ZamModelViewer.Heroes.AnimData.Vec3.prototype.interpolate = function(v1, v2, r, result) {
  14078. return vec3.lerp(result, v1, v2, r)
  14079. };
  14080. ZamModelViewer.Heroes.AnimData.Vec3.prototype.set = function(result, value) {
  14081. vec3.copy(result, value);
  14082. return result
  14083. };
  14084. ZamModelViewer.Heroes.AnimData.Vec3.prototype.readValue = function(r) {
  14085. return vec3.set(vec3.create(), r.getFloat(), r.getFloat(), r.getFloat())
  14086. };
  14087. ZamModelViewer.Heroes.AnimData.Quaternion = function(r) {
  14088. var self = this;
  14089. self.read(r)
  14090. };
  14091. ZamModelViewer.Heroes.AnimData.Quaternion.prototype = new ZamModelViewer.Heroes.AnimData.Base;
  14092. ZamModelViewer.Heroes.AnimData.Quaternion.prototype.constructor = ZamModelViewer.Heroes.AnimData.Quaternion;
  14093. ZamModelViewer.Heroes.AnimData.Quaternion.prototype.createValue = function() {
  14094. return quat.clone(this.defaultValue)
  14095. };
  14096. ZamModelViewer.Heroes.AnimData.Quaternion.prototype.defaultValue = quat.create();
  14097. ZamModelViewer.Heroes.AnimData.Quaternion.prototype.getDefault = function(result) {
  14098. quat.copy(result, this.defaultValue);
  14099. return result
  14100. };
  14101. ZamModelViewer.Heroes.AnimData.Quaternion.prototype.interpolate = function(v1, v2, r, result) {
  14102. return quat.slerp(result, v1, v2, r)
  14103. };
  14104. ZamModelViewer.Heroes.AnimData.Quaternion.prototype.set = function(result, value) {
  14105. quat.copy(result, value);
  14106. return result
  14107. };
  14108. ZamModelViewer.Heroes.AnimData.Quaternion.prototype.readValue = function(r) {
  14109. return quat.set(quat.create(), r.getFloat(), r.getFloat(), r.getFloat(), r.getFloat())
  14110. };
  14111. ZamModelViewer.Heroes.AnimData.Color = function(r) {
  14112. var self = this;
  14113. self.read(r)
  14114. };
  14115. ZamModelViewer.Heroes.AnimData.Color.prototype = new ZamModelViewer.Heroes.AnimData.Base;
  14116. ZamModelViewer.Heroes.AnimData.Color.prototype.constructor = ZamModelViewer.Heroes.AnimData.Color;
  14117. ZamModelViewer.Heroes.AnimData.Color.prototype.createValue = function() {
  14118. return vec4.clone(this.defaultValue)
  14119. };
  14120. ZamModelViewer.Heroes.AnimData.Color.prototype.defaultValue = vec4.create();
  14121. ZamModelViewer.Heroes.AnimData.Color.prototype.getDefault = function(result) {
  14122. vec4.copy(result, this.defaultValue);
  14123. return result
  14124. };
  14125. ZamModelViewer.Heroes.AnimData.Color.prototype.interpolate = function(v1, v2, r, result) {
  14126. return vec4.lerp(result, v1, v2, r)
  14127. };
  14128. ZamModelViewer.Heroes.AnimData.Color.prototype.set = function(result, value) {
  14129. vec4.copy(result, value);
  14130. return result
  14131. };
  14132. ZamModelViewer.Heroes.AnimData.Color.prototype.readValue = function(r) {
  14133. return vec4.set(vec4.create(), r.getFloat(), r.getFloat(), r.getFloat(), r.getFloat())
  14134. };
  14135. ZamModelViewer.Heroes.AnimReference = function() {};
  14136. ZamModelViewer.Heroes.AnimReference.prototype = {
  14137. read: function(r) {
  14138. var self = this;
  14139. self.flags = r.getUint16();
  14140. self.animFlags = r.getUint16();
  14141. self.animId = r.getUint32()
  14142. }
  14143. };
  14144. ZamModelViewer.Heroes.AnimVec3 = function(r) {
  14145. var self = this;
  14146. self.read(r);
  14147. self.value = [r.getFloat(), r.getFloat(), r.getFloat()]
  14148. };
  14149. ZamModelViewer.Heroes.AnimVec3.prototype = new ZamModelViewer.Heroes.AnimReference;
  14150. ZamModelViewer.Heroes.AnimVec3.prototype.constructor = ZamModelViewer.Heroes.AnimVec3;
  14151. ZamModelViewer.Heroes.AnimQuaternion = function(r) {
  14152. var self = this;
  14153. self.read(r);
  14154. self.value = [r.getFloat(), r.getFloat(), r.getFloat(), r.getFloat()]
  14155. };
  14156. ZamModelViewer.Heroes.AnimQuaternion.prototype = new ZamModelViewer.Heroes.AnimReference;
  14157. ZamModelViewer.Heroes.AnimQuaternion.prototype.constructor = ZamModelViewer.Heroes.AnimQuaternion;
  14158. ZamModelViewer.Heroes.Texture = function(model, url) {
  14159. var self = this;
  14160. self.model = model;
  14161. self.url = model.opts.contentPath + "textures/" + url;
  14162. if (model.opts.cacheBuster) {
  14163. self.url += "?" + model.opts.cacheBuster
  14164. } else {
  14165. self.url += "?1"
  14166. }
  14167. self.alphaUrl = self.url.replace(".png", ".alpha.png");
  14168. self.texture = null;
  14169. self.alphaTexture = null;
  14170. self.load()
  14171. };
  14172. ZamModelViewer.Heroes.Texture.prototype = {
  14173. destroy: function() {
  14174. var self = this,
  14175. gl = self.model.renderer.context;
  14176. if (self.texture) gl.deleteTexture(self.texture);
  14177. if (self.alphaTexture) gl.deleteTexture(self.alphaTexture);
  14178. self.texture = null;
  14179. self.alphatexture = null;
  14180. self.img = null;
  14181. self.alphaImg = null;
  14182. self.model = null
  14183. },
  14184. load: function() {
  14185. var self = this,
  14186. gl = self.model.renderer.context;
  14187. (function(self, gl) {
  14188. self.img = new Image;
  14189. self.img.crossOrigin = "";
  14190. self.img.onload = function() {
  14191. self.img.loaded = true;
  14192. self.texture = gl.createTexture();
  14193. gl.bindTexture(gl.TEXTURE_2D, self.texture);
  14194. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, self.img);
  14195. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
  14196. };
  14197. self.img.onerror = function() {
  14198. self.img = null;
  14199. self.error = true
  14200. };
  14201. self.img.src = self.url;
  14202. self.alphaImg = new Image;
  14203. self.alphaImg.crossOrigin = "";
  14204. self.alphaImg.onload = function() {
  14205. self.alphaImg.loaded = true;
  14206. self.alphaTexture = gl.createTexture();
  14207. gl.bindTexture(gl.TEXTURE_2D, self.alphaTexture);
  14208. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, self.alphaImg);
  14209. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
  14210. };
  14211. self.alphaImg.onerror = function() {
  14212. self.alphaImg = null
  14213. };
  14214. self.alphaImg.src = self.alphaUrl
  14215. })(self, gl)
  14216. }
  14217. };
Add Comment
Please, Sign In to add comment