示例#1
0
        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);
        }
示例#2
0
        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;
                }
            }
        }
示例#3
0
        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);
            }
        }
示例#4
0
 public static Stream GetStream(this MapStream mapStream, NormalOffset offset)
 {
     return(mapStream.GetStream((byte)offset.Location));
 }
示例#5
0
 public static Stream GetStream(this MapStream mapStream, DataFile location)
 {
     return(mapStream.GetStream((byte)location));
 }
示例#6
0
        //[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);
            }
        }
示例#7
0
 /// <inheritdoc/>
 public virtual void Load(byte selfIdentifier, MapStream mapStream)
 {
     this.mapStream   = mapStream;
     this.localStream = mapStream.GetStream(selfIdentifier);
 }