PageRenderTime 43ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/SharpGL/Core/SharpGL.Serialization/Discreet/Chunks.cs

#
C# | 347 lines | 257 code | 46 blank | 44 comment | 28 complexity | 99804fe0a41c154312baa4e1ee48f1b4 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using SharpGL.SceneGraph;
  6. using System.IO;
  7. using SharpGL.SceneGraph.Collections;
  8. using SharpGL.SceneGraph.Primitives;
  9. using SharpGL.SceneGraph.Core;
  10. namespace SharpGL.Serialization.Discreet
  11. {
  12. public enum ChunkType : ushort
  13. {
  14. CHUNK_RGBF = 0x0010,
  15. CHUNK_RGBB = 0x0011,
  16. CHUNK_MAIN = 0x4D4D,
  17. CHUNK_OBJMESH = 0x3D3D,
  18. CHUNK_BKGCOLOR = 0x1200,
  19. CHUNK_AMBCOLOR = 0x2100,
  20. CHUNK_OBJBLOCK = 0x4000,
  21. CHUNK_TRIMESH = 0x4100,
  22. CHUNK_VERTLIST = 0x4110,
  23. CHUNK_FACELIST = 0x4120,
  24. CHUNK_FACEMAT = 0x4130,
  25. CHUNK_MAPLIST = 0x4140,
  26. CHUNK_SMOOLIST = 0x4150,
  27. CHUNK_TRMATRIX = 0x4160,
  28. CHUNK_LIGHT = 0x4600,
  29. CHUNK_SPOTLIGHT = 0x4610,
  30. CHUNK_CAMERA = 0x4700,
  31. CHUNK_MATERIAL = 0xAFFF,
  32. CHUNK_MATNAME = 0xA000,
  33. CHUNK_AMBIENT = 0xA010,
  34. CHUNK_DIFFUSE = 0xA020,
  35. CHUNK_SPECULAR = 0xA030,
  36. CHUNK_TEXTURE = 0xA200,
  37. CHUNK_BUMPMAP = 0xA230,
  38. CHUNK_MAPFILE = 0xA300,
  39. CHUNK_KEYFRAMER = 0xB000,
  40. CHUNK_FRAMES = 0xB008
  41. };
  42. internal class MAXChunkHeader
  43. {
  44. public virtual void Read(BinaryReader stream)
  45. {
  46. // Read the data.
  47. type = (ChunkType)stream.ReadInt16();
  48. allDataBytes = stream.ReadInt32();
  49. dataBytes = allDataBytes - 6; // data - header
  50. }
  51. public static MAXChunkHeader Peep(BinaryReader stream)
  52. {
  53. // Read a header.
  54. MAXChunkHeader header = new MAXChunkHeader();
  55. header.Read(stream);
  56. // Go back.
  57. stream.BaseStream.Seek(-6, System.IO.SeekOrigin.Current);
  58. // Return the header.
  59. return header;
  60. }
  61. public ChunkType type;
  62. public long allDataBytes;
  63. public long dataBytes;
  64. };
  65. internal class MAXChunk
  66. {
  67. public virtual void Read(Scene scene, BinaryReader stream)
  68. {
  69. // Set the start position.
  70. startPosition = stream.BaseStream.Position;
  71. // Read the header.
  72. ReadHeader(stream);
  73. // Read the data itself.
  74. ReadData(scene, stream);
  75. }
  76. protected virtual void ReadHeader(BinaryReader stream)
  77. {
  78. // Read the chunk header.
  79. chunkHeader.Read(stream);
  80. }
  81. /// <summary>
  82. /// This function reads the chunk and bangs the data in it into the scene.
  83. /// </summary>
  84. /// <param name="stream">The file stream to read from.</param>
  85. /// <param name="scene">The scene to put data into.</param>
  86. public virtual void ReadData(Scene scene, BinaryReader stream)
  87. {
  88. // This is the code that is executed when an unknown chunk is read.
  89. // Advance the stream.
  90. stream.BaseStream.Seek(chunkHeader.dataBytes, System.IO.SeekOrigin.Current);
  91. }
  92. public virtual bool MoreChunks(BinaryReader reader)
  93. {
  94. if (reader.BaseStream.Position < (startPosition + chunkHeader.allDataBytes))
  95. return true;
  96. return false;
  97. }
  98. public MAXChunkHeader chunkHeader = new MAXChunkHeader();
  99. long startPosition = 0;
  100. }
  101. internal class MainChunk : MAXChunk
  102. {
  103. public override void ReadData(Scene scene, BinaryReader stream)
  104. {
  105. do
  106. {
  107. // Peep at the next chunk.
  108. MAXChunkHeader next = MAXChunkHeader.Peep(stream);
  109. // If it's an Object Mesh, we can read that.
  110. if (next.type == ChunkType.CHUNK_OBJMESH)
  111. {
  112. ObjectMeshChunk chunk = new ObjectMeshChunk();
  113. chunk.Read(scene, stream);
  114. }
  115. else
  116. {
  117. // We don't know what this chunk is, so just read the generic one.
  118. MAXChunk chunk = new MAXChunk();
  119. chunk.Read(scene, stream);
  120. }
  121. } while (MoreChunks(stream));
  122. }
  123. }
  124. internal class ObjectMeshChunk : MAXChunk
  125. {
  126. public override void ReadData(Scene scene, BinaryReader stream)
  127. {
  128. do
  129. {
  130. // Peep at the next chunk.
  131. MAXChunkHeader next = MAXChunkHeader.Peep(stream);
  132. // If it's an Object Block, we can read that.
  133. if (next.type == ChunkType.CHUNK_OBJBLOCK)
  134. {
  135. ObjectBlockChunk chunk = new ObjectBlockChunk();
  136. chunk.Read(scene, stream);
  137. }
  138. else
  139. {
  140. // We don't know what this chunk is, so just read the generic one.
  141. MAXChunk chunk = new MAXChunk();
  142. chunk.Read(scene, stream);
  143. }
  144. } while (MoreChunks(stream));
  145. }
  146. }
  147. internal class ObjectBlockChunk : MAXChunk
  148. {
  149. public override void ReadData(Scene scene, BinaryReader stream)
  150. {
  151. do
  152. {
  153. // Peep at the next chunk.
  154. MAXChunkHeader next = MAXChunkHeader.Peep(stream);
  155. // If it's an Trimesh Block, we can read that.
  156. if (next.type == ChunkType.CHUNK_TRIMESH)
  157. {
  158. TriangleMeshChunk chunk = new TriangleMeshChunk();
  159. chunk.Read(scene, stream);
  160. }
  161. else
  162. {
  163. // We don't know what this chunk is, so just read the generic one.
  164. MAXChunk chunk = new MAXChunk();
  165. chunk.Read(scene, stream);
  166. }
  167. } while (MoreChunks(stream));
  168. }
  169. }
  170. internal class TriangleMeshChunk : MAXChunk
  171. {
  172. public override void ReadData(Scene scene, BinaryReader stream)
  173. {
  174. // A triangle mesh is basicly a Polygon, so create it.
  175. Polygon poly = new Polygon();
  176. Matrix matrix = new Matrix(Matrix.Identity(4));
  177. do
  178. {
  179. // Peep at the next chunk.
  180. MAXChunkHeader next = MAXChunkHeader.Peep(stream);
  181. if (next.type == ChunkType.CHUNK_VERTLIST)
  182. {
  183. // Read the vertices.
  184. VertexListChunk chunk = new VertexListChunk();
  185. chunk.Read(scene, stream);
  186. // Set them into the polygon.
  187. poly.Vertices = chunk.vertices;
  188. }
  189. else if (next.type == ChunkType.CHUNK_FACELIST)
  190. {
  191. // Read the faces.
  192. FaceListChunk chunk = new FaceListChunk();
  193. chunk.Read(scene, stream);
  194. // Set them into the polygon.
  195. poly.Faces = chunk.faces;
  196. }
  197. else if (next.type == ChunkType.CHUNK_MAPLIST)
  198. {
  199. // Read the uvs.
  200. MapListChunk chunk = new MapListChunk();
  201. chunk.Read(scene, stream);
  202. // Set them into the polygon.
  203. poly.UVs = chunk.uvs;
  204. }
  205. else if (next.type == ChunkType.CHUNK_TRMATRIX)
  206. {
  207. // Here we just read the matrix (we'll use it later).
  208. TrMatrixChunk chunk = new TrMatrixChunk();
  209. chunk.Read(scene, stream);
  210. matrix = chunk.matrix;
  211. }
  212. else
  213. {
  214. // We don't know what this chunk is, so just read the generic one.
  215. MAXChunk chunk = new MAXChunk();
  216. chunk.Read(scene, stream);
  217. }
  218. } while (MoreChunks(stream));
  219. // Now we multiply each vertex by the matrix.
  220. for (int i = 0; i < poly.Vertices.Count; i++)
  221. poly.Vertices[i] *= matrix;
  222. // Add the poly to the scene.
  223. scene.SceneContainer.AddChild(poly);
  224. }
  225. }
  226. internal class VertexListChunk : MAXChunk
  227. {
  228. public override void ReadData(Scene scene, BinaryReader stream)
  229. {
  230. // Read number of vertices.
  231. short vertexCount = 0;
  232. vertexCount = stream.ReadInt16();
  233. // Read each vertex and add it.
  234. for (short i = 0; i < vertexCount; i++)
  235. {
  236. Vertex v = new Vertex();
  237. v.X = stream.ReadSingle();
  238. v.Y = stream.ReadSingle();
  239. v.Z = stream.ReadSingle();
  240. vertices.Add(v);
  241. }
  242. }
  243. public List<Vertex> vertices = new List<Vertex>();
  244. }
  245. internal class FaceListChunk : MAXChunk
  246. {
  247. public override void ReadData(Scene scene, BinaryReader stream)
  248. {
  249. // Note: A max face is three indices and
  250. // a flag short.
  251. // Read number of faces.
  252. short faceCount = 0;
  253. faceCount = stream.ReadInt16();
  254. // Read each face and add it.
  255. for (short i = 0; i < faceCount; i++)
  256. {
  257. Face f = new Face();
  258. Index index = new Index(stream.ReadInt16());
  259. f.Indices.Add(index);
  260. index = new Index(stream.ReadInt16());
  261. f.Indices.Add(index);
  262. index = new Index(stream.ReadInt16());
  263. f.Indices.Add(index);
  264. stream.ReadInt16();
  265. faces.Add(f);
  266. }
  267. }
  268. public List<Face> faces = new List<Face>();
  269. }
  270. internal class MapListChunk : MAXChunk
  271. {
  272. public override void ReadData(Scene scene, BinaryReader stream)
  273. {
  274. // Read number of uvs.
  275. short uvCount = 0;
  276. uvCount = stream.ReadInt16();
  277. // Read each uv and add it.
  278. for (short i = 0; i < uvCount; i++)
  279. {
  280. UV uv = new UV();
  281. uv.U = stream.ReadSingle();
  282. uv.V = stream.ReadSingle();
  283. uvs.Add(uv);
  284. }
  285. }
  286. public List<UV> uvs = new List<UV>();
  287. }
  288. internal class TrMatrixChunk : MAXChunk
  289. {
  290. public override void ReadData(Scene scene, BinaryReader stream)
  291. {
  292. for (int i = 0; i < 3; i++)
  293. {
  294. for (int j = 0; j < 4; j++)
  295. matrix[i,j] = stream.ReadSingle();
  296. }
  297. matrix.Transpose();
  298. }
  299. public Matrix matrix = new Matrix(4,4);
  300. }
  301. }