AWDLoader.js 28 KB

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