AWDLoader.js 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222
  1. /**
  2. * Author: Pierre Lepers
  3. * Date: 09/12/2013 17:21
  4. */
  5. THREE.AWDLoader = (function () {
  6. var UNCOMPRESSED = 0,
  7. DEFLATE = 1,
  8. LZMA = 2,
  9. AWD_FIELD_INT8 = 1,
  10. AWD_FIELD_INT16 = 2,
  11. AWD_FIELD_INT32 = 3,
  12. AWD_FIELD_UINT8 = 4,
  13. AWD_FIELD_UINT16 = 5,
  14. AWD_FIELD_UINT32 = 6,
  15. AWD_FIELD_FLOAT32 = 7,
  16. AWD_FIELD_FLOAT64 = 8,
  17. AWD_FIELD_BOOL = 21,
  18. AWD_FIELD_COLOR = 22,
  19. AWD_FIELD_BADDR = 23,
  20. AWD_FIELD_STRING = 31,
  21. AWD_FIELD_BYTEARRAY = 32,
  22. AWD_FIELD_VECTOR2x1 = 41,
  23. AWD_FIELD_VECTOR3x1 = 42,
  24. AWD_FIELD_VECTOR4x1 = 43,
  25. AWD_FIELD_MTX3x2 = 44,
  26. AWD_FIELD_MTX3x3 = 45,
  27. AWD_FIELD_MTX4x3 = 46,
  28. AWD_FIELD_MTX4x4 = 47,
  29. BOOL = 21,
  30. COLOR = 22,
  31. BADDR = 23,
  32. INT8 = 1,
  33. INT16 = 2,
  34. INT32 = 3,
  35. UINT8 = 4,
  36. UINT16 = 5,
  37. UINT32 = 6,
  38. FLOAT32 = 7,
  39. FLOAT64 = 8;
  40. var littleEndian = true;
  41. // ResourcesLoader
  42. // =============
  43. // handle loading for external resources
  44. function ResourcesLoader( awdUrl ) {
  45. this._baseDir = awdUrl.substr( 0, awdUrl.lastIndexOf( '/' ) + 1 );
  46. this._loadingManager = new THREE.LoadingManager();
  47. }
  48. ResourcesLoader.prototype = {
  49. loadTexture : function( path ) {
  50. var tex = new THREE.Texture();
  51. var loader = new THREE.ImageLoader( this._loadingManager );
  52. loader.load( this._baseDir + path, function( image ) {
  53. tex.image = image;
  54. tex.needsUpdate = true;
  55. });
  56. return tex;
  57. }
  58. };
  59. function Block() {
  60. this.id = 0;
  61. this.data = null;
  62. }
  63. function AWDLoader( showStatus ) {
  64. THREE.Loader.call( this, showStatus );
  65. this.trunk = new THREE.Object3D();
  66. this.materialFactory = undefined;
  67. this._resourceLoader = null;
  68. this._url = '';
  69. this._data;
  70. this._ptr = 0;
  71. this._version = [];
  72. this._streaming = false;
  73. this._optimized_for_accuracy = false;
  74. this._compression = 0;
  75. this._bodylen = 0xFFFFFFFF;
  76. this._blocks = [ new Block() ];
  77. this._accuracyMatrix = false;
  78. this._accuracyGeo = false;
  79. this._accuracyProps = false;
  80. }
  81. AWDLoader.prototype = Object.create( THREE.Loader.prototype );
  82. AWDLoader.prototype.constructor = AWDLoader;
  83. AWDLoader.prototype.load = function ( url, callback ) {
  84. var that = this;
  85. this._url = url;
  86. var xhr = new XMLHttpRequest();
  87. xhr.open( "GET", url, true );
  88. xhr.responseType = 'arraybuffer';
  89. xhr.onreadystatechange = function () {
  90. if ( xhr.readyState == 4 ) {
  91. if ( xhr.status == 200 || xhr.status == 0 ) {
  92. that.parse( xhr.response );
  93. callback( that.trunk );
  94. } else {
  95. console.error( 'AWDLoader: Couldn\'t load ' + url + ' (' + xhr.status + ')' );
  96. }
  97. }
  98. };
  99. xhr.send( null );
  100. };
  101. AWDLoader.prototype.parse = function ( data ) {
  102. var blen = data.byteLength;
  103. this._ptr = 0;
  104. this._data = new DataView( data );
  105. this._parseHeader( );
  106. if ( this._compression != 0 ) {
  107. console.error( 'compressed AWD not supported' );
  108. }
  109. if (!this._streaming && this._bodylen != data.byteLength - this._ptr ) {
  110. console.error('AWDLoader: body len does not match file length', this._bodylen, blen - this._ptr);
  111. }
  112. while ( this._ptr < blen ) {
  113. this.parseNextBlock();
  114. }
  115. return this.trunk;
  116. };
  117. AWDLoader.prototype.parseNextBlock = function ( ) {
  118. var assetData,
  119. ns, type, len, block,
  120. blockId = this.readU32(),
  121. ns = this.readU8(),
  122. type = this.readU8(),
  123. flags = this.readU8(),
  124. len = this.readU32();
  125. switch (type) {
  126. case 1:
  127. assetData = this.parseMeshData(len);
  128. break;
  129. case 22:
  130. assetData = this.parseContainer(len);
  131. break;
  132. case 23:
  133. assetData = this.parseMeshInstance(len);
  134. break;
  135. case 81:
  136. assetData = this.parseMaterial(len);
  137. break;
  138. case 82:
  139. assetData = this.parseTexture(len);
  140. break;
  141. case 101:
  142. assetData = this.parseSkeleton(len);
  143. break;
  144. // case 111:
  145. // assetData = this.parseMeshPoseAnimation(len, true);
  146. // break;
  147. case 112:
  148. assetData = this.parseMeshPoseAnimation(len, false);
  149. break;
  150. case 113:
  151. assetData = this.parseVertexAnimationSet(len);
  152. break;
  153. case 102:
  154. assetData = this.parseSkeletonPose(len);
  155. break;
  156. case 103:
  157. assetData = this.parseSkeletonAnimation(len);
  158. break;
  159. case 122:
  160. assetData = this.parseAnimatorSet(len);
  161. break;
  162. // case 121:
  163. // assetData = parseUVAnimation(len);
  164. // break;
  165. default:
  166. //debug('Ignoring block!',type, len);
  167. this._ptr += len;
  168. break;
  169. }
  170. // Store block reference for later use
  171. this._blocks[blockId] = block = new Block();
  172. block.data = assetData;
  173. block.id = blockId;
  174. };
  175. AWDLoader.prototype._parseHeader = function () {
  176. var version = this._version,
  177. awdmagic =
  178. ( this.readU8()<<16)
  179. | ( this.readU8()<<8 )
  180. | this.readU8();
  181. if ( awdmagic != 4282180 )
  182. throw new Error( "AWDLoader - bad magic" );
  183. version[0] = this.readU8();
  184. version[1] = this.readU8();
  185. var flags = this.readU16();
  186. this._streaming = (flags & 0x1) == 0x1;
  187. if ((version[0] === 2) && (version[1] === 1)) {
  188. this._accuracyMatrix = (flags & 0x2) === 0x2;
  189. this._accuracyGeo = (flags & 0x4) === 0x4;
  190. this._accuracyProps = (flags & 0x8) === 0x8;
  191. }
  192. this._geoNrType = this._accuracyGeo ? FLOAT64 : FLOAT32;
  193. this._matrixNrType = this._accuracyMatrix ? FLOAT64 : FLOAT32;
  194. this._propsNrType = this._accuracyProps ? FLOAT64 : FLOAT32;
  195. this._optimized_for_accuracy = (flags & 0x2) === 0x2;
  196. this._compression = this.readU8();
  197. this._bodylen = this.readU32();
  198. };
  199. AWDLoader.prototype.parseContainer = function ( len ) {
  200. var parent,
  201. ctr = new THREE.Object3D(),
  202. par_id = this.readU32(),
  203. mtx = this.parseMatrix4();
  204. ctr.name = this.readUTF();
  205. ctr.applyMatrix( mtx );
  206. parent = this._blocks[par_id].data || this.trunk;
  207. parent.add(ctr);
  208. this.parseProperties({
  209. 1:this._matrixNrType,
  210. 2:this._matrixNrType,
  211. 3:this._matrixNrType,
  212. 4:UINT8
  213. });
  214. ctr.extra = this.parseUserAttributes();
  215. return ctr;
  216. };
  217. AWDLoader.prototype.parseMeshInstance = function ( len ) {
  218. var name,
  219. mesh, geometries, meshLen, meshes,
  220. par_id, data_id,
  221. mtx,
  222. materials, mat, mat_id,
  223. num_materials,
  224. materials_parsed,
  225. parent,
  226. i;
  227. par_id = this.readU32();
  228. mtx = this.parseMatrix4();
  229. name = this.readUTF();
  230. data_id = this.readU32();
  231. num_materials = this.readU16();
  232. geometries = this.getBlock( data_id );
  233. materials = [];
  234. materials_parsed = 0;
  235. for ( i = 0; i < num_materials; i ++) {
  236. mat_id = this.readU32();
  237. mat = this.getBlock( mat_id );
  238. materials.push( mat );
  239. }
  240. meshLen = geometries.length;
  241. meshes = [];
  242. // TODO : BufferGeometry don't support "geometryGroups" for now.
  243. // so we create sub meshes for each groups
  244. if ( meshLen > 1 ) {
  245. mesh = new THREE.Object3D();
  246. for ( i = 0; i < meshLen; i ++) {
  247. var sm = new THREE.Mesh( geometries[i] );
  248. meshes.push( sm );
  249. mesh.add( sm );
  250. }
  251. }
  252. else {
  253. mesh = new THREE.Mesh( geometries[0] );
  254. meshes.push( mesh );
  255. }
  256. mesh.applyMatrix( mtx );
  257. mesh.name = name;
  258. parent = this.getBlock( par_id ) || this.trunk;
  259. parent.add( mesh );
  260. var matLen = materials.length;
  261. var maxLen = Math.max( meshLen, matLen);
  262. for ( i = 0; i < maxLen; i ++ )
  263. meshes[ i%meshLen ].material = materials[ i % matLen ];
  264. // Ignore for now
  265. this.parseProperties( null );
  266. mesh.extra = this.parseUserAttributes();
  267. return mesh;
  268. };
  269. AWDLoader.prototype.parseMaterial = function ( len ) {
  270. var name,
  271. type,
  272. props,
  273. mat,
  274. attributes,
  275. finalize,
  276. num_methods,
  277. methods_parsed;
  278. name = this.readUTF();
  279. type = this.readU8();
  280. num_methods = this.readU8();
  281. //log( "AWDLoader parseMaterial ",name )
  282. // Read material numerical properties
  283. // (1=color, 2=bitmap url, 11=alpha_blending, 12=alpha_threshold, 13=repeat)
  284. props = this.parseProperties({
  285. 1: AWD_FIELD_INT32,
  286. 2: AWD_FIELD_BADDR,
  287. 11: AWD_FIELD_BOOL,
  288. 12: AWD_FIELD_FLOAT32,
  289. 13: AWD_FIELD_BOOL
  290. });
  291. methods_parsed = 0;
  292. while ( methods_parsed < num_methods ) {
  293. var method_type = this.readU16();
  294. this.parseProperties( null );
  295. this.parseUserAttributes();
  296. }
  297. attributes = this.parseUserAttributes();
  298. if ( this.materialFactory !== undefined ) {
  299. mat = this.materialFactory( name );
  300. if ( mat ) return mat;
  301. }
  302. mat = new THREE.MeshPhongMaterial();
  303. if (type === 1) { // Color material
  304. mat.color.setHex( props.get(1, 0xcccccc) );
  305. }
  306. else if (type === 2) { // Bitmap material
  307. var tex_addr = props.get(2, 0);
  308. mat.map = this.getBlock( tex_addr );
  309. }
  310. mat.extra = attributes;
  311. mat.alphaThreshold = props.get(12, 0.0);
  312. mat.repeat = props.get(13, false);
  313. return mat;
  314. };
  315. AWDLoader.prototype.parseTexture = function( len ) {
  316. var name = this.readUTF(),
  317. type = this.readU8(),
  318. asset,
  319. data_len;
  320. // External
  321. if (type === 0) {
  322. data_len = this.readU32();
  323. var url = this.readUTFBytes(data_len);
  324. console.log( url );
  325. asset = this.loadTexture( url );
  326. } else {
  327. // embed texture not supported
  328. }
  329. // Ignore for now
  330. this.parseProperties( null );
  331. this.parseUserAttributes();
  332. return asset;
  333. };
  334. AWDLoader.prototype.loadTexture = function( url ) {
  335. if ( null === this._resourceLoader )
  336. this._resourceLoader = new ResourcesLoader( this._url );
  337. return this._resourceLoader.loadTexture( url );
  338. };
  339. // broken : skeleton pose format is different than threejs one
  340. AWDLoader.prototype.parseSkeleton = function(len) // Array<Bone>
  341. {
  342. var name = this.readUTF(),
  343. num_joints = this.readU16(),
  344. skeleton = [],
  345. joints_parsed = 0;
  346. this.parseProperties( null );
  347. while (joints_parsed < num_joints) {
  348. var joint, ibp;
  349. // Ignore joint id
  350. this.readU16();
  351. joint = new THREE.Bone();
  352. joint.parent = this.readU16() - 1; // 0=null in AWD
  353. joint.name = this.readUTF();
  354. ibp = this.parseMatrix4();
  355. joint.skinMatrix = ibp;
  356. // Ignore joint props/attributes for now
  357. this.parseProperties(null);
  358. this.parseUserAttributes();
  359. skeleton.push(joint);
  360. joints_parsed ++;
  361. }
  362. // Discard attributes for now
  363. this.parseUserAttributes();
  364. return skeleton;
  365. };
  366. AWDLoader.prototype.parseSkeletonPose = function(blockID)
  367. {
  368. var name = this.readUTF();
  369. var num_joints = this.readU16();
  370. this.parseProperties(null);
  371. // debug( 'parse Skeleton Pose. joints : ' + num_joints);
  372. var pose = [];
  373. var joints_parsed = 0;
  374. while (joints_parsed < num_joints) {
  375. var joint_pose;
  376. var has_transform; //:uint;
  377. var mtx_data;
  378. has_transform = this.readU8();
  379. if (has_transform === 1) {
  380. mtx_data = this.parseMatrix4();
  381. } else
  382. {
  383. mtx_data = new THREE.Matrix4();
  384. }
  385. pose[joints_parsed] = mtx_data;
  386. joints_parsed ++;
  387. }
  388. // Skip attributes for now
  389. this.parseUserAttributes();
  390. return pose
  391. };
  392. AWDLoader.prototype.parseSkeletonAnimation = function(blockID)
  393. {
  394. var frame_dur;
  395. var pose_addr;
  396. var pose;
  397. var name = this.readUTF();
  398. var clip = [];
  399. var num_frames = this.readU16();
  400. this.parseProperties(null);
  401. var frames_parsed = 0;
  402. var returnedArray;
  403. // debug( 'parse Skeleton Animation. frames : ' + num_frames);
  404. while (frames_parsed < num_frames) {
  405. pose_addr = this.readU32();
  406. frame_dur = this.readU16();
  407. pose = this._blocks[pose_addr].data;
  408. // debug( 'pose address ',pose[2].elements[12],pose[2].elements[13],pose[2].elements[14] );
  409. clip.push( {
  410. pose : pose,
  411. duration : frame_dur
  412. } );
  413. frames_parsed ++;
  414. }
  415. if (clip.length == 0) {
  416. // debug("Could not this SkeletonClipNode, because no Frames where set.");
  417. return;
  418. }
  419. // Ignore attributes for now
  420. this.parseUserAttributes();
  421. return clip;
  422. };
  423. AWDLoader.prototype.parseVertexAnimationSet = function(len)
  424. {
  425. var poseBlockAdress,
  426. name = this.readUTF(),
  427. num_frames = this.readU16(),
  428. props = this.parseProperties({ 1:UINT16 }),
  429. frames_parsed = 0,
  430. skeletonFrames = [];
  431. while (frames_parsed < num_frames) {
  432. poseBlockAdress = this.readU32();
  433. skeletonFrames.push(this._blocks[poseBlockAdress].data);
  434. frames_parsed ++;
  435. }
  436. this.parseUserAttributes();
  437. return skeletonFrames;
  438. };
  439. AWDLoader.prototype.parseAnimatorSet = function(len)
  440. {
  441. var targetMesh;
  442. var animSetBlockAdress; //:int
  443. var targetAnimationSet; //:AnimationSetBase;
  444. var outputString = ""; //:String = "";
  445. var name = this.readUTF();
  446. var type = this.readU16();
  447. var props = this.parseProperties({ 1:BADDR });
  448. animSetBlockAdress = this.readU32();
  449. var targetMeshLength = this.readU16();
  450. var meshAdresses = []; //:Vector.<uint> = new Vector.<uint>;
  451. for (var i = 0; i < targetMeshLength; i ++)
  452. meshAdresses.push( this.readU32() );
  453. var activeState = this.readU16();
  454. var autoplay = Boolean(this.readU8());
  455. this.parseUserAttributes();
  456. this.parseUserAttributes();
  457. var returnedArray;
  458. var targetMeshes = []; //:Vector.<Mesh> = new Vector.<Mesh>;
  459. for (i = 0; i < meshAdresses.length; i ++) {
  460. // returnedArray = getAssetByID(meshAdresses[i], [AssetType.MESH]);
  461. // if (returnedArray[0])
  462. targetMeshes.push(this._blocks[meshAdresses[i]].data);
  463. }
  464. targetAnimationSet = this._blocks[animSetBlockAdress].data;
  465. var thisAnimator;
  466. if (type == 1) {
  467. thisAnimator = {
  468. animationSet : targetAnimationSet,
  469. skeleton : this._blocks[props.get(1, 0)].data
  470. };
  471. } else if (type == 2) {
  472. // debug( "vertex Anim???");
  473. }
  474. for (i = 0; i < targetMeshes.length; i ++) {
  475. targetMeshes[i].animator = thisAnimator;
  476. }
  477. // debug("Parsed a Animator: Name = " + name);
  478. return thisAnimator;
  479. };
  480. AWDLoader.prototype.parseMeshData = function ( len ) {
  481. var name = this.readUTF(),
  482. num_subs = this.readU16(),
  483. geom,
  484. subs_parsed = 0,
  485. props,
  486. buffer,
  487. skinW, skinI,
  488. geometries = [];
  489. props = this.parseProperties({
  490. 1: this._geoNrType,
  491. 2: this._geoNrType
  492. });
  493. // Loop through sub meshes
  494. while (subs_parsed < num_subs) {
  495. var sm_len, sm_end, attrib;
  496. geom = new THREE.BufferGeometry();
  497. geom.name = name;
  498. geometries.push( geom );
  499. sm_len = this.readU32();
  500. sm_end = this._ptr + sm_len;
  501. // Ignore for now
  502. this.parseProperties({ 1:this._geoNrType, 2:this._geoNrType });
  503. // Loop through data streams
  504. while ( this._ptr < sm_end ) {
  505. var idx = 0,
  506. str_type = this.readU8(),
  507. str_ftype = this.readU8(),
  508. str_len = this.readU32(),
  509. str_end = str_len + this._ptr;
  510. // VERTICES
  511. // ------------------
  512. if ( str_type === 1 ) {
  513. buffer = new Float32Array( ( str_len / 12 ) * 3 );
  514. attrib = new THREE.BufferAttribute( buffer, 3 );
  515. geom.addAttribute( 'position', attrib );
  516. idx = 0;
  517. while (this._ptr < str_end) {
  518. buffer[idx] = -this.readF32();
  519. buffer[idx + 1] = this.readF32();
  520. buffer[idx + 2] = this.readF32();
  521. idx+=3;
  522. }
  523. }
  524. // INDICES
  525. // -----------------
  526. else if (str_type === 2) {
  527. buffer = new Uint16Array( str_len / 2 );
  528. attrib = new THREE.BufferAttribute( buffer, 1 );
  529. geom.addAttribute( 'index', attrib );
  530. geom.addDrawCall( 0, str_len / 2, 0 );
  531. idx = 0;
  532. while (this._ptr < str_end) {
  533. buffer[idx + 1] = this.readU16();
  534. buffer[idx] = this.readU16();
  535. buffer[idx + 2] = this.readU16();
  536. idx+=3;
  537. }
  538. }
  539. // UVS
  540. // -------------------
  541. else if (str_type === 3) {
  542. buffer = new Float32Array( ( str_len / 8 ) * 2 );
  543. attrib = new THREE.BufferAttribute( buffer, 2 );
  544. geom.addAttribute( 'uv', attrib );
  545. idx = 0;
  546. while (this._ptr < str_end) {
  547. buffer[idx] = this.readF32();
  548. buffer[idx + 1] = 1.0 - this.readF32();
  549. idx+=2;
  550. }
  551. }
  552. // NORMALS
  553. else if (str_type === 4) {
  554. buffer = new Float32Array( ( str_len / 12 ) * 3 );
  555. attrib = new THREE.BufferAttribute( buffer, 3 );
  556. geom.addAttribute( 'normal', attrib );
  557. idx = 0;
  558. while (this._ptr < str_end) {
  559. buffer[idx] = -this.readF32();
  560. buffer[idx + 1] = this.readF32();
  561. buffer[idx + 2] = this.readF32();
  562. idx+=3;
  563. }
  564. }
  565. // else if (str_type == 6) {
  566. // skinI = new Float32Array( str_len>>1 );
  567. // idx = 0
  568. // while (this._ptr < str_end) {
  569. // skinI[idx] = this.readU16();
  570. // idx++;
  571. // }
  572. // }
  573. // else if (str_type == 7) {
  574. // skinW = new Float32Array( str_len>>2 );
  575. // idx = 0;
  576. // while (this._ptr < str_end) {
  577. // skinW[idx] = this.readF32();
  578. // idx++;
  579. // }
  580. // }
  581. else {
  582. this._ptr = str_end;
  583. }
  584. }
  585. this.parseUserAttributes();
  586. geom.computeBoundingSphere();
  587. subs_parsed ++;
  588. }
  589. //geom.computeFaceNormals();
  590. this.parseUserAttributes();
  591. //finalizeAsset(geom, name);
  592. return geometries;
  593. };
  594. AWDLoader.prototype.parseMeshPoseAnimation = function(len, poseOnly)
  595. {
  596. var num_frames = 1,
  597. num_submeshes,
  598. frames_parsed,
  599. subMeshParsed,
  600. frame_dur,
  601. x, y, z,
  602. str_len,
  603. str_end,
  604. geom,
  605. subGeom,
  606. idx = 0,
  607. clip = {},
  608. indices,
  609. verts,
  610. num_Streams,
  611. streamsParsed,
  612. streamtypes = [],
  613. props,
  614. thisGeo,
  615. name = this.readUTF(),
  616. geoAdress = this.readU32();
  617. var mesh = this.getBlock( geoAdress );
  618. if (mesh == null) {
  619. console.log( "parseMeshPoseAnimation target mesh not found at:", geoAdress );
  620. return;
  621. }
  622. geom = mesh.geometry;
  623. geom.morphTargets = [];
  624. if (!poseOnly)
  625. num_frames = this.readU16();
  626. num_submeshes = this.readU16();
  627. num_Streams = this.readU16();
  628. // debug("VA num_frames : ", num_frames );
  629. // debug("VA num_submeshes : ", num_submeshes );
  630. // debug("VA numstreams : ", num_Streams );
  631. streamsParsed = 0;
  632. while (streamsParsed < num_Streams) {
  633. streamtypes.push(this.readU16());
  634. streamsParsed ++;
  635. }
  636. props = this.parseProperties({ 1:BOOL, 2:BOOL });
  637. clip.looping = props.get(1, true);
  638. clip.stitchFinalFrame = props.get(2, false);
  639. frames_parsed = 0;
  640. while (frames_parsed < num_frames) {
  641. frame_dur = this.readU16();
  642. subMeshParsed = 0;
  643. while (subMeshParsed < num_submeshes) {
  644. streamsParsed = 0;
  645. str_len = this.readU32();
  646. str_end = this._ptr + str_len;
  647. while (streamsParsed < num_Streams) {
  648. if (streamtypes[streamsParsed] == 1) {
  649. //geom.addAttribute( 'morphTarget'+frames_parsed, Float32Array, str_len/12, 3 );
  650. var buffer = new Float32Array(str_len / 4);
  651. geom.morphTargets.push( {
  652. array : buffer
  653. });
  654. //buffer = geom.attributes['morphTarget'+frames_parsed].array
  655. idx = 0;
  656. while ( this._ptr < str_end ) {
  657. buffer[idx] = this.readF32();
  658. buffer[idx + 1] = this.readF32();
  659. buffer[idx + 2] = this.readF32();
  660. idx += 3;
  661. }
  662. subMeshParsed ++;
  663. } else
  664. this._ptr = str_end;
  665. streamsParsed ++;
  666. }
  667. }
  668. frames_parsed ++;
  669. }
  670. this.parseUserAttributes();
  671. return null;
  672. };
  673. AWDLoader.prototype.getBlock = function ( id ) {
  674. return this._blocks[id].data;
  675. },
  676. AWDLoader.prototype.parseMatrix4 = function ( ) {
  677. var mtx = new THREE.Matrix4();
  678. var e = mtx.elements;
  679. e[0] = this.readF32();
  680. e[1] = this.readF32();
  681. e[2] = this.readF32();
  682. e[3] = 0.0;
  683. //e[3] = 0.0;
  684. e[4] = this.readF32();
  685. e[5] = this.readF32();
  686. e[6] = this.readF32();
  687. //e[7] = this.readF32();
  688. e[7] = 0.0;
  689. e[8] = this.readF32();
  690. e[9] = this.readF32();
  691. e[10] = this.readF32();
  692. //e[11] = this.readF32();
  693. e[11] = 0.0;
  694. e[12] = -this.readF32();
  695. e[13] = this.readF32();
  696. e[14] = this.readF32();
  697. //e[15] = this.readF32();
  698. e[15] = 1.0;
  699. return mtx;
  700. };
  701. AWDLoader.prototype.parseProperties = function ( expected ) {
  702. var list_len = this.readU32();
  703. var list_end = this._ptr + list_len;
  704. var props = new AWDProperties();
  705. if ( expected ) {
  706. while ( this._ptr < list_end ) {
  707. var key = this.readU16();
  708. var len = this.readU32();
  709. var type;
  710. if ( expected.hasOwnProperty( key ) ) {
  711. type = expected[ key ];
  712. props.set( key, this.parseAttrValue( type, len ) );
  713. } else {
  714. this._ptr += len;
  715. }
  716. }
  717. }
  718. return props;
  719. };
  720. AWDLoader.prototype.parseUserAttributes = function ( ) {
  721. // skip for now
  722. this._ptr = this.readU32() + this._ptr;
  723. return null;
  724. };
  725. AWDLoader.prototype.parseAttrValue = function ( type, len ) {
  726. var elem_len;
  727. var read_func;
  728. switch (type) {
  729. case AWD_FIELD_INT8:
  730. elem_len = 1;
  731. read_func = this.readI8;
  732. break;
  733. case AWD_FIELD_INT16:
  734. elem_len = 2;
  735. read_func = this.readI16;
  736. break;
  737. case AWD_FIELD_INT32:
  738. elem_len = 4;
  739. read_func = this.readI32;
  740. break;
  741. case AWD_FIELD_BOOL:
  742. case AWD_FIELD_UINT8:
  743. elem_len = 1;
  744. read_func = this.readU8;
  745. break;
  746. case AWD_FIELD_UINT16:
  747. elem_len = 2;
  748. read_func = this.readU16;
  749. break;
  750. case AWD_FIELD_UINT32:
  751. case AWD_FIELD_BADDR:
  752. elem_len = 4;
  753. read_func = this.readU32;
  754. break;
  755. case AWD_FIELD_FLOAT32:
  756. elem_len = 4;
  757. read_func = this.readF32;
  758. break;
  759. case AWD_FIELD_FLOAT64:
  760. elem_len = 8;
  761. read_func = this.readF64;
  762. break;
  763. case AWD_FIELD_VECTOR2x1:
  764. case AWD_FIELD_VECTOR3x1:
  765. case AWD_FIELD_VECTOR4x1:
  766. case AWD_FIELD_MTX3x2:
  767. case AWD_FIELD_MTX3x3:
  768. case AWD_FIELD_MTX4x3:
  769. case AWD_FIELD_MTX4x4:
  770. elem_len = 8;
  771. read_func = this.readF64;
  772. break;
  773. }
  774. if (elem_len < len) {
  775. var list;
  776. var num_read;
  777. var num_elems;
  778. list = [];
  779. num_read = 0;
  780. num_elems = len / elem_len;
  781. while (num_read < num_elems) {
  782. list.push(read_func.call( this ) );
  783. num_read ++;
  784. }
  785. return list;
  786. }
  787. else {
  788. return read_func.call( this );
  789. }
  790. };
  791. AWDLoader.prototype.readU8 = function () {
  792. return this._data.getUint8( this._ptr ++ );
  793. };
  794. AWDLoader.prototype.readI8 = function () {
  795. return this._data.getInt8( this._ptr ++ );
  796. };
  797. AWDLoader.prototype.readU16 = function () {
  798. var a = this._data.getUint16( this._ptr, littleEndian );
  799. this._ptr += 2;
  800. return a;
  801. };
  802. AWDLoader.prototype.readI16 = function () {
  803. var a = this._data.getInt16( this._ptr, littleEndian );
  804. this._ptr += 2;
  805. return a;
  806. };
  807. AWDLoader.prototype.readU32 = function () {
  808. var a = this._data.getUint32( this._ptr, littleEndian );
  809. this._ptr += 4;
  810. return a;
  811. };
  812. AWDLoader.prototype.readI32 = function () {
  813. var a = this._data.getInt32( this._ptr, littleEndian );
  814. this._ptr += 4;
  815. return a;
  816. };
  817. AWDLoader.prototype.readF32 = function () {
  818. var a = this._data.getFloat32( this._ptr, littleEndian );
  819. this._ptr += 4;
  820. return a;
  821. };
  822. AWDLoader.prototype.readF64 = function () {
  823. var a = this._data.getFloat64( this._ptr, littleEndian );
  824. this._ptr += 8;
  825. return a;
  826. };
  827. /**
  828. * Converts a UTF-8 byte array to JavaScript's 16-bit Unicode.
  829. * @param {Array.<number>} bytes UTF-8 byte array.
  830. * @return {string} 16-bit Unicode string.
  831. */
  832. AWDLoader.prototype.readUTF = function () {
  833. var len = this.readU16();
  834. return this.readUTFBytes( len );
  835. };
  836. /**
  837. * Converts a UTF-8 byte array to JavaScript's 16-bit Unicode.
  838. * @param {Array.<number>} bytes UTF-8 byte array.
  839. * @return {string} 16-bit Unicode string.
  840. */
  841. AWDLoader.prototype.readUTFBytes = function ( len ) {
  842. // TODO(user): Use native implementations if/when available
  843. var out = [], c = 0;
  844. while ( out.length < len ) {
  845. var c1 = this._data.getUint8( this._ptr ++, littleEndian );
  846. if (c1 < 128) {
  847. out[c ++] = String.fromCharCode(c1);
  848. } else if (c1 > 191 && c1 < 224) {
  849. var c2 = this._data.getUint8( this._ptr ++, littleEndian );
  850. out[c ++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63);
  851. } else {
  852. var c2 = this._data.getUint8( this._ptr ++, littleEndian );
  853. var c3 = this._data.getUint8( this._ptr ++, littleEndian );
  854. out[c ++] = String.fromCharCode(
  855. (c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63
  856. );
  857. }
  858. }
  859. return out.join('');
  860. };
  861. AWDProperties = function() {};
  862. AWDProperties.prototype = {
  863. set : function(key, value)
  864. {
  865. this[key] = value;
  866. },
  867. get : function(key, fallback)
  868. {
  869. if ( this.hasOwnProperty(key) )
  870. return this[key];
  871. else return fallback;
  872. }
  873. };
  874. return AWDLoader;
  875. })();