public MetadataHeader(DependencyReader reader) { reader.RegisterInstance(this); Header = reader.ReadObject <TagHeader>(); Dependencies = reader.ReadEnumerable <TagDependency>(Header.DependencyCount).ToList(); DataBlocks = reader.ReadEnumerable <DataBlock>(Header.DataBlockCount).ToList(); StructureDefinitions = reader.ReadEnumerable <TagStructureDefinition>(Header.TagStructureCount).ToList(); DataReferences = reader.ReadEnumerable <DataBlockReference>(Header.DataReferenceCount).ToList(); TagReferences = reader.ReadEnumerable <TagBlockReference>(Header.TagReferenceCount).ToList(); StringIds = reader.ReadEnumerable <StringId>(Header.StringIdCount).ToList(); stringTable = new List <string>(StringIds.Count); stringsByOffset = new Dictionary <int, int>(StringIds.Count); stringsByHash = new Dictionary <uint, int>(StringIds.Count); var startPos = reader.BaseStream.Position; while (reader.BaseStream.Position < startPos + Header.StringTableSize) { var relative = reader.BaseStream.Position - startPos; var currentValue = reader.ReadNullTerminatedString(); stringsByOffset.Add((int)relative, stringTable.Count); var hash = MurMur3.Hash32(currentValue); if (!stringsByHash.ContainsKey(hash)) { stringsByHash.Add(hash, stringTable.Count); } stringTable.Add(currentValue); } }
private IEnumerable <GeometryMesh> ReadPCMeshes(DependencyReader reader) { var tagIndex = cache.TagIndex as ITagIndexGen1; if (tagIndex == null) { throw new NotSupportedException(); } foreach (var section in Sections) { var indices = new List <int>(); var vertices = new List <UncompressedVertex>(); var submeshes = new List <IGeometrySubmesh>(); foreach (var submesh in section.Submeshes) { var gSubmesh = new GeometrySubmesh { MaterialIndex = submesh.ShaderIndex, IndexStart = indices.Count, IndexLength = submesh.IndexCount + 2 }; submeshes.Add(gSubmesh); reader.Seek(tagIndex.VertexDataOffset + tagIndex.IndexDataOffset + submesh.IndexOffset, SeekOrigin.Begin); indices.AddRange(reader.ReadEnumerable <ushort>(gSubmesh.IndexLength).Select(i => i + vertices.Count)); reader.Seek(tagIndex.VertexDataOffset + submesh.VertexOffset, SeekOrigin.Begin); var vertsTemp = reader.ReadEnumerable <UncompressedVertex>(submesh.VertexCount).ToList(); if (UScale != 1 || VScale != 1) { vertsTemp.ForEach((v) => { var vec = v.TexCoords; vec.X *= UScale; vec.Y *= VScale; v.TexCoords = vec; }); } if (Flags.HasFlag(ModelFlags.UseLocalNodes)) { var address = section.Submeshes.Pointer.Address; address += section.Submeshes.IndexOf(submesh) * 132; reader.Seek(address + 107, SeekOrigin.Begin); var nodeCount = reader.ReadByte(); var nodes = reader.ReadEnumerable <byte>(nodeCount).ToArray(); vertsTemp.ForEach((v) => { v.NodeIndex1 = nodes[v.NodeIndex1]; v.NodeIndex2 = nodes[v.NodeIndex2]; }); } vertices.AddRange(vertsTemp); } yield return(new GeometryMesh { IndexFormat = IndexFormat.TriangleStrip, VertexWeights = VertexWeights.Skinned, Indicies = indices.ToArray(), Vertices = vertices.ToArray(), Submeshes = submeshes }); } }
private IEnumerable <GeometryMesh> ReadXboxMeshes(DependencyReader reader) { var tagIndex = cache.TagIndex as ITagIndexGen1; if (tagIndex == null) { throw new NotSupportedException(); } foreach (var section in Sections) { var indices = new List <int>(); var vertices = new List <CompressedVertex>(); var submeshes = new List <IGeometrySubmesh>(); foreach (var submesh in section.Submeshes) { if (submesh.IndexCount == 0 || submesh.VertexCount == 0) { continue; } try { var gSubmesh = new GeometrySubmesh { MaterialIndex = submesh.ShaderIndex, IndexStart = indices.Count, IndexLength = submesh.IndexCount + 2 }; submeshes.Add(gSubmesh); reader.Seek(submesh.IndexOffset - tagIndex.Magic, SeekOrigin.Begin); reader.ReadInt32(); reader.Seek(reader.ReadInt32() - tagIndex.Magic, SeekOrigin.Begin); var indicesTemp = reader.ReadEnumerable <ushort>(gSubmesh.IndexLength).ToList(); indices.AddRange(indicesTemp.Select(i => i + vertices.Count)); reader.Seek(submesh.VertexOffset - tagIndex.Magic, SeekOrigin.Begin); reader.ReadInt32(); reader.Seek(reader.ReadInt32() - tagIndex.Magic, SeekOrigin.Begin); var vertsTemp = new List <CompressedVertex>(); for (int i = 0; i < submesh.VertexCount; i++) { vertsTemp.Add(new CompressedVertex(reader)); } if (UScale != 1 || VScale != 1) { vertsTemp.ForEach((v) => { var vec = v.TexCoords; vec.X *= UScale; vec.Y *= VScale; v.TexCoords = vec; }); } //if (Flags.HasFlag(ModelFlags.UseLocalNodes)) //{ // var address = section.Submeshes.Pointer.Address; // address += section.Submeshes.IndexOf(submesh) * 208; // reader.Seek(address + 107, SeekOrigin.Begin); // var nodeCount = reader.ReadByte(); // var nodes = reader.ReadEnumerable<byte>(nodeCount).ToArray(); // vertsTemp.ForEach((v) => // { // v.NodeIndex1 = nodes[v.NodeIndex1]; // v.NodeIndex2 = nodes[v.NodeIndex2]; // }); //} vertices.AddRange(vertsTemp); } catch { } } yield return(new GeometryMesh { IndexFormat = IndexFormat.TriangleStrip, VertexWeights = VertexWeights.Skinned, Indicies = indices.ToArray(), Vertices = vertices.ToArray(), Submeshes = submeshes }); } }