public ModelMD5(Game game, MD5Mesh meshFile) { ResourceContentManager rm = new ResourceContentManager(game.Services, XNAQ3Lib.MD5.Resources.MD5Resources.ResourceManager); mesh = meshFile; graphicsDevice = game.GraphicsDevice; animationController = new MD5AnimationController(mesh.Hierarchy); UseMaximumBounds = true; modelEffect = rm.Load <Effect>("SkinnedModelEffect"); boundingBoxEffect = rm.Load <Effect>("BoundingBoxEffect"); vertices = new MD5VertexFormat[mesh.Submeshes.Length][]; indices = new short[mesh.Submeshes.Length][]; MD5Logger logger = new MD5Logger(game.Content.RootDirectory + "\\" + meshFile.Filename + ".txt"); for (int i = 0; i < mesh.Submeshes.Length; i++) { vertices[i] = new MD5VertexFormat[mesh.Submeshes[i].Vertices.Length]; if (System.IO.File.Exists(game.Content.RootDirectory + @"\" + mesh.Submeshes[i].Shader + ".xnb")) { mesh.Submeshes[i].Texture = game.Content.Load <Texture2D>(mesh.Submeshes[i].Shader); } else { logger.WriteLine("Missing texture: " + mesh.Submeshes[i].Shader); } } SetIndices(); SetVertices(); SetBoundingBoxVerticesAndIndices(graphicsDevice); }
private void SetVertices() { int i, j, k; for (i = 0; i < mesh.Submeshes.Length; i++) { for (j = 0; j < vertices[i].Length; j++) { MD5VertexFormat vert = new MD5VertexFormat(); MD5Vertex input = mesh.Submeshes[i].Vertices[j]; vert.Position = new Vector4(BuildVertexPosition(i, j), 1.0f); vert.Normal = Vector3.Zero; vert.TexCoord = input.TexCoord; vert.BoneIndices = Vector4.Zero; vert.BoneWeights = Vector4.Zero; // Determine the boneIndices and boneWeights, if there aren't four bones effecting this joint the default zeros will work vert.BoneIndices.X = mesh.Submeshes[i].Weights[input.FirstWeight].Joint; vert.BoneWeights.X = mesh.Submeshes[i].Weights[input.FirstWeight].Weight; if (input.NumberOfWeights > 1) { vert.BoneIndices.Y = mesh.Submeshes[i].Weights[input.FirstWeight + 1].Joint; vert.BoneWeights.Y = mesh.Submeshes[i].Weights[input.FirstWeight + 1].Weight; } if (input.NumberOfWeights > 2) { vert.BoneIndices.Z = mesh.Submeshes[i].Weights[input.FirstWeight + 2].Joint; vert.BoneWeights.Z = mesh.Submeshes[i].Weights[input.FirstWeight + 2].Weight; } if (input.NumberOfWeights > 3) { vert.BoneIndices.W = mesh.Submeshes[i].Weights[input.FirstWeight + 3].Joint; vert.BoneWeights.W = mesh.Submeshes[i].Weights[input.FirstWeight + 3].Weight; } vertices[i][j] = vert; } for (j = 0; j < mesh.Submeshes[i].NumberOfTriangles; j++) { int index0, index1, index2; index0 = indices[i][3 * j]; index1 = indices[i][3 * j + 1]; index2 = indices[i][3 * j + 2]; Vector3 side1 = BuildVertexPosition(i, index0) - BuildVertexPosition(i, index1); Vector3 side2 = BuildVertexPosition(i, index0) - BuildVertexPosition(i, index2); Vector3 normal = Vector3.Cross(side1, side2); vertices[i][index0].Normal += normal; vertices[i][index1].Normal += normal; vertices[i][index2].Normal += normal; } for (j = 0; j < mesh.Submeshes[i].Vertices.Length; j++) { MD5Vertex vertex = mesh.Submeshes[i].Vertices[j]; Vector3 normal = Vector3.Zero; for (k = 0; k < vertex.NumberOfWeights; k++) { MD5Weight weight = mesh.Submeshes[i].Weights[vertex.FirstWeight + k]; normal = Vector3.Transform(normal, Quaternion.Inverse(mesh.Joints[weight.Joint].Rotation)); vertices[i][j].Normal += normal * weight.Weight; } } } }