Example #1
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);
        }
        private static void RegisterVertex(MeshDesc.Vertex vertex,
                                           Dictionary <MeshDesc.Vertex, ushort> vertexMap, List <MeshDesc.Vertex> vertexList, List <ushort> indices)
        {
            ushort index;

            if (!vertexMap.TryGetValue(vertex, out index))
            {
                index             = (ushort)vertexList.Count;
                vertexMap[vertex] = index;
                vertexList.Add(vertex);
            }
            indices.Add(index);
        }
Example #3
0
        public static void TransformVertex(
            MeshDesc.Vertex vertex,
            Matrix worldMatrix, Matrix[] boneMatrices, short[] boneIndexMap,
            out Vector3 position, out Vector3 normal)
        {
            Matrix m =
                boneMatrices[boneIndexMap[vertex.boneIndicesLocal[0]]] * vertex.boneWeights[0] +
                boneMatrices[boneIndexMap[vertex.boneIndicesLocal[1]]] * vertex.boneWeights[1] +
                boneMatrices[boneIndexMap[vertex.boneIndicesLocal[2]]] * vertex.boneWeights[2] +
                boneMatrices[boneIndexMap[vertex.boneIndicesLocal[3]]] * vertex.boneWeights[3];

            m       *= worldMatrix;
            position = Vector3.Transform(vertex.position, m);
            m.M41    = 0;
            m.M42    = 0;
            m.M43    = 0;
            normal   = Vector3.Transform(vertex.normal, m);
        }
 private static bool BelongsToThorGauntletRight(MeshDesc.Vertex vertex)
 {
     return(vertex.position.Y > 1.25 && vertex.position.X < 0);
 }
 private static bool BelongsToThorBelt(MeshDesc.Vertex vertex)
 {
     return(vertex.position.Y < 1.25);
 }
        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 #7
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 #8
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);
         }
     }
 }