Пример #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);
                }
            }
        }