/// <summary> /// Loads a scene from the specified file, returning a list of mesh objects /// </summary> /// <param name="meshFilename"></param> /// <param name="shaderPathLocation"></param> /// <param name="texturePathLocation"></param> /// <returns></returns> public static IEnumerable <CMOAnimateMeshComponent> LoadFromFile(string meshFilename) { var loadedMeshes = new List <CMOAnimateMeshComponent>(); Stream fs = null; try { using (fs = File.OpenRead(meshFilename)) using (BinaryReader br = new BinaryReader(fs)) { // Read how many meshes are in the scene var meshCount = br.ReadUInt32(); for (var i = 0; i < meshCount; i++) { // Load the mesh var mesh = CMOAnimateMeshComponent.Load(br); if (mesh != null) { loadedMeshes.Add(mesh); } } } } catch (Exception e) { Debug.WriteLine("Unable to load mesh file '" + meshFilename + "': " + e.ToString()); } return(loadedMeshes); }
/// <summary> /// Load a mesh /// </summary> /// <param name="br"></param> /// <returns></returns> internal static CMOAnimateMeshComponent Load(BinaryReader br) { // Create new mesh object CMOAnimateMeshComponent mesh = new CMOAnimateMeshComponent(); // UINT - Length of name // wchar_t[] - Name of mesh (if length > 0) // UINT - Material count // { [Material count] // UINT - Length of material name // wchar_t[] - Name of material (if length > 0) // Vector4 Ambient; // Vector4 Diffuse; // Vector4 Specular; // float SpecularPower; // Vector4 Emissive; // Matrix UVTransform; // UINT - Length of pixel shader name // wchar_t[] - Name of pixel shader (if length > 0) // { [8] // UINT - Length of texture name // wchar_t[] - Name of texture (if length > 0) // } // } // read name of mesh mesh.Name = br.ReadCMO_wchar(); // read material count int numMaterials = (int)br.ReadUInt32(); mesh.Materials = new List <Material>(numMaterials); // load each material for (int i = 0; i < numMaterials; i++) { Material material = new Material(); material.Name = br.ReadCMO_wchar(); material.Ambient = br.ReadStructure <Vector4>(); material.Diffuse = br.ReadStructure <Vector4>(); material.Specular = br.ReadStructure <Vector4>(); material.SpecularPower = br.ReadSingle(); material.Emissive = br.ReadStructure <Vector4>(); material.UVTransform = br.ReadStructure <Matrix4x4>(); // read pixel shader name material.PixelShaderName = br.ReadCMO_wchar(); //material.Textures = new string[Mesh.MaxTextures]; List <String> textures = new List <string>(); for (int t = 0; t < MaxTextures; t++) { // read name of texture var textureName = br.ReadCMO_wchar(); textures.Add(textureName); } material.Textures = textures.ToArray(); mesh.Materials.Add(material); } // BYTE - 1 if there is skeletal animation data present // is there skeletal animation data present? bool isAnimationData = br.ReadByte() == 1; // UINT - SubMesh count // { [SubMesh count] // SubMesh structure // } // load sub meshes if any int subMeshCount = (int)br.ReadUInt32(); mesh.SubMeshes = new List <SubMesh>(subMeshCount); for (int i = 0; i < subMeshCount; i++) { mesh.SubMeshes.Add(br.ReadStructure <SubMesh>()); } // UINT - IB Count // { [IB Count] // UINT - Number of USHORTs in IB // USHORT[] - Array of indices // } // load index buffers int indexBufferCount = (int)br.ReadUInt32(); mesh.IndexBuffers = new List <ushort[]>(indexBufferCount); for (var i = 0; i < indexBufferCount; i++) { mesh.IndexBuffers.Add(br.ReadUInt16((int)br.ReadUInt32())); } // UINT - VB Count // { [VB Count] // UINT - Number of verts in VB // Vertex[] - Array of vertices // } // load vertex buffers int vertexBufferCount = (int)br.ReadUInt32(); mesh.VertexBuffers = new List <Vertex[]>(vertexBufferCount); for (var i = 0; i < vertexBufferCount; i++) { mesh.VertexBuffers.Add(br.ReadStructure <Vertex>((int)br.ReadUInt32())); } // UINT - Skinning VB Count // { [Skinning VB Count] // UINT - Number of verts in Skinning VB // SkinningVertex[] - Array of skinning verts // } // load vertex skinning buffers int skinningVertexBufferCount = (int)br.ReadUInt32(); mesh.SkinningVertexBuffers = new List <SkinningVertex[]>(skinningVertexBufferCount); for (var i = 0; i < skinningVertexBufferCount; i++) { mesh.SkinningVertexBuffers.Add(br.ReadStructure <SkinningVertex>((int)br.ReadUInt32())); } // load mesh extent mesh.Extent = br.ReadStructure <MeshExtent>(); // load bone animation data if (isAnimationData) { // UINT - Bone count // { [Bone count] // UINT - Length of bone name // wchar_t[] - Bone name (if length > 0) // Bone structure // } int boneCount = (int)br.ReadUInt32(); mesh.BoneNames = new List <string>(boneCount); mesh.Bones = new List <Bone>(boneCount); for (var i = 0; i < boneCount; i++) { mesh.BoneNames.Add(br.ReadCMO_wchar()); mesh.Bones.Add(br.ReadStructure <Bone>()); } // UINT - Animation clip count // { [Animation clip count] // UINT - Length of clip name // wchar_t[] - Clip name (if length > 0) // float - Start time // float - End time // UINT - Keyframe count // { [Keyframe count] // Keyframe structure // } // } int animationCount = (int)br.ReadUInt32(); mesh.Animations = new Dictionary <string, Animation>(animationCount); for (var i = 0; i < animationCount; i++) { Animation animation; string animationName = br.ReadCMO_wchar(); animation.StartTime = br.ReadSingle(); animation.EndTime = br.ReadSingle(); int keyframeCount = (int)br.ReadUInt32(); animation.Keyframes = new List <Keyframe>(keyframeCount); for (var j = 0; j < keyframeCount; j++) { animation.Keyframes.Add(br.ReadStructure <Keyframe>()); } mesh.Animations.Add(animationName, animation); } } mesh.Triangles = new List <Triangle>(); // Load triangles and precalculate face normal foreach (var subMesh in mesh.SubMeshes) { var indexBuffer = mesh.IndexBuffers[(int)subMesh.IndexBufferIndex]; var vertexBuffer = mesh.VertexBuffers[(int)subMesh.VertexBufferIndex]; for (int i = 0; i < indexBuffer.Length; i += 3) { var v0 = vertexBuffer[(int)indexBuffer[i]]; var v1 = vertexBuffer[(int)indexBuffer[i + 1]]; var v2 = vertexBuffer[(int)indexBuffer[i + 2]]; Vertex[] vertices = new Vertex[3] { v0, v1, v2 }; mesh.Triangles.Add(new Triangle(vertices, i, i + 1, i + 2)); } } // return the final result return(mesh); }