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); }
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; }