예제 #1
0
        public static Model ReadModel(BinaryReader rdr)
        {
            byte[] magic = rdr.ReadBytes(4);
            if (!BitConverter.ToString(magic, 0).Equals("UMDL"))
            {
                return(null);
            }

            Model ret = new Model();

            uint vertexBufferCt = rdr.ReadUInt32();

            //Read the vertex buffers
            for (uint i = 0; i < vertexBufferCt; ++i)
            {
                uint   vertCt     = rdr.ReadUInt32();
                uint   vertMask   = rdr.ReadUInt32();
                uint   vertexSize = GetVertexSize(vertMask);
                uint   morphStart = rdr.ReadUInt32();
                uint   morphCt    = rdr.ReadUInt32();
                byte[] vertexData = rdr.ReadBytes((int)(vertCt * vertexSize));
                ret.VertexBuffers.Add(new VertexBuffer(vertexData, (int)vertexSize));
            }

            uint indexBufferCt = rdr.ReadUInt32();

            for (uint i = 0; i < indexBufferCt; ++i)
            {
                uint   indexCt   = rdr.ReadUInt32();
                uint   indexSize = rdr.ReadUInt32();
                byte[] indexData = rdr.ReadBytes((int)(indexCt * indexSize));
                ret.IndexBuffers.Add(new IndexBuffer(indexData));
            }

            uint geomCt = rdr.ReadUInt32();

            for (uint i = 0; i < geomCt; ++i)
            {
                Geometry geom = new Geometry();

                uint   boneMapCt        = rdr.ReadUInt32();
                byte[] boneMappingBytes = rdr.ReadBytes((int)(sizeof(uint) * boneMapCt));
                uint[] boneMapping      = new uint[boneMapCt];
                for (int idx = 0, boneIdx = 0; idx < boneMappingBytes.Length; idx += 4, boneIdx += 1)
                {
                    boneMapping[boneIdx] = BitConverter.ToUInt32(boneMappingBytes, idx);
                }
                geom.BoneMapping = boneMapping;

                uint lodCt = rdr.ReadUInt32();

                for (int lodIdx = 0; lodIdx < lodCt; ++lodIdx)
                {
                    float dist             = rdr.ReadSingle();
                    uint  prim             = rdr.ReadUInt32();
                    uint  vertBufferIndex  = rdr.ReadUInt32();
                    uint  indexBufferIndex = rdr.ReadUInt32();
                    uint  drawRangeStart   = rdr.ReadUInt32();
                    uint  drawRangeEnd     = rdr.ReadUInt32();

                    LOD lod = new LOD();
                    lod.VertexBuffer = ret.VertexBuffers[(int)vertBufferIndex];
                    lod.IndexBuffer  = ret.IndexBuffers[(int)indexBufferIndex];
                    lod.IndexStart   = drawRangeStart;
                    lod.IndexEnd     = drawRangeEnd;
                    lod.Distance     = dist;
                    lod.Primitive    = prim;

                    geom.LODs.Add(lod);
                }

                ret.Geometries.Add(geom);
            }

            uint vertexMorphCt = rdr.ReadUInt32();

            for (int i = 0; i < vertexMorphCt; ++i)
            {
                string name            = ReadCString(rdr);
                uint   affectedBuffers = rdr.ReadUInt32();

                VertexMorph morph = new VertexMorph();
                morph.Name = name;

                for (int bufIdx = 0; bufIdx < affectedBuffers; ++i)
                {
                    MorphAffectedBuffer buff = new MorphAffectedBuffer();
                    buff.Idx    = rdr.ReadUInt32();
                    buff.Mask   = rdr.ReadUInt32();
                    buff.VertCt = rdr.ReadUInt32();
                    buff.Buffer = ret.VertexBuffers[(int)buff.Idx];
                    morph.Buffers.Add(buff);

                    for (int vertIdx = 0; vertIdx < buff.VertCt; ++vertIdx)
                    {
                        uint morphVertexIndex = rdr.ReadUInt32();
                        //\todo check mask
                        MorphVertex vert = new MorphVertex();

                        if ((buff.Mask & 0x1) != 0)
                        {
                            vert.Position = ReadVector3(rdr);
                        }
                        if ((buff.Mask & 0x2) != 0)
                        {
                            vert.Normal = ReadVector3(rdr);
                        }
                        if ((buff.Mask & 0x80) != 0)
                        {
                            vert.Tangent = ReadVector3(rdr);
                        }
                        buff.Vertices.Add(vert);
                    }
                }
            }

            //Skeleton data
            Skeleton skel = new Skeleton();

            uint boneCount = rdr.ReadUInt32();

            for (int i = 0; i < boneCount; ++i)
            {
                Bone bone = new Bone();
                bone.Name     = ReadCString(rdr);
                bone.Parent   = rdr.ReadUInt32();
                bone.Position = ReadVector3(rdr);
                bone.Rotation = ReadVector4(rdr);
                bone.Scale    = ReadVector3(rdr);

                byte[] offsetTrans = rdr.ReadBytes(sizeof(float) * 12);
                bone.ColMask = rdr.ReadByte();
                if ((bone.ColMask & Bone.BONECOLLISION_SPHERE) != 0)
                {
                    bone.ColRadius = rdr.ReadSingle();
                }
                else if ((bone.ColMask & Bone.BONECOLLISION_BOX) != 0)
                {
                    bone.BoundsMin = ReadVector3(rdr);
                    bone.BoundsMax = ReadVector3(rdr);
                }
                skel.Bones.Add(bone);
            }

            ret.Skeleton = skel;

            ret.BoundsMin = ReadVector3(rdr);
            ret.BoundsMax = ReadVector3(rdr);

            for (int i = 0; i < geomCt; ++i)
            {
                ret.Geometries[i].Center = ReadVector3(rdr);
            }

            return(ret);
        }
예제 #2
0
        public static Model ReadModel(BinaryReader rdr)
        {
            byte[] magic = rdr.ReadBytes(4);
            if (!BitConverter.ToString(magic, 0).Equals("UMDL"))
                return null;

            Model ret = new Model();

            uint vertexBufferCt = rdr.ReadUInt32();
            //Read the vertex buffers
            for (uint i = 0; i < vertexBufferCt; ++i)
            {
                uint vertCt = rdr.ReadUInt32();
                uint vertMask = rdr.ReadUInt32();
                uint vertexSize = GetVertexSize(vertMask);
                uint morphStart = rdr.ReadUInt32();
                uint morphCt = rdr.ReadUInt32();
                byte[] vertexData = rdr.ReadBytes((int)(vertCt * vertexSize));
                ret.VertexBuffers.Add(new VertexBuffer(vertexData, (int)vertexSize));
            }

            uint indexBufferCt = rdr.ReadUInt32();
            for (uint i = 0; i < indexBufferCt; ++i)
            {
                uint indexCt = rdr.ReadUInt32();
                uint indexSize = rdr.ReadUInt32();
                byte[] indexData = rdr.ReadBytes((int)(indexCt * indexSize));
                ret.IndexBuffers.Add(new IndexBuffer(indexData));
            }

            uint geomCt = rdr.ReadUInt32();
            for (uint i = 0; i < geomCt; ++i)
            {
                Geometry geom = new Geometry();

                uint boneMapCt = rdr.ReadUInt32();
                byte[] boneMappingBytes = rdr.ReadBytes((int)(sizeof(uint) * boneMapCt));
                uint[] boneMapping = new uint[boneMapCt];
                for (int idx = 0, boneIdx = 0; idx < boneMappingBytes.Length; idx += 4, boneIdx += 1)
                {
                    boneMapping[boneIdx] = BitConverter.ToUInt32(boneMappingBytes, idx);
                }
                geom.BoneMapping = boneMapping;

                uint lodCt = rdr.ReadUInt32();

                for (int lodIdx = 0; lodIdx < lodCt; ++lodIdx)
                {
                    float dist = rdr.ReadSingle();
                    uint prim = rdr.ReadUInt32();
                    uint vertBufferIndex = rdr.ReadUInt32();
                    uint indexBufferIndex = rdr.ReadUInt32();
                    uint drawRangeStart = rdr.ReadUInt32();
                    uint drawRangeEnd = rdr.ReadUInt32();

                    LOD lod = new LOD();
                    lod.VertexBuffer = ret.VertexBuffers[(int)vertBufferIndex];
                    lod.IndexBuffer = ret.IndexBuffers[(int)indexBufferIndex];
                    lod.IndexStart = drawRangeStart;
                    lod.IndexEnd = drawRangeEnd;
                    lod.Distance = dist;
                    lod.Primitive = prim;

                    geom.LODs.Add(lod);
                }

                ret.Geometries.Add(geom);
            }

            uint vertexMorphCt = rdr.ReadUInt32();

            for (int i = 0; i < vertexMorphCt; ++i)
            {
                string name = ReadCString(rdr);
                uint affectedBuffers = rdr.ReadUInt32();

                VertexMorph morph = new VertexMorph();
                morph.Name = name;

                for (int bufIdx = 0; bufIdx < affectedBuffers; ++i)
                {
                    MorphAffectedBuffer buff = new MorphAffectedBuffer();
                    buff.Idx = rdr.ReadUInt32();
                    buff.Mask = rdr.ReadUInt32();
                    buff.VertCt = rdr.ReadUInt32();
                    buff.Buffer = ret.VertexBuffers[(int)buff.Idx];
                    morph.Buffers.Add(buff);

                    for (int vertIdx = 0; vertIdx < buff.VertCt; ++vertIdx)
                    {
                        uint morphVertexIndex = rdr.ReadUInt32();
                        //\todo check mask
                        MorphVertex vert = new MorphVertex();

                        if ((buff.Mask & 0x1) != 0)
                            vert.Position = ReadVector3(rdr);
                        if ((buff.Mask & 0x2) != 0)
                            vert.Normal = ReadVector3(rdr);
                        if ((buff.Mask & 0x80) != 0)
                            vert.Tangent = ReadVector3(rdr);
                        buff.Vertices.Add(vert);
                    }
                }
            }

            //Skeleton data
            Skeleton skel = new Skeleton();

            uint boneCount = rdr.ReadUInt32();
            for (int i = 0; i < boneCount; ++i)
            {
                Bone bone = new Bone();
                bone.Name = ReadCString(rdr);
                bone.Parent = rdr.ReadUInt32();
                bone.Position = ReadVector3(rdr);
                bone.Rotation = ReadVector4(rdr);
                bone.Scale = ReadVector3(rdr);

                byte[] offsetTrans = rdr.ReadBytes(sizeof(float) * 12);
                bone.ColMask = rdr.ReadByte();
                if ((bone.ColMask & Bone.BONECOLLISION_SPHERE) != 0)
                {
                    bone.ColRadius = rdr.ReadSingle();
                }
                else if ((bone.ColMask & Bone.BONECOLLISION_BOX) != 0)
                {
                    bone.BoundsMin = ReadVector3(rdr);
                    bone.BoundsMax = ReadVector3(rdr);
                }
                skel.Bones.Add(bone);
            }

            ret.Skeleton = skel;

            ret.BoundsMin = ReadVector3(rdr);
            ret.BoundsMax = ReadVector3(rdr);

            for (int i = 0; i < geomCt; ++i)
            {
                ret.Geometries[i].Center = ReadVector3(rdr);
            }

            return ret;
        }