public override void PopulateExternalData(MapStream reader) { foreach (var part in Parts) { var headerOffset = new NormalOffset((int)part.DataBlockRawOffset); var mapData = reader.GetStream(headerOffset.Location); part.Header = BlamSerializer.Deserialize<ModelResourceBlockHeader>(mapData, headerOffset.Value); foreach (var resource in part.Resources) { var dataOffset = part.DataBlockRawOffset + 8 + part.DataPreambleSize + resource.Offset; mapData.Position = new NormalOffset((int)dataOffset).Value; var resourceData = new byte[resource.Size]; var readCount = mapData.Read(resourceData, 0, resource.Size); Debug.Assert(readCount == resource.Size); resource.Data = resourceData; } var meshes = ModelResourceContainerProcessor.ProcessContainer(part, ModelShaderReferences); if(this.BoundingBoxes.Length > 0) { var bbIndex = 0; var maxBounds = new Vector3( this.BoundingBoxes[bbIndex].MaxX, this.BoundingBoxes[bbIndex].MaxY, this.BoundingBoxes[bbIndex].MaxZ); var minBounds = new Vector3( this.BoundingBoxes[bbIndex].MinX, this.BoundingBoxes[bbIndex].MinY, this.BoundingBoxes[bbIndex].MinZ); var maxUV = new Vector2( this.BoundingBoxes[bbIndex].MaxU, this.BoundingBoxes[bbIndex].MaxV); var minUV = new Vector2( this.BoundingBoxes[bbIndex].MinU, this.BoundingBoxes[bbIndex].MinV); var mesh = meshes[0]; for (var i = 0; i < mesh.Verticies.Length; i++) { var vert = mesh.Verticies[i]; var newPos = part.Flags.HasFlag(Properties.CompressedVerts) ? new Vector3( Decompress(vert.Position.X, minBounds.X, maxBounds.X), Decompress(vert.Position.Y, minBounds.Y, maxBounds.Y), Decompress(vert.Position.Z, minBounds.Z, maxBounds.Z) ) : vert.Position; var newTex = part.Flags.HasFlag(Properties.CompressedTexCoords) ? new Vector2( Decompress(vert.TexCoords.X, minUV.X, maxUV.X), Decompress(vert.TexCoords.Y, minUV.Y, maxUV.Y) ) : vert.TexCoords; // Workaround for JIT issue // https://github.com/dotnet/runtime/issues/1241 var newVert = new VertexFormat(newPos, newTex, vert.Normal, vert.Tangent, vert.Bitangent); mesh.Verticies[i] = newVert; } } part.Model = new MeshCollection(meshes); } }
//[InternalReferenceValue(540)] //public object[] MiscObject20Cao { get; set; } //[InternalReferenceValue(548)] //public object[] MiscObject21Cao { get; set; } //[InternalReferenceValue(556)] //public object[] MiscObject22Cao { get; set; } //[InternalReferenceValue(564)] //public object[] MiscObject23Cao { get; set; } public override void PopulateExternalData(MapStream reader) { foreach (var part in RenderChunks) { if (part.DataBlockRawOffset == uint.MaxValue) { // TODO: determine why this happens, and if it's expected? //Console.WriteLine("Bsp part with max DataBlock offset"); part.Model = new MeshCollection(new ModelMesh[0]); continue; } var headerOffset = new NormalOffset((int)part.DataBlockRawOffset); var mapData = reader.GetStream(headerOffset.Location); part.Header = BlamSerializer.Deserialize <ModelResourceBlockHeader>(mapData, headerOffset.Value); foreach (var resource in part.Resources) { var dataOffset = part.DataBlockRawOffset + 8 + part.DataPreambleSize + resource.Offset; mapData.Position = new NormalOffset((int)dataOffset).Value; var resourceData = new byte[resource.Size]; var readCount = mapData.Read(resourceData, 0, resource.Size); Debug.Assert(readCount == resource.Size); resource.Data = resourceData; } var meshes = ModelResourceContainerProcessor.ProcessContainer(part, ModelShaderReferences); part.Model = new MeshCollection(meshes); } foreach (var def in InstancedGeometryDefinitions) { if (def.DataBlockRawOffset == uint.MaxValue) { Console.WriteLine("InstancedGeometry with max DataBlock offset"); def.Model = new MeshCollection(new ModelMesh[0]); continue; } var headerOffset = new NormalOffset((int)def.DataBlockRawOffset); var mapData = reader.GetStream(headerOffset.Location); def.Header = BlamSerializer.Deserialize <ModelResourceBlockHeader>(mapData, headerOffset.Value); foreach (var resource in def.Resources) { var dataOffset = def.DataBlockRawOffset + 8 + def.DataPreambleSize + resource.Offset; mapData.Position = new NormalOffset((int)dataOffset).Value; var resourceData = new byte[resource.Size]; var readCount = mapData.Read(resourceData, 0, resource.Size); Debug.Assert(readCount == resource.Size); resource.Data = resourceData; } var meshes = ModelResourceContainerProcessor.ProcessContainer(def, ModelShaderReferences, "InstancedGeometry_" + def.DataBlockRawOffset); def.Model = new MeshCollection(meshes); } }