Example #1
0
        public Model LoadModel(string filename)
        {
            BinaryReader file = null;

            try {
                file = new BinaryReader(new FileStream(filename, FileMode.Open));
                Model model = new Model(game);
                model.Armature = LoadArmature(file, model);
                int meshCount = file.ReadInt32();
                for (int meshID = 0; meshID < meshCount; meshID++)
                {
                    MeshDesc mesh = LoadMesh(file, model.Armature != null);
                    if (mesh.boneIndexMap.Length > MaxBoneCount)
                    {
                        MessageBox.Show(string.Format("The mesh \"{0}\" contains more than {1} bones ({2}) and will be ignored.", mesh.name, MaxBoneCount, mesh.boneIndexMap.Length),
                                        "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        continue;
                    }
                    model.AddMeshDesc(mesh);
                }
                file.Close();
                return(model);
            }
            catch (Exception ex) {
                MessageBox.Show(string.Format("Loading model \"{0}\" failed.\n{1}\n\n{2}", filename, ex.Message, ex.StackTrace),
                                "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                if (file != null)
                {
                    file.Close();
                }
                return(null);
            }
        }
Example #2
0
        public Mesh(GraphicsDevice graphicsDevice, TextureManager textureManager,
                    MeshDesc meshDesc, VertexFormat vertexFormat)
        {
            this.graphicsDevice = graphicsDevice;
            this.textureManager = textureManager;
            this.meshDesc       = meshDesc;
            this.vertexFormat   = vertexFormat;

            this.name    = meshDesc.name;
            vertexBuffer = vertexFormat.BuildVertexBuffer(graphicsDevice, meshDesc);
            indexBuffer  = new IndexBuffer(graphicsDevice, typeof(ushort), meshDesc.indices.Length, BufferUsage.WriteOnly);
            indexBuffer.SetData(meshDesc.indices);
            vertexDeclaration = new VertexDeclaration(graphicsDevice, vertexFormat.VertexElements);
            vertexCount       = meshDesc.vertices.Length;
            faceCount         = meshDesc.indices.Length / 3;
            vertexDataSize    = vertexFormat.SizeInBytes;

            int textureCount = meshDesc.textures.Length;

            textures = new Texture2D[textureCount];
            for (int i = 0; i < textureCount; i++)
            {
                string    textureFilename = meshDesc.textures[i].filename;
                Texture2D texture         = textureManager.GetTexture(textureFilename, meshDesc.textures[i].useMipmaps);
                if (texture == null)
                {
                    Console.WriteLine("Texture \"{0}\" not found!", textureFilename);
                }
                textures[i] = texture;
            }

            isTransparentVertices = false;
            foreach (MeshDesc.Vertex vertex in meshDesc.vertices)
            {
                if (vertex.color.W < 1.0)
                {
                    isTransparentVertices = true;
                    break;
                }
            }

            isTransparentTextures = false;
            foreach (Texture2D texture in textures)
            {
                if (textureManager.IsTransparent(texture))
                {
                    isTransparentTextures = true;
                    break;
                }
            }

            boneIndexMap = meshDesc.boneIndexMap;
            if (meshDesc.renderParams != null)
            {
                renderParams = meshDesc.renderParams;
            }
            isShadeless = meshDesc.isShadeless;
            isVisible   = true;
            boundingBox = CalculateBoundingBox(meshDesc);
        }
Example #3
0
        private MeshDesc BuildMeshDesc(string name, Material material, List <Vertex> vertices, List <Face> faces)
        {
            MeshDesc meshDesc = new MeshDesc();

            meshDesc.name     = name;
            meshDesc.vertices = new MeshDesc.Vertex[vertices.Count];
            for (int i = 0; i < vertices.Count; i++)
            {
                MeshDesc.Vertex v = new MeshDesc.Vertex();
                v.position           = vertices[i].coord;
                v.normal             = vertices[i].normal;
                v.texCoords          = new Vector2[] { vertices[i].texCoord };
                v.color              = vertices[i].color;
                v.boneIndicesGlobal  = new short[] { 0, 0, 0, 0 };
                v.boneIndicesLocal   = new short[] { 0, 0, 0, 0 };
                v.boneWeights        = new float[] { 1, 0, 0, 0 };
                meshDesc.vertices[i] = v;
            }
            meshDesc.indices = new ushort[faces.Count * 3];
            int j = 0;

            for (int i = 0; i < faces.Count; i++)
            {
                meshDesc.indices[j + 0] = (ushort)faces[i].vertexIndices[0];
                meshDesc.indices[j + 1] = (ushort)faces[i].vertexIndices[1];
                meshDesc.indices[j + 2] = (ushort)faces[i].vertexIndices[2];
                j += 3;
            }
            meshDesc.boneIndexMap = new short[] { 0 };
            meshDesc.uvLayerCount = 1;
            CalculateTangents(meshDesc);

            MeshDesc.Texture textureDiffuse = new MeshDesc.Texture();
            textureDiffuse.filename     = material.textureDiffuse;
            textureDiffuse.uvLayerIndex = 0;

            MeshDesc.Texture textureLightmap = null;

            MeshDesc.Texture textureNormal = null;
            if (material.textureNormal != null)
            {
                textureNormal              = new MeshDesc.Texture();
                textureNormal.filename     = material.textureNormal;
                textureNormal.uvLayerIndex = 0;
            }

            MeshDesc.Texture textureSpecular = null;
            if (material.textureSpecular != null)
            {
                textureSpecular              = new MeshDesc.Texture();
                textureSpecular.filename     = material.textureSpecular;
                textureSpecular.uvLayerIndex = 0;
            }

            meshDesc.textures     = new MeshDesc.Texture[] { textureDiffuse, textureLightmap, textureNormal, textureSpecular };
            meshDesc.renderParams = new object[] { material.specular };
            meshDesc.isShadeless  = material.ambient > 0.99f;
            return(meshDesc);
        }
Example #4
0
        public Mesh InitMesh(string meshName, VertexFormat vertexFormat)
        {
            MeshDesc meshDesc = meshDescDict[meshName];
            Mesh     mesh     = new Mesh(graphicsDevice, textureManager, meshDesc, vertexFormat);

            meshDict[meshName] = mesh;
            return(mesh);
        }
Example #5
0
 public void InitMeshes(VertexFormat vertexFormat)
 {
     foreach (KeyValuePair <string, MeshDesc> entry in meshDescDict)
     {
         string   meshName = entry.Key;
         MeshDesc meshDesc = entry.Value;
         Mesh     mesh     = new Mesh(graphicsDevice, textureManager, meshDesc, vertexFormat);
         meshDict[meshName] = mesh;
     }
 }
        private static MeshDesc DeriveMeshDesc(MeshDesc origMeshDesc, string newName, MeshDesc.Vertex[] newVertices, ushort[] newIndices)
        {
            MeshDesc newMeshDesc = new MeshDesc();

            newMeshDesc.name         = newName;
            newMeshDesc.uvLayerCount = origMeshDesc.uvLayerCount;
            newMeshDesc.textures     = origMeshDesc.textures;
            newMeshDesc.vertices     = newVertices;
            newMeshDesc.indices      = newIndices;
            newMeshDesc.boneIndexMap = origMeshDesc.boneIndexMap;
            newMeshDesc.renderParams = origMeshDesc.renderParams;
            newMeshDesc.isShadeless  = origMeshDesc.isShadeless;
            return(newMeshDesc);
        }
Example #7
0
        private BoundingBox CalculateBoundingBox(MeshDesc meshDesc)
        {
            float xMin = float.PositiveInfinity;
            float yMin = float.PositiveInfinity;
            float zMin = float.PositiveInfinity;
            float xMax = float.NegativeInfinity;
            float yMax = float.NegativeInfinity;
            float zMax = float.NegativeInfinity;

            foreach (MeshDesc.Vertex vertex in meshDesc.vertices)
            {
                Vector3 v = vertex.position;
                if (v.X < xMin)
                {
                    xMin = v.X;
                }
                if (v.Y < yMin)
                {
                    yMin = v.Y;
                }
                if (v.Z < zMin)
                {
                    zMin = v.Z;
                }
                if (v.X > xMax)
                {
                    xMax = v.X;
                }
                if (v.Y > yMax)
                {
                    yMax = v.Y;
                }
                if (v.Z > zMax)
                {
                    zMax = v.Z;
                }
            }
            Vector3 min = new Vector3(xMin, yMin, zMin);
            Vector3 max = new Vector3(xMax, yMax, zMax);

            return(new BoundingBox(min, max));
        }
        public static void SplitThorWireframe(Model model)
        {
            MeshDesc meshDesc = model.GetMeshDesc("thorwireframe");

            if (meshDesc == null)
            {
                return;
            }
            model.RemoveMeshDesc(meshDesc.name);

            Dictionary <MeshDesc.Vertex, ushort> vertexMapBelt          = new Dictionary <MeshDesc.Vertex, ushort>();
            Dictionary <MeshDesc.Vertex, ushort> vertexMapGauntletLeft  = new Dictionary <MeshDesc.Vertex, ushort>();
            Dictionary <MeshDesc.Vertex, ushort> vertexMapGauntletRight = new Dictionary <MeshDesc.Vertex, ushort>();

            List <MeshDesc.Vertex> vertexListBelt          = new List <MeshDesc.Vertex>();
            List <MeshDesc.Vertex> vertexListGauntletLeft  = new List <MeshDesc.Vertex>();
            List <MeshDesc.Vertex> vertexListGauntletRight = new List <MeshDesc.Vertex>();

            List <ushort> indicesBelt          = new List <ushort>();
            List <ushort> indicesGauntletLeft  = new List <ushort>();
            List <ushort> indicesGauntletRight = new List <ushort>();

            for (int i = 0; i < meshDesc.indices.Length; i += 3)
            {
                ushort i1 = meshDesc.indices[i + 0];
                ushort i2 = meshDesc.indices[i + 1];
                ushort i3 = meshDesc.indices[i + 2];

                MeshDesc.Vertex v1 = meshDesc.vertices[i1];
                MeshDesc.Vertex v2 = meshDesc.vertices[i2];
                MeshDesc.Vertex v3 = meshDesc.vertices[i3];

                if (BelongsToThorBelt(v1) || BelongsToThorBelt(v2) || BelongsToThorBelt(v3))
                {
                    RegisterVertex(v1, vertexMapBelt, vertexListBelt, indicesBelt);
                    RegisterVertex(v2, vertexMapBelt, vertexListBelt, indicesBelt);
                    RegisterVertex(v3, vertexMapBelt, vertexListBelt, indicesBelt);
                }
                if (BelongsToThorGauntletLeft(v1) || BelongsToThorGauntletLeft(v2) || BelongsToThorGauntletLeft(v3))
                {
                    RegisterVertex(v1, vertexMapGauntletLeft, vertexListGauntletLeft, indicesGauntletLeft);
                    RegisterVertex(v2, vertexMapGauntletLeft, vertexListGauntletLeft, indicesGauntletLeft);
                    RegisterVertex(v3, vertexMapGauntletLeft, vertexListGauntletLeft, indicesGauntletLeft);
                }
                if (BelongsToThorGauntletRight(v1) || BelongsToThorGauntletRight(v2) || BelongsToThorGauntletRight(v3))
                {
                    RegisterVertex(v1, vertexMapGauntletRight, vertexListGauntletRight, indicesGauntletRight);
                    RegisterVertex(v2, vertexMapGauntletRight, vertexListGauntletRight, indicesGauntletRight);
                    RegisterVertex(v3, vertexMapGauntletRight, vertexListGauntletRight, indicesGauntletRight);
                }
            }

            MeshDesc meshDescBelt          = DeriveMeshDesc(meshDesc, "thorglowbelt", vertexListBelt.ToArray(), indicesBelt.ToArray());
            MeshDesc meshDescGauntletLeft  = DeriveMeshDesc(meshDesc, "thorglowgauntletleft", vertexListGauntletLeft.ToArray(), indicesGauntletLeft.ToArray());
            MeshDesc meshDescGauntletRight = DeriveMeshDesc(meshDesc, "thorglowgauntletright", vertexListGauntletRight.ToArray(), indicesGauntletRight.ToArray());

            if (meshDescBelt.vertices.Length > 0)
            {
                model.AddMeshDesc(meshDescBelt);
            }
            if (meshDescGauntletLeft.vertices.Length > 0)
            {
                model.AddMeshDesc(meshDescGauntletLeft);
            }
            if (meshDescGauntletRight.vertices.Length > 0)
            {
                model.AddMeshDesc(meshDescGauntletRight);
            }
        }
Example #9
0
 public abstract VertexBuffer BuildVertexBuffer(GraphicsDevice graphicsDevice, MeshDesc mesh);
Example #10
0
        private MeshDesc LoadMesh(BinaryReader file, bool hasArmature)
        {
            MeshDesc mesh = new MeshDesc();

            mesh.name = file.ReadString();
            int uvLayerCount = file.ReadInt32();

            mesh.uvLayerCount = uvLayerCount;
            int textureCount = file.ReadInt32();

            mesh.textures = new MeshDesc.Texture[textureCount];
            for (int textureID = 0; textureID < textureCount; textureID++)
            {
                MeshDesc.Texture texture = new MeshDesc.Texture();
                texture.filename         = file.ReadString();
                texture.uvLayerIndex     = file.ReadInt32();
                mesh.textures[textureID] = texture;
            }
            Dictionary <short, short> boneIndexDict = new Dictionary <short, short>();
            List <short> boneIndexMap = new List <short>();
            int          vertexCount  = file.ReadInt32();

            mesh.vertices = new MeshDesc.Vertex[vertexCount];
            for (int vertexID = 0; vertexID < vertexCount; vertexID++)
            {
                MeshDesc.Vertex vertex    = new MeshDesc.Vertex();
                float           positionX = file.ReadSingle();
                float           positionY = file.ReadSingle();
                float           positionZ = file.ReadSingle();
                vertex.position = new Vector3(positionX, positionY, positionZ);
                float normalX = file.ReadSingle();
                float normalY = file.ReadSingle();
                float normalZ = file.ReadSingle();
                vertex.normal = new Vector3(normalX, normalY, normalZ);
                float colorR = file.ReadByte() / 255.0f;
                float colorG = file.ReadByte() / 255.0f;
                float colorB = file.ReadByte() / 255.0f;
                float colorA = file.ReadByte() / 255.0f;
                vertex.color     = new Vector4(colorR, colorG, colorB, 1.0f);
                vertex.texCoords = new Vector2[uvLayerCount];
                for (int uvLayerID = 0; uvLayerID < uvLayerCount; uvLayerID++)
                {
                    float texCoordX = file.ReadSingle();
                    float texCoordY = file.ReadSingle();
                    vertex.texCoords[uvLayerID] = new Vector2(texCoordX, texCoordY);
                }
                vertex.tangents = new Vector4[uvLayerCount];
                for (int uvLayerID = 0; uvLayerID < uvLayerCount; uvLayerID++)
                {
                    float tangentX = file.ReadSingle();
                    float tangentY = file.ReadSingle();
                    float tangentZ = file.ReadSingle();
                    float tangentW = file.ReadSingle();
                    vertex.tangents[uvLayerID] = new Vector4(tangentX, tangentY, tangentZ, tangentW);
                }
                if (hasArmature)
                {
                    vertex.boneIndicesGlobal = new short[4];
                    vertex.boneIndicesLocal  = new short[4];
                    for (int i = 0; i < 4; i++)
                    {
                        vertex.boneIndicesGlobal[i] = file.ReadInt16();
                    }
                    vertex.boneWeights = new float[4];
                    float weightSum = 0;
                    for (int i = 0; i < 4; i++)
                    {
                        float weight = file.ReadSingle();
                        vertex.boneWeights[i] = weight;
                        weightSum            += weight;
                    }
                    if (weightSum == 0)
                    {
                        vertex.boneWeights[0] = 1.0f;
                    }
                    else
                    {
                        if (weightSum != 1.0f)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                vertex.boneWeights[i] /= weightSum;
                            }
                        }
                    }
                    short indexDefault = -1;
                    for (int i = 0; i < 4; i++)
                    {
                        if (vertex.boneWeights[i] > 0)
                        {
                            indexDefault = vertex.boneIndicesGlobal[i];
                            break;
                        }
                    }
                    for (int i = 0; i < 4; i++)
                    {
                        short indexGlobal = vertex.boneIndicesGlobal[i];
                        if (vertex.boneWeights[i] == 0)
                        {
                            indexGlobal = indexDefault;
                        }
                        short indexLocal;
                        if (!boneIndexDict.TryGetValue(indexGlobal, out indexLocal))
                        {
                            indexLocal = (short)boneIndexMap.Count;
                            boneIndexDict[indexGlobal] = indexLocal;
                            boneIndexMap.Add(indexGlobal);
                        }
                        vertex.boneIndicesLocal[i] = indexLocal;
                    }
                }
                mesh.vertices[vertexID] = vertex;
            }
            mesh.boneIndexMap = boneIndexMap.ToArray();
            int faceCount = file.ReadInt32();

            mesh.indices = new ushort[faceCount * 3];
            int index = 0;

            for (int faceID = 0; faceID < faceCount; faceID++)
            {
                mesh.indices[index + 0] = (ushort)file.ReadInt32();
                mesh.indices[index + 1] = (ushort)file.ReadInt32();
                mesh.indices[index + 2] = (ushort)file.ReadInt32();
                index += 3;
            }
            return(mesh);
        }
Example #11
0
        public override VertexBuffer BuildVertexBuffer(GraphicsDevice graphicsDevice, MeshDesc meshDesc)
        {
            VertexBuffer vertexBuffer = new VertexBuffer(graphicsDevice, meshDesc.vertices.Length * SizeInBytes, BufferUsage.WriteOnly);

            VertexData[] vertexData = new VertexData[meshDesc.vertices.Length];
            for (int i = 0; i < vertexData.Length; i++)
            {
                vertexData[i].position   = meshDesc.vertices[i].position;
                vertexData[i].normal     = meshDesc.vertices[i].normal;
                vertexData[i].texCoords1 = meshDesc.vertices[i].texCoords[0];
                if (meshDesc.vertices[i].texCoords.Length > 1)
                {
                    vertexData[i].texCoords2 = meshDesc.vertices[i].texCoords[1];
                }
            }
            vertexBuffer.SetData(vertexData);
            return(vertexBuffer);
        }
Example #12
0
 private void CalculateTangents(MeshDesc meshDesc)
 {
     Vector3[,] tangentsU = new Vector3[meshDesc.vertices.Length, meshDesc.uvLayerCount];
     Vector3[,] tangentsV = new Vector3[meshDesc.vertices.Length, meshDesc.uvLayerCount];
     for (int vertexID = 0; vertexID < meshDesc.vertices.Length; vertexID++)
     {
         MeshDesc.Vertex vertex = meshDesc.vertices[vertexID];
         vertex.tangents = new Vector4[meshDesc.uvLayerCount];
         for (int uvLayerID = 0; uvLayerID < meshDesc.uvLayerCount; uvLayerID++)
         {
             tangentsU[vertexID, uvLayerID] = Vector3.Zero;
             tangentsV[vertexID, uvLayerID] = Vector3.Zero;
         }
     }
     for (int uvLayerID = 0; uvLayerID < meshDesc.uvLayerCount; uvLayerID++)
     {
         for (int i = 0; i < meshDesc.indices.Length; i += 3)
         {
             int             vertexID0 = meshDesc.indices[i + 0];
             int             vertexID1 = meshDesc.indices[i + 1];
             int             vertexID2 = meshDesc.indices[i + 2];
             MeshDesc.Vertex v0        = meshDesc.vertices[vertexID0];
             MeshDesc.Vertex v1        = meshDesc.vertices[vertexID1];
             MeshDesc.Vertex v2        = meshDesc.vertices[vertexID2];
             Vector3         p0        = v0.position;
             Vector3         p1        = v1.position;
             Vector3         p2        = v2.position;
             Vector3         q1        = new Vector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
             Vector3         q2        = new Vector3(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z);
             float           s1        = v1.texCoords[uvLayerID].X - v0.texCoords[uvLayerID].X;
             float           t1        = v1.texCoords[uvLayerID].Y - v0.texCoords[uvLayerID].Y;
             float           s2        = v2.texCoords[uvLayerID].X - v0.texCoords[uvLayerID].X;
             float           t2        = v2.texCoords[uvLayerID].Y - v0.texCoords[uvLayerID].Y;
             float           d         = s1 * t2 - s2 * t1;
             if (d == 0)
             {
                 continue;
             }
             float   k            = 1 / d;
             Vector3 faceTangentU = new Vector3(
                 (t2 * q1.X - t1 * q2.X) * k,
                 (t2 * q1.Y - t1 * q2.Y) * k,
                 (t2 * q1.Z - t1 * q2.Z) * k);
             Vector3 faceTangentV = new Vector3(
                 (s1 * q2.X - s2 * q1.X) * k,
                 (s1 * q2.Y - s2 * q1.Y) * k,
                 (s1 * q2.Z - s2 * q1.Z) * k);
             if (faceTangentU.Length() > 0)
             {
                 faceTangentU.Normalize();
             }
             if (faceTangentV.Length() > 0)
             {
                 faceTangentV.Normalize();
             }
             tangentsU[vertexID0, uvLayerID] += faceTangentU;
             tangentsU[vertexID1, uvLayerID] += faceTangentU;
             tangentsU[vertexID2, uvLayerID] += faceTangentU;
             tangentsV[vertexID0, uvLayerID] += faceTangentV;
             tangentsV[vertexID1, uvLayerID] += faceTangentV;
             tangentsV[vertexID2, uvLayerID] += faceTangentV;
         }
     }
     for (int vertexID = 0; vertexID < meshDesc.vertices.Length; vertexID++)
     {
         MeshDesc.Vertex vertex = meshDesc.vertices[vertexID];
         vertex.tangents = new Vector4[meshDesc.uvLayerCount];
         Vector3 normal = vertex.normal;
         for (int uvLayerID = 0; uvLayerID < meshDesc.uvLayerCount; uvLayerID++)
         {
             Vector3 tangentU = tangentsU[vertexID, uvLayerID];
             Vector3 tangentV = tangentsV[vertexID, uvLayerID];
             if (tangentU.Length() > 0)
             {
                 tangentU.Normalize();
             }
             if (tangentV.Length() > 0)
             {
                 tangentV.Normalize();
             }
             Vector3 tangent = tangentU - normal * (normal * tangentU);
             if (tangent.Length() > 0)
             {
                 tangent.Normalize();
             }
             float w = Vector3.Dot(Vector3.Cross(normal, tangentU), tangentV) > 0 ? 1 : -1;
             vertex.tangents[uvLayerID] =
                 new Vector4(tangent.X, tangent.Y, tangent.Z, w);
         }
     }
 }
Example #13
0
        private Model LoadModel(string filenameObj, Dictionary <string, Material> materials)
        {
            StreamReader file = null;

            try {
                file = new StreamReader(filenameObj);
            }
            catch (Exception) {
                MessageBox.Show("Could not open OBJ file.",
                                "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(null);
            }
            try {
                Model          model           = new Model(game);
                List <Vector3> vertexCoords    = new List <Vector3>();
                List <Vector3> vertexNormals   = new List <Vector3>();
                List <Vector2> vertexTexCoords = new List <Vector2>();
                List <Vector4> vertexColors    = new List <Vector4>();

                List <Vertex>            vertexList = new List <Vertex>();
                Dictionary <Vertex, int> vertexDict = new Dictionary <Vertex, int>();
                List <Face> faces = new List <Face>();

                int      meshID   = 0;
                Material material = null;
                lineCounter = 0;

                while (true)
                {
                    lineCounter++;
                    string line = file.ReadLine();
                    if (line != null)
                    {
                        line = line.TrimStart();
                    }

                    if (line == null || line.StartsWith("usemtl "))
                    {
                        if (faces.Count > 0)
                        {
                            if (material == null)
                            {
                                throw new Exception(string.Format("No material assigned (line {0}).", lineCounter));
                            }
                            if (material.textureDiffuse == null)
                            {
                                throw new Exception(string.Format("No diffuse texture defined for material \"{0}\".", material.name));
                            }
                            meshID++;
                            string   meshName = string.Format("Mesh{0}", meshID);
                            MeshDesc meshDesc = BuildMeshDesc(meshName, material, vertexList, faces);
                            model.AddMeshDesc(meshDesc);
                            vertexList.Clear();
                            vertexDict.Clear();
                            faces.Clear();
                        }
                        if (line == null)
                        {
                            break;
                        }
                        string materialName = line.Substring(7).Trim();
                        material = materials[materialName];
                    }

                    if (line.StartsWith("v "))
                    {
                        Vector3 coord = ParseVertexCoord(line.Substring(2));
                        vertexCoords.Add(coord);
                        continue;
                    }
                    if (line.StartsWith("vn "))
                    {
                        Vector3 normal = ParseVertexNormal(line.Substring(3));
                        normal.Normalize();
                        vertexNormals.Add(normal);
                        continue;
                    }
                    if (line.StartsWith("vt "))
                    {
                        Vector2 texCoord = ParseVertexTexCoord(line.Substring(3));
                        vertexTexCoords.Add(texCoord);
                        continue;
                    }
                    if (line.StartsWith("vc "))
                    {
                        Vector4 color = ParseVertexColor(line.Substring(3));
                        vertexColors.Add(color);
                        continue;
                    }
                    if (line.StartsWith("f "))
                    {
                        Face face = ParseFace(line.Substring(2));
                        try {
                            for (int i = 0; i < face.vertexIndices.Length; i++)
                            {
                                Vertex vertex = new Vertex();
                                int    index;
                                index           = face.coordIndices[i];
                                vertex.coord    = index > 0 ? vertexCoords[index - 1] : vertexCoords[vertexCoords.Count + index];
                                index           = face.normalIndices[i];
                                vertex.normal   = index > 0 ? vertexNormals[index - 1] : vertexNormals[vertexNormals.Count + index];
                                index           = face.texCoordIndices[i];
                                vertex.texCoord = index > 0 ? vertexTexCoords[index - 1] : vertexTexCoords[vertexTexCoords.Count + index];
                                if (face.colorIndices != null)
                                {
                                    index        = face.colorIndices[i];
                                    vertex.color = index > 0 ? vertexColors[index - 1] : vertexColors[vertexColors.Count + index];
                                }
                                else
                                {
                                    vertex.color = new Vector4(1, 1, 1, 1);
                                }
                                if (!vertexDict.TryGetValue(vertex, out index))
                                {
                                    index = vertexList.Count;
                                    vertexList.Add(vertex);
                                    vertexDict[vertex] = index;
                                }
                                face.vertexIndices[i] = index;
                            }
                        }
                        catch (Exception) {
                            throw new Exception(string.Format("Invalid face: invalid vertex index (line {0}).", lineCounter));
                        }
                        if (face.vertexIndices.Length == 3)
                        {
                            FlipTriangularFace(face);
                            faces.Add(face);
                        }
                        else
                        {
                            Face[] triFaces = Triangulate(face);
                            FlipTriangularFace(triFaces[0]);
                            FlipTriangularFace(triFaces[1]);
                            faces.Add(triFaces[0]);
                            faces.Add(triFaces[1]);
                        }
                        continue;
                    }
                }

                Armature      armature = new Armature(model);
                Armature.Bone bone     = new Armature.Bone();
                bone.armature    = armature;
                bone.id          = 0;
                bone.name        = "root";
                bone.absPosition = Vector3.Zero;
                bone.parent      = null;
                armature.Bones   = new Armature.Bone[] { bone };
                model.Armature   = armature;

                file.Close();
                return(model);
            }
            catch (Exception ex) {
                MessageBox.Show("Could not load OBJ file.\n" + ex.Message,
                                "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(null);
            }
        }
Example #14
0
        public override VertexBuffer BuildVertexBuffer(GraphicsDevice graphicsDevice, MeshDesc meshDesc)
        {
            VertexBuffer vertexBuffer = new VertexBuffer(graphicsDevice, meshDesc.vertices.Length * SizeInBytes, BufferUsage.WriteOnly);

            VertexData[] vertexData = new VertexData[meshDesc.vertices.Length];
            for (int i = 0; i < vertexData.Length; i++)
            {
                vertexData[i].position  = meshDesc.vertices[i].position;
                vertexData[i].color     = meshDesc.vertices[i].color;
                vertexData[i].normal    = meshDesc.vertices[i].normal;
                vertexData[i].texCoords = meshDesc.vertices[i].texCoords[0];
                if (meshDesc.vertices[i].tangents != null)
                {
                    vertexData[i].tangent = meshDesc.vertices[i].tangents[0];
                }
                short[] boneIndices = meshDesc.vertices[i].boneIndicesLocal;
                float[] boneWeights = meshDesc.vertices[i].boneWeights;
                if (boneIndices != null)
                {
                    vertexData[i].boneIndices = new Vector4(boneIndices[0], boneIndices[1], boneIndices[2], boneIndices[3]);
                }
                if (boneWeights != null)
                {
                    vertexData[i].boneWeights = new Vector4(boneWeights[0], boneWeights[1], boneWeights[2], boneWeights[3]);
                }
            }
            vertexBuffer.SetData(vertexData);
            return(vertexBuffer);
        }
Example #15
0
 public void AddMeshDesc(MeshDesc meshDesc)
 {
     meshDescDict[meshDesc.name] = meshDesc;
 }