/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
- #region Using directives
-
- using System;
- using System.IO;
-
- using Microsoft.DirectX;
- using Microsoft.DirectX.Direct3D;
-
- using JadEngine.Video;
- using JadEngine.Core;
- using JadEngine.Scene;
- using JadEngine.Mathematics;
- using JadEngine.Tools;
-
- #endregion
-
- namespace JadEngine.Import
- {
- /// <summary>
- /// DirectX importing
- /// </summary>
- internal class JXLoader
- {
- #region Internal Classes
-
- /// <summary>
- /// The frame that will hold mesh animation
- /// </summary>
- public class AnimationFrame : Frame
- {
- #region Fields
-
- /// <summary>
- /// Store the combined transformation matrix
- /// </summary>
- private Matrix combined = Matrix.Identity;
-
- #endregion
-
- #region Properties
-
- /// <summary>
- /// Gets or sets the combined transformation matrix
- /// </summary>
- public Matrix CombinedTransformationMatrix
- {
- get { return combined; }
- set { combined = value; }
- }
-
- #endregion
- }
-
- /// <summary>
- /// The mesh container class that will hold the animation data
- /// </summary>
- public class AnimationMeshContainer : MeshContainer
- {
- #region Fields
-
- // Array data
-
- /// <summary>
- /// TODO
- /// </summary>
- private Texture[] meshTextures = null;
-
- /// <summary>
- /// TODO
- /// </summary>
- private BoneCombination[] bones;
-
- /// <summary>
- /// TODO
- /// </summary>
- private Matrix[] offsetMatrices;
-
- /// <summary>
- /// TODO
- /// </summary>
- private AnimationFrame[] frameMatrices;
-
- /// <summary>
- /// TODO
- /// </summary>
- internal ExtendedMaterial[] meshMaterials = null; // array of materials
-
- // Instance data
-
- /// <summary>
- /// The total number of attributes this mesh container contains
- /// </summary>
- private int numAttributes = 0;
-
- /// <summary>
- /// The total number of influences this mesh container contains
- /// </summary>
- private int numInfluences = 0;
-
- /// <summary>
- /// The total number of palette entries this mesh container contains
- /// </summary>
- private int numPalette = 0;
-
- #endregion
-
- #region Properties
-
- /// <summary>
- /// Gets or sets the total number of attributes this mesh container contains
- /// </summary>
- public int NumberAttributes
- {
- get { return numAttributes; }
- set { numAttributes = value; }
- }
-
- /// <summary>
- /// Gets or sets the total number of influences this mesh container contains
- /// </summary>
- public int NumberInfluences
- {
- get { return numInfluences; }
- set { numInfluences = value; }
- }
-
- /// <summary>
- /// Gets or sets the total number of palette entries this mesh container contains
- /// </summary>
- public int NumberPaletteEntries
- {
- get { return numPalette; }
- set { numPalette = value; }
- }
-
- #endregion
-
- #region Methods
-
- /// <summary>
- /// Retrieve the textures used for this container
- /// </summary>
- /// <returns>TODO</returns>
- public Texture[] GetTextures() { return meshTextures; }
-
- /// <summary>
- /// Set the textures used for this container
- /// </summary>
- /// <param name="textures">TODO</param>
- public void SetTextures(Texture[] textures) { meshTextures = textures; }
-
- /// <summary>
- /// Retrieve the bone combinations used for this container
- /// </summary>
- /// <returns>TODO</returns>
- public BoneCombination[] GetBones() { return bones; }
-
- /// <summary>
- /// Set the bone combinations used for this container
- /// </summary>
- /// <param name="b">TODO</param>
- public void SetBones(BoneCombination[] b) { bones = b; }
-
- /// <summary>
- /// Retrieve the animation frames used for this container
- /// </summary>
- /// <returns>TODO</returns>
- public AnimationFrame[] GetFrames() { return frameMatrices; }
-
- /// <summary>
- /// Set the animation frames used for this container
- /// </summary>
- /// <param name="frames">TODO</param>
- public void SetFrames(AnimationFrame[] frames) { frameMatrices = frames; }
-
- /// <summary>
- /// Retrieve the offset matrices used for this container
- /// </summary>
- /// <returns>TODO</returns>
- public Matrix[] GetOffsetMatrices() { return offsetMatrices; }
-
- /// <summary>
- /// Set the offset matrices used for this container
- /// </summary>
- /// <param name="matrices">TODO</param>
- public void SetOffsetMatrices(Matrix[] matrices) { offsetMatrices = matrices; }
-
- #endregion
- }
-
- /// <summary>
- /// AllocateHierarchy derived class
- /// </summary>
- public class AnimationAllocation : AllocateHierarchy
- {
- #region Fields
-
- /// <summary>
- /// TODO
- /// </summary>
- JXLoader parent = null;
-
- #endregion
-
- #region Constructors
-
- /// <summary>
- /// Create new instance of this class
- /// </summary>
- public AnimationAllocation(JXLoader p) { parent = p; }
-
- #endregion
-
- #region Methods
-
- /// <summary>
- /// Creates a new frame
- /// </summary>
- /// <param name="name">TODO</param>
- /// <returns>TODO</returns>
- public override Frame CreateFrame(string name)
- {
- AnimationFrame frame = new AnimationFrame();
- frame.Name = name;
- frame.TransformationMatrix = Matrix.Identity;
- frame.CombinedTransformationMatrix = Matrix.Identity;
-
- Jad.LogWriter.WriteLine("Frame:" + name);
-
- return frame;
- }
-
- /// <summary>
- /// Creates a new mesh container
- /// </summary>
- /// <param name="name">TODO</param>
- /// <param name="meshData">TODO</param>
- /// <param name="materials">TODO</param>
- /// <param name="effectInstances">TODO</param>
- /// <param name="adjacency">TODO</param>
- /// <param name="skinInfo">TODO</param>
- /// <returns>TODO</returns>
- public override MeshContainer CreateMeshContainer(string name,
- MeshData meshData, ExtendedMaterial[] materials,
- EffectInstance[] effectInstances, GraphicsStream adjacency,
- SkinInformation skinInfo)
- {
- // We only handle meshes here
- if (meshData.Mesh == null)
- throw new ArgumentException();
-
- // We must have a vertex format mesh
- if (meshData.Mesh.VertexFormat == VertexFormats.None)
- throw new ArgumentException();
-
- AnimationMeshContainer mesh = new AnimationMeshContainer();
-
- mesh.Name = name;
- int numFaces = meshData.Mesh.NumberFaces;
- Device dev = meshData.Mesh.Device;
-
- Jad.LogWriter.WriteLine("MeshContainer");
- Jad.LogWriter.WriteLine("\tName:" + name);
- Jad.LogWriter.WriteLine("\tNumFaces:" + numFaces.ToString());
- Jad.LogWriter.WriteLine("\tVertexFormat:" + meshData.Mesh.VertexFormat.ToString());
-
- // Make sure there are normals
- if ((meshData.Mesh.VertexFormat & VertexFormats.Normal) == 0)
- {
- // Clone the mesh
- Mesh tempMesh = meshData.Mesh.Clone(meshData.Mesh.Options.Value,
- meshData.Mesh.VertexFormat | VertexFormats.Normal, dev);
-
- // Destroy current mesh, use the new one
- meshData.Mesh.Dispose();
- meshData.Mesh = tempMesh;
- meshData.Mesh.ComputeNormals();
- }
-
- mesh.meshMaterials = materials;
- /*
- // Store the materials
- mesh.SetMaterials(materials);
- mesh.SetAdjacency(adjacency);
- Texture[] meshTextures = new Texture[materials.Length];
-
- // Create any textures
- for (int i = 0; i < materials.Length; i++)
- {
- if (materials[i].TextureFilename != null)
- {
- meshTextures[i] = ResourceCache.GetGlobalInstance().CreateTextureFromFile(
- dev, materials[i].TextureFilename);
- }
- }
- mesh.SetTextures(meshTextures);
- */
- mesh.MeshData = meshData;
-
- return mesh;
- }
-
- #endregion
- }
-
- #endregion
-
- #region Fields
-
- /// <summary>
- /// TODO
- /// </summary>
- Mesh mesh;
-
- /// <summary>
- /// TODO
- /// </summary>
- Device device;
-
- /// <summary>
- /// Array of materials
- /// </summary>
- ExtendedMaterial[] meshMaterials = null;
-
- /// <summary>
- /// TODO
- /// </summary>
- string fileName;
-
- /// <summary>
- /// TODO
- /// </summary>
- Vector3 inScale;
-
- /// <summary>
- /// TODO
- /// </summary>
- AnimationRootFrame rootFrame;
-
- #endregion
-
- #region Methods
-
- /// <summary>
- /// TODO
- /// </summary>
- /// <param name="fileName">TODO</param>
- /// <param name="scale">TODO</param>
- /// <returns>TODO</returns>
- internal bool LoadHierarchy(string fileName, Vector3 scale)
- {
- device = Jad.Video.Device;
-
- inScale = scale;
-
- this.fileName = fileName;
-
- Jad.LogWriter.WriteLine("Loading a Hierarchy .X");
- Jad.LogWriter.WriteLine("filename:" + fileName);
- Jad.LogWriter.WriteLine("scale:" + JMath.Vector3ToString(scale));
-
- // Create our allocate hierarchy derived class
- AnimationAllocation alloc = new AnimationAllocation(this);
-
- rootFrame = Mesh.LoadHierarchyFromFile(fileName, MeshFlags.Managed, device, alloc, null);
-
- ConvertHierarchy(rootFrame.FrameHierarchy as AnimationFrame, Jad.ActiveScene.Root);
-
- Jad.LogWriter.WriteLine("Destroying");
-
- Destroy();
-
- return true;
- }
-
- /// <summary>
- /// Converts the hierarchy to the Jad meshes
- /// </summary>
- /// <param name="frame">TODO</param>
- /// <param name="parent">TODO</param>
- /// <remarks>Empty method</remarks>
- private void ConvertHierarchy(AnimationFrame frame, JNode parent)
- {
- /*
- AnimationMeshContainer mesh = frame.MeshContainer as AnimationMeshContainer;
- // Create a new frame
- HFrame hFrame = new HFrame(frame.Name);
- parent.AddChild(hFrame);
-
- while (mesh != null)
- {
- // Here is the mesh information
-
- JMeshObject meshObject=FromMeshContainerToMesh(mesh);
-
- parent.AddChild(meshObject);
-
- mesh = mesh.NextContainer as AnimationMeshContainer;
- }
- // The same matrix
- if (frame.FrameSibling != null)
- {
- ConvertHierarchy(frame.FrameSibling as AnimationFrame, hFrame);
- }
- // The combined matrix
- if (frame.FrameFirstChild != null)
- {
- ConvertHierarchy(frame.FrameFirstChild as AnimationFrame, hFrame);
- }
- */
- }
-
- /// <summary>
- /// TODO
- /// </summary>
- void Destroy()
- {
- Frame.Destroy(rootFrame.FrameHierarchy, new AnimationAllocation(this));
-
- if (rootFrame.AnimationController != null)
- rootFrame.AnimationController.Dispose();
- }
-
- /// <summary>
- /// TODO
- /// </summary>
- /// <param name="container">TODO</param>
- /// <returns>TODO</returns>
- JMeshObject FromMeshContainerToMesh(AnimationMeshContainer container)
- {
- mesh = container.MeshData.Mesh;
- meshMaterials = container.meshMaterials;
-
- return Convert(container.Name);
- }
-
- /// <summary>
- /// TODO
- /// </summary>
- /// <param name="name">TODO</param>
- /// <returns>TODO</returns>
- internal JMeshObject Convert(string name)
- {
- // Make sure there are normals, which are required for the tesselation
- // enhancement.
-
- VertexFormats vf = mesh.VertexFormat;
-
- // If we have no vertexformat, this is a declaration vertex format.
- // We should check it, but here we assume that this must be the valid vertexformat
- if (vf == VertexFormats.None) vf = VertexFormats.Position | VertexFormats.Texture1;
-
- int numCoordText;
- uint f = (uint) vf & (uint) VertexFormats.TextureCountMask;
-
- f >>= 8;
-
- numCoordText = (int) (f & 255);
-
- if (numCoordText == 0) vf |= VertexFormats.Texture1;
-
- if ((vf & VertexFormats.Normal) == 0 || numCoordText == 0)
- {
- Mesh temporaryMesh = mesh.Clone(mesh.Options.Value,
- vf | VertexFormats.Normal, device);
-
- // Compute normals now
- temporaryMesh.ComputeNormals();
-
- // Set the mesh
- mesh.Dispose();
- mesh = temporaryMesh;
- }
-
- // Optimize to get a good attribute table
- /*
- int[] Adjacency = new int[mesh.NumberFaces * 3];
- mesh.GenerateAdjacency(0.0f, Adjacency);
- mesh.OptimizeInPlace(MeshFlags.OptimizeAttributeSort, Adjacency);
- */
-
- int numAt = meshMaterials.Length;
-
- JMeshObject meshObject = Jad.ActiveScene.MeshObjects.Create(true);
-
- Jad.Import.MeshObjects.Add(meshObject);
-
- meshObject.Mesh.NormalsComputed = true;
-
- meshObject.Mesh.NumAttributes = numAt;
-
- AttributeRange[] attributeRange = JMeshHelper.Optimize(mesh);
-
- JVertexBuffer vb = null;
- JIndexBuffer ib = null;
-
- JMeshHelper.BuffersFromMesh(mesh, out vb, out ib);
-
- meshObject.Mesh.VertexBuffer = vb;
- meshObject.Mesh.IndexBuffer = ib;
-
- mesh.Dispose();
-
- meshObject.Mesh.AttributeRange = attributeRange;
-
- if (inScale.X != 1 || inScale.Y != 1 || inScale.Z != 1)
- meshObject.Mesh.ProcessMatrix(Matrix.Scaling(inScale));
-
- meshObject.Mesh.CenterAtOrigin();
-
- meshObject.Mesh.ComputeTangent();
-
- meshObject.Transform.Position = meshObject.Mesh.TranslationToLocal;
-
- //meshObject.Material = new JMaterial[numAt];
-
- for (int i = 0; i < numAt; i++)
- {
- JMaterial mat = Jad.ActiveScene.Materials.Create();
- meshObject.Materials.Add(mat);
-
- JMaterialLayer layer = new JMaterialLayer();
- layer.DiffuseMap.Color = new JColor(meshMaterials[i].Material3D.DiffuseColor.Red, meshMaterials[i].Material3D.DiffuseColor.Green, meshMaterials[i].Material3D.DiffuseColor.Blue);
-
- if (meshMaterials[i].TextureFilename != null)
- {
- layer.DiffuseMap.Texture = Jad.Video.Textures.Create2D(meshMaterials[i].TextureFilename, true);
- layer.DiffuseMap.Enabled = true;
- }
-
- mat.AddLayer(layer);
- }
-
- return meshObject;
- }
-
- /// <summary>
- /// TODO
- /// </summary>
- /// <param name="fileName">TODO</param>
- /// <param name="scale">TODO</param>
- /// <returns>TODO</returns>
- internal bool Load(string fileName, Vector3 scale)
- {
- Stream stream = null;
-
- //return LoadHierarchy(fileName, scale);
-
- device = Jad.Video.Device;
-
- this.fileName = fileName;
-
- stream = Jad.VFS.GetFileFromDefinedPath("3D", fileName, true);
-
- mesh = Mesh.FromStream(stream, (int) stream.Length, MeshFlags.Managed, device, out meshMaterials);
-
- inScale = scale;
-
- Convert(Path.GetFileNameWithoutExtension(fileName));
-
- return true;
- }
-
- #endregion
- }
- }