예제 #1
0
        private void LoadMeshData(BlamCacheFile cacheFile, StructureLayout meshLayout)
        {
            IReader reader = cacheFile.Reader;
            StructureValueCollection meshValueCollection = StructureReader.ReadStructure(reader, meshLayout);

            ulong numSubmeshes    = meshValueCollection.GetInteger("number of submeshes");
            ulong numVertexGroups = meshValueCollection.GetInteger("number of vertex groups");

            uint submeshTableOffset     = (uint)cacheFile.PointerToFileOffset((uint)meshValueCollection.GetInteger("submesh table address"));
            uint vertexGroupTableOffset = (uint)cacheFile.PointerToFileOffset((uint)meshValueCollection.GetInteger("vertex group table address"));

            Submeshes = new List <BlamModelSubmesh>((int)numSubmeshes);
            for (int i = 0; i < Submeshes.Capacity; i++)
            {
                Submeshes.Add(new BlamModelSubmesh(submeshTableOffset, i, cacheFile));
            }
            VertexGroups = new List <BlamModelVertexGroup>((int)numVertexGroups);
            for (int i = 0; i < VertexGroups.Capacity; i++)
            {
                VertexGroups.Add(new BlamModelVertexGroup(vertexGroupTableOffset, i, cacheFile));
            }
            VertexType = (MeshVertexType)meshValueCollection.GetInteger("vertex format");

            for (int i = 1; i <= VertexBufferIndices.Length; i++)
            {
                string indexerString = string.Format("vertex buffer {0}", i);
                VertexBufferIndices[i - 1] = (Int16)meshValueCollection.GetInteger(indexerString);
            }

            for (int i = 1; i <= IndexBufferIndices.Length; i++)
            {
                string indexerString = string.Format("index buffer {0}", i);
                IndexBufferIndices[i - 1] = (Int16)meshValueCollection.GetInteger(indexerString);
            }
        }
예제 #2
0
        private void LoadRegions(ITag modelTag, BlamCacheFile blamCacheFile)
        {
            IReader         reader            = blamCacheFile.Reader;
            StructureLayout renderModelLayout = blamCacheFile.GetLayout("render model");

            reader.SeekTo(modelTag.MetaLocation.AsOffset());
            renderModelValues = StructureReader.ReadStructure(blamCacheFile.Reader, renderModelLayout);

            ulong numRegions         = renderModelValues.GetInteger("number of regions");
            ulong regionTableAddress = renderModelValues.GetInteger("region table address");

            long expandedRegionTableOffset = blamCacheFile.PointerToFileOffset((uint)regionTableAddress);

            StructureLayout modelRegionLayout = blamCacheFile.GetLayout("model region");

            ResourceDatumIndex = new DatumIndex(renderModelValues.GetInteger("resource datum index"));
            Regions            = new List <BlamRenderModelRegion>();

            var x = blamCacheFile.Get().Resources.LoadResourceTable(blamCacheFile.Reader).Resources[ResourceDatumIndex.Index];

            for (ulong regionNum = 0ul; regionNum < numRegions; regionNum++)
            {
                long regionPointer = expandedRegionTableOffset + (long)((ulong)modelRegionLayout.Size * regionNum);
                Regions.Add(new BlamRenderModelRegion(regionPointer, blamCacheFile));
            }
        }
        private void ReadResourceBuffers(BlamCacheFile cacheFile, ref Resource resourceRef)
        {
            bool[] convertedVertexBuffers = new bool[100];
            bool[] convertedIndexBuffers  = new bool[100];

            using (EndianWriter writer = new EndianWriter(new MemoryStream(resourceRef.Info), Endian.LittleEndian))
            {
                foreach (ResourceFixup fixup in resourceRef.ResourceFixups)
                {
                    BlamCacheAddress address = new BlamCacheAddress(fixup.Address);
                    writer.SeekTo(fixup.Offset);
                    writer.WriteUInt32(address.Value);
                }
            }

            byte[] primaryResource   = ReadResourcePageData(cacheFile, resourceRef.Location.PrimaryPage);
            byte[] secondaryResource = ReadResourcePageData(cacheFile, resourceRef.Location.SecondaryPage);

            using (EndianReader definitionReader = new EndianReader(new MemoryStream(resourceRef.Info), Endian.LittleEndian))
                using (EndianReader primaryReader = new EndianReader(new MemoryStream(primaryResource), Endian.LittleEndian))
                    using (EndianReader secondaryReader = new EndianReader(new MemoryStream(secondaryResource), Endian.LittleEndian))
                    {
                        BlamCacheAddress cacheAddress = new BlamCacheAddress((uint)resourceRef.BaseDefinitionAddress);
                        Logger.AssertMsg(cacheAddress.Type == BlamCacheAddressType.Definition, "INVALID CACHE ADDRESS");
                        definitionReader.SeekTo(cacheAddress.Offset);
                        StructureLayout          layout = cacheFile.GetLayout("render geometry api resource definition");
                        StructureValueCollection values = StructureReader.ReadStructure(definitionReader, layout);

                        BlamCacheAddress uselessCrap3Address = new BlamCacheAddress((uint)values.GetInteger("address of useless crap3"));
                        BlamCacheAddress uselessCrap4Address = new BlamCacheAddress((uint)values.GetInteger("address of useless crap4"));
                    }
        }
예제 #4
0
            public BlamRenderModelPermutation(long addr, BlamCacheFile blamCacheFile, StructureLayout permutationLayout)
            {
                blamCacheFile.Reader.SeekTo(addr);
                StructureValueCollection values = StructureReader.ReadStructure(blamCacheFile.Reader, permutationLayout);

                Name         = blamCacheFile.Get().StringIDs.GetString(new StringID(values.GetInteger("name stringid")));
                ModelSection = (Int16)(values.GetInteger("model section"));
                ModelCount   = (Int16)(values.GetInteger("model count"));
            }
예제 #5
0
        public void Read(BlamCacheFile cacheFile, Resource resourceRef)
        {
            IReader         reader     = cacheFile.Reader;
            StructureLayout meshLayout = cacheFile.GetLayout("model section");

            for (int i = 0; i < Meshes.Capacity; i++)
            {
                reader.SeekTo(meshTableOffset + (i * meshLayout.Size));
                Meshes.Add(new BlamModelMesh(cacheFile, i, meshLayout));
            }

            ReadResourceBuffers(cacheFile, ref resourceRef);
        }
예제 #6
0
            public BlamModelVertexGroup(uint baseTableOffset, int vertexGroupIdx, BlamCacheFile cacheFile)
            {
                IReader reader = cacheFile.Reader;

                VertexGroupIndex = vertexGroupIdx;

                StructureLayout vertexGroupLayout = cacheFile.GetLayout("model vertex group");

                reader.SeekTo(baseTableOffset + (vertexGroupIdx * vertexGroupLayout.Size));
                StructureValueCollection vertexGroupValues = StructureReader.ReadStructure(reader, vertexGroupLayout);

                IndexBufferStart   = (Int32)vertexGroupValues.GetInteger("index buffer start");
                IndexBufferCount   = (Int32)vertexGroupValues.GetInteger("index buffer count");
                ParentSubmeshIndex = (Int16)vertexGroupValues.GetInteger("parent submesh index");
                VertexBufferCount  = (Int16)vertexGroupValues.GetInteger("vertex buffer count");
            }
예제 #7
0
            public BlamModelSubmesh(uint baseTableOffset, int submeshIdx, BlamCacheFile cacheFile)
            {
                IReader reader = cacheFile.Reader;

                SubmeshIdx = submeshIdx;

                StructureLayout submeshLayout = cacheFile.GetLayout("model submesh");

                reader.SeekTo(baseTableOffset + (submeshIdx * submeshLayout.Size));
                StructureValueCollection submeshValues = StructureReader.ReadStructure(reader, submeshLayout);

                ShaderIdx         = (Int16)submeshValues.GetInteger("shader index");
                IndexBufferStart  = (Int16)submeshValues.GetInteger("index buffer start");
                IndexBufferCount  = (Int16)submeshValues.GetInteger("index buffer count");
                VertexGroupStart  = (Int16)submeshValues.GetInteger("subpart index");
                VertexGroupCount  = (Int16)submeshValues.GetInteger("subpart count");
                VertexBufferCount = (Int16)submeshValues.GetInteger("vertex buffer count");
            }
예제 #8
0
        private void LoadModelCompressionData(ITag modelTag, BlamCacheFile blamCacheFile)
        {
            ulong numBoundingBoxes       = renderModelValues.GetInteger("number of bounding boxes");
            ulong boundingBoxTableAddr   = renderModelValues.GetInteger("bounding box table address");
            ulong boundingboxTableOffset = (ulong)blamCacheFile.PointerToFileOffset((uint)boundingBoxTableAddr);

            StructureLayout boundingBoxElementLayout = blamCacheFile.GetLayout("model bounding box");

            Compression = new BlamModelCompression();
            List <StructureValueCollection> boundingBoxTableData = new List <StructureValueCollection>((int)numBoundingBoxes);

            for (ulong i = 0; i < numBoundingBoxes; i++)
            {
                ulong offset = (i * (ulong)boundingBoxElementLayout.Size);
                blamCacheFile.Reader.SeekTo((long)(boundingboxTableOffset + offset));
                boundingBoxTableData.Add(StructureReader.ReadStructure(blamCacheFile.Reader, boundingBoxElementLayout));
            }
            Compression.ReadCompressionData(boundingBoxTableData);
        }
예제 #9
0
            public BlamRenderModelRegion(long addr, BlamCacheFile blamCacheFile)
            {
                Permutations = new List <BlamRenderModelPermutation>();

                StructureLayout regionLayout      = blamCacheFile.GetLayout("model region");
                StructureLayout permutationLayout = blamCacheFile.GetLayout("model permutation");

                blamCacheFile.Reader.SeekTo(addr);
                StructureValueCollection values = StructureReader.ReadStructure(blamCacheFile.Reader, regionLayout);

                Name = blamCacheFile.Get().StringIDs.GetString(new StringID(values.GetInteger("name stringid")));
                ulong numPermutations              = values.GetInteger("number of permutations");
                long  permutationTableAddress      = blamCacheFile.ExpandPointer((uint)values.GetInteger("permutation table address"));
                long  permutationRegionTableOffset = blamCacheFile.Get().MetaArea.PointerToOffset(permutationTableAddress);

                for (ulong permutationNum = 0; permutationNum < numPermutations; permutationNum++)
                {
                    long permutationAddr = permutationRegionTableOffset + (long)((ulong)permutationLayout.Size * permutationNum);
                    Permutations.Add(new BlamRenderModelPermutation(permutationAddr, blamCacheFile, permutationLayout));
                }
            }
예제 #10
0
        private void LoadRenderGeometry(ITag modelTag, BlamCacheFile blamCacheFile)
        {
            ulong runtimeGeometryFlags = renderModelValues.GetInteger("render geometry runtime flags");
            ulong numMeshes            = renderModelValues.GetInteger("number of sections");
            ulong meshTableAddress     = renderModelValues.GetInteger("section table address");

            ulong meshTableOffset = (ulong)blamCacheFile.PointerToFileOffset((uint)meshTableAddress);

            Geometry = new BlamModelRenderGeometry((RenderGeometryRuntimeFlags)runtimeGeometryFlags, meshTableOffset, numMeshes);
            var resources = blamCacheFile.ResourceTable;

            foreach (var res in resources.Resources)
            {
                ITag tag = res.ParentTag;
                if (tag != modelTag)
                {
                    continue;
                }

                Geometry.Read(blamCacheFile, res);
                break;
            }
        }
        private byte[] ReadResourcePageData(BlamCacheFile cacheFile, ResourcePage page)
        {
            BlamCacheFile cache         = cacheFile;
            string        cacheFilePath = "";
            bool          cleanup       = false;

            if (page.FilePath != null)
            {
                cacheFilePath = Util.VisualStudioProvider.TryGetSolutionDirectoryInfo().FullName + "\\" + page.FilePath;
                cleanup       = true;
                cache         = new BlamCacheFile(cacheFilePath);
            }

            byte[] decompressed = new byte[page.UncompressedSize];
            cacheFile.Reader.SeekTo(page.Offset);

            byte[] compressed = cacheFile.Reader.ReadBlock(page.CompressedSize);

            if (page.CompressionMethod == ResourcePageCompression.None)
            {
                decompressed = compressed;
            }
            else if (page.CompressionMethod == ResourcePageCompression.Deflate)
            {
                using (DeflateStream stream = new DeflateStream(new MemoryStream(compressed), CompressionMode.Decompress))
                    stream.Read(decompressed, 0, BitConverter.ToInt32(BitConverter.GetBytes(page.UncompressedSize), 0));
            }


            if (cleanup)
            {
                cache.Dispose();
            }

            return(decompressed);
        }
예제 #12
0
 public BlamRenderModel(ITag modelTag, BlamCacheFile cacheFile)
 {
     LoadRegions(modelTag, cacheFile);
     LoadRenderGeometry(modelTag, cacheFile);
     LoadModelCompressionData(modelTag, cacheFile);
 }
예제 #13
0
 private void ReadResourceBuffers(BlamCacheFile cacheFile, ref Resource resourceRef)
 {
 }
예제 #14
0
 public BlamModelMesh(BlamCacheFile cacheFile, int index, StructureLayout meshLayout)
 {
     MeshIndex = index;
     LoadMeshData(cacheFile, meshLayout);
 }