AWDLoader.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227
  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 = new THREE.Loader();
  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.offsets.push({
  531. start: 0,
  532. index: 0,
  533. count: str_len/2
  534. });
  535. idx = 0;
  536. while (this._ptr < str_end) {
  537. buffer[idx+1] = this.readU16();
  538. buffer[idx] = this.readU16();
  539. buffer[idx+2] = this.readU16();
  540. idx+=3;
  541. }
  542. }
  543. // UVS
  544. // -------------------
  545. else if (str_type === 3) {
  546. buffer = new Float32Array( ( str_len / 8 ) * 2 );
  547. attrib = new THREE.BufferAttribute( buffer, 2 );
  548. geom.addAttribute( 'uv', attrib );
  549. idx = 0;
  550. while (this._ptr < str_end) {
  551. buffer[idx] = this.readF32();
  552. buffer[idx+1] = 1.0-this.readF32();
  553. idx+=2;
  554. }
  555. }
  556. // NORMALS
  557. else if (str_type === 4) {
  558. buffer = new Float32Array( ( str_len / 12 ) * 3 );
  559. attrib = new THREE.BufferAttribute( buffer, 3 );
  560. geom.addAttribute( 'normal', attrib );
  561. idx = 0;
  562. while (this._ptr < str_end) {
  563. buffer[idx] = -this.readF32();
  564. buffer[idx+1] = this.readF32();
  565. buffer[idx+2] = this.readF32();
  566. idx+=3;
  567. }
  568. }
  569. // else if (str_type == 6) {
  570. // skinI = new Float32Array( str_len>>1 );
  571. // idx = 0
  572. // while (this._ptr < str_end) {
  573. // skinI[idx] = this.readU16();
  574. // idx++;
  575. // }
  576. // }
  577. // else if (str_type == 7) {
  578. // skinW = new Float32Array( str_len>>2 );
  579. // idx = 0;
  580. // while (this._ptr < str_end) {
  581. // skinW[idx] = this.readF32();
  582. // idx++;
  583. // }
  584. // }
  585. else {
  586. this._ptr = str_end;
  587. }
  588. }
  589. this.parseUserAttributes();
  590. geom.computeBoundingSphere();
  591. subs_parsed++;
  592. }
  593. //geom.computeFaceNormals();
  594. this.parseUserAttributes();
  595. //finalizeAsset(geom, name);
  596. return geometries;
  597. }
  598. AWDLoader.prototype.parseMeshPoseAnimation = function(len, poseOnly)
  599. {
  600. var num_frames = 1,
  601. num_submeshes,
  602. frames_parsed,
  603. subMeshParsed,
  604. frame_dur,
  605. x, y, z,
  606. str_len,
  607. str_end,
  608. geom,
  609. subGeom,
  610. idx = 0,
  611. clip = {},
  612. indices,
  613. verts,
  614. num_Streams,
  615. streamsParsed,
  616. streamtypes = [],
  617. props,
  618. thisGeo,
  619. name = this.readUTF(),
  620. geoAdress = this.readU32();
  621. var mesh = this.getBlock( geoAdress );
  622. if (mesh == null) {
  623. console.log( "parseMeshPoseAnimation target mesh not found at:", geoAdress );
  624. return;
  625. }
  626. geom = mesh.geometry;
  627. geom.morphTargets = [];
  628. if (!poseOnly)
  629. num_frames = this.readU16();
  630. num_submeshes = this.readU16();
  631. num_Streams = this.readU16();
  632. // debug("VA num_frames : ", num_frames );
  633. // debug("VA num_submeshes : ", num_submeshes );
  634. // debug("VA numstreams : ", num_Streams );
  635. streamsParsed = 0;
  636. while (streamsParsed < num_Streams) {
  637. streamtypes.push(this.readU16());
  638. streamsParsed++;
  639. }
  640. props = this.parseProperties({1:BOOL, 2:BOOL});
  641. clip.looping = props.get(1, true);
  642. clip.stitchFinalFrame = props.get(2, false);
  643. frames_parsed = 0;
  644. while (frames_parsed < num_frames) {
  645. frame_dur = this.readU16();
  646. subMeshParsed = 0;
  647. while (subMeshParsed < num_submeshes) {
  648. streamsParsed = 0;
  649. str_len = this.readU32();
  650. str_end = this._ptr + str_len;
  651. while (streamsParsed < num_Streams) {
  652. if (streamtypes[streamsParsed] == 1) {
  653. //geom.addAttribute( 'morphTarget'+frames_parsed, Float32Array, str_len/12, 3 );
  654. var buffer = new Float32Array(str_len/4);
  655. geom.morphTargets.push( {
  656. array : buffer
  657. });
  658. //buffer = geom.attributes['morphTarget'+frames_parsed].array
  659. idx = 0;
  660. while ( this._ptr < str_end ) {
  661. buffer[idx] = this.readF32();
  662. buffer[idx+1] = this.readF32();
  663. buffer[idx+2] = this.readF32();
  664. idx += 3;
  665. }
  666. subMeshParsed++;
  667. } else
  668. this._ptr = str_end;
  669. streamsParsed++;
  670. }
  671. }
  672. frames_parsed++;
  673. }
  674. this.parseUserAttributes();
  675. return null;
  676. }
  677. AWDLoader.prototype.getBlock = function ( id ) {
  678. return this._blocks[id].data;
  679. },
  680. AWDLoader.prototype.parseMatrix4 = function ( ) {
  681. var mtx = new THREE.Matrix4();
  682. var e = mtx.elements;
  683. e[0] = this.readF32();
  684. e[1] = this.readF32();
  685. e[2] = this.readF32();
  686. e[3] = 0.0;
  687. //e[3] = 0.0;
  688. e[4] = this.readF32();
  689. e[5] = this.readF32();
  690. e[6] = this.readF32();
  691. //e[7] = this.readF32();
  692. e[7] = 0.0;
  693. e[8] = this.readF32();
  694. e[9] = this.readF32();
  695. e[10] = this.readF32();
  696. //e[11] = this.readF32();
  697. e[11] = 0.0;
  698. e[12] = -this.readF32();
  699. e[13] = this.readF32();
  700. e[14] = this.readF32();
  701. //e[15] = this.readF32();
  702. e[15] = 1.0;
  703. return mtx;
  704. }
  705. AWDLoader.prototype.parseProperties = function ( expected ) {
  706. var list_len = this.readU32();
  707. var list_end = this._ptr + list_len;
  708. var props = new AWDProperties();
  709. if( expected ) {
  710. while( this._ptr < list_end ) {
  711. var key = this.readU16();
  712. var len = this.readU32();
  713. var type;
  714. if( expected.hasOwnProperty( key ) ) {
  715. type = expected[ key ];
  716. props.set( key, this.parseAttrValue( type, len ) );
  717. } else {
  718. this._ptr += len;
  719. }
  720. }
  721. }
  722. return props;
  723. };
  724. AWDLoader.prototype.parseUserAttributes = function ( ) {
  725. // skip for now
  726. this._ptr = this.readU32() + this._ptr;
  727. return null;
  728. };
  729. AWDLoader.prototype.parseAttrValue = function ( type, len ) {
  730. var elem_len;
  731. var read_func;
  732. switch (type) {
  733. case AWD_FIELD_INT8:
  734. elem_len = 1;
  735. read_func = this.readI8;
  736. break;
  737. case AWD_FIELD_INT16:
  738. elem_len = 2;
  739. read_func = this.readI16;
  740. break;
  741. case AWD_FIELD_INT32:
  742. elem_len = 4;
  743. read_func = this.readI32;
  744. break;
  745. case AWD_FIELD_BOOL:
  746. case AWD_FIELD_UINT8:
  747. elem_len = 1;
  748. read_func = this.readU8;
  749. break;
  750. case AWD_FIELD_UINT16:
  751. elem_len = 2;
  752. read_func = this.readU16;
  753. break;
  754. case AWD_FIELD_UINT32:
  755. case AWD_FIELD_BADDR:
  756. elem_len = 4;
  757. read_func = this.readU32;
  758. break;
  759. case AWD_FIELD_FLOAT32:
  760. elem_len = 4;
  761. read_func = this.readF32;
  762. break;
  763. case AWD_FIELD_FLOAT64:
  764. elem_len = 8;
  765. read_func = this.readF64;
  766. break;
  767. case AWD_FIELD_VECTOR2x1:
  768. case AWD_FIELD_VECTOR3x1:
  769. case AWD_FIELD_VECTOR4x1:
  770. case AWD_FIELD_MTX3x2:
  771. case AWD_FIELD_MTX3x3:
  772. case AWD_FIELD_MTX4x3:
  773. case AWD_FIELD_MTX4x4:
  774. elem_len = 8;
  775. read_func = this.readF64;
  776. break;
  777. }
  778. if (elem_len < len) {
  779. var list;
  780. var num_read;
  781. var num_elems;
  782. list = [];
  783. num_read = 0;
  784. num_elems = len / elem_len;
  785. while (num_read < num_elems) {
  786. list.push(read_func.call( this ) );
  787. num_read++;
  788. }
  789. return list;
  790. }
  791. else {
  792. return read_func.call( this );
  793. }
  794. }
  795. AWDLoader.prototype.readU8 = function () {
  796. return this._data.getUint8( this._ptr++ );
  797. }
  798. AWDLoader.prototype.readI8 = function () {
  799. return this._data.getInt8( this._ptr++ );
  800. }
  801. AWDLoader.prototype.readU16 = function () {
  802. var a = this._data.getUint16( this._ptr, littleEndian );
  803. this._ptr += 2;
  804. return a;
  805. }
  806. AWDLoader.prototype.readI16 = function () {
  807. var a = this._data.getInt16( this._ptr, littleEndian );
  808. this._ptr += 2;
  809. return a;
  810. }
  811. AWDLoader.prototype.readU32 = function () {
  812. var a = this._data.getUint32( this._ptr, littleEndian );
  813. this._ptr += 4;
  814. return a;
  815. }
  816. AWDLoader.prototype.readI32 = function () {
  817. var a = this._data.getInt32( this._ptr, littleEndian );
  818. this._ptr += 4;
  819. return a;
  820. }
  821. AWDLoader.prototype.readF32 = function () {
  822. var a = this._data.getFloat32( this._ptr, littleEndian );
  823. this._ptr += 4;
  824. return a;
  825. }
  826. AWDLoader.prototype.readF64 = function () {
  827. var a = this._data.getFloat64( this._ptr, littleEndian );
  828. this._ptr += 8;
  829. return a;
  830. }
  831. /**
  832. * Converts a UTF-8 byte array to JavaScript's 16-bit Unicode.
  833. * @param {Array.<number>} bytes UTF-8 byte array.
  834. * @return {string} 16-bit Unicode string.
  835. */
  836. AWDLoader.prototype.readUTF = function () {
  837. var len = this.readU16();
  838. return this.readUTFBytes( len );
  839. };
  840. /**
  841. * Converts a UTF-8 byte array to JavaScript's 16-bit Unicode.
  842. * @param {Array.<number>} bytes UTF-8 byte array.
  843. * @return {string} 16-bit Unicode string.
  844. */
  845. AWDLoader.prototype.readUTFBytes = function ( len ) {
  846. // TODO(user): Use native implementations if/when available
  847. var out = [], c = 0;
  848. while ( out.length < len ) {
  849. var c1 = this._data.getUint8( this._ptr++, littleEndian );
  850. if (c1 < 128) {
  851. out[c++] = String.fromCharCode(c1);
  852. } else if (c1 > 191 && c1 < 224) {
  853. var c2 = this._data.getUint8( this._ptr++, littleEndian );
  854. out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63);
  855. } else {
  856. var c2 = this._data.getUint8( this._ptr++, littleEndian );
  857. var c3 = this._data.getUint8( this._ptr++, littleEndian );
  858. out[c++] = String.fromCharCode(
  859. (c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63
  860. );
  861. }
  862. }
  863. return out.join('');
  864. };
  865. AWDProperties = function(){}
  866. AWDProperties.prototype = {
  867. set : function(key, value)
  868. {
  869. this[key] = value;
  870. },
  871. get : function(key, fallback)
  872. {
  873. if ( this.hasOwnProperty(key) )
  874. return this[key];
  875. else return fallback;
  876. }
  877. }
  878. return AWDLoader;
  879. })();