/// <summary>
        /// Prepare mesh for rendering
        /// </summary>
        void PrepareMesh()
        {
            int i, j, k;

            meshes.Clear();

            // Calculate the final Position ingame Position of all the model vertexes
            for (k = 0; k < numMesh; k++)
            {
                numOfFaces = model[k].numTris;
                vertices   = new Vertex[numOfFaces * 3];

                for (i = 0; i < model[k].numVert; i++)
                {
                    Vector3 finalVertex = new Vector3(0, 0, 0);
                    for (j = 0; j < model[k].verts[i].countw; j++)
                    {
                        MD5Weight wt    = model[k].weights[model[k].verts[i].startw + j];
                        MD5Joint  joint = skeleton[wt.joint];

                        Vector3 wv = MathExt.RotatePoint(ref joint.orient, ref wt.pos);
                        finalVertex.X += (joint.pos.X + wv.X) * wt.bias;
                        finalVertex.Y += (joint.pos.Y + wv.Y) * wt.bias;
                        finalVertex.Z += (joint.pos.Z + wv.Z) * wt.bias;
                    }
                    finalVert[i] = finalVertex;
                }

                // aika laskea normaalit uudelleen?
                if (updateNormalsCount == FramesBetweenNormalsUpdate)
                {
                    MathExt.CalcNormals(ref finalVert, ref model[k].faces, ref normals, false);
                    updateNormalsCount = 0;
                }
                else
                {
                    updateAnimCount++;
                }

                int count = 0;
                // Organize the final vertexes acording to the meshes triangles
                for (i = 0; i < model[k].numTris; i++)
                {
                    vertices[count]     = new Vertex(finalVert[(int)model[k].faces[i][0]], normals[(int)model[k].faces[i][0]], model[k].verts[(int)model[k].faces[i][0]].uv);
                    vertices[count + 1] = new Vertex(finalVert[(int)model[k].faces[i][1]], normals[(int)model[k].faces[i][1]], model[k].verts[(int)model[k].faces[i][1]].uv);
                    vertices[count + 2] = new Vertex(finalVert[(int)model[k].faces[i][2]], normals[(int)model[k].faces[i][2]], model[k].verts[(int)model[k].faces[i][2]].uv);

                    count += 3;
                }
                meshes.Add(vertices);

                if (model[k].vbo != null)
                {
                    model[k].vbo.Update(vertices);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Prepare mesh for rendering
        /// </summary>
        void PrepareMesh()
        {
            int i, j, k;

            meshes.Clear();

            // Calculate the final Position ingame Position of all the model vertexes
            for (k = 0; k < numMesh; k++)
            {
                numOfFaces   = model[k].numTris;
                VertexBuffer = new Vertex[numOfFaces * 3];

                for (i = 0; i < model[k].numVert; i++)
                {
                    Vector3 finalVertex = new Vector3(0, 0, 0);
                    for (j = 0; j < model[k].verts[i].countw; j++)
                    {
                        MD5Weight wt    = model[k].weights[model[k].verts[i].startw + j];
                        MD5Joint  joint = skeleton[wt.joint];

                        Vector3 wv = QuaternionExt.RotatePoint(joint.orient, wt.pos);
                        finalVertex.X += (joint.pos.X + wv.X) * wt.bias;
                        finalVertex.Y += (joint.pos.Y + wv.Y) * wt.bias;
                        finalVertex.Z += (joint.pos.Z + wv.Z) * wt.bias;
                    }
                    finalVert[i] = finalVertex;
                }

                int count = 0;
                // Organize the final vertexes acording to the meshes triangles
                for (i = 0; i < model[k].numTris; i++)
                {
                    VertexBuffer[count]     = new Vertex(finalVert[(int)model[k].faces[i][0]], normals[(int)model[k].faces[i][0]], model[k].verts[(int)model[k].faces[i][0]].uv);
                    VertexBuffer[count + 1] = new Vertex(finalVert[(int)model[k].faces[i][1]], normals[(int)model[k].faces[i][1]], model[k].verts[(int)model[k].faces[i][1]].uv);
                    VertexBuffer[count + 2] = new Vertex(finalVert[(int)model[k].faces[i][2]], normals[(int)model[k].faces[i][2]], model[k].verts[(int)model[k].faces[i][2]].uv);

                    count += 3;
                }
                meshes.Add(VertexBuffer);

                if (model[k].vbo != null)
                {
                    model[k].vbo.Update(VertexBuffer);
                }
            }
        }
Пример #3
0
        bool ReadWeights()
        {
            // weights
            Advance("numweights");
            int weightNum = int.Parse(NextToken);

            weights = new MD5Weight[weightNum];
            for (int j = 0; j < weightNum; j++)
            {
                Advance("weight");
                //sanity check
                int currentWeightNum = int.Parse(NextToken);
                System.Diagnostics.Debug.Assert(j == currentWeightNum, "Invalid weight num!");

                MD5Weight weight = new MD5Weight();
                weight.BoneIndex  = int.Parse(NextToken);
                weight.BiasFactor = NextFloat;
                weight.Vector     = new Vector3(NextFloat, NextFloat, NextFloat);
                weights[j]        = weight;
            }
            return(true);
        }
Пример #4
0
        public MD5MeshContent(string filename)
        {
            int    i, j;
            string line;

            string[] split;

            if (!File.Exists(filename))
            {
                throw new FileNotFoundException("File " + filename + " not found in directory " + Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + ".");
            }

            FileStream   fs     = new FileStream(filename, FileMode.Open);
            StreamReader reader = new StreamReader(fs);

            #region LINE 1 - MD5Version
            line = MD5MeshContent.ReadLine(reader);
            if (!line.StartsWith("MD5Version"))
            {
                throw new Exception("File " + filename + "is not a valid .md5mesh.");
            }
            int Version = int.Parse(line.Substring(10));
            #endregion

            #region LINE 2 - commandline (discard)
            line = MD5MeshContent.ReadLine(reader);
            #endregion

            #region LINE 3 - numJoints
            line = MD5MeshContent.LookForLine(reader, "numJoints ");
            int NumberOfJoints = int.Parse(line.Substring(10));
            #endregion

            #region LINE 4 - numMeshes
            line = MD5MeshContent.LookForLine(reader, "numMeshes ");
            int NumberOfMeshes = int.Parse(line.Substring(10));
            #endregion

            #region CHUNK - Joints
            line = MD5MeshContent.LookForLine(reader, "joints");
            MD5Joint[] joints = new MD5Joint[NumberOfJoints];
            for (i = 0; i < joints.Length; i++)
            {
                MD5Joint joint = new MD5Joint();
                line = MD5MeshContent.ReadLine(reader);

                if (line.StartsWith("}"))
                {
                    throw new Exception("MD5Mesh " + filename + " is invalid: Joints chuck has missing joints.");
                }

                //Line format: "name" parent ( x y z ) ( rX rY rZ )
                split = line.Split(new Char[] { '"', '"', '(', ')', '(', ')' });
                for (j = 0; j < split.Length; j++)
                {
                    split[j] = split[j].Trim();
                }

                if (split.Length != 7)
                {
                    throw new Exception("MD5Mesh " + filename + " is invalid: Joint " + i + " appears to be malformed. ");
                }

                joint.Name   = split[1];
                joint.Parent = int.Parse(split[2]);

                // Position
                string[] pos = split[3].Split(' ', ' ');
                if (pos.Length != 3)
                {
                    throw new Exception("MD5Mesh " + filename + " is invalid: Joint " + i + "'s position data appears to be malformed. ");
                }

                joint.Position = new Vector3(float.Parse(pos[0]), float.Parse(pos[2]), float.Parse(pos[1]));

                // Rotation
                string[] rot = split[5].Split(' ', ' ');
                if (rot.Length != 3)
                {
                    throw new Exception("MD5Mesh " + filename + " is invalid: Joint " + i + "'s rotation data appears to be malformed. ");
                }
                float x, y, z, w;
                x = float.Parse(rot[0]);
                y = float.Parse(rot[2]);
                z = float.Parse(rot[1]);
                w = MD5AnimationContent.ComputeW(x, y, z);

                joint.Rotation = new Quaternion(x, y, z, w);

                joints[i] = joint;
            }
            #endregion

            #region CHUNKS - Meshes
            MD5Submesh[] submeshes = new MD5Submesh[NumberOfMeshes];
            for (i = 0; i < NumberOfMeshes; i++)
            {
                #region Pull the Mesh Chunk Out
                string chunk = "";
                line = MD5MeshContent.LookForLine(reader, "mesh {");

                while (!line.Contains("}"))
                {
                    if (reader.EndOfStream)
                    {
                        throw new Exception("MD5Mesh " + filename + " is invalid: Mesh chunk " + i + " is malformed.");
                    }

                    line   = MD5MeshContent.ReadLine(reader);
                    chunk += line + '\n';
                }
                StringReader sr = new StringReader(chunk);
                #endregion

                MD5Submesh mesh = new MD5Submesh();

                #region mesh.Shader
                line = MD5MeshContent.LookForLine(sr, "shader");
                line = line.Substring(8);
                if (line.LastIndexOf('.') > 0)
                {
                    line = line.Substring(0, line.LastIndexOf('.'));
                }
                if (line.Length > 1 && line[0] == '/' && line[1] == '/')
                {
                    line = line.Substring(2);
                }
                if (line.Length > 1 && line[line.Length - 1] == '"')
                {
                    line = mesh.Shader.Substring(0, line.Length - 1);
                }

                mesh.Shader = line;
                #endregion

                line = MD5MeshContent.LookForLine(sr, "numverts");
                mesh.NumberOfVertices = int.Parse(line.Substring(9));
                mesh.Vertices         = new MD5Vertex[mesh.NumberOfVertices];

                #region mesh.Vertices[j]
                for (j = 0; j < mesh.NumberOfVertices; j++)
                {
                    MD5Vertex vert;

                    line  = MD5MeshContent.LookForLine(sr, "vert");
                    split = line.Split(new char[] { ' ', '(', ' ', ')', ' ' });

                    if (int.Parse(split[1]) != j)
                    {
                        throw new Exception("MD5Mesh " + filename + " is invalid: Vertex " + j + " in mesh chunk " + i + " is missing.");
                    }

                    vert.S               = float.Parse(split[4]);
                    vert.T               = float.Parse(split[5]);
                    vert.FirstWeight     = int.Parse(split[8]);
                    vert.NumberOfWeights = int.Parse(split[9]);

                    mesh.Vertices[j] = vert;
                }
                #endregion

                line = MD5MeshContent.LookForLine(sr, "numtris");
                mesh.NumberOfTriangles = int.Parse(line.Substring(8));
                mesh.Triangles         = new MD5Triangle[mesh.NumberOfTriangles];

                #region mesh.Triangles[j]
                for (j = 0; j < mesh.NumberOfTriangles; j++)
                {
                    MD5Triangle tri = new MD5Triangle();

                    line  = MD5MeshContent.LookForLine(sr, "tri");
                    split = line.Split(new char[] { ' ' });

                    if (int.Parse(split[1]) != j)
                    {
                        throw new Exception("MD5Mesh " + filename + " is invalid: Triangle " + j + " in mesh chunk " + i + " is missing.");
                    }

                    tri.Indices = new int[] { int.Parse(split[2]), int.Parse(split[3]), int.Parse(split[4]) };

                    mesh.Triangles[j] = tri;
                }
                #endregion

                line = MD5MeshContent.LookForLine(sr, "numweights");
                mesh.NumberOfWeights = int.Parse(line.Substring(10));
                mesh.Weights         = new MD5Weight[mesh.NumberOfWeights];

                #region mesh.Weights[j]
                for (j = 0; j < mesh.NumberOfWeights; j++)
                {
                    MD5Weight weight = new MD5Weight();

                    line  = MD5MeshContent.LookForLine(sr, "weight");
                    split = line.Split(new char[] { ' ', '(', ')' });

                    if (int.Parse(split[1]) != j)
                    {
                        throw new Exception("MD5Mesh " + filename + " is invalid: Weight " + j + " in mesh chunk " + i + " is missing.");
                    }

                    weight.Joint    = int.Parse(split[2]);
                    weight.Weight   = float.Parse(split[3]);
                    weight.Position = new Vector3(float.Parse(split[6]), float.Parse(split[8]), float.Parse(split[7]));

                    mesh.Weights[j] = weight;
                }
                #endregion

                submeshes[i] = mesh;
            }
            #endregion

            this.Filename  = filename.Substring(filename.LastIndexOf("Content") + 8);
            this.Joints    = joints;
            this.Submeshes = submeshes;
        }
Пример #5
0
        bool ReadMeshes()
        {
            Advance("nummeshes");
            int meshNum = int.Parse(NextToken);

            mesh = new Mesh();

            for (int i = 0; i < 1 /*meshNum*/; i++)
            {
                Advance("mesh");

                // sanity check
                int num = int.Parse(NextToken);
                System.Diagnostics.Debug.Assert(num == i, "Invalid mesh num!");

                // read mesh data - shader, verts
                Advance("shader");
                string   shaderPath  = NextToken;
                FileInfo info        = new FileInfo(shaderPath);
                string   localPath   = shaderPath.Insert(shaderPath.Length - info.Extension.Length, "_local");
                string   diffusePath = shaderPath.Insert(shaderPath.Length - info.Extension.Length, "_d");
                Textures textures    = new Textures();
                ITexture texture     = null;
                try {
                    texture = TextureManager.Instance.Load(shaderPath);
                } catch {
                    texture = TextureManager.Instance.Load(diffusePath);
                }
                ITexture normalMap = TextureManager.Instance.Load(localPath);
                textures["color"]  = texture;
                textures["normal"] = normalMap;

                if (!ReadVertices())
                {
                    return(false);
                }

                if (!ReadTriangles())
                {
                    return(false);
                }

                if (!ReadWeights())
                {
                    return(false);
                }

                // let's test it
                VertexUnit     vertexUnit     = new VertexUnit(VertexFormat.PositionTexture2Tangent, vertices.Length);
                PositionStream positionStream = (PositionStream)vertexUnit[0];
                TextureStream  textureStream  = (TextureStream)vertexUnit[1];
                TextureStream  normalStream   = (TextureStream)vertexUnit[2];
                for (int j = 0; j < vertices.Length; j++)
                {
                    Vector3   pos    = Vector3.Zero;
                    MD5Vertex vertex = vertices[j];
                    for (int k = 0; k < vertex.WeightCount; k++)
                    {
                        MD5Weight weight = weights[vertex.WeightIndex + k];
                        MD5Bone   bone   = bones[weight.BoneIndex];

                        pos += weight.Vector * bone.Matrix * weight.BiasFactor;
                    }
                    positionStream[j] = pos;
                    textureStream[j]  = vertex.UV;
                    normalStream[j]   = vertex.UV;
                }

                // add tangent space stuff
                IGraphicsStream[] streams = Util.CalcTangentSpaceStreams(positionStream, textureStream, indexStream);

                Array.Copy(streams[0].Data, vertexUnit[3].Data, vertices.Length);
                Array.Copy(streams[1].Data, vertexUnit[4].Data, vertices.Length);
                Array.Copy(streams[2].Data, vertexUnit[5].Data, vertices.Length);
                //mesh.SubSets.Add( new SubSet(vertexUnit, indexStream, material));
            }

            return(true);
        }