AWDLoader.js 25 KB

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