Пример #1
0
        private static SELib.SEModelMesh SaveMesh(STGenericObject mesh)
        {
            var seMesh = new SELib.SEModelMesh();

            var MeshLevel = mesh.lodMeshes[mesh.DisplayLODIndex];

            for (int i = 0; i < MeshLevel.faces.Count; i++)
            {
                seMesh.AddFace((uint)MeshLevel.faces[i], (uint)MeshLevel.faces[i++], (uint)MeshLevel.faces[i++]);
            }
            return(seMesh);
        }
Пример #2
0
        /// <summary>
        /// Reads a SEAnim from a stream
        /// </summary>
        /// <param name="Stream">The stream to read from</param>
        /// <returns>A SEAnim if successful, otherwise throws an error and returns null</returns>
        public static SEModel Read(Stream Stream)
        {
            // Create a new model
            var model = new SEModel();

            // Setup a new reader
            using (ExtendedBinaryReader readFile = new ExtendedBinaryReader(Stream))
            {
                // Magic
                var Magic = readFile.ReadChars(7);
                // Version
                var Version = readFile.ReadInt16();
                // Header size
                var HeaderSize = readFile.ReadInt16();
                // Check magic
                if (!Magic.SequenceEqual(new char[] { 'S', 'E', 'M', 'o', 'd', 'e', 'l' }))
                {
                    // Bad file
                    throw new Exception("Bad SEModel file, magic was invalid");
                }
                // Data present flags
                var DataPresentFlags = readFile.ReadByte();
                // Bone data present flags
                var BoneDataPresentFlags = readFile.ReadByte();
                // Mesh data present flags
                var MeshDataPresentFlags = readFile.ReadByte();

                // Read counts
                var BoneCount = readFile.ReadInt32();
                var MeshCount = readFile.ReadInt32();
                var MatCount  = readFile.ReadInt32();

                // Skip 3 reserved bytes
                readFile.BaseStream.Position += 3;

                // Read bone tag names
                List <string> BoneNames = new List <string>();
                // Loop
                for (int i = 0; i < BoneCount; i++)
                {
                    BoneNames.Add(readFile.ReadNullTermString());
                }

                // Loop and read bones
                for (int i = 0; i < BoneCount; i++)
                {
                    // Read bone flags (unused)
                    var BoneFlags = readFile.ReadByte();

                    // Read bone index
                    var ParentIndex = readFile.ReadInt32();

                    // Check for global matricies
                    Vector3    GlobalPosition = Vector3.Zero;
                    Quaternion GlobalRotation = Quaternion.Identity;
                    // Check
                    if (Convert.ToBoolean(BoneDataPresentFlags & (byte)SEModel_BoneDataPresenceFlags.SEMODEL_PRESENCE_GLOBAL_MATRIX))
                    {
                        GlobalPosition = new Vector3(readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle());
                        GlobalRotation = new Quaternion(readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle());
                    }

                    // Check for local matricies
                    Vector3    LocalPosition = Vector3.Zero;
                    Quaternion LocalRotation = Quaternion.Identity;
                    // Check
                    if (Convert.ToBoolean(BoneDataPresentFlags & (byte)SEModel_BoneDataPresenceFlags.SEMODEL_PRESENCE_LOCAL_MATRIX))
                    {
                        LocalPosition = new Vector3(readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle());
                        LocalRotation = new Quaternion(readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle());
                    }

                    // Check for scales
                    Vector3 Scale = Vector3.One;
                    // Check
                    if (Convert.ToBoolean(BoneDataPresentFlags & (byte)SEModel_BoneDataPresenceFlags.SEMODEL_PRESENCE_SCALES))
                    {
                        Scale = new Vector3(readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle());
                    }

                    // Add the bone
                    model.AddBone(BoneNames[i], ParentIndex, GlobalPosition, GlobalRotation, LocalPosition, LocalRotation, Scale);
                }

                // Loop and read meshes
                for (int i = 0; i < MeshCount; i++)
                {
                    // Make a new submesh
                    var mesh = new SEModelMesh();

                    // Read mesh flags (unused)
                    var MeshFlags = readFile.ReadByte();

                    // Read counts
                    var MatIndiciesCount      = readFile.ReadByte();
                    var MaxSkinInfluenceCount = readFile.ReadByte();
                    var VertexCount           = readFile.ReadInt32();
                    var FaceCount             = readFile.ReadInt32();

                    // Loop and read positions
                    for (int v = 0; v < VertexCount; v++)
                    {
                        mesh.AddVertex(new SEModelVertex()
                        {
                            Position = new Vector3(readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle())
                        });
                    }

                    // Read uvlayers
                    if (Convert.ToBoolean(MeshDataPresentFlags & (byte)SEModel_MeshDataPresenceFlags.SEMODEL_PRESENCE_UVSET))
                    {
                        for (int v = 0; v < VertexCount; v++)
                        {
                            for (int l = 0; l < MatIndiciesCount; l++)
                            {
                                mesh.Verticies[v].UVSets.Add(new Vector2(readFile.ReadSingle(), readFile.ReadSingle()));
                            }
                        }
                    }

                    // Read normals
                    if (Convert.ToBoolean(MeshDataPresentFlags & (byte)SEModel_MeshDataPresenceFlags.SEMODEL_PRESENCE_NORMALS))
                    {
                        // Loop and read vertex normals
                        for (int v = 0; v < VertexCount; v++)
                        {
                            mesh.Verticies[v].VertexNormal = new Vector3(readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle());
                        }
                    }

                    // Read colors
                    if (Convert.ToBoolean(MeshDataPresentFlags & (byte)SEModel_MeshDataPresenceFlags.SEMODEL_PRESENCE_COLOR))
                    {
                        // Loop and read colors
                        for (int v = 0; v < VertexCount; v++)
                        {
                            mesh.Verticies[v].VertexColor = new Color(readFile.ReadByte(), readFile.ReadByte(), readFile.ReadByte(), readFile.ReadByte());
                        }
                    }

                    // Read weights
                    if (Convert.ToBoolean(MeshDataPresentFlags & (byte)SEModel_MeshDataPresenceFlags.SEMODEL_PRESENCE_WEIGHTS))
                    {
                        for (int v = 0; v < VertexCount; v++)
                        {
                            // Read IDs and Values
                            for (int l = 0; l < MaxSkinInfluenceCount; l++)
                            {
                                if (BoneCount <= 0xFF)
                                {
                                    mesh.Verticies[v].Weights.Add(new SEModelWeight()
                                    {
                                        BoneIndex = readFile.ReadByte(), BoneWeight = readFile.ReadSingle()
                                    });
                                }
                                else if (BoneCount <= 0xFFFF)
                                {
                                    mesh.Verticies[v].Weights.Add(new SEModelWeight()
                                    {
                                        BoneIndex = readFile.ReadUInt16(), BoneWeight = readFile.ReadSingle()
                                    });
                                }
                                else
                                {
                                    mesh.Verticies[v].Weights.Add(new SEModelWeight()
                                    {
                                        BoneIndex = readFile.ReadUInt32(), BoneWeight = readFile.ReadSingle()
                                    });
                                }
                            }
                        }
                    }

                    // Loop and read faces
                    for (int f = 0; f < FaceCount; f++)
                    {
                        if (VertexCount <= 0xFF)
                        {
                            mesh.AddFace(readFile.ReadByte(), readFile.ReadByte(), readFile.ReadByte());
                        }
                        else if (VertexCount <= 0xFFFF)
                        {
                            mesh.AddFace(readFile.ReadUInt16(), readFile.ReadUInt16(), readFile.ReadUInt16());
                        }
                        else
                        {
                            mesh.AddFace(readFile.ReadUInt32(), readFile.ReadUInt32(), readFile.ReadUInt32());
                        }
                    }

                    // Read material reference indicies
                    for (int f = 0; f < MatIndiciesCount; f++)
                    {
                        mesh.AddMaterialIndex(readFile.ReadInt32());
                    }

                    // Add the mesh
                    model.AddMesh(mesh);
                }

                // Loop and read materials
                for (int m = 0; m < MatCount; m++)
                {
                    var mat = new SEModelMaterial();

                    // Read the name
                    mat.Name = readFile.ReadNullTermString();
                    // Read IsSimpleMaterial
                    var IsSimpleMaterial = readFile.ReadBoolean();

                    // Read the material
                    if (IsSimpleMaterial)
                    {
                        mat.MaterialData = new SEModelSimpleMaterial()
                        {
                            DiffuseMap  = readFile.ReadNullTermString(),
                            NormalMap   = readFile.ReadNullTermString(),
                            SpecularMap = readFile.ReadNullTermString()
                        };
                    }

                    // Add the material
                    model.AddMaterial(mat);
                }
            }
            // Return result
            return(model);
        }
Пример #3
0
 /// <summary>
 /// Adds the given mesh to the model
 /// </summary>
 /// <param name="Mesh">The mesh to add</param>
 public void AddMesh(SEModelMesh Mesh)
 {
     // Add it
     Meshes.Add(Mesh);
 }
Пример #4
0
        public STGenericObject CreateGenericObject(SELib.SEModel seModel, SELib.SEModelMesh seMesh)
        {
            int Index = seModel.Meshes.IndexOf(seMesh);

            STGenericObject mesh = new STGenericObject();

            mesh.ObjectName = $"Mesh_{Index}";
            if (seMesh.MaterialReferenceIndicies.Count > 0)
            {
                mesh.MaterialIndex = seMesh.MaterialReferenceIndicies[0];
            }

            mesh.HasPos = true;
            for (int v = 0; v < seMesh.VertexCount; v++)
            {
                if (seMesh.Verticies[v].UVSets.Count > 0)
                {
                    mesh.HasUv0 = true;
                }
                if (seMesh.Verticies[v].Weights.Count > 0)
                {
                    mesh.HasIndices = true;
                    for (int w = 0; w < seMesh.Verticies[v].WeightCount; w++)
                    {
                        if (seMesh.Verticies[v].Weights[w].BoneWeight != 0)
                        {
                            mesh.HasWeights = true;
                        }
                    }
                }
                if (seMesh.Verticies[v].VertexColor != SELib.Utilities.Color.White)
                {
                    mesh.HasVertColors = true;
                }
                if (seMesh.Verticies[v].VertexNormal != SELib.Utilities.Vector3.Zero)
                {
                    mesh.HasNrm = true;
                }

                Vertex vertex = new Vertex();
                mesh.vertices.Add(vertex);

                vertex.pos = ToTKVector3(seMesh.Verticies[v].Position);
                vertex.nrm = ToTKVector3(seMesh.Verticies[v].VertexNormal);
                vertex.col = ToTKVector4(seMesh.Verticies[v].VertexColor);

                for (int u = 0; u < seMesh.Verticies[v].UVSetCount; u++)
                {
                    if (u == 0)
                    {
                        vertex.uv0 = ToTKVector2(seMesh.Verticies[v].UVSets[u]);
                    }
                    if (u == 1)
                    {
                        vertex.uv1 = ToTKVector2(seMesh.Verticies[v].UVSets[u]);
                    }
                    if (u == 2)
                    {
                        vertex.uv2 = ToTKVector2(seMesh.Verticies[v].UVSets[u]);
                    }
                }

                for (int w = 0; w < seMesh.Verticies[v].WeightCount; w++)
                {
                    //Get the bone name from the index. Indices for formats get set after the importer
                    string BoneName   = seModel.Bones[(int)seMesh.Verticies[v].Weights[w].BoneIndex].BoneName;
                    float  BoneWeight = seMesh.Verticies[v].Weights[w].BoneWeight;

                    vertex.boneNames.Add(BoneName);
                    vertex.boneWeights.Add(BoneWeight);
                }
            }



            mesh.lodMeshes = new List <STGenericObject.LOD_Mesh>();
            var lodMesh = new STGenericObject.LOD_Mesh();

            lodMesh.PrimativeType = STPrimitiveType.Triangles;
            mesh.lodMeshes.Add(lodMesh);
            for (int f = 0; f < seMesh.FaceCount; f++)
            {
                lodMesh.faces.Add((int)seMesh.Faces[f].FaceIndex1);
                lodMesh.faces.Add((int)seMesh.Faces[f].FaceIndex2);
                lodMesh.faces.Add((int)seMesh.Faces[f].FaceIndex3);
            }

            return(mesh);
        }