AWDLoader.js 26 KB

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