/src/away3d/loaders/parsers/Max3DSParser.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 885 lines · 654 code · 145 blank · 86 comment · 91 complexity · e48612e1f5fcfffa1f168190495b02ca MD5 · raw file

  1. package away3d.loaders.parsers
  2. {
  3. import away3d.*;
  4. import away3d.containers.*;
  5. import away3d.core.base.*;
  6. import away3d.entities.*;
  7. import away3d.library.assets.*;
  8. import away3d.loaders.misc.*;
  9. import away3d.loaders.parsers.utils.*;
  10. import away3d.materials.*;
  11. import away3d.materials.utils.*;
  12. import away3d.textures.*;
  13. import away3d.tools.utils.*;
  14. import flash.geom.*;
  15. import flash.net.*;
  16. import flash.utils.*;
  17. use namespace arcane;
  18. /**
  19. * Max3DSParser provides a parser for the 3ds data type.
  20. */
  21. public class Max3DSParser extends ParserBase
  22. {
  23. private var _byteData:ByteArray;
  24. private var _textures:Object;
  25. private var _materials:Object;
  26. private var _unfinalized_objects:Object;
  27. private var _cur_obj_end:uint;
  28. private var _cur_obj:ObjectVO;
  29. private var _cur_mat_end:uint;
  30. private var _cur_mat:MaterialVO;
  31. private var _useSmoothingGroups:Boolean;
  32. /**
  33. * Creates a new <code>Max3DSParser</code> object.
  34. *
  35. * @param useSmoothingGroups Determines whether the parser looks for smoothing groups in the 3ds file or assumes uniform smoothing. Defaults to true.
  36. */
  37. public function Max3DSParser(useSmoothingGroups:Boolean = true)
  38. {
  39. super(ParserDataFormat.BINARY);
  40. _useSmoothingGroups = useSmoothingGroups;
  41. }
  42. /**
  43. * Indicates whether or not a given file extension is supported by the parser.
  44. * @param extension The file extension of a potential file to be parsed.
  45. * @return Whether or not the given file type is supported.
  46. */
  47. public static function supportsType(extension:String):Boolean
  48. {
  49. extension = extension.toLowerCase();
  50. return extension == "3ds";
  51. }
  52. /**
  53. * Tests whether a data block can be parsed by the parser.
  54. * @param data The data block to potentially be parsed.
  55. * @return Whether or not the given data is supported.
  56. */
  57. public static function supportsData(data:*):Boolean
  58. {
  59. var ba:ByteArray;
  60. ba = ParserUtil.toByteArray(data);
  61. if (ba) {
  62. ba.position = 0;
  63. if (ba.readShort() == 0x4d4d)
  64. return true;
  65. }
  66. return false;
  67. }
  68. /**
  69. * @inheritDoc
  70. */
  71. arcane override function resolveDependency(resourceDependency:ResourceDependency):void
  72. {
  73. if (resourceDependency.assets.length == 1) {
  74. var asset:IAsset;
  75. asset = resourceDependency.assets[0];
  76. if (asset.assetType == AssetType.TEXTURE) {
  77. var tex:TextureVO;
  78. tex = _textures[resourceDependency.id];
  79. tex.texture = asset as Texture2DBase;
  80. }
  81. }
  82. }
  83. /**
  84. * @inheritDoc
  85. */
  86. arcane override function resolveDependencyFailure(resourceDependency:ResourceDependency):void
  87. {
  88. // TODO: Implement
  89. }
  90. /**
  91. * @inheritDoc
  92. */
  93. protected override function startParsing(frameLimit:Number):void
  94. {
  95. super.startParsing(frameLimit);
  96. _byteData = ParserUtil.toByteArray(_data);
  97. _byteData.position = 0;
  98. _byteData.endian = Endian.LITTLE_ENDIAN;
  99. _textures = {};
  100. _materials = {};
  101. _unfinalized_objects = {};
  102. }
  103. /**
  104. * @inheritDoc
  105. */
  106. protected override function proceedParsing():Boolean
  107. {
  108. // TODO: With this construct, the loop will run no-op for as long
  109. // as there is time once file has finished reading. Consider a nice
  110. // way to stop loop when byte array is empty, without putting it in
  111. // the while-conditional, which will prevent finalizations from
  112. // happening after the last chunk.
  113. while (hasTime()) {
  114. // If we are currently working on an object, and the most recent chunk was
  115. // the last one in that object, finalize the current object.
  116. if (_cur_mat && _byteData.position >= _cur_mat_end)
  117. finalizeCurrentMaterial();
  118. else if (_cur_obj && _byteData.position >= _cur_obj_end) {
  119. // Can't finalize at this point, because we have to wait until the full
  120. // animation section has been parsed for any potential pivot definitions
  121. _unfinalized_objects[_cur_obj.name] = _cur_obj;
  122. _cur_obj_end = uint.MAX_VALUE;
  123. _cur_obj = null;
  124. }
  125. if (_byteData.bytesAvailable) {
  126. var cid:uint;
  127. var len:uint;
  128. var end:uint;
  129. cid = _byteData.readUnsignedShort();
  130. len = _byteData.readUnsignedInt();
  131. end = _byteData.position + (len - 6);
  132. switch (cid) {
  133. case 0x4D4D: // MAIN3DS
  134. case 0x3D3D: // EDIT3DS
  135. case 0xB000: // KEYF3DS
  136. // This types are "container chunks" and contain only
  137. // sub-chunks (no data on their own.) This means that
  138. // there is nothing more to parse at this point, and
  139. // instead we should progress to the next chunk, which
  140. // will be the first sub-chunk of this one.
  141. continue;
  142. break;
  143. case 0xAFFF: // MATERIAL
  144. _cur_mat_end = end;
  145. _cur_mat = parseMaterial();
  146. break;
  147. case 0x4000: // EDIT_OBJECT
  148. _cur_obj_end = end;
  149. _cur_obj = new ObjectVO();
  150. _cur_obj.name = readNulTermString();
  151. _cur_obj.materials = new Vector.<String>();
  152. _cur_obj.materialFaces = {};
  153. break;
  154. case 0x4100: // OBJ_TRIMESH
  155. _cur_obj.type = AssetType.MESH;
  156. break;
  157. case 0x4110: // TRI_VERTEXL
  158. parseVertexList();
  159. break;
  160. case 0x4120: // TRI_FACELIST
  161. parseFaceList();
  162. break;
  163. case 0x4140: // TRI_MAPPINGCOORDS
  164. parseUVList();
  165. break;
  166. case 0x4130: // Face materials
  167. parseFaceMaterialList();
  168. break;
  169. case 0x4160: // Transform
  170. _cur_obj.transform = readTransform();
  171. break;
  172. case 0xB002: // Object animation (including pivot)
  173. parseObjectAnimation(end);
  174. break;
  175. case 0x4150: // Smoothing groups
  176. parseSmoothingGroups();
  177. break;
  178. default:
  179. // Skip this (unknown) chunk
  180. _byteData.position += (len - 6);
  181. break;
  182. }
  183. // Pause parsing if there were any dependencies found during this
  184. // iteration (i.e. if there are any dependencies that need to be
  185. // retrieved at this time.)
  186. if (dependencies.length) {
  187. pauseAndRetrieveDependencies();
  188. break;
  189. }
  190. }
  191. }
  192. // More parsing is required if the entire byte array has not yet
  193. // been read, or if there is a currently non-finalized object in
  194. // the pipeline.
  195. if (_byteData.bytesAvailable || _cur_obj || _cur_mat)
  196. return MORE_TO_PARSE;
  197. else {
  198. var name:String;
  199. // Finalize any remaining objects before ending.
  200. for (name in _unfinalized_objects) {
  201. var obj:ObjectContainer3D;
  202. obj = constructObject(_unfinalized_objects[name]);
  203. if (obj)
  204. finalizeAsset(obj, name);
  205. }
  206. return PARSING_DONE;
  207. }
  208. }
  209. private function parseMaterial():MaterialVO
  210. {
  211. var mat:MaterialVO;
  212. mat = new MaterialVO();
  213. while (_byteData.position < _cur_mat_end) {
  214. var cid:uint;
  215. var len:uint;
  216. var end:uint;
  217. cid = _byteData.readUnsignedShort();
  218. len = _byteData.readUnsignedInt();
  219. end = _byteData.position + (len - 6);
  220. switch (cid) {
  221. case 0xA000: // Material name
  222. mat.name = readNulTermString();
  223. break;
  224. case 0xA010: // Ambient color
  225. mat.ambientColor = readColor();
  226. break;
  227. case 0xA020: // Diffuse color
  228. mat.diffuseColor = readColor();
  229. break;
  230. case 0xA030: // Specular color
  231. mat.specularColor = readColor();
  232. break;
  233. case 0xA081: // Two-sided, existence indicates "true"
  234. mat.twoSided = true;
  235. break;
  236. case 0xA200: // Main (color) texture
  237. mat.colorMap = parseTexture(end);
  238. break;
  239. case 0xA204: // Specular map
  240. mat.specularMap = parseTexture(end);
  241. break;
  242. default:
  243. _byteData.position = end;
  244. break;
  245. }
  246. }
  247. return mat;
  248. }
  249. private function parseTexture(end:uint):TextureVO
  250. {
  251. var tex:TextureVO;
  252. tex = new TextureVO();
  253. while (_byteData.position < end) {
  254. var cid:uint;
  255. var len:uint;
  256. cid = _byteData.readUnsignedShort();
  257. len = _byteData.readUnsignedInt();
  258. switch (cid) {
  259. case 0xA300:
  260. tex.url = readNulTermString();
  261. break;
  262. default:
  263. // Skip this unknown texture sub-chunk
  264. _byteData.position += (len - 6);
  265. break;
  266. }
  267. }
  268. _textures[tex.url] = tex;
  269. addDependency(tex.url, new URLRequest(tex.url));
  270. return tex;
  271. }
  272. private function parseVertexList():void
  273. {
  274. var i:uint;
  275. var len:uint;
  276. var count:uint;
  277. count = _byteData.readUnsignedShort();
  278. _cur_obj.verts = new Vector.<Number>(count*3, true);
  279. i = 0;
  280. len = _cur_obj.verts.length;
  281. while (i < len) {
  282. var x:Number, y:Number, z:Number;
  283. x = _byteData.readFloat();
  284. y = _byteData.readFloat();
  285. z = _byteData.readFloat();
  286. _cur_obj.verts[i++] = x;
  287. _cur_obj.verts[i++] = z;
  288. _cur_obj.verts[i++] = y;
  289. }
  290. }
  291. private function parseFaceList():void
  292. {
  293. var i:uint;
  294. var len:uint;
  295. var count:uint;
  296. count = _byteData.readUnsignedShort();
  297. _cur_obj.indices = new Vector.<uint>(count*3, true);
  298. i = 0;
  299. len = _cur_obj.indices.length;
  300. while (i < len) {
  301. var i0:uint, i1:uint, i2:uint;
  302. i0 = _byteData.readUnsignedShort();
  303. i1 = _byteData.readUnsignedShort();
  304. i2 = _byteData.readUnsignedShort();
  305. _cur_obj.indices[i++] = i0;
  306. _cur_obj.indices[i++] = i2;
  307. _cur_obj.indices[i++] = i1;
  308. // Skip "face info", irrelevant in Away3D
  309. _byteData.position += 2;
  310. }
  311. _cur_obj.smoothingGroups = new Vector.<uint>(count, true);
  312. }
  313. private function parseSmoothingGroups():void
  314. {
  315. var len:uint = _cur_obj.indices.length/3;
  316. var i:uint = 0;
  317. while (i < len) {
  318. _cur_obj.smoothingGroups[i] = _byteData.readUnsignedInt();
  319. i++;
  320. }
  321. }
  322. private function parseUVList():void
  323. {
  324. var i:uint;
  325. var len:uint;
  326. var count:uint;
  327. count = _byteData.readUnsignedShort();
  328. _cur_obj.uvs = new Vector.<Number>(count*2, true);
  329. i = 0;
  330. len = _cur_obj.uvs.length;
  331. while (i < len) {
  332. _cur_obj.uvs[i++] = _byteData.readFloat();
  333. _cur_obj.uvs[i++] = 1.0 - _byteData.readFloat();
  334. }
  335. }
  336. private function parseFaceMaterialList():void
  337. {
  338. var mat:String;
  339. var count:uint;
  340. var i:uint;
  341. var faces:Vector.<uint>;
  342. mat = readNulTermString();
  343. count = _byteData.readUnsignedShort();
  344. faces = new Vector.<uint>(count, true);
  345. i = 0;
  346. while (i < faces.length)
  347. faces[i++] = _byteData.readUnsignedShort();
  348. _cur_obj.materials.push(mat);
  349. _cur_obj.materialFaces[mat] = faces;
  350. }
  351. private function parseObjectAnimation(end:Number):void
  352. {
  353. var vo:ObjectVO;
  354. var obj:ObjectContainer3D;
  355. var pivot:Vector3D;
  356. var name:String;
  357. var hier:int;
  358. // Pivot defaults to origin
  359. pivot = new Vector3D;
  360. while (_byteData.position < end) {
  361. var cid:uint;
  362. var len:uint;
  363. cid = _byteData.readUnsignedShort();
  364. len = _byteData.readUnsignedInt();
  365. switch (cid) {
  366. case 0xb010: // Name/hierarchy
  367. name = readNulTermString();
  368. _byteData.position += 4;
  369. hier = _byteData.readShort();
  370. break;
  371. case 0xb013: // Pivot
  372. pivot.x = _byteData.readFloat();
  373. pivot.z = _byteData.readFloat();
  374. pivot.y = _byteData.readFloat();
  375. break;
  376. default:
  377. _byteData.position += (len - 6);
  378. break;
  379. }
  380. }
  381. // If name is "$$$DUMMY" this is an empty object (e.g. a container)
  382. // and will be ignored in this version of the parser
  383. // TODO: Implement containers in 3DS parser.
  384. if (name != '$$$DUMMY' && _unfinalized_objects.hasOwnProperty(name)) {
  385. vo = _unfinalized_objects[name];
  386. obj = constructObject(vo, pivot);
  387. if (obj)
  388. finalizeAsset(obj, vo.name);
  389. delete _unfinalized_objects[name];
  390. }
  391. }
  392. private function constructObject(obj:ObjectVO, pivot:Vector3D = null):ObjectContainer3D
  393. {
  394. if (obj.type == AssetType.MESH) {
  395. var i:uint;
  396. var subs:Vector.<ISubGeometry>;
  397. var geom:Geometry;
  398. var mat:MaterialBase;
  399. var mesh:Mesh;
  400. var mtx:Matrix3D;
  401. var vertices:Vector.<VertexVO>;
  402. var faces:Vector.<FaceVO>;
  403. if (obj.materials.length > 1)
  404. trace('The Away3D 3DS parser does not support multiple materials per mesh at this point.');
  405. // Ignore empty objects
  406. if (!obj.indices || obj.indices.length == 0)
  407. return null;
  408. vertices = new Vector.<VertexVO>(obj.verts.length/3, false);
  409. faces = new Vector.<FaceVO>(obj.indices.length/3, true);
  410. prepareData(vertices, faces, obj);
  411. if (_useSmoothingGroups)
  412. applySmoothGroups(vertices, faces);
  413. obj.verts = new Vector.<Number>(vertices.length*3, true);
  414. for (i = 0; i < vertices.length; i++) {
  415. obj.verts[i*3] = vertices[i].x;
  416. obj.verts[i*3 + 1] = vertices[i].y;
  417. obj.verts[i*3 + 2] = vertices[i].z;
  418. }
  419. obj.indices = new Vector.<uint>(faces.length*3, true);
  420. for (i = 0; i < faces.length; i++) {
  421. obj.indices[i*3] = faces[i].a;
  422. obj.indices[i*3 + 1] = faces[i].b;
  423. obj.indices[i*3 + 2] = faces[i].c;
  424. }
  425. if (obj.uvs) {
  426. // If the object had UVs to start with, use UVs generated by
  427. // smoothing group splitting algorithm. Otherwise those UVs
  428. // will be nonsense and should be skipped.
  429. obj.uvs = new Vector.<Number>(vertices.length*2, true);
  430. for (i = 0; i < vertices.length; i++) {
  431. obj.uvs[i*2] = vertices[i].u;
  432. obj.uvs[i*2 + 1] = vertices[i].v;
  433. }
  434. }
  435. geom = new Geometry();
  436. // Construct sub-geometries (potentially splitting buffers)
  437. // and add them to geometry.
  438. subs = GeomUtil.fromVectors(obj.verts, obj.indices, obj.uvs, null, null, null, null);
  439. for (i = 0; i < subs.length; i++)
  440. geom.subGeometries.push(subs[i]);
  441. if (obj.materials.length > 0) {
  442. var mname:String;
  443. mname = obj.materials[0];
  444. mat = _materials[mname].material;
  445. }
  446. // Apply pivot translation to geometry if a pivot was
  447. // found while parsing the keyframe chunk earlier.
  448. if (pivot) {
  449. if (obj.transform) {
  450. // If a transform was found while parsing the
  451. // object chunk, use it to find the local pivot vector
  452. var dat:Vector.<Number> = obj.transform.concat();
  453. dat[12] = 0;
  454. dat[13] = 0;
  455. dat[14] = 0;
  456. mtx = new Matrix3D(dat);
  457. pivot = mtx.transformVector(pivot);
  458. }
  459. pivot.scaleBy(-1);
  460. mtx = new Matrix3D();
  461. mtx.appendTranslation(pivot.x, pivot.y, pivot.z);
  462. geom.applyTransformation(mtx);
  463. }
  464. // Apply transformation to geometry if a transformation
  465. // was found while parsing the object chunk earlier.
  466. if (obj.transform) {
  467. mtx = new Matrix3D(obj.transform);
  468. mtx.invert();
  469. geom.applyTransformation(mtx);
  470. }
  471. // Final transform applied to geometry. Finalize the geometry,
  472. // which will no longer be modified after this point.
  473. finalizeAsset(geom, obj.name.concat('_geom'));
  474. // Build mesh and return it
  475. mesh = new Mesh(geom, mat);
  476. mesh.transform = new Matrix3D(obj.transform);
  477. return mesh;
  478. }
  479. // If reached, unknown
  480. return null;
  481. }
  482. private function prepareData(vertices:Vector.<VertexVO>, faces:Vector.<FaceVO>, obj:ObjectVO):void
  483. {
  484. // convert raw ObjectVO's data to structured VertexVO and FaceVO
  485. var i:int;
  486. var j:int;
  487. var k:int;
  488. var len:int = obj.verts.length;
  489. for (i = 0, j = 0, k = 0; i < len; ) {
  490. var v:VertexVO = new VertexVO;
  491. v.x = obj.verts[i++];
  492. v.y = obj.verts[i++];
  493. v.z = obj.verts[i++];
  494. if (obj.uvs) {
  495. v.u = obj.uvs[j++];
  496. v.v = obj.uvs[j++];
  497. }
  498. vertices[k++] = v;
  499. }
  500. len = obj.indices.length;
  501. for (i = 0, k = 0; i < len; ) {
  502. var f:FaceVO = new FaceVO();
  503. f.a = obj.indices[i++];
  504. f.b = obj.indices[i++];
  505. f.c = obj.indices[i++];
  506. f.smoothGroup = obj.smoothingGroups[k];
  507. faces[k++] = f;
  508. }
  509. }
  510. private function applySmoothGroups(vertices:Vector.<VertexVO>, faces:Vector.<FaceVO>):void
  511. {
  512. // clone vertices according to following rule:
  513. // clone if vertex's in faces from groups 1+2 and 3
  514. // don't clone if vertex's in faces from groups 1+2, 3 and 1+3
  515. var i:int;
  516. var j:int;
  517. var k:int;
  518. var l:int;
  519. var len:int;
  520. var numVerts:uint = vertices.length;
  521. var numFaces:uint = faces.length;
  522. // extract groups data for vertices
  523. var vGroups:Vector.<Vector.<uint>> = new Vector.<Vector.<uint>>(numVerts, true);
  524. for (i = 0; i < numVerts; i++)
  525. vGroups[i] = new Vector.<uint>;
  526. for (i = 0; i < numFaces; i++) {
  527. var face:FaceVO = FaceVO(faces[i]);
  528. for (j = 0; j < 3; j++) {
  529. var groups:Vector.<uint> = vGroups[(j == 0)? face.a : ((j == 1)? face.b : face.c)];
  530. var group:uint = face.smoothGroup;
  531. for (k = groups.length - 1; k >= 0; k--) {
  532. if ((group & groups[k]) > 0) {
  533. group |= groups[k];
  534. groups.splice(k, 1);
  535. k = groups.length - 1;
  536. }
  537. }
  538. groups.push(group);
  539. }
  540. }
  541. // clone vertices
  542. var vClones:Vector.<Vector.<uint>> = new Vector.<Vector.<uint>>(numVerts, true);
  543. for (i = 0; i < numVerts; i++) {
  544. if ((len = vGroups[i].length) < 1)
  545. continue;
  546. var clones:Vector.<uint> = new Vector.<uint>(len, true);
  547. vClones[i] = clones;
  548. clones[0] = i;
  549. var v0:VertexVO = vertices[i];
  550. for (j = 1; j < len; j++) {
  551. var v1:VertexVO = new VertexVO;
  552. v1.x = v0.x;
  553. v1.y = v0.y;
  554. v1.z = v0.z;
  555. v1.u = v0.u;
  556. v1.v = v0.v;
  557. clones[j] = vertices.length;
  558. vertices.push(v1);
  559. }
  560. }
  561. numVerts = vertices.length;
  562. for (i = 0; i < numFaces; i++) {
  563. face = FaceVO(faces[i]);
  564. group = face.smoothGroup;
  565. for (j = 0; j < 3; j++) {
  566. k = (j == 0)? face.a : ((j == 1)? face.b : face.c);
  567. groups = vGroups[k];
  568. len = groups.length;
  569. clones = vClones[k];
  570. for (l = 0; l < len; l++) {
  571. if (((group == 0) && (groups[l] == 0)) ||
  572. ((group & groups[l]) > 0)) {
  573. var index:uint = clones[l];
  574. if (group == 0) {
  575. // vertex is unique if no smoothGroup found
  576. groups.splice(l, 1);
  577. clones.splice(l, 1);
  578. }
  579. if (j == 0)
  580. face.a = index;
  581. else if (j == 1)
  582. face.b = index;
  583. else
  584. face.c = index;
  585. l = len;
  586. }
  587. }
  588. }
  589. }
  590. }
  591. private function finalizeCurrentMaterial():void
  592. {
  593. var mat:MaterialBase;
  594. if (materialMode < 2) {
  595. if (_cur_mat.colorMap)
  596. mat = new TextureMaterial(_cur_mat.colorMap.texture || DefaultMaterialManager.getDefaultTexture());
  597. else
  598. mat = new ColorMaterial(_cur_mat.diffuseColor);
  599. SinglePassMaterialBase(mat).ambientColor = _cur_mat.ambientColor;
  600. SinglePassMaterialBase(mat).specularColor = _cur_mat.specularColor;
  601. } else {
  602. if (_cur_mat.colorMap)
  603. mat = new TextureMultiPassMaterial(_cur_mat.colorMap.texture || DefaultMaterialManager.getDefaultTexture());
  604. else
  605. mat = new ColorMultiPassMaterial(_cur_mat.diffuseColor);
  606. MultiPassMaterialBase(mat).ambientColor = _cur_mat.ambientColor;
  607. MultiPassMaterialBase(mat).specularColor = _cur_mat.specularColor;
  608. }
  609. mat.bothSides = _cur_mat.twoSided;
  610. finalizeAsset(mat, _cur_mat.name);
  611. _materials[_cur_mat.name] = _cur_mat;
  612. _cur_mat.material = mat;
  613. _cur_mat = null;
  614. }
  615. private function readNulTermString():String
  616. {
  617. var chr:uint;
  618. var str:String = new String();
  619. while ((chr = _byteData.readUnsignedByte()) > 0)
  620. str += String.fromCharCode(chr);
  621. return str;
  622. }
  623. private function readTransform():Vector.<Number>
  624. {
  625. var data:Vector.<Number>;
  626. data = new Vector.<Number>(16, true);
  627. // X axis
  628. data[0] = _byteData.readFloat(); // X
  629. data[2] = _byteData.readFloat(); // Z
  630. data[1] = _byteData.readFloat(); // Y
  631. data[3] = 0;
  632. // Z axis
  633. data[8] = _byteData.readFloat(); // X
  634. data[10] = _byteData.readFloat(); // Z
  635. data[9] = _byteData.readFloat(); // Y
  636. data[11] = 0;
  637. // Y Axis
  638. data[4] = _byteData.readFloat(); // X
  639. data[6] = _byteData.readFloat(); // Z
  640. data[5] = _byteData.readFloat(); // Y
  641. data[7] = 0;
  642. // Translation
  643. data[12] = _byteData.readFloat(); // X
  644. data[14] = _byteData.readFloat(); // Z
  645. data[13] = _byteData.readFloat(); // Y
  646. data[15] = 1;
  647. return data;
  648. }
  649. private function readColor():uint
  650. {
  651. var cid:uint;
  652. var len:uint;
  653. var r:uint, g:uint, b:uint;
  654. cid = _byteData.readUnsignedShort();
  655. len = _byteData.readUnsignedInt();
  656. switch (cid) {
  657. case 0x0010: // Floats
  658. r = _byteData.readFloat()*255;
  659. g = _byteData.readFloat()*255;
  660. b = _byteData.readFloat()*255;
  661. break;
  662. case 0x0011: // 24-bit color
  663. r = _byteData.readUnsignedByte();
  664. g = _byteData.readUnsignedByte();
  665. b = _byteData.readUnsignedByte();
  666. break;
  667. default:
  668. _byteData.position += (len - 6);
  669. break;
  670. }
  671. return (r << 16) | (g << 8) | b;
  672. }
  673. }
  674. }
  675. import away3d.materials.MaterialBase;
  676. import away3d.textures.Texture2DBase;
  677. import flash.geom.Vector3D;
  678. internal class TextureVO
  679. {
  680. public var url:String;
  681. public var texture:Texture2DBase;
  682. public function TextureVO()
  683. {
  684. }
  685. }
  686. internal class MaterialVO
  687. {
  688. public var name:String;
  689. public var ambientColor:uint;
  690. public var diffuseColor:uint;
  691. public var specularColor:uint;
  692. public var twoSided:Boolean;
  693. public var colorMap:TextureVO;
  694. public var specularMap:TextureVO;
  695. public var material:MaterialBase;
  696. public function MaterialVO()
  697. {
  698. }
  699. }
  700. internal class ObjectVO
  701. {
  702. public var name:String;
  703. public var type:String;
  704. public var pivotX:Number;
  705. public var pivotY:Number;
  706. public var pivotZ:Number;
  707. public var transform:Vector.<Number>;
  708. public var verts:Vector.<Number>;
  709. public var indices:Vector.<uint>;
  710. public var uvs:Vector.<Number>;
  711. public var materialFaces:Object;
  712. public var materials:Vector.<String>;
  713. public var smoothingGroups:Vector.<uint>;
  714. public function ObjectVO()
  715. {
  716. }
  717. }
  718. internal class VertexVO
  719. {
  720. public var x:Number;
  721. public var y:Number;
  722. public var z:Number;
  723. public var u:Number;
  724. public var v:Number;
  725. public var normal:Vector3D;
  726. public var tangent:Vector3D;
  727. public function VertexVO()
  728. {
  729. }
  730. }
  731. internal class FaceVO
  732. {
  733. public var a:uint;
  734. public var b:uint;
  735. public var c:uint;
  736. public var smoothGroup:uint;
  737. public function FaceVO()
  738. {
  739. }
  740. }