public static BaseTag CreateTag(uint id, string name, TagIndexEntry index, IH2Map map, MapStream reader) { var tagType = GetTypeForTag(index.Tag); BaseTag tag; if (tagType == null) { tag = new UnknownTag(id, index.Tag.ToString()) { Name = name, Length = (uint)index.DataSize, Offset = (uint)index.Offset.Value, InternalSecondaryMagic = map.SecondaryMagic + index.Offset.Value }; } else { BaseTag instance; // PERF: check ctor existence ahead of time try { //var ctor = tagType.GetConstructor(new[] { typeof(uint) }); //instance = (BaseTag)ctor.Invoke(new object[] { id }); instance = Activator.CreateInstance(tagType, new object[] { id }) as BaseTag; } catch { instance = (BaseTag)FormatterServices.GetUninitializedObject(tagType); } tag = (BaseTag)BlamSerializer.DeserializeInto(instance, tagType, reader.GetStream(map.OriginFile), index.Offset.Value, map.SecondaryMagic, map); } tag.Name = name; tag.TagIndexEntry = index; tag.DataFile = map.OriginFile; tag.PopulateExternalData(reader); return(tag); }
public override void PopulateExternalData(MapStream sceneReader) { foreach (var info in this.TextureInfos) { info.LevelsOfDetail = new BitmapLevelOfDetail[6]; for (int i = 0; i < 6; i++) { var lod = new BitmapLevelOfDetail { Offset = new NormalOffset((int)info.LodOffsets[i]), Size = info.LodSizes[i] }; if (lod.Offset.Value != 0 && lod.Offset.Value != int.MaxValue && lod.Size != 0) { var reader = sceneReader.GetStream(lod.Offset); // Can be null if non-local readers aren't setup if (reader != null) { reader.Position = lod.Offset.Value + 2; using (var decompress = new DeflateStream(reader, CompressionMode.Decompress, true)) using (var outputStream = new MemoryStream()) { var buffer = new byte[80000]; var read = -1; var endOfInput = lod.Offset.Value + lod.Size; while (read != 0) { read = decompress.Read(buffer, 0, 80000); outputStream.Write(buffer, 0, read); } lod.Data = new Memory <byte>(outputStream.GetBuffer(), 0, (int)outputStream.Length); } } } info.LevelsOfDetail[i] = lod; } } }
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); } }
public static Stream GetStream(this MapStream mapStream, NormalOffset offset) { return(mapStream.GetStream((byte)offset.Location)); }
public static Stream GetStream(this MapStream mapStream, DataFile location) { return(mapStream.GetStream((byte)location)); }
//[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); } }
/// <inheritdoc/> public virtual void Load(byte selfIdentifier, MapStream mapStream) { this.mapStream = mapStream; this.localStream = mapStream.GetStream(selfIdentifier); }