예제 #1
0
        public static WTModel ReadBinary(Stream stream)
        {
            var reader      = new BinaryReader(stream);
            var returnModel = new WTModel();

            //determine filetype
            bool isSceneFile = false;

            reader.BaseStream.Seek(24, SeekOrigin.Begin);

            float version = reader.ReadSingle();

            if (version == 1f)
            {
                isSceneFile = true;
            }
            else
            {
                reader.BaseStream.Seek(0, SeekOrigin.Begin);
                version = reader.ReadSingle();
                if (version != 1f)
                {
                    throw new System.Exception($"Expected version 1.0, got version {version}. Either not a MDL/SCN file, or wrong version.");
                }
            }

            //read data
            int meshCount   = reader.ReadInt32();
            int lightCount  = reader.ReadInt32();
            int helperCount = reader.ReadInt32();
            int splineCount = reader.ReadInt32();

            int materialCount = reader.ReadInt32();
            int textureCount  = reader.ReadInt32();

            //textures
            for (int i = 0; i < textureCount; i++)
            {
                string tex = reader.ReadNullTerminatedString();
                int    id  = reader.ReadInt32();
                returnModel.Textures.Add(id, tex);
            }

            //materials
            for (int i = 0; i < materialCount; i++)
            {
                var material = WTMaterial.ReadBinary(reader);
                returnModel.Materials.Add(material.ID, material);
            }

            //meshes
            for (int i = 0; i < meshCount; i++)
            {
                returnModel.Meshes.Add(WTMesh.ReadBinary(reader, isSceneFile));
            }

            //lights
            for (int i = 0; i < lightCount; i++)
            {
                returnModel.Lights.Add(WTLight.ReadBinary(reader));
            }

            //helpers
            for (int i = 0; i < helperCount; i++)
            {
                returnModel.Helpers.Add(WTHelper.ReadBinary(reader));
            }

            //splines
            for (int i = 0; i < splineCount; i++)
            {
                returnModel.Splines.Add(WTSpline.ReadBinary(reader));
            }

            reader.Dispose();
            return(returnModel);
        }
예제 #2
0
        public static WTMesh ReadBinary(BinaryReader reader, bool isSceneMesh)
        {
            var returnMesh = new WTMesh
            {
                Position = reader.ReadVector3()
            };

            if (isSceneMesh)
            {
                returnMesh.HasSecondUVChannel = reader.ReadUInt16() != 0;
            }

            //INDICES
            int indexCount = reader.ReadInt32();

            for (int i = 0; i < indexCount; i++)
            {
                returnMesh.VertexIndexMap.Add(reader.ReadInt32());
            }

            //VERTICES
            int vertCount = reader.ReadInt32();

            for (int i = 0; i < vertCount; i++)
            {
                returnMesh.Vertices.Add(reader.ReadVector3());
            }

            //UVS
            //Console.WriteLine($"reading uvs at {reader.BaseStream.Position}, idxc {indexCount} uv2 {returnMesh.SceneThing}");
            bool modelHasUvs = (reader.ReadUInt16() != 0);

            if (modelHasUvs)
            {
                for (int i = 0; i < indexCount; i++)
                {
                    returnMesh.UVsIndexMap.Add(reader.ReadInt32());
                    if (returnMesh.HasSecondUVChannel && isSceneMesh)
                    {
                        returnMesh.UVsIndexMapC2.Add(reader.ReadInt32());
                    }
                }

                int uvCount = reader.ReadInt32();
                for (int i = 0; i < uvCount; i++)
                {
                    returnMesh.UVs.Add(reader.ReadVector2());
                }
            }

            //NORMALS
            bool modelHasNormals = (reader.ReadUInt16() != 0);

            if (modelHasNormals)
            {
                for (int i = 0; i < indexCount; i++)
                {
                    returnMesh.NormalsIndexMap.Add(reader.ReadInt32());
                }

                int normalCount = reader.ReadInt32();
                for (int i = 0; i < normalCount; i++)
                {
                    float elevation = reader.ReadByte() * 1.411764752387544784530887019841f / 57.29578f;
                    float polar     = reader.ReadByte() * 1.411764752387544784530887019841f / 57.29578f;

#if UNITY
                    float   a      = (float)(1f * Mathf.Sin(elevation));
                    Vector3 normal = new Vector3
                    {
                        x = (float)(a * Mathf.Cos(polar)),
                        y = (float)(Mathf.Cos(elevation)),
                        z = (float)(a * Mathf.Sin(polar))
                    };
#else
                    float   a      = (float)(1f * Math.Sin(elevation));
                    Vector3 normal = new Vector3
                    {
                        X = (float)(a * Math.Cos(polar)),
                        Y = (float)(Math.Cos(elevation)),
                        Z = (float)(a * Math.Sin(polar))
                    };
#endif
                    returnMesh.Normals.Add(normal);
                }
            }

            //COLORS
            int numColors = reader.ReadInt32();
            if (numColors > 0)
            {
                for (int i = 0; i < numColors; i++)
                {
                    returnMesh.Colors.Add(reader.ReadColor48());
                }
            }

            //FACES
            int faceCountTotal = reader.ReadInt32();
            int faceSubmeshes  = reader.ReadInt32();
            for (int i = 0; i < faceSubmeshes; i++)
            {
                var submesh = new WTSubmesh
                {
                    MaterialIndex = reader.ReadInt16()
                };
                if (returnMesh.HasSecondUVChannel && isSceneMesh)
                {
                    submesh.MaterialIndexAlt = reader.ReadInt16();
                }

                int submeshIndexCount = reader.ReadInt32();
                int submeshTriCount   = submeshIndexCount * 3;

                for (int j = 0; j < submeshTriCount; j++)
                {
                    submesh.Indices.Add(reader.ReadInt32());
                }

                //add to data list
                returnMesh.Submeshes.Add(submesh);
            }

            return(returnMesh);
        }