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); } }
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")); } }
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")); }
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); }
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"); }
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"); }
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); }
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)); } }
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); }
public BlamRenderModel(ITag modelTag, BlamCacheFile cacheFile) { LoadRegions(modelTag, cacheFile); LoadRenderGeometry(modelTag, cacheFile); LoadModelCompressionData(modelTag, cacheFile); }
private void ReadResourceBuffers(BlamCacheFile cacheFile, ref Resource resourceRef) { }
public BlamModelMesh(BlamCacheFile cacheFile, int index, StructureLayout meshLayout) { MeshIndex = index; LoadMeshData(cacheFile, meshLayout); }