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);
            }
        }
Beispiel #2
0
        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
                });
            }
        }
Beispiel #3
0
        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
                });
            }
        }