示例#1
0
文件: Gcmf.cs 项目: trashbyte/LibGC
        private int SizeOf2MeshData(GcGame game)
        {
            bool isVtx16Bit = (SectionFlags & (uint)GcmfSectionFlags._16Bit) != 0 &&
                              !GcmfVersionDetails.Is16BitEffectiveModelIgnored(game);

            return(PaddingUtils.Align(Meshes.Sum(mesh => mesh.SizeOfIndexedData(isVtx16Bit)), 0x20));
        }
示例#2
0
        private void RefreshBuffers()
        {
            int totalVertexCount = Meshes.Sum(x => x.VertexCount);

            if (totalVertexCount == 0)
            {
                _vertexArray = null;
                _indexArray  = null;
                return;
            }

            // Resize vertex array if necessary
            if (totalVertexCount != _vertexArray?.Length)
            {
                _vertexArray = new VertexPositionColorTexture[totalVertexCount];
            }

            // Fill vertex array
            int i = 0;

            foreach (IVisualMesh mesh in Meshes)
            {
                mesh.CopyToVertexArray(_vertexArray, i);
                i += mesh.VertexCount;
            }

            // Skip index array if none provided
            int totalIndexCount = Meshes.Sum(x => x.TriangulationIndexCount);

            if (totalIndexCount == 0)
            {
                _indexArray = null;
                return;
            }

            // Resize index buffer if necessary
            if (totalIndexCount != _indexArray?.Length)
            {
                _indexArray = new int[totalIndexCount];
            }

            // Fill index array
            i = 0;
            foreach (IVisualMesh mesh in Meshes)
            {
                mesh.CopyToIndexArray(_indexArray, i);
                i += mesh.TriangulationIndexCount;
            }
        }
示例#3
0
        // ---- METHODS ------------------------------------------------------------------------------------------------

        void IResData.Load(ResFileLoader loader)
        {
            loader.CheckSignature(_signature);
            if (loader.IsSwitch)
            {
                Switch.ShapeParser.Read((Switch.Core.ResFileSwitchLoader)loader, this);
            }
            else
            {
                Name  = loader.LoadString();
                Flags = loader.ReadEnum <ShapeFlags>(true);
                ushort idx = loader.ReadUInt16();
                MaterialIndex     = loader.ReadUInt16();
                BoneIndex         = loader.ReadUInt16();
                VertexBufferIndex = loader.ReadUInt16();
                ushort numSkinBoneIndex = loader.ReadUInt16();
                VertexSkinCount = loader.ReadByte();
                byte numMesh     = loader.ReadByte();
                byte numKeyShape = loader.ReadByte();
                TargetAttribCount = loader.ReadByte();
                ushort numSubMeshBoundingNodes = loader.ReadUInt16(); // Padding in engine.

                if (loader.ResFile.Version >= 0x04050000)
                {
                    RadiusArray = loader.LoadCustom(() => loader.ReadSingles(numMesh))?.ToList();
                }
                else
                {
                    RadiusArray = loader.ReadSingles(1).ToList();
                }
                VertexBuffer    = loader.Load <VertexBuffer>();
                Meshes          = loader.LoadList <Mesh>(numMesh).ToList();
                SkinBoneIndices = loader.LoadCustom(() => loader.ReadUInt16s(numSkinBoneIndex))?.ToList();
                KeyShapes       = loader.LoadDict <KeyShape>();

                // TODO: At least BotW has more data following the Boundings, or that are no boundings at all.
                if (numSubMeshBoundingNodes == 0)
                {
                    if (loader.ResFile.Version >= 0x04050000)
                    {
                        numSubMeshBoundingNodes = (ushort)(Meshes.Count + Meshes.Sum(x => x.SubMeshes.Count));
                    }
                    else
                    {
                        numSubMeshBoundingNodes = (ushort)(1 + Meshes[0].SubMeshes.Count + 1);
                    }
                    SubMeshBoundings = loader.LoadCustom(() => loader.ReadBoundings(numSubMeshBoundingNodes))?.ToList();
                }
                else
                {
                    SubMeshBoundingNodes   = loader.LoadList <BoundingNode>(numSubMeshBoundingNodes)?.ToList();
                    SubMeshBoundings       = loader.LoadCustom(() => loader.ReadBoundings(numSubMeshBoundingNodes))?.ToList();
                    SubMeshBoundingIndices = loader.LoadCustom(() => loader.ReadUInt16s(numSubMeshBoundingNodes))?.ToList();
                }

                if (SubMeshBoundingNodes == null)
                {
                    SubMeshBoundingNodes = new List <BoundingNode>();
                }
                if (SubMeshBoundings == null)
                {
                    SubMeshBoundings = new List <Bounding>();
                }
                if (SubMeshBoundingIndices == null)
                {
                    SubMeshBoundingIndices = new List <ushort>();
                }

                uint userPointer = loader.ReadUInt32();
            }
        }
示例#4
0
        /// <summary>
        /// Writes FLVER data to a BinaryWriterEx.
        /// </summary>
        protected override void Write(BinaryWriterEx bw)
        {
            bw.BigEndian = Header.BigEndian;
            bw.WriteASCII("FLVER\0");
            bw.WriteASCII(Header.BigEndian ? "B\0" : "L\0");
            bw.WriteInt32(Header.Version);

            bw.ReserveInt32("DataOffset");
            bw.ReserveInt32("DataSize");
            bw.WriteInt32(Dummies.Count);
            bw.WriteInt32(Materials.Count);
            bw.WriteInt32(Bones.Count);
            bw.WriteInt32(Meshes.Count);
            bw.WriteInt32(Meshes.Sum(m => m.VertexBuffers.Count));
            bw.WriteVector3(Header.BoundingBoxMin);
            bw.WriteVector3(Header.BoundingBoxMax);

            int trueFaceCount  = 0;
            int totalFaceCount = 0;

            foreach (Mesh mesh in Meshes)
            {
                bool allowPrimitiveRestarts = mesh.Vertices.Length < ushort.MaxValue;
                foreach (FaceSet faceSet in mesh.FaceSets)
                {
                    faceSet.AddFaceCounts(allowPrimitiveRestarts, ref trueFaceCount, ref totalFaceCount);
                }
            }
            bw.WriteInt32(trueFaceCount);
            bw.WriteInt32(totalFaceCount);

            byte vertexIndicesSize = 0;

            if (Header.Version < 0x20013)
            {
                vertexIndicesSize = 16;
                foreach (Mesh mesh in Meshes)
                {
                    foreach (FaceSet fs in mesh.FaceSets)
                    {
                        vertexIndicesSize = (byte)Math.Max(vertexIndicesSize, fs.GetVertexIndexSize());
                    }
                }
            }

            bw.WriteByte(vertexIndicesSize);
            bw.WriteBoolean(Header.Unicode);
            bw.WriteBoolean(Header.Unk4A);
            bw.WriteByte(0);

            bw.WriteInt32(Header.Unk4C);

            bw.WriteInt32(Meshes.Sum(m => m.FaceSets.Count));
            bw.WriteInt32(BufferLayouts.Count);
            bw.WriteInt32(Materials.Sum(m => m.Textures.Count));

            bw.WriteByte(Header.Unk5C);
            bw.WriteByte(Header.Unk5D);
            bw.WriteByte(0);
            bw.WriteByte(0);

            bw.WriteInt32(0);
            bw.WriteInt32(0);
            bw.WriteInt32(Header.Unk68);
            bw.WriteInt32(0);
            bw.WriteInt32(0);
            bw.WriteInt32(0);
            bw.WriteInt32(0);
            bw.WriteInt32(0);

            foreach (FLVER.Dummy dummy in Dummies)
            {
                dummy.Write(bw, Header.Version);
            }

            for (int i = 0; i < Materials.Count; i++)
            {
                Materials[i].Write(bw, i);
            }

            for (int i = 0; i < Bones.Count; i++)
            {
                Bones[i].Write(bw, i);
            }

            for (int i = 0; i < Meshes.Count; i++)
            {
                Meshes[i].Write(bw, i);
            }

            int faceSetIndex = 0;

            foreach (Mesh mesh in Meshes)
            {
                for (int i = 0; i < mesh.FaceSets.Count; i++)
                {
                    int indexSize = vertexIndicesSize;
                    if (indexSize == 0)
                    {
                        indexSize = mesh.FaceSets[i].GetVertexIndexSize();
                    }

                    mesh.FaceSets[i].Write(bw, Header, indexSize, faceSetIndex + i);
                }
                faceSetIndex += mesh.FaceSets.Count;
            }

            int vertexBufferIndex = 0;

            foreach (Mesh mesh in Meshes)
            {
                for (int i = 0; i < mesh.VertexBuffers.Count; i++)
                {
                    mesh.VertexBuffers[i].Write(bw, Header, vertexBufferIndex + i, i, BufferLayouts, mesh.Vertices.Length);
                }
                vertexBufferIndex += mesh.VertexBuffers.Count;
            }

            for (int i = 0; i < BufferLayouts.Count; i++)
            {
                BufferLayouts[i].Write(bw, i);
            }

            int textureIndex = 0;

            for (int i = 0; i < Materials.Count; i++)
            {
                Materials[i].WriteTextures(bw, i, textureIndex);
                textureIndex += Materials[i].Textures.Count;
            }

            if (Header.Version >= 0x2001A)
            {
                SekiroUnk.Write(bw);
            }

            bw.Pad(0x10);
            for (int i = 0; i < BufferLayouts.Count; i++)
            {
                BufferLayouts[i].WriteMembers(bw, i);
            }

            bw.Pad(0x10);
            for (int i = 0; i < Meshes.Count; i++)
            {
                Meshes[i].WriteBoundingBox(bw, i, Header);
            }

            bw.Pad(0x10);
            int boneIndicesStart = (int)bw.Position;

            for (int i = 0; i < Meshes.Count; i++)
            {
                Meshes[i].WriteBoneIndices(bw, i, boneIndicesStart);
            }

            bw.Pad(0x10);
            faceSetIndex = 0;
            for (int i = 0; i < Meshes.Count; i++)
            {
                bw.FillInt32($"MeshFaceSetIndices{i}", (int)bw.Position);
                for (int j = 0; j < Meshes[i].FaceSets.Count; j++)
                {
                    bw.WriteInt32(faceSetIndex + j);
                }
                faceSetIndex += Meshes[i].FaceSets.Count;
            }

            bw.Pad(0x10);
            vertexBufferIndex = 0;
            for (int i = 0; i < Meshes.Count; i++)
            {
                bw.FillInt32($"MeshVertexBufferIndices{i}", (int)bw.Position);
                for (int j = 0; j < Meshes[i].VertexBuffers.Count; j++)
                {
                    bw.WriteInt32(vertexBufferIndex + j);
                }
                vertexBufferIndex += Meshes[i].VertexBuffers.Count;
            }

            bw.Pad(0x10);
            var gxOffsets = new List <int>();

            foreach (GXList gxList in GXLists)
            {
                gxOffsets.Add((int)bw.Position);
                gxList.Write(bw, Header);
            }
            for (int i = 0; i < Materials.Count; i++)
            {
                Materials[i].FillGXOffset(bw, i, gxOffsets);
            }

            bw.Pad(0x10);
            textureIndex = 0;
            for (int i = 0; i < Materials.Count; i++)
            {
                Material material = Materials[i];
                material.WriteStrings(bw, Header, i);

                for (int j = 0; j < material.Textures.Count; j++)
                {
                    material.Textures[j].WriteStrings(bw, Header, textureIndex + j);
                }
                textureIndex += material.Textures.Count;
            }

            bw.Pad(0x10);
            for (int i = 0; i < Bones.Count; i++)
            {
                Bones[i].WriteStrings(bw, Header.Unicode, i);
            }

            int alignment = Header.Version <= 0x2000E ? 0x20 : 0x10;

            bw.Pad(alignment);
            if (Header.Version == 0x2000F || Header.Version == 0x20010)
            {
                bw.Pad(0x20);
            }

            int dataStart = (int)bw.Position;

            bw.FillInt32("DataOffset", dataStart);

            faceSetIndex      = 0;
            vertexBufferIndex = 0;
            for (int i = 0; i < Meshes.Count; i++)
            {
                Mesh mesh = Meshes[i];
                for (int j = 0; j < mesh.FaceSets.Count; j++)
                {
                    int indexSize = vertexIndicesSize;
                    if (indexSize == 0)
                    {
                        indexSize = mesh.FaceSets[j].GetVertexIndexSize();
                    }

                    bw.Pad(alignment);
                    mesh.FaceSets[j].WriteVertices(bw, indexSize, faceSetIndex + j, dataStart);
                }
                faceSetIndex += mesh.FaceSets.Count;

                foreach (FLVER.Vertex vertex in mesh.Vertices)
                {
                    vertex.PrepareWrite();
                }

                for (int j = 0; j < mesh.VertexBuffers.Count; j++)
                {
                    bw.Pad(alignment);
                    mesh.VertexBuffers[j].WriteBuffer(bw, vertexBufferIndex + j, BufferLayouts, mesh.Vertices, dataStart, Header);
                }

                foreach (FLVER.Vertex vertex in mesh.Vertices)
                {
                    vertex.FinishWrite();
                }

                vertexBufferIndex += mesh.VertexBuffers.Count;
            }

            bw.Pad(alignment);
            bw.FillInt32("DataSize", (int)bw.Position - dataStart);
            if (Header.Version == 0x2000F || Header.Version == 0x20010)
            {
                bw.Pad(0x20);
            }
        }
示例#5
0
文件: Gcmf.cs 项目: trashbyte/LibGC
 private int SizeOf2MeshHeaders()
 {
     return(Meshes.Sum(mesh => mesh.SizeOfHeader()));
 }
示例#6
0
 private int SizeOf2MeshData()
 {
     return(PaddingUtils.Align(Meshes.Sum(mesh => mesh.SizeOfIndexedData()), 0x20));
 }