Пример #1
0
        public static FLVER2 Read(byte[] bytes, FlverCache cache)
        {
            BinaryReaderEx br   = new BinaryReaderEx(false, bytes);
            FLVER2         file = new FLVER2();

            file.Cache = cache;
            br         = SFUtil.GetDecompressedBR(br, out file.Compression);
            file.Read(br);
            return(file);
        }
Пример #2
0
 /// <summary>
 /// Loads a file from the specified path, automatically decompressing it if necessary.
 /// </summary>
 public static FLVER2 Read(string path, FlverCache cache)
 {
     using (FileStream stream = File.OpenRead(path))
     {
         BinaryReaderEx br   = new BinaryReaderEx(false, stream);
         FLVER2         file = new FLVER2();
         file.Cache = cache;
         br         = SFUtil.GetDecompressedBR(br, out file.Compression);
         file.Read(br);
         return(file);
     }
 }
Пример #3
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}");
                }
            }
Пример #4
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.");
            }
        }
Пример #5
0
            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);
                }
            }