示例#1
0
            internal Texture(BinaryReaderEx br, FLVERHeader header)
            {
                int pathOffset = br.ReadInt32();
                int typeOffset = br.ReadInt32();

                Scale = br.ReadVector2();

                Unk10 = br.AssertByte(0, 1, 2);
                Unk11 = br.ReadBoolean();
                br.AssertByte(0);
                br.AssertByte(0);

                Unk14 = br.ReadSingle();
                Unk18 = br.ReadSingle();
                Unk1C = br.ReadSingle();

                if (header.Unicode)
                {
                    Type = br.GetUTF16(typeOffset);
                    Path = br.GetUTF16(pathOffset);
                }
                else
                {
                    Type = br.GetShiftJIS(typeOffset);
                    Path = br.GetShiftJIS(pathOffset);
                }
            }
示例#2
0
            internal Bone(BinaryReaderEx br, FLVERHeader header)
            {
                Position = br.ReadVector3();
                int nameOffset = br.ReadInt32();

                Rotation             = br.ReadVector3();
                ParentIndex          = br.ReadInt16();
                ChildIndex           = br.ReadInt16();
                Scale                = br.ReadVector3();
                NextSiblingIndex     = br.ReadInt16();
                PreviousSiblingIndex = br.ReadInt16();
                BoundingBoxMin       = br.ReadVector3();
                Unk3C                = br.ReadInt32();
                BoundingBoxMax       = br.ReadVector3();
                br.AssertPattern(0x34, 0x00);

                if (header.Unicode)
                {
                    Name = br.GetUTF16(nameOffset);
                }
                else
                {
                    Name = br.GetShiftJIS(nameOffset);
                }
            }
示例#3
0
            internal Mesh(BinaryReaderEx br, FLVERHeader header)
            {
                Dynamic = br.ReadBoolean();
                br.AssertByte(0);
                br.AssertByte(0);
                br.AssertByte(0);

                MaterialIndex = br.ReadInt32();
                br.AssertInt32(0);
                br.AssertInt32(0);
                DefaultBoneIndex = br.ReadInt32();
                int boneCount          = br.ReadInt32();
                int boundingBoxOffset  = br.ReadInt32();
                int boneOffset         = br.ReadInt32();
                int faceSetCount       = br.ReadInt32();
                int faceSetOffset      = br.ReadInt32();
                int vertexBufferCount  = br.AssertInt32(1, 2, 3);
                int vertexBufferOffset = br.ReadInt32();

                if (boundingBoxOffset != 0)
                {
                    br.StepIn(boundingBoxOffset);
                    {
                        BoundingBox = new BoundingBoxes(br, header);
                    }
                    br.StepOut();
                }

                BoneIndices         = new List <int>(br.GetInt32s(boneOffset, boneCount));
                faceSetIndices      = br.GetInt32s(faceSetOffset, faceSetCount);
                vertexBufferIndices = br.GetInt32s(vertexBufferOffset, vertexBufferCount);
            }
示例#4
0
 internal BoundingBoxes(BinaryReaderEx br, FLVERHeader header)
 {
     Min = br.ReadVector3();
     Max = br.ReadVector3();
     if (header.Version >= 0x2001A)
     {
         Unk = br.ReadVector3();
     }
 }
示例#5
0
 internal void Write(BinaryWriterEx bw, FLVERHeader header)
 {
     bw.WriteVector3(Min);
     bw.WriteVector3(Max);
     if (header.Version >= 0x2001A)
     {
         bw.WriteVector3(Unk);
     }
 }
示例#6
0
 /// <summary>
 /// Creates a FLVER with a default header and empty lists.
 /// </summary>
 public FLVER2()
 {
     Header        = new FLVERHeader();
     Dummies       = new List <FLVER.Dummy>();
     Materials     = new List <Material>();
     GXLists       = new List <GXList>();
     Bones         = new List <FLVER.Bone>();
     Meshes        = new List <Mesh>();
     BufferLayouts = new List <BufferLayout>();
 }
示例#7
0
            internal FaceSet(BinaryReaderEx br, FLVERHeader header, int headerIndexSize, int dataOffset)
            {
                Flags         = (FSFlags)br.ReadUInt32();
                TriangleStrip = br.ReadBoolean();
                CullBackfaces = br.ReadBoolean();
                Unk06         = br.ReadInt16();
                int indexCount    = br.ReadInt32();
                int indicesOffset = br.ReadInt32();

                int indexSize = 0;

                if (header.Version > 0x20005)
                {
                    br.ReadInt32(); // Indices length
                    br.AssertInt32(0);
                    indexSize = br.AssertInt32(0, 16, 32);
                    br.AssertInt32(0);
                }

                if (indexSize == 0)
                {
                    indexSize = headerIndexSize;
                }

                if (indexSize == 8 ^ Flags.HasFlag(FSFlags.EdgeCompressed))
                {
                    throw new InvalidDataException("FSFlags.EdgeCompressed probably doesn't mean edge compression after all. Please investigate this.");
                }

                if (indexSize == 8)
                {
                    br.StepIn(dataOffset + indicesOffset);
                    {
                        Indices = EdgeIndexCompression.ReadEdgeIndexGroup(br, indexCount);
                    }
                    br.StepOut();
                }
                else if (indexSize == 16)
                {
                    Indices = new List <int>(indexCount);
                    foreach (ushort index in br.GetUInt16s(dataOffset + indicesOffset, indexCount))
                    {
                        Indices.Add(index);
                    }
                }
                else if (indexSize == 32)
                {
                    Indices = new List <int>(br.GetInt32s(dataOffset + indicesOffset, indexCount));
                }
                else
                {
                    throw new NotImplementedException($"Unsupported index size: {indexSize}");
                }
            }
示例#8
0
            internal void Write(BinaryWriterEx bw, FLVERHeader header)
            {
                foreach (GXItem item in this)
                {
                    item.Write(bw, header);
                }

                bw.WriteInt32(int.MaxValue);
                bw.WriteInt32(100);
                bw.WriteInt32(TerminatorLength + 0xC);
                bw.WritePattern(TerminatorLength, 0x00);
            }
示例#9
0
            internal GXList(BinaryReaderEx br, FLVERHeader header) : base()
            {
                while (br.GetInt32(br.Position) != int.MaxValue)
                {
                    Add(new GXItem(br, header));
                }

                br.AssertInt32(int.MaxValue);
                br.AssertInt32(100);
                TerminatorLength = br.ReadInt32() - 0xC;
                br.AssertPattern(TerminatorLength, 0x00);
            }
示例#10
0
 internal void WriteBoundingBox(BinaryWriterEx bw, int index, FLVERHeader header)
 {
     if (BoundingBox == null)
     {
         bw.FillInt32($"MeshBoundingBox{index}", 0);
     }
     else
     {
         bw.FillInt32($"MeshBoundingBox{index}", (int)bw.Position);
         BoundingBox.Write(bw, header);
     }
 }
示例#11
0
 internal void WriteStrings(BinaryWriterEx bw, FLVERHeader header, int index)
 {
     bw.FillInt32($"BoneName{index}", (int)bw.Position);
     if (header.Unicode)
     {
         bw.WriteUTF16(Name, true);
     }
     else
     {
         bw.WriteShiftJIS(Name, true);
     }
 }
            internal void Write(BinaryWriterEx bw, FLVERHeader header, int index, int bufferIndex, List <BufferLayout> layouts, int vertexCount)
            {
                BufferLayout layout = layouts[LayoutIndex];

                bw.WriteInt32(bufferIndex);
                bw.WriteInt32(LayoutIndex);
                bw.WriteInt32(layout.Size);
                bw.WriteInt32(vertexCount);
                bw.WriteInt32(0);
                bw.WriteInt32(0);
                bw.WriteInt32(header.Version > 0x20005 ? layout.Size * vertexCount : 0);
                bw.ReserveInt32($"VertexBufferOffset{index}");
            }
示例#13
0
            internal GXItem(BinaryReaderEx br, FLVERHeader header)
            {
                if (header.Version <= 0x20010)
                {
                    ID = br.ReadInt32().ToString();
                }
                else
                {
                    ID = br.ReadFixStr(4);
                }
                Unk04 = br.ReadInt32();
                int length = br.ReadInt32();

                Data = br.ReadBytes(length - 0xC);
            }
示例#14
0
            internal FaceSet(BinaryReaderEx br, FLVERHeader header, FlverCache cache, int headerIndexSize, int dataOffset)
            {
                Flags         = (FSFlags)br.ReadUInt32();
                TriangleStrip = br.ReadBoolean();
                CullBackfaces = br.ReadBoolean();
                Unk06         = br.ReadByte();
                Unk07         = br.ReadByte();
                int indexCount    = br.ReadInt32();
                int indicesOffset = br.ReadInt32();

                int indexSize = 0;

                if (header.Version > 0x20005)
                {
                    br.ReadInt32(); // Indices length
                    br.AssertInt32(0);
                    indexSize = br.AssertInt32(0, 16, 32);
                    br.AssertInt32(0);
                }

                if (indexSize == 0)
                {
                    indexSize = headerIndexSize;
                }

                if (indexSize == 16)
                {
                    //Indices = new int[indexCount];
                    IndicesCount = indexCount;
                    Indices      = cache.GetCachedIndices(indexCount);
                    int i = 0;
                    foreach (ushort index in br.GetUInt16s(dataOffset + indicesOffset, indexCount))
                    {
                        Indices[i] = index;
                        i++;
                    }
                }
                else if (indexSize == 32)
                {
                    IndicesCount = indexCount;
                    Indices      = br.GetInt32s(dataOffset + indicesOffset, indexCount);
                }
                else
                {
                    throw new NotImplementedException($"Unsupported index size: {indexSize}");
                }
            }
示例#15
0
            internal void Write(BinaryWriterEx bw, FLVERHeader header, int indexSize, int index)
            {
                bw.WriteUInt32((uint)Flags);
                bw.WriteBoolean(TriangleStrip);
                bw.WriteBoolean(CullBackfaces);
                bw.WriteInt16(Unk06);
                bw.WriteInt32(Indices.Count);
                bw.ReserveInt32($"FaceSetVertices{index}");

                if (header.Version > 0x20005)
                {
                    bw.WriteInt32(Indices.Count * (indexSize / 8));
                    bw.WriteInt32(0);
                    bw.WriteInt32(header.Version >= 0x20013 ? indexSize : 0);
                    bw.WriteInt32(0);
                }
            }
示例#16
0
            internal void Write(BinaryWriterEx bw, FLVERHeader header)
            {
                if (header.Version < 0x20010)
                {
                    this[0].Write(bw, header);
                }
                else
                {
                    foreach (GXItem item in this)
                    {
                        item.Write(bw, header);
                    }

                    bw.WriteInt32(TerminatorID);
                    bw.WriteInt32(100);
                    bw.WriteInt32(TerminatorLength + 0xC);
                    bw.WritePattern(TerminatorLength, 0x00);
                }
            }
示例#17
0
            internal Material(BinaryReaderEx br, FLVERHeader header, List <GXList> gxLists, Dictionary <int, int> gxListIndices)
            {
                int nameOffset = br.ReadInt32();
                int mtdOffset  = br.ReadInt32();

                textureCount = br.ReadInt32();
                textureIndex = br.ReadInt32();
                Flags        = br.ReadInt32();
                int gxOffset = br.ReadInt32();

                Unk18 = br.ReadInt32();
                br.AssertInt32(0);

                if (header.Unicode)
                {
                    Name = br.GetUTF16(nameOffset);
                    MTD  = br.GetUTF16(mtdOffset);
                }
                else
                {
                    Name = br.GetShiftJIS(nameOffset);
                    MTD  = br.GetShiftJIS(mtdOffset);
                }

                if (gxOffset == 0)
                {
                    GXIndex = -1;
                }
                else
                {
                    if (!gxListIndices.ContainsKey(gxOffset))
                    {
                        br.StepIn(gxOffset);
                        {
                            gxListIndices[gxOffset] = gxLists.Count;
                            gxLists.Add(new GXList(br, header));
                        }
                        br.StepOut();
                    }
                    GXIndex = gxListIndices[gxOffset];
                }
            }
示例#18
0
            internal GXList(BinaryReaderEx br, FLVERHeader header) : base()
            {
                if (header.Version < 0x20010)
                {
                    Add(new GXItem(br, header));
                }
                else
                {
                    int id;
                    while ((id = br.GetInt32(br.Position)) != int.MaxValue && id != -1)
                    {
                        Add(new GXItem(br, header));
                    }

                    TerminatorID = br.AssertInt32(id);
                    br.AssertInt32(100);
                    TerminatorLength = br.ReadInt32() - 0xC;
                    br.AssertPattern(TerminatorLength, 0x00);
                }
            }
示例#19
0
 internal void Write(BinaryWriterEx bw, FLVERHeader header)
 {
     if (header.Version <= 0x20010)
     {
         if (int.TryParse(ID, out int id))
         {
             bw.WriteInt32(id);
         }
         else
         {
             throw new FormatException("For Dark Souls 2, GX IDs must be convertible to int.");
         }
     }
     else
     {
         bw.WriteFixStr(ID, 4);
     }
     bw.WriteInt32(Unk04);
     bw.WriteInt32(Data.Length + 0xC);
     bw.WriteBytes(Data);
 }
示例#20
0
            internal void WriteStrings(BinaryWriterEx bw, FLVERHeader header, int index)
            {
                bw.FillInt32($"TexturePath{index}", (int)bw.Position);
                if (header.Unicode)
                {
                    bw.WriteUTF16(Path, true);
                }
                else
                {
                    bw.WriteShiftJIS(Path, true);
                }

                bw.FillInt32($"TextureType{index}", (int)bw.Position);
                if (header.Unicode)
                {
                    bw.WriteUTF16(Type, true);
                }
                else
                {
                    bw.WriteShiftJIS(Type, true);
                }
            }
示例#21
0
 internal void Write(BinaryWriterEx bw, FLVERHeader header)
 {
     bw.WriteVector3(Position);
     if (header.Version == 0x20010)
     {
         bw.WriteBGRA(Color);
     }
     else
     {
         bw.WriteARGB(Color);
     }
     bw.WriteVector3(Forward);
     bw.WriteInt16(ReferenceID);
     bw.WriteInt16(DummyBoneIndex);
     bw.WriteVector3(Upward);
     bw.WriteInt16(AttachBoneIndex);
     bw.WriteBoolean(Flag1);
     bw.WriteBoolean(UseUpwardVector);
     bw.WriteInt32(Unk30);
     bw.WriteInt32(Unk34);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
 }
示例#22
0
 internal Dummy(BinaryReaderEx br, FLVERHeader header)
 {
     Position = br.ReadVector3();
     // Not certain about the ordering of RGB here
     if (header.Version == 0x20010)
     {
         Color = br.ReadBGRA();
     }
     else
     {
         Color = br.ReadARGB();
     }
     Forward         = br.ReadVector3();
     ReferenceID     = br.ReadInt16();
     DummyBoneIndex  = br.ReadInt16();
     Upward          = br.ReadVector3();
     AttachBoneIndex = br.ReadInt16();
     Flag1           = br.ReadBoolean();
     UseUpwardVector = br.ReadBoolean();
     Unk30           = br.ReadInt32();
     Unk34           = br.ReadInt32();
     br.AssertInt32(0);
     br.AssertInt32(0);
 }
示例#23
0
        /// <summary>
        /// Reads FLVER data from a BinaryReaderEx.
        /// </summary>
        protected override void Read(BinaryReaderEx br)
        {
            if (Cache == null)
            {
                Cache = new FlverCache();
            }

            br.BigEndian = false;

            Header = new FLVERHeader();
            br.AssertASCII("FLVER\0");
            Header.BigEndian = br.AssertASCII("L\0", "B\0") == "B\0";
            br.BigEndian     = Header.BigEndian;

            // Gundam Unicorn: 0x20005, 0x2000E
            // DS1: 2000C, 2000D
            // DS2 NT: 2000F, 20010
            // DS2: 20010, 20009 (armor 9320)
            // SFS: 20010
            // BB:  20013, 20014
            // DS3: 20013, 20014
            // SDT: 2001A, 20016 (test chr)
            Header.Version = br.AssertInt32(0x20005, 0x20009, 0x2000C, 0x2000D, 0x2000E, 0x2000F, 0x20010, 0x20013, 0x20014, 0x20016, 0x2001A);

            int dataOffset = br.ReadInt32();

            br.ReadInt32(); // Data length
            int dummyCount        = br.ReadInt32();
            int materialCount     = br.ReadInt32();
            int boneCount         = br.ReadInt32();
            int meshCount         = br.ReadInt32();
            int vertexBufferCount = br.ReadInt32();

            Header.BoundingBoxMin = br.ReadVector3();
            Header.BoundingBoxMax = br.ReadVector3();

            br.ReadInt32(); // Face count not including motion blur meshes or degenerate faces
            br.ReadInt32(); // Total face count

            int vertexIndicesSize = br.AssertByte(0, 16, 32);

            Header.Unicode = br.ReadBoolean();
            Header.Unk4A   = br.ReadBoolean();
            br.AssertByte(0);

            Header.Unk4C = br.ReadInt32();

            int faceSetCount      = br.ReadInt32();
            int bufferLayoutCount = br.ReadInt32();
            int textureCount      = br.ReadInt32();

            Header.Unk5C = br.ReadByte();
            Header.Unk5D = br.ReadByte();
            br.AssertByte(0);
            br.AssertByte(0);

            br.AssertInt32(0);
            br.AssertInt32(0);
            Header.Unk68 = br.AssertInt32(0, 1, 2, 3, 4);
            br.AssertInt32(0);
            br.AssertInt32(0);
            br.AssertInt32(0);
            br.AssertInt32(0);
            br.AssertInt32(0);

            Dummies = new List <FLVER.Dummy>(dummyCount);
            for (int i = 0; i < dummyCount; i++)
            {
                Dummies.Add(new FLVER.Dummy(br, Header.Version));
            }

            Materials = new List <Material>(materialCount);
            var gxListIndices = new Dictionary <int, int>();

            GXLists = new List <GXList>();
            for (int i = 0; i < materialCount; i++)
            {
                Materials.Add(new Material(br, Header, GXLists, gxListIndices));
            }

            Bones = new List <FLVER.Bone>(boneCount);
            for (int i = 0; i < boneCount; i++)
            {
                Bones.Add(new FLVER.Bone(br, Header.Unicode));
            }

            Meshes = new List <Mesh>(meshCount);
            for (int i = 0; i < meshCount; i++)
            {
                Meshes.Add(new Mesh(br, Header));
            }

            var faceSets = new List <FaceSet>(faceSetCount);

            for (int i = 0; i < faceSetCount; i++)
            {
                faceSets.Add(new FaceSet(br, Header, Cache, vertexIndicesSize, dataOffset));
            }

            var vertexBuffers = new List <VertexBuffer>(vertexBufferCount);

            for (int i = 0; i < vertexBufferCount; i++)
            {
                vertexBuffers.Add(new VertexBuffer(br));
            }

            BufferLayouts = new List <BufferLayout>(bufferLayoutCount);
            for (int i = 0; i < bufferLayoutCount; i++)
            {
                BufferLayouts.Add(new BufferLayout(br));
            }

            var textures = new List <Texture>(textureCount);

            for (int i = 0; i < textureCount; i++)
            {
                textures.Add(new Texture(br, Header));
            }

            if (Header.Version >= 0x2001A)
            {
                SekiroUnk = new SekiroUnkStruct(br);
            }

            Dictionary <int, Texture> textureDict = SFUtil.Dictionize(textures);

            foreach (Material material in Materials)
            {
                material.TakeTextures(textureDict);
            }
            if (textureDict.Count != 0)
            {
                throw new NotSupportedException("Orphaned textures found.");
            }

            Dictionary <int, FaceSet>      faceSetDict      = SFUtil.Dictionize(faceSets);
            Dictionary <int, VertexBuffer> vertexBufferDict = SFUtil.Dictionize(vertexBuffers);

            foreach (Mesh mesh in Meshes)
            {
                mesh.TakeFaceSets(faceSetDict);
                mesh.TakeVertexBuffers(vertexBufferDict, BufferLayouts);
                mesh.ReadVertices(br, dataOffset, BufferLayouts, Header, Cache);
            }
            if (faceSetDict.Count != 0)
            {
                throw new NotSupportedException("Orphaned face sets found.");
            }
            if (vertexBufferDict.Count != 0)
            {
                throw new NotSupportedException("Orphaned vertex buffers found.");
            }
        }
            internal void ReadVertices(BinaryReaderEx br, int dataOffset, List <BufferLayout> layouts, FLVERHeader header, FlverCache cache)
            {
                var layoutMembers = layouts.SelectMany(l => l);
                int uvCap         = layoutMembers.Where(m => m.Semantic == FLVER.LayoutSemantic.UV).Count();
                int tanCap        = layoutMembers.Where(m => m.Semantic == FLVER.LayoutSemantic.Tangent).Count();
                int colorCap      = layoutMembers.Where(m => m.Semantic == FLVER.LayoutSemantic.VertexColor).Count();

                VertexCount = VertexBuffers[0].VertexCount;
                Vertices    = cache.GetCachedVertexArray(VertexCount);
                if (Vertices == null)
                {
                    Vertices = new FLVER.Vertex[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        Vertices[i] = new FLVER.Vertex(uvCap, tanCap, colorCap);
                    }
                    cache.CacheVertexArray(Vertices);
                }
                else
                {
                    for (int i = 0; i < Vertices.Length; i++)
                    {
                        Vertices[i].UVCount      = 0;
                        Vertices[i].TangentCount = 0;
                    }
                }

                foreach (VertexBuffer buffer in VertexBuffers)
                {
                    buffer.ReadBuffer(br, layouts, Vertices, VertexCount, dataOffset, header);
                }
            }
示例#25
0
            internal void ReadVertices(BinaryReaderEx br, int dataOffset, List <BufferLayout> layouts, FLVERHeader header)
            {
                var layoutMembers = layouts.SelectMany(l => l);
                int uvCap         = layoutMembers.Where(m => m.Semantic == FLVER.LayoutSemantic.UV).Count();
                int tanCap        = layoutMembers.Where(m => m.Semantic == FLVER.LayoutSemantic.Tangent).Count();
                int colorCap      = layoutMembers.Where(m => m.Semantic == FLVER.LayoutSemantic.VertexColor).Count();

                int vertexCount = VertexBuffers[0].VertexCount;

                Vertices = new List <FLVER.Vertex>(vertexCount);
                for (int i = 0; i < vertexCount; i++)
                {
                    Vertices.Add(new FLVER.Vertex(uvCap, tanCap, colorCap));
                }

                foreach (VertexBuffer buffer in VertexBuffers)
                {
                    buffer.ReadBuffer(br, layouts, Vertices, dataOffset, header);
                }
            }
            internal void ReadBuffer(BinaryReaderEx br, List <BufferLayout> layouts, FLVER.Vertex[] vertices, int count, int dataOffset, FLVERHeader header)
            {
                BufferLayout layout = layouts[LayoutIndex];

                if (VertexSize != layout.Size)
                {
                    throw new InvalidDataException($"Mismatched vertex buffer and buffer layout sizes.");
                }

                br.StepIn(dataOffset + BufferOffset);
                {
                    float uvFactor = 1024;
                    if (header.Version >= 0x2000F)
                    {
                        uvFactor = 2048;
                    }

                    for (int i = 0; i < count; i++)
                    {
                        vertices[i].Read(br, layout, uvFactor);
                    }
                }
                br.StepOut();

                VertexSize   = -1;
                BufferIndex  = -1;
                VertexCount  = -1;
                BufferOffset = -1;
            }
            internal void WriteBuffer(BinaryWriterEx bw, int index, List <BufferLayout> layouts, FLVER.Vertex[] Vertices, int dataStart, FLVERHeader header)
            {
                BufferLayout layout = layouts[LayoutIndex];

                bw.FillInt32($"VertexBufferOffset{index}", (int)bw.Position - dataStart);

                float uvFactor = 1024;

                if (header.Version >= 0x2000F)
                {
                    uvFactor = 2048;
                }

                foreach (FLVER.Vertex vertex in Vertices)
                {
                    vertex.Write(bw, layout, uvFactor);
                }
            }