PageRenderTime 51ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/JadEngine-Development/Jad/Import/JXLoader.cs

#
C# | 566 lines | 222 code | 125 blank | 219 comment | 25 complexity | 2963f83355e4fa4a342d561db41edfb6 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause
  1. #region Using directives
  2. using System;
  3. using System.IO;
  4. using Microsoft.DirectX;
  5. using Microsoft.DirectX.Direct3D;
  6. using JadEngine.Video;
  7. using JadEngine.Core;
  8. using JadEngine.Scene;
  9. using JadEngine.Mathematics;
  10. using JadEngine.Tools;
  11. #endregion
  12. namespace JadEngine.Import
  13. {
  14. /// <summary>
  15. /// DirectX importing
  16. /// </summary>
  17. internal class JXLoader
  18. {
  19. #region Internal Classes
  20. /// <summary>
  21. /// The frame that will hold mesh animation
  22. /// </summary>
  23. public class AnimationFrame : Frame
  24. {
  25. #region Fields
  26. /// <summary>
  27. /// Store the combined transformation matrix
  28. /// </summary>
  29. private Matrix combined = Matrix.Identity;
  30. #endregion
  31. #region Properties
  32. /// <summary>
  33. /// Gets or sets the combined transformation matrix
  34. /// </summary>
  35. public Matrix CombinedTransformationMatrix
  36. {
  37. get { return combined; }
  38. set { combined = value; }
  39. }
  40. #endregion
  41. }
  42. /// <summary>
  43. /// The mesh container class that will hold the animation data
  44. /// </summary>
  45. public class AnimationMeshContainer : MeshContainer
  46. {
  47. #region Fields
  48. // Array data
  49. /// <summary>
  50. /// TODO
  51. /// </summary>
  52. private Texture[] meshTextures = null;
  53. /// <summary>
  54. /// TODO
  55. /// </summary>
  56. private BoneCombination[] bones;
  57. /// <summary>
  58. /// TODO
  59. /// </summary>
  60. private Matrix[] offsetMatrices;
  61. /// <summary>
  62. /// TODO
  63. /// </summary>
  64. private AnimationFrame[] frameMatrices;
  65. /// <summary>
  66. /// TODO
  67. /// </summary>
  68. internal ExtendedMaterial[] meshMaterials = null; // array of materials
  69. // Instance data
  70. /// <summary>
  71. /// The total number of attributes this mesh container contains
  72. /// </summary>
  73. private int numAttributes = 0;
  74. /// <summary>
  75. /// The total number of influences this mesh container contains
  76. /// </summary>
  77. private int numInfluences = 0;
  78. /// <summary>
  79. /// The total number of palette entries this mesh container contains
  80. /// </summary>
  81. private int numPalette = 0;
  82. #endregion
  83. #region Properties
  84. /// <summary>
  85. /// Gets or sets the total number of attributes this mesh container contains
  86. /// </summary>
  87. public int NumberAttributes
  88. {
  89. get { return numAttributes; }
  90. set { numAttributes = value; }
  91. }
  92. /// <summary>
  93. /// Gets or sets the total number of influences this mesh container contains
  94. /// </summary>
  95. public int NumberInfluences
  96. {
  97. get { return numInfluences; }
  98. set { numInfluences = value; }
  99. }
  100. /// <summary>
  101. /// Gets or sets the total number of palette entries this mesh container contains
  102. /// </summary>
  103. public int NumberPaletteEntries
  104. {
  105. get { return numPalette; }
  106. set { numPalette = value; }
  107. }
  108. #endregion
  109. #region Methods
  110. /// <summary>
  111. /// Retrieve the textures used for this container
  112. /// </summary>
  113. /// <returns>TODO</returns>
  114. public Texture[] GetTextures() { return meshTextures; }
  115. /// <summary>
  116. /// Set the textures used for this container
  117. /// </summary>
  118. /// <param name="textures">TODO</param>
  119. public void SetTextures(Texture[] textures) { meshTextures = textures; }
  120. /// <summary>
  121. /// Retrieve the bone combinations used for this container
  122. /// </summary>
  123. /// <returns>TODO</returns>
  124. public BoneCombination[] GetBones() { return bones; }
  125. /// <summary>
  126. /// Set the bone combinations used for this container
  127. /// </summary>
  128. /// <param name="b">TODO</param>
  129. public void SetBones(BoneCombination[] b) { bones = b; }
  130. /// <summary>
  131. /// Retrieve the animation frames used for this container
  132. /// </summary>
  133. /// <returns>TODO</returns>
  134. public AnimationFrame[] GetFrames() { return frameMatrices; }
  135. /// <summary>
  136. /// Set the animation frames used for this container
  137. /// </summary>
  138. /// <param name="frames">TODO</param>
  139. public void SetFrames(AnimationFrame[] frames) { frameMatrices = frames; }
  140. /// <summary>
  141. /// Retrieve the offset matrices used for this container
  142. /// </summary>
  143. /// <returns>TODO</returns>
  144. public Matrix[] GetOffsetMatrices() { return offsetMatrices; }
  145. /// <summary>
  146. /// Set the offset matrices used for this container
  147. /// </summary>
  148. /// <param name="matrices">TODO</param>
  149. public void SetOffsetMatrices(Matrix[] matrices) { offsetMatrices = matrices; }
  150. #endregion
  151. }
  152. /// <summary>
  153. /// AllocateHierarchy derived class
  154. /// </summary>
  155. public class AnimationAllocation : AllocateHierarchy
  156. {
  157. #region Fields
  158. /// <summary>
  159. /// TODO
  160. /// </summary>
  161. JXLoader parent = null;
  162. #endregion
  163. #region Constructors
  164. /// <summary>
  165. /// Create new instance of this class
  166. /// </summary>
  167. public AnimationAllocation(JXLoader p) { parent = p; }
  168. #endregion
  169. #region Methods
  170. /// <summary>
  171. /// Creates a new frame
  172. /// </summary>
  173. /// <param name="name">TODO</param>
  174. /// <returns>TODO</returns>
  175. public override Frame CreateFrame(string name)
  176. {
  177. AnimationFrame frame = new AnimationFrame();
  178. frame.Name = name;
  179. frame.TransformationMatrix = Matrix.Identity;
  180. frame.CombinedTransformationMatrix = Matrix.Identity;
  181. Jad.LogWriter.WriteLine("Frame:" + name);
  182. return frame;
  183. }
  184. /// <summary>
  185. /// Creates a new mesh container
  186. /// </summary>
  187. /// <param name="name">TODO</param>
  188. /// <param name="meshData">TODO</param>
  189. /// <param name="materials">TODO</param>
  190. /// <param name="effectInstances">TODO</param>
  191. /// <param name="adjacency">TODO</param>
  192. /// <param name="skinInfo">TODO</param>
  193. /// <returns>TODO</returns>
  194. public override MeshContainer CreateMeshContainer(string name,
  195. MeshData meshData, ExtendedMaterial[] materials,
  196. EffectInstance[] effectInstances, GraphicsStream adjacency,
  197. SkinInformation skinInfo)
  198. {
  199. // We only handle meshes here
  200. if (meshData.Mesh == null)
  201. throw new ArgumentException();
  202. // We must have a vertex format mesh
  203. if (meshData.Mesh.VertexFormat == VertexFormats.None)
  204. throw new ArgumentException();
  205. AnimationMeshContainer mesh = new AnimationMeshContainer();
  206. mesh.Name = name;
  207. int numFaces = meshData.Mesh.NumberFaces;
  208. Device dev = meshData.Mesh.Device;
  209. Jad.LogWriter.WriteLine("MeshContainer");
  210. Jad.LogWriter.WriteLine("\tName:" + name);
  211. Jad.LogWriter.WriteLine("\tNumFaces:" + numFaces.ToString());
  212. Jad.LogWriter.WriteLine("\tVertexFormat:" + meshData.Mesh.VertexFormat.ToString());
  213. // Make sure there are normals
  214. if ((meshData.Mesh.VertexFormat & VertexFormats.Normal) == 0)
  215. {
  216. // Clone the mesh
  217. Mesh tempMesh = meshData.Mesh.Clone(meshData.Mesh.Options.Value,
  218. meshData.Mesh.VertexFormat | VertexFormats.Normal, dev);
  219. // Destroy current mesh, use the new one
  220. meshData.Mesh.Dispose();
  221. meshData.Mesh = tempMesh;
  222. meshData.Mesh.ComputeNormals();
  223. }
  224. mesh.meshMaterials = materials;
  225. /*
  226. // Store the materials
  227. mesh.SetMaterials(materials);
  228. mesh.SetAdjacency(adjacency);
  229. Texture[] meshTextures = new Texture[materials.Length];
  230. // Create any textures
  231. for (int i = 0; i < materials.Length; i++)
  232. {
  233. if (materials[i].TextureFilename != null)
  234. {
  235. meshTextures[i] = ResourceCache.GetGlobalInstance().CreateTextureFromFile(
  236. dev, materials[i].TextureFilename);
  237. }
  238. }
  239. mesh.SetTextures(meshTextures);
  240. */
  241. mesh.MeshData = meshData;
  242. return mesh;
  243. }
  244. #endregion
  245. }
  246. #endregion
  247. #region Fields
  248. /// <summary>
  249. /// TODO
  250. /// </summary>
  251. Mesh mesh;
  252. /// <summary>
  253. /// TODO
  254. /// </summary>
  255. Device device;
  256. /// <summary>
  257. /// Array of materials
  258. /// </summary>
  259. ExtendedMaterial[] meshMaterials = null;
  260. /// <summary>
  261. /// TODO
  262. /// </summary>
  263. string fileName;
  264. /// <summary>
  265. /// TODO
  266. /// </summary>
  267. Vector3 inScale;
  268. /// <summary>
  269. /// TODO
  270. /// </summary>
  271. AnimationRootFrame rootFrame;
  272. #endregion
  273. #region Methods
  274. /// <summary>
  275. /// TODO
  276. /// </summary>
  277. /// <param name="fileName">TODO</param>
  278. /// <param name="scale">TODO</param>
  279. /// <returns>TODO</returns>
  280. internal bool LoadHierarchy(string fileName, Vector3 scale)
  281. {
  282. device = Jad.Video.Device;
  283. inScale = scale;
  284. this.fileName = fileName;
  285. Jad.LogWriter.WriteLine("Loading a Hierarchy .X");
  286. Jad.LogWriter.WriteLine("filename:" + fileName);
  287. Jad.LogWriter.WriteLine("scale:" + JMath.Vector3ToString(scale));
  288. // Create our allocate hierarchy derived class
  289. AnimationAllocation alloc = new AnimationAllocation(this);
  290. rootFrame = Mesh.LoadHierarchyFromFile(fileName, MeshFlags.Managed, device, alloc, null);
  291. ConvertHierarchy(rootFrame.FrameHierarchy as AnimationFrame, Jad.ActiveScene.Root);
  292. Jad.LogWriter.WriteLine("Destroying");
  293. Destroy();
  294. return true;
  295. }
  296. /// <summary>
  297. /// Converts the hierarchy to the Jad meshes
  298. /// </summary>
  299. /// <param name="frame">TODO</param>
  300. /// <param name="parent">TODO</param>
  301. /// <remarks>Empty method</remarks>
  302. private void ConvertHierarchy(AnimationFrame frame, JNode parent)
  303. {
  304. /*
  305. AnimationMeshContainer mesh = frame.MeshContainer as AnimationMeshContainer;
  306. // Create a new frame
  307. HFrame hFrame = new HFrame(frame.Name);
  308. parent.AddChild(hFrame);
  309. while (mesh != null)
  310. {
  311. // Here is the mesh information
  312. JMeshObject meshObject=FromMeshContainerToMesh(mesh);
  313. parent.AddChild(meshObject);
  314. mesh = mesh.NextContainer as AnimationMeshContainer;
  315. }
  316. // The same matrix
  317. if (frame.FrameSibling != null)
  318. {
  319. ConvertHierarchy(frame.FrameSibling as AnimationFrame, hFrame);
  320. }
  321. // The combined matrix
  322. if (frame.FrameFirstChild != null)
  323. {
  324. ConvertHierarchy(frame.FrameFirstChild as AnimationFrame, hFrame);
  325. }
  326. */
  327. }
  328. /// <summary>
  329. /// TODO
  330. /// </summary>
  331. void Destroy()
  332. {
  333. Frame.Destroy(rootFrame.FrameHierarchy, new AnimationAllocation(this));
  334. if (rootFrame.AnimationController != null)
  335. rootFrame.AnimationController.Dispose();
  336. }
  337. /// <summary>
  338. /// TODO
  339. /// </summary>
  340. /// <param name="container">TODO</param>
  341. /// <returns>TODO</returns>
  342. JMeshObject FromMeshContainerToMesh(AnimationMeshContainer container)
  343. {
  344. mesh = container.MeshData.Mesh;
  345. meshMaterials = container.meshMaterials;
  346. return Convert(container.Name);
  347. }
  348. /// <summary>
  349. /// TODO
  350. /// </summary>
  351. /// <param name="name">TODO</param>
  352. /// <returns>TODO</returns>
  353. internal JMeshObject Convert(string name)
  354. {
  355. // Make sure there are normals, which are required for the tesselation
  356. // enhancement.
  357. VertexFormats vf = mesh.VertexFormat;
  358. // If we have no vertexformat, this is a declaration vertex format.
  359. // We should check it, but here we assume that this must be the valid vertexformat
  360. if (vf == VertexFormats.None) vf = VertexFormats.Position | VertexFormats.Texture1;
  361. int numCoordText;
  362. uint f = (uint) vf & (uint) VertexFormats.TextureCountMask;
  363. f >>= 8;
  364. numCoordText = (int) (f & 255);
  365. if (numCoordText == 0) vf |= VertexFormats.Texture1;
  366. if ((vf & VertexFormats.Normal) == 0 || numCoordText == 0)
  367. {
  368. Mesh temporaryMesh = mesh.Clone(mesh.Options.Value,
  369. vf | VertexFormats.Normal, device);
  370. // Compute normals now
  371. temporaryMesh.ComputeNormals();
  372. // Set the mesh
  373. mesh.Dispose();
  374. mesh = temporaryMesh;
  375. }
  376. // Optimize to get a good attribute table
  377. /*
  378. int[] Adjacency = new int[mesh.NumberFaces * 3];
  379. mesh.GenerateAdjacency(0.0f, Adjacency);
  380. mesh.OptimizeInPlace(MeshFlags.OptimizeAttributeSort, Adjacency);
  381. */
  382. int numAt = meshMaterials.Length;
  383. JMeshObject meshObject = Jad.ActiveScene.MeshObjects.Create(true);
  384. Jad.Import.MeshObjects.Add(meshObject);
  385. meshObject.Mesh.NormalsComputed = true;
  386. meshObject.Mesh.NumAttributes = numAt;
  387. AttributeRange[] attributeRange = JMeshHelper.Optimize(mesh);
  388. JVertexBuffer vb = null;
  389. JIndexBuffer ib = null;
  390. JMeshHelper.BuffersFromMesh(mesh, out vb, out ib);
  391. meshObject.Mesh.VertexBuffer = vb;
  392. meshObject.Mesh.IndexBuffer = ib;
  393. mesh.Dispose();
  394. meshObject.Mesh.AttributeRange = attributeRange;
  395. if (inScale.X != 1 || inScale.Y != 1 || inScale.Z != 1)
  396. meshObject.Mesh.ProcessMatrix(Matrix.Scaling(inScale));
  397. meshObject.Mesh.CenterAtOrigin();
  398. meshObject.Mesh.ComputeTangent();
  399. meshObject.Transform.Position = meshObject.Mesh.TranslationToLocal;
  400. //meshObject.Material = new JMaterial[numAt];
  401. for (int i = 0; i < numAt; i++)
  402. {
  403. JMaterial mat = Jad.ActiveScene.Materials.Create();
  404. meshObject.Materials.Add(mat);
  405. JMaterialLayer layer = new JMaterialLayer();
  406. layer.DiffuseMap.Color = new JColor(meshMaterials[i].Material3D.DiffuseColor.Red, meshMaterials[i].Material3D.DiffuseColor.Green, meshMaterials[i].Material3D.DiffuseColor.Blue);
  407. if (meshMaterials[i].TextureFilename != null)
  408. {
  409. layer.DiffuseMap.Texture = Jad.Video.Textures.Create2D(meshMaterials[i].TextureFilename, true);
  410. layer.DiffuseMap.Enabled = true;
  411. }
  412. mat.AddLayer(layer);
  413. }
  414. return meshObject;
  415. }
  416. /// <summary>
  417. /// TODO
  418. /// </summary>
  419. /// <param name="fileName">TODO</param>
  420. /// <param name="scale">TODO</param>
  421. /// <returns>TODO</returns>
  422. internal bool Load(string fileName, Vector3 scale)
  423. {
  424. Stream stream = null;
  425. //return LoadHierarchy(fileName, scale);
  426. device = Jad.Video.Device;
  427. this.fileName = fileName;
  428. stream = Jad.VFS.GetFileFromDefinedPath("3D", fileName, true);
  429. mesh = Mesh.FromStream(stream, (int) stream.Length, MeshFlags.Managed, device, out meshMaterials);
  430. inScale = scale;
  431. Convert(Path.GetFileNameWithoutExtension(fileName));
  432. return true;
  433. }
  434. #endregion
  435. }
  436. }