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