예제 #1
0
        /// <summary>
        /// Load the mesh from a stream
        /// </summary>
        /// <param name="filename">The filename and path of the file containing the mesh data</param>
        public virtual void LoadMesh(string filename)
        {
            using(FileStream meshData = new FileStream(filename, FileMode.Open, FileAccess.Read))
            using (EndianAwareBinaryReader reader = new EndianAwareBinaryReader(meshData))
            {
                Header = TrimAt0(reader.ReadString(24));
                if (!String.Equals(Header, MeshHeader))
                    throw new FileLoadException("Unrecognized mesh format");

                // Populate base mesh parameters
                HasWeights = (reader.ReadByte() != 0);
                HasDetailTexCoords = (reader.ReadByte() != 0);
                Position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                RotationAngles = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                /* RotationOrder = */ reader.ReadByte();
                Scale = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                // Populate the vertex array
                NumVertices = reader.ReadUInt16();
                Vertices = new Vertex[NumVertices];
                for (int i = 0; i < NumVertices; i++)
                    Vertices[i].Coord = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                for (int i = 0; i < NumVertices; i++)
                    Vertices[i].Normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                for (int i = 0; i < NumVertices; i++)
                    Vertices[i].BiNormal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                for (int i = 0; i < NumVertices; i++)
                    Vertices[i].TexCoord = new Vector2(reader.ReadSingle(), reader.ReadSingle());

                if (HasDetailTexCoords)
                {
                    for (int i = 0; i < NumVertices; i++)
                        Vertices[i].DetailTexCoord = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                }

                if (HasWeights)
                {
                    for (int i = 0; i < NumVertices; i++)
                        Vertices[i].Weight = reader.ReadSingle();
                }

                NumFaces = reader.ReadUInt16();
                Faces = new Face[NumFaces];

                for (int i = 0; i < NumFaces; i++)
                    Faces[i].Indices = new[] { reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16() };

                if (HasWeights)
                {
                    NumSkinJoints = reader.ReadUInt16();
                    SkinJoints = new string[NumSkinJoints];

                    for (int i = 0; i < NumSkinJoints; i++)
                    {
                        SkinJoints[i] = TrimAt0(reader.ReadString(64));
                    }
                }
                else
                {
                    NumSkinJoints = 0;
                    SkinJoints = new string[0];
                }

                // Grab morphs
                List<Morph> morphs = new List<Morph>();
                string morphName = TrimAt0(reader.ReadString(64));

                while (morphName != MorphFooter)
                {
                    if (reader.BaseStream.Position + 48 >= reader.BaseStream.Length)
                        throw new FileLoadException("Encountered end of file while parsing morphs");

                    Morph morph = new Morph();
                    morph.Name = morphName;
                    morph.NumVertices = reader.ReadInt32();
                    morph.Vertices = new MorphVertex[morph.NumVertices];

                    for (int i = 0; i < morph.NumVertices; i++)
                    {
                        morph.Vertices[i].VertexIndex = reader.ReadUInt32();
                        morph.Vertices[i].Coord = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        morph.Vertices[i].Normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        morph.Vertices[i].BiNormal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        morph.Vertices[i].TexCoord = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                    }

                    morphs.Add(morph);

                    // Grab the next name
                    morphName = TrimAt0(reader.ReadString(64));
                }

                Morphs = morphs.ToArray();

                // Check if there are remaps or if we're at the end of the file
                if (reader.BaseStream.Position < reader.BaseStream.Length - 1)
                {
                    NumRemaps = reader.ReadInt32();
                    VertexRemaps = new VertexRemap[NumRemaps];

                    for (int i = 0; i < NumRemaps; i++)
                    {
                        VertexRemaps[i].RemapSource = reader.ReadInt32();
                        VertexRemaps[i].RemapDestination = reader.ReadInt32();
                    }
                }
                else
                {
                    NumRemaps = 0;
                    VertexRemaps = new VertexRemap[0];
                }
            }

            // uncompress the skin weights
            if (Skeleton != null)
            {
                // some meshes aren't weighted, which doesn't make much sense.
                // we check for left and right eyeballs, and assign them a 100%
                // to their respective bone
                List<string> expandedJointList = Skeleton.BuildExpandedJointList(SkinJoints);
                if (expandedJointList.Count == 0)
                {
                    if (Name == "eyeBallLeftMesh")
                    {
                        expandedJointList.AddRange(new[] { "mEyeLeft", "mSkull" });
                    }
                    else if (Name == "eyeBallRightMesh")
                    {
                        expandedJointList.AddRange(new[] { "mEyeRight", "mSkull" });
                    }
                }

                if (expandedJointList.Count > 0)
                    ExpandCompressedSkinWeights(expandedJointList);
            }
        }
예제 #2
0
        /// <summary>
        /// Load the mesh from a stream
        /// </summary>
        /// <param name="filename">The filename and path of the file containing the mesh data</param>
        public virtual void LoadMesh(string filename)
        {
            using (FileStream meshData = new FileStream(filename, FileMode.Open, FileAccess.Read))
                using (EndianAwareBinaryReader reader = new EndianAwareBinaryReader(meshData))
                {
                    Header = TrimAt0(reader.ReadString(24));
                    if (!String.Equals(Header, MeshHeader))
                    {
                        throw new FileLoadException("Unrecognized mesh format");
                    }

                    // Populate base mesh parameters
                    HasWeights         = (reader.ReadByte() != 0);
                    HasDetailTexCoords = (reader.ReadByte() != 0);
                    Position           = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    RotationAngles     = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    /* RotationOrder = */
                    reader.ReadByte();
                    Scale = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                    // Populate the vertex array
                    NumVertices = reader.ReadUInt16();
                    Vertices    = new Vertex[NumVertices];
                    for (int i = 0; i < NumVertices; i++)
                    {
                        Vertices[i].Coord = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    }

                    for (int i = 0; i < NumVertices; i++)
                    {
                        Vertices[i].Normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    }

                    for (int i = 0; i < NumVertices; i++)
                    {
                        Vertices[i].BiNormal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    }

                    for (int i = 0; i < NumVertices; i++)
                    {
                        Vertices[i].TexCoord = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                    }

                    if (HasDetailTexCoords)
                    {
                        for (int i = 0; i < NumVertices; i++)
                        {
                            Vertices[i].DetailTexCoord = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                        }
                    }

                    if (HasWeights)
                    {
                        for (int i = 0; i < NumVertices; i++)
                        {
                            Vertices[i].Weight = reader.ReadSingle();
                        }
                    }

                    NumFaces = reader.ReadUInt16();
                    Faces    = new Face[NumFaces];

                    for (int i = 0; i < NumFaces; i++)
                    {
                        Faces[i].Indices = new[] { reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16() }
                    }
                    ;

                    if (HasWeights)
                    {
                        NumSkinJoints = reader.ReadUInt16();
                        SkinJoints    = new string[NumSkinJoints];

                        for (int i = 0; i < NumSkinJoints; i++)
                        {
                            SkinJoints[i] = TrimAt0(reader.ReadString(64));
                        }
                    }
                    else
                    {
                        NumSkinJoints = 0;
                        SkinJoints    = new string[0];
                    }

                    // Grab morphs
                    List <Morph> morphs    = new List <Morph>();
                    string       morphName = TrimAt0(reader.ReadString(64));

                    while (morphName != MorphFooter)
                    {
                        if (reader.BaseStream.Position + 48 >= reader.BaseStream.Length)
                        {
                            throw new FileLoadException("Encountered end of file while parsing morphs");
                        }

                        Morph morph = new Morph();
                        morph.Name        = morphName;
                        morph.NumVertices = reader.ReadInt32();
                        morph.Vertices    = new MorphVertex[morph.NumVertices];

                        for (int i = 0; i < morph.NumVertices; i++)
                        {
                            morph.Vertices[i].VertexIndex = reader.ReadUInt32();
                            morph.Vertices[i].Coord       = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                            morph.Vertices[i].Normal      = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                            morph.Vertices[i].BiNormal    = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                            morph.Vertices[i].TexCoord    = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                        }

                        morphs.Add(morph);

                        // Grab the next name
                        morphName = TrimAt0(reader.ReadString(64));
                    }

                    Morphs = morphs.ToArray();

                    // Check if there are remaps or if we're at the end of the file
                    if (reader.BaseStream.Position < reader.BaseStream.Length - 1)
                    {
                        NumRemaps    = reader.ReadInt32();
                        VertexRemaps = new VertexRemap[NumRemaps];

                        for (int i = 0; i < NumRemaps; i++)
                        {
                            VertexRemaps[i].RemapSource      = reader.ReadInt32();
                            VertexRemaps[i].RemapDestination = reader.ReadInt32();
                        }
                    }
                    else
                    {
                        NumRemaps    = 0;
                        VertexRemaps = new VertexRemap[0];
                    }
                }

            // uncompress the skin weights
            if (Skeleton != null)
            {
                // some meshes aren't weighted, which doesn't make much sense.
                // we check for left and right eyeballs, and assign them a 100%
                // to their respective bone
                List <string> expandedJointList = Skeleton.BuildExpandedJointList(SkinJoints);
                if (expandedJointList.Count == 0)
                {
                    if (Name == "eyeBallLeftMesh")
                    {
                        expandedJointList.AddRange(new[] { "mEyeLeft", "mSkull" });
                    }
                    else if (Name == "eyeBallRightMesh")
                    {
                        expandedJointList.AddRange(new[] { "mEyeRight", "mSkull" });
                    }
                }

                if (expandedJointList.Count > 0)
                {
                    ExpandCompressedSkinWeights(expandedJointList);
                }
            }
        }