PageRenderTime 2887ms CodeModel.GetById 19ms RepoModel.GetById 3ms app.codeStats 0ms

/sandy/as3/branches/1.5/sandy/util/_3ds/Parser3DS.as

http://sandy.googlecode.com/
ActionScript | 513 lines | 349 code | 104 blank | 60 comment | 18 complexity | 7778e35e73283cd1c05a0595e7749ae1 MD5 | raw file
  1. package sandy.util._3ds
  2. {
  3. import flash.display.Graphics;
  4. import flash.display.Sprite;
  5. import flash.events.*;
  6. import flash.geom.Matrix;
  7. import flash.net.FileReference;
  8. import flash.net.URLLoader;
  9. import flash.net.URLLoaderDataFormat;
  10. import flash.net.URLRequest;
  11. import flash.utils.ByteArray;
  12. import flash.utils.Endian;
  13. import flash.utils.getTimer;
  14. import sandy.core.Object3D;
  15. import sandy.core.data.Keyframer;
  16. import sandy.core.data.Matrix4;
  17. import sandy.core.data.Quaternion;
  18. import sandy.core.data.Vector;
  19. import sandy.core.data.Vertex;
  20. import sandy.core.face.Face;
  21. import sandy.core.face.TriFace3D;
  22. import sandy.events.ParserEvent;
  23. import sandy.math.QuaternionMath;
  24. import sandy.math.VectorMath;
  25. import sandy.math.VertexMath;
  26. import sandy.core.transform.Transform3D;
  27. public class Parser3DS extends EventDispatcher
  28. {
  29. /**
  30. * The load has failed
  31. */
  32. static public const onFailEVENT:String = 'onFailEVENT';
  33. /**
  34. * The OBject3D object is initialized
  35. */
  36. static public const onInitEVENT:String = 'onInitEVENT';
  37. /**
  38. * The load has started
  39. */
  40. static public const onLoadEVENT:String = 'onLoadEVENT';
  41. /**
  42. * The load is in progress
  43. */
  44. public static const onProgressEVENT:String = 'onProgressEVENT';
  45. private static const _eProgress:ParserEvent = new ParserEvent( Parser3DS.onProgressEVENT, 0, "" );
  46. /////////////////////
  47. /// PROPERTIES ///
  48. /////////////////////
  49. public const loader:URLLoader = new URLLoader();
  50. private var _scene:Array;
  51. private var _rot_m:Array;
  52. private var currentObjectName:String;
  53. private var data:ByteArray;
  54. private var _animation:Array;
  55. private var startFrame:uint;
  56. private var endFrame:uint;
  57. private var lastRotation:Quaternion;
  58. /**
  59. * Initialize the object passed in parameter (which should be new) with the datas
  60. * stored in the 3DS file given in second parameter
  61. *
  62. * @param scene Array All 3D objects will be added here
  63. * @param url String The url of the .3DS file used to initialized the Object3D
  64. */
  65. public function parse( scene:Array, url:String, animation:Array = null ):void
  66. {
  67. // Construction d'un objet URLRequest qui encapsule le chemin d'accès
  68. var urlRequest:URLRequest = new URLRequest(url);
  69. // Ecoute de l'evennement COMPLETE
  70. loader.addEventListener( Event.COMPLETE, _parse );
  71. loader.addEventListener( IOErrorEvent.IO_ERROR , _io_error );
  72. //Scene initializing
  73. _scene = scene;
  74. if (animation != null)
  75. {
  76. _animation = animation;
  77. }
  78. loader.dataFormat = URLLoaderDataFormat.BINARY;
  79. loader.load(urlRequest);
  80. }
  81. private function _parse(event:Event):void
  82. {
  83. var time:uint = getTimer();
  84. var file:URLLoader = URLLoader(event.target);
  85. data = file.data;
  86. data.endian = Endian.LITTLE_ENDIAN;
  87. //trace("endian: " + data.endian);
  88. /*while (data.bytesAvailable > 0)
  89. {
  90. trace(data.readByte());
  91. }*/
  92. var f:TriFace3D;
  93. var uvCoordinates:Array = new Array();
  94. var faces:Array = new Array();
  95. var scene:Array = _scene;
  96. var _rot_m:Array = new Array();
  97. // var o:Object3D = _object;
  98. var ad:Array = new Array();
  99. var pi180:Number = 180 / Math.PI;
  100. while(data.bytesAvailable > 0)
  101. {
  102. var id:uint = data.readUnsignedShort();
  103. //trace("chunk id: " + id);
  104. //trace("bytesAvailable: " + data.bytesAvailable);
  105. var l_chunk_length:uint = data.readUnsignedInt();
  106. //trace("chunk length: " + l_chunk_length);
  107. //trace("bytesAvailable: " + data.bytesAvailable);
  108. switch(id)
  109. {
  110. case Parser3DSChunkTypes.MAIN3DS:
  111. trace("0x4d4d MAIN3DS");
  112. break;
  113. case Parser3DSChunkTypes.EDIT3DS:
  114. trace("0x3d3d EDIT3DS");
  115. break;
  116. case Parser3DSChunkTypes.KEYF3DS:
  117. trace("0xB000 KEYF3DS");
  118. break;
  119. case Parser3DSChunkTypes.EDIT_OBJECT:
  120. trace("0x4000");
  121. i=0;
  122. var str:String = readString();
  123. var o:Object3D = new Object3D(str);
  124. currentObjectName = str;
  125. scene[str] = o;
  126. break;
  127. case Parser3DSChunkTypes.OBJ_TRIMESH:
  128. trace("0x4100");
  129. break;
  130. case Parser3DSChunkTypes.TRI_VERTEXL: //vertices
  131. trace("0x4110 vertices");
  132. var l_qty:uint = data.readUnsignedShort();
  133. for (var i:int=0; i<l_qty; i++)
  134. {
  135. var x:Number = data.readFloat();
  136. y = data.readFloat();
  137. z = data.readFloat();
  138. //trace("vertice["+o.name+"] [" + x +","+y+","+z+"][" + x +","+(-z)+","+y+"]");
  139. //o.addPoint( v1 , -1*v2, v3 );
  140. o.addPoint( x,-z, y );
  141. }
  142. //trace("In " + (getTimer() - time) + " ms we have list of " + vertex_list.length + " vertices");
  143. break;
  144. case Parser3DSChunkTypes.TRI_TEXCOORD: // texture coords
  145. trace("0x4140 texture coords");
  146. l_qty = data.readUnsignedShort();
  147. for (i=0; i<l_qty; i++)
  148. {
  149. var u:Number = data.readFloat();
  150. var v:Number = data.readFloat();
  151. //trace("u v: " + u + " , " + v);
  152. uvCoordinates.push( o.addUVCoordinate( u, 1 - v ) );
  153. }
  154. break;
  155. case Parser3DSChunkTypes.TRI_FACEL1: // faces
  156. trace("0x4120 faces");
  157. l_qty = data.readUnsignedShort();
  158. for (i = 0; i<l_qty; i++)
  159. {
  160. var vertex_a:int = data.readUnsignedShort();
  161. var vertex_b:int = data.readUnsignedShort();
  162. var vertex_c:int = data.readUnsignedShort();
  163. var faceId:int = data.readUnsignedShort();
  164. faces.push( [vertex_a, vertex_b, vertex_c]);
  165. }
  166. for (i = 0; i<l_qty; i++)
  167. {
  168. var p:Array = faces[i]
  169. f = new TriFace3D( o, o.aPoints[ p[1] ], o.aPoints[ p[0] ], o.aPoints[ p[2] ] )
  170. f.setUVCoordinates( uvCoordinates[ p[0] ], uvCoordinates[ p[1] ], uvCoordinates[ p[2] ] );
  171. o.addFace( f );
  172. }
  173. break;
  174. case Parser3DSChunkTypes.TRI_LOCAL: //ParseLocalCoordinateSystem
  175. trace("0x4160 TRI_LOCAL");
  176. var localX:Vector = readVector();
  177. var localY:Vector = readVector();
  178. var localZ:Vector = readVector();
  179. var origin:Vector = readVector();
  180. var init_m:Matrix4 = new Matrix4( localX.x, localX.y, localX.z,0,
  181. localZ.x, localZ.y, localZ.z,0,
  182. localY.x, localY.y, localY.z,0,
  183. 0,0,0,1 );
  184. _rot_m[currentObjectName] = init_m;
  185. var originVertex:Vertex = origin.toVertex();
  186. var len:int = o.aPoints.length;
  187. for (i = 0; i<l_qty; i++)
  188. {
  189. o.aPoints[i] = VertexMath.sub( o.aPoints[i], originVertex );
  190. }
  191. break;
  192. case Parser3DSChunkTypes.OBJ_LIGHT: //Lights
  193. trace("0x4600 Light");
  194. var light:Vector = readVector();
  195. break;
  196. case Parser3DSChunkTypes.LIT_SPOT: //Light Spot
  197. var tx:Number = data.readFloat();
  198. var ty:Number = data.readFloat();
  199. var tz:Number = data.readFloat();
  200. var hotspot:Number = data.readFloat();
  201. var falloff:Number = data.readFloat();
  202. break;
  203. case Parser3DSChunkTypes.COL_TRU: //RGB color
  204. var r:Number = data.readFloat();
  205. var y:Number = data.readFloat();
  206. var z:Number = data.readFloat();
  207. break;
  208. case Parser3DSChunkTypes.COL_RGB: //RGB color
  209. x = data.readByte();
  210. y = data.readByte();
  211. z = data.readByte();
  212. break;
  213. case Parser3DSChunkTypes.OBJ_CAMERA: //Cameras
  214. trace("0x4700 Cameras");
  215. x = data.readFloat();
  216. y = data.readFloat();
  217. z = data.readFloat();
  218. tx = data.readFloat();
  219. ty = data.readFloat();
  220. tz = data.readFloat();
  221. var angle:Number = data.readFloat();
  222. var fov:Number = data.readFloat();
  223. break;
  224. // animation
  225. case Parser3DSChunkTypes.KEYF_FRAMES:
  226. trace("0xB008 KEYF_FRAMES");
  227. startFrame = data.readInt();
  228. endFrame = data.readInt();
  229. break;
  230. case Parser3DSChunkTypes.KEYF_OBJDES:
  231. trace("0xB002 KEYF_OBJDES");
  232. //var startFrame:uint = data.readInt();
  233. //var endFrame:uint = data.readInt();
  234. break;
  235. case Parser3DSChunkTypes.NODE_ID:
  236. trace("0xB030 NODE_ID");
  237. var node_id:uint = data.readUnsignedShort();
  238. var keyframer:Keyframer = new Keyframer();
  239. keyframer.startFrame = startFrame;
  240. keyframer.endFrame = endFrame;
  241. lastRotation = null;
  242. //ad.push(keyframer.);
  243. break;
  244. case Parser3DSChunkTypes.NODE_HDR:
  245. trace("0xB010 NODE_HDR");
  246. var name:String = readString();
  247. var flag1:uint = data.readUnsignedShort();
  248. var flag2:uint = data.readUnsignedShort();
  249. var parent:int = data.readShort();
  250. keyframer.name = name;
  251. _animation[name] = keyframer;
  252. keyframer.flag1 = flag1;
  253. keyframer.flag2 = flag2;
  254. keyframer.parent = parent;
  255. //var endFrame:uint = data.readInt();
  256. break;
  257. case Parser3DSChunkTypes.PIVOT:
  258. trace("0xB013 PIVOTR");
  259. x = data.readFloat();
  260. y = data.readFloat();
  261. z = data.readFloat();
  262. keyframer.pivot = new Vector(x,z,y);
  263. trace("PIVOT: " + keyframer.pivot);
  264. //var endFrame:uint = data.readInt();
  265. break;
  266. case Parser3DSChunkTypes.POS_TRACK_TAG:
  267. trace("0xB020 POS_TRACK_TAG");
  268. flag1 = data.readUnsignedShort();
  269. for (var j:int=0; j<8; j++)
  270. {
  271. var unknown:Number = data.readByte();
  272. }
  273. var keys:uint = data.readInt();
  274. var frame0pos:Vector;
  275. keyframer.track_data.pos_track_keys = keys;
  276. for (j = 0; j<keys; j++)
  277. {
  278. var posObj:Object = keyframer.getPositionObject();
  279. var key:uint = data.readInt();
  280. var acc:int = data.readShort();
  281. //position
  282. var rx:Number = data.readFloat();
  283. var ry:Number = data.readFloat();
  284. var rz:Number = data.readFloat();
  285. posObj.key = key;
  286. posObj.acc = acc;
  287. posObj.position = new Vector(rx,rz,ry);
  288. // trace("keyframer ["+keyframer.name+"] pos => " + posObj.position);
  289. }
  290. break;
  291. case Parser3DSChunkTypes.ROT_TRACK_TAG:
  292. trace("0xB021 ROT_TRACK_TAG");
  293. flag1 = data.readUnsignedShort();
  294. for (j = 0; j<8; j++)
  295. {
  296. unknown = data.readByte();
  297. }
  298. keys = data.readInt();
  299. keyframer.track_data.rot_track_keys = keys;
  300. //keyframer.track_data.rot_track_data = new Array();
  301. for (j = 0; j<keys; j++)
  302. {
  303. var rotObj:Object = keyframer.getRotationObject();
  304. key = data.readInt();
  305. acc = data.readShort();
  306. var AnimAngle:Number = data.readFloat();
  307. //axis
  308. rx = data.readFloat();
  309. ry = data.readFloat();
  310. rz = data.readFloat();
  311. rotObj.key = key;
  312. rotObj.acc = acc;
  313. var rotation:Quaternion = QuaternionMath.setAxisAngle(new Vector(rx,-rz,-ry), AnimAngle);
  314. // trace("keyframer ["+keyframer.name+"] lastRotation1 => " + rotation);
  315. if (lastRotation != null)
  316. {
  317. lastRotation = QuaternionMath.multiply(lastRotation, rotation);
  318. }
  319. else
  320. {
  321. lastRotation = QuaternionMath.setByMatrix(_rot_m[keyframer.name]);
  322. lastRotation = QuaternionMath.multiply(lastRotation, rotation);
  323. //lastRotation = QuaternionMath.clone(rotation);
  324. }
  325. if (key > 60)
  326. {
  327. trace("keyframer ["+keyframer.name+"] lastRotation2["+key+"] => " + QuaternionMath.toEuler(lastRotation));
  328. }
  329. rotObj.axis = lastRotation;
  330. }
  331. break;
  332. case Parser3DSChunkTypes.SCL_TRACK_TAG:
  333. trace("0xB022 SCL_TRACK_TAG");
  334. flag1 = data.readUnsignedShort();
  335. for (j=0; j<8; j++)
  336. {
  337. unknown = data.readByte();
  338. }
  339. keys = data.readInt();
  340. keyframer.track_data.scl_track_keys = keys;
  341. // ATTENTION:
  342. // The rotation is relative to last frame to avoid the gimbal lock problem.
  343. //So if you want the "global" rotation, you need to concatenate them with quaterinion multiplication.
  344. for (j = 0; j<keys; j++)
  345. {
  346. var sclObj:Object = keyframer.getScaleObject();
  347. key = data.readInt();
  348. acc = data.readShort();
  349. //size
  350. rx = data.readFloat();
  351. ry = data.readFloat();
  352. rz = data.readFloat();
  353. sclObj.key = key;
  354. sclObj.acc = acc;
  355. sclObj.size = new Vector(rx,rz,ry);
  356. //trace("keyframer ["+keyframer.name+"] scl => " + sclObj.size);
  357. }
  358. break;
  359. default:
  360. trace("default");
  361. data.position += l_chunk_length-6;
  362. }
  363. }
  364. dispatchEvent( new ParserEvent(Parser3DS.onInitEVENT ) );
  365. }
  366. /**
  367. * Function is call in case of IO error
  368. * @param e IOErrorEvent IO_ERROR
  369. */
  370. private function _io_error( e:IOErrorEvent ):void
  371. {
  372. dispatchEvent( new ParserEvent( Parser3DS.onFailEVENT ) );
  373. }
  374. private function readVector():Vector
  375. {
  376. var x:Number = data.readFloat();
  377. var y:Number = data.readFloat();
  378. var z:Number = data.readFloat();
  379. return new Vector(x, z, y);
  380. }
  381. private function readByte():int
  382. {
  383. return data.readByte();
  384. }
  385. private function readChar():uint
  386. {
  387. return data.readUnsignedByte();
  388. }
  389. private function readInt():uint
  390. {
  391. var temp:uint = readChar();
  392. return ( temp | (readChar() << 8));
  393. }
  394. private function readString():String
  395. {
  396. var name:String = "";
  397. var ch:uint;
  398. while(ch = readChar())
  399. {
  400. if (ch == 0)
  401. {
  402. break;
  403. }
  404. name += String.fromCharCode(ch);
  405. }
  406. return name
  407. }
  408. }
  409. }