Exemple #1
0
 internal override void WriteTypeData(BinaryWriterEx bw)
 {
     bw.WriteVector3(Position);
     bw.WriteSingle(Degree);
 }
 private protected override void WriteTypeData(BinaryWriterEx bw)
 {
     bw.WriteVector3(Position);
     bw.WriteSingle(Degree);
 }
Exemple #3
0
            internal void Write(BinaryWriterEx bw, List <LayoutMember> layout, float uvFactor)
            {
                foreach (LayoutMember member in layout)
                {
                    if (member.Semantic == LayoutSemantic.Position)
                    {
                        if (member.Type == LayoutType.Float3)
                        {
                            bw.WriteVector3(Position);
                        }
                        else if (member.Type == LayoutType.Float4)
                        {
                            bw.WriteVector3(Position);
                            bw.WriteSingle(0);
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else if (member.Semantic == LayoutSemantic.BoneWeights)
                    {
                        if (member.Type == LayoutType.Byte4A)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteSByte((sbyte)Math.Round(BoneWeights[i] * 127));
                            }
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteByte((byte)Math.Round(BoneWeights[i] * 255));
                            }
                        }
                        else if (member.Type == LayoutType.UVPair)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteInt16((short)Math.Round(BoneWeights[i] * 32767));
                            }
                        }
                        else if (member.Type == LayoutType.Short4toFloat4A)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteInt16((short)Math.Round(BoneWeights[i] * 32767));
                            }
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else if (member.Semantic == LayoutSemantic.BoneIndices)
                    {
                        if (member.Type == LayoutType.Byte4B)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteByte((byte)BoneIndices[i]);
                            }
                        }
                        else if (member.Type == LayoutType.ShortBoneIndices)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteUInt16((ushort)BoneIndices[i]);
                            }
                        }
                        else if (member.Type == LayoutType.Byte4E)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteByte((byte)BoneIndices[i]);
                            }
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else if (member.Semantic == LayoutSemantic.Normal)
                    {
                        if (member.Type == LayoutType.Float3)
                        {
                            bw.WriteVector3(Normal);
                        }
                        else if (member.Type == LayoutType.Float4)
                        {
                            bw.WriteVector3(Normal);
                            bw.WriteSingle(NormalW);
                        }
                        else if (member.Type == LayoutType.Byte4A)
                        {
                            WriteByteNormXYZ(bw, Normal);
                            bw.WriteByte((byte)NormalW);
                        }
                        else if (member.Type == LayoutType.Byte4B)
                        {
                            WriteByteNormXYZ(bw, Normal);
                            bw.WriteByte((byte)NormalW);
                        }
                        else if (member.Type == LayoutType.Short2toFloat2)
                        {
                            bw.WriteByte((byte)NormalW);
                            WriteSByteNormZYX(bw, Normal);
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            WriteByteNormXYZ(bw, Normal);
                            bw.WriteByte((byte)NormalW);
                        }
                        else if (member.Type == LayoutType.Short4toFloat4A)
                        {
                            WriteShortNormXYZ(bw, Normal);
                            bw.WriteInt16((short)NormalW);
                        }
                        else if (member.Type == LayoutType.Short4toFloat4B)
                        {
                            WriteUShortNormXYZ(bw, Normal);
                            bw.WriteInt16((short)NormalW);
                        }
                        else if (member.Type == LayoutType.Byte4E)
                        {
                            WriteByteNormXYZ(bw, Normal);
                            bw.WriteByte((byte)NormalW);
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else if (member.Semantic == LayoutSemantic.UV)
                    {
                        Vector3 uv = uvQueue.Dequeue() * uvFactor;
                        if (member.Type == LayoutType.Float2)
                        {
                            bw.WriteSingle(uv.X);
                            bw.WriteSingle(uv.Y);
                        }
                        else if (member.Type == LayoutType.Float3)
                        {
                            bw.WriteVector3(uv);
                        }
                        else if (member.Type == LayoutType.Float4)
                        {
                            bw.WriteSingle(uv.X);
                            bw.WriteSingle(uv.Y);

                            uv = uvQueue.Dequeue() * uvFactor;
                            bw.WriteSingle(uv.X);
                            bw.WriteSingle(uv.Y);
                        }
                        else if (member.Type == LayoutType.Byte4A)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.Byte4B)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.Short2toFloat2)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.UV)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.UVPair)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));

                            uv = uvQueue.Dequeue() * uvFactor;
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.Short4toFloat4B)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                            bw.WriteInt16((short)Math.Round(uv.Z));
                            bw.WriteInt16(0);
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else if (member.Semantic == LayoutSemantic.Tangent)
                    {
                        Vector4 tangent = tangentQueue.Dequeue();
                        if (member.Type == LayoutType.Float4)
                        {
                            bw.WriteVector4(tangent);
                        }
                        else if (member.Type == LayoutType.Byte4A)
                        {
                            WriteByteNormXYZW(bw, tangent);
                        }
                        else if (member.Type == LayoutType.Byte4B)
                        {
                            WriteByteNormXYZW(bw, tangent);
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            WriteByteNormXYZW(bw, tangent);
                        }
                        else if (member.Type == LayoutType.Short4toFloat4A)
                        {
                            WriteShortNormXYZW(bw, tangent);
                        }
                        else if (member.Type == LayoutType.Byte4E)
                        {
                            WriteByteNormXYZW(bw, tangent);
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else if (member.Semantic == LayoutSemantic.Bitangent)
                    {
                        if (member.Type == LayoutType.Byte4A)
                        {
                            WriteByteNormXYZW(bw, Bitangent);
                        }
                        else if (member.Type == LayoutType.Byte4B)
                        {
                            WriteByteNormXYZW(bw, Bitangent);
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            WriteByteNormXYZW(bw, Bitangent);
                        }
                        else if (member.Type == LayoutType.Byte4E)
                        {
                            WriteByteNormXYZW(bw, Bitangent);
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else if (member.Semantic == LayoutSemantic.VertexColor)
                    {
                        VertexColor color = colorQueue.Dequeue();
                        if (member.Type == LayoutType.Float4)
                        {
                            color.WriteFloatRGBA(bw);
                        }
                        else if (member.Type == LayoutType.Byte4A)
                        {
                            color.WriteByteRGBA(bw);
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            color.WriteByteRGBA(bw);
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else
                    {
                        throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                    }
                }
            }
            internal override void Write(BinaryWriterEx bw, int id)
            {
                long start = bw.Position;

                bw.ReserveInt64("NameOffset");
                bw.WriteUInt32((uint)Type);
                bw.WriteInt32(id);
                bw.WriteUInt32((uint)Shape.Type);
                bw.WriteVector3(Position);
                bw.WriteVector3(Rotation);
                bw.WriteInt32(Unk2C);
                bw.ReserveInt64("BaseDataOffset1");
                bw.ReserveInt64("BaseDataOffset2");
                bw.WriteInt32(-1);
                bw.WriteUInt32(MapStudioLayer);
                bw.ReserveInt64("ShapeDataOffset");
                bw.ReserveInt64("BaseDataOffset3");
                bw.ReserveInt64("TypeDataOffset");

                bw.FillInt64("NameOffset", bw.Position - start);
                bw.WriteUTF16(MSB.ReambiguateName(Name), true);
                bw.Pad(4);

                bw.FillInt64("BaseDataOffset1", bw.Position - start);
                bw.WriteInt16((short)UnkA.Count);
                bw.WriteInt16s(UnkA);
                bw.Pad(4);

                bw.FillInt64("BaseDataOffset2", bw.Position - start);
                bw.WriteInt16((short)UnkB.Count);
                bw.WriteInt16s(UnkB);
                bw.Pad(8);

                if (Shape.HasShapeData)
                {
                    bw.FillInt64("ShapeDataOffset", bw.Position - start);
                    Shape.WriteShapeData(bw);
                }
                else
                {
                    bw.FillInt64("ShapeDataOffset", 0);
                }

                bw.FillInt64("BaseDataOffset3", bw.Position - start);
                bw.WriteInt32(ActivationPartIndex);
                bw.WriteInt32(EntityID);

                if (HasTypeData)
                {
                    if (Type == RegionType.Region23 || Type == RegionType.PartsGroup || Type == RegionType.AutoDrawGroup)
                    {
                        bw.Pad(8);
                    }

                    bw.FillInt64("TypeDataOffset", bw.Position - start);
                    WriteTypeData(bw);
                }
                else
                {
                    bw.FillInt64("TypeDataOffset", 0);
                }
                bw.Pad(8);
            }
Exemple #5
0
            internal void Write(BinaryWriterEx bw, BufferLayout layout, int vertexSize, int version)
            {
                var tangentQueue = new Queue <Vector4>(Tangents);
                var colorQueue   = new Queue <Color>(Colors);
                var uvQueue      = new Queue <Vector3>(UVs);

                float uvFactor = 1024;

                foreach (BufferLayout.Member member in layout)
                {
                    switch (member.Semantic)
                    {
                    case BufferLayout.MemberSemantic.Position:
                        if (member.Type == BufferLayout.MemberType.Float3)
                        {
                            bw.WriteVector3(Position);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.BoneWeights:
                        if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteSByte((sbyte)Math.Round(BoneWeights[i] * sbyte.MaxValue));
                            }
                        }
                        else if (member.Type == BufferLayout.MemberType.Short4toFloat4A)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteInt16((short)Math.Round(BoneWeights[i] * short.MaxValue));
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.BoneIndices:
                        if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteByte((byte)BoneIndices[i]);
                            }
                        }
                        else if (member.Type == BufferLayout.MemberType.ShortBoneIndices)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteUInt16((ushort)BoneIndices[i]);
                            }
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4E)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteByte((byte)BoneIndices[i]);
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.Normal:
                        if (member.Type == BufferLayout.MemberType.Float4)
                        {
                            bw.WriteVector4(Normal);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            bw.WriteByte((byte)Math.Round(Normal.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.W * 127 + 127));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            bw.WriteByte((byte)Math.Round(Normal.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.W * 127 + 127));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteByte((byte)Math.Round(Normal.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.W * 127 + 127));
                        }
                        else if (member.Type == BufferLayout.MemberType.Short4toFloat4B)
                        {
                            bw.WriteInt16((short)Math.Round(Normal.X * 32767 + 32767));
                            bw.WriteInt16((short)Math.Round(Normal.Y * 32767 + 32767));
                            bw.WriteInt16((short)Math.Round(Normal.Z * 32767 + 32767));
                            bw.WriteInt16((short)Math.Round(Normal.W * 32767 + 32767));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.UV:
                        Vector3 uv = uvQueue.Dequeue() * uvFactor;
                        if (member.Type == BufferLayout.MemberType.Float2)
                        {
                            bw.WriteSingle(uv.X);
                            bw.WriteSingle(uv.Y);
                        }
                        else if (member.Type == BufferLayout.MemberType.Float3)
                        {
                            bw.WriteVector3(uv);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == BufferLayout.MemberType.Short2toFloat2)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == BufferLayout.MemberType.UV)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == BufferLayout.MemberType.UVPair)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));

                            uv = uvQueue.Dequeue() * uvFactor;
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.Tangent:
                        Vector4 tangent = tangentQueue.Dequeue();
                        if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            bw.WriteByte((byte)Math.Round(tangent.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.W * 127 + 127));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            bw.WriteByte((byte)Math.Round(tangent.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.W * 127 + 127));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteByte((byte)Math.Round(tangent.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.W * 127 + 127));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.UnknownVector4A:
                        if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            bw.WriteBytes(UnknownVector4);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteBytes(UnknownVector4);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.VertexColor:
                        Color color = colorQueue.Dequeue();
                        if (member.Type == BufferLayout.MemberType.Float4)
                        {
                            bw.WriteSingle(color.R);
                            bw.WriteSingle(color.G);
                            bw.WriteSingle(color.B);
                            bw.WriteSingle(color.A);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            bw.WriteByte((byte)Math.Round(color.A * 255));
                            bw.WriteByte((byte)Math.Round(color.R * 255));
                            bw.WriteByte((byte)Math.Round(color.G * 255));
                            bw.WriteByte((byte)Math.Round(color.B * 255));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteByte((byte)Math.Round(color.R * 255));
                            bw.WriteByte((byte)Math.Round(color.G * 255));
                            bw.WriteByte((byte)Math.Round(color.B * 255));
                            bw.WriteByte((byte)Math.Round(color.A * 255));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
            }
Exemple #6
0
        /// <summary>
        /// Writes FLVER data to a BinaryWriterEx.
        /// </summary>
        internal 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.Count < 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 (Dummy dummy in Dummies)
            {
                dummy.Write(bw, Header);
            }

            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.Count);
                }
                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, 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);
            }
        }
 internal override void Write(BinaryWriterEx bw, int id)
 {
     base.Write(bw, id);
     bw.WriteVector3(Position);
     bw.WriteSingle(Degree);
 }
Exemple #8
0
        internal override void Write(BinaryWriterEx bw)
        {
            bw.BigEndian = BigEndian;

            bw.WriteInt32(1);
            bw.WriteInt32(Vertices.Count);
            bw.ReserveInt32("VertexOffset");
            bw.WriteInt32(Triangles.Count);
            bw.ReserveInt32("TriangleOffset");
            bw.ReserveInt32("RootBoxOffset");
            bw.WriteInt32(0);
            bw.WriteInt32(Entities.Count);
            bw.ReserveInt32("EntityOffset");
            for (int i = 0; i < 23; i++)
            {
                bw.WriteInt32(0);
            }

            bw.FillInt32("VertexOffset", (int)bw.Position);
            foreach (Vector3 vertex in Vertices)
            {
                bw.WriteVector3(vertex);
            }

            bw.FillInt32("TriangleOffset", (int)bw.Position);
            foreach (Triangle triangle in Triangles)
            {
                triangle.Write(bw);
            }

            var boxTriangleIndexOffsets = new Queue <int>();

            void WriteBoxTriangleIndices(Box box)
            {
                if (box == null)
                {
                    return;
                }

                WriteBoxTriangleIndices(box.ChildBox1);
                WriteBoxTriangleIndices(box.ChildBox2);
                WriteBoxTriangleIndices(box.ChildBox3);
                WriteBoxTriangleIndices(box.ChildBox4);

                if (box.TriangleIndices.Count == 0)
                {
                    boxTriangleIndexOffsets.Enqueue(0);
                }
                else
                {
                    boxTriangleIndexOffsets.Enqueue((int)bw.Position);
                    bw.WriteInt32s(box.TriangleIndices);
                }
            }

            WriteBoxTriangleIndices(RootBox);

            int rootBoxOffset = RootBox.Write(bw, boxTriangleIndexOffsets);

            bw.FillInt32("RootBoxOffset", rootBoxOffset);

            var entityTriangleIndexOffsets = new List <int>();

            foreach (Entity entity in Entities)
            {
                entityTriangleIndexOffsets.Add((int)bw.Position);
                bw.WriteInt32s(entity.TriangleIndices);
            }

            bw.FillInt32("EntityOffset", (int)bw.Position);
            for (int i = 0; i < Entities.Count; i++)
            {
                Entities[i].Write(bw, entityTriangleIndexOffsets[i]);
            }
        }