Beispiel #1
0
        private VpuPacket(Stream stream)
        {
            var vpu = BinaryMapping.ReadObject <VpuHeader>(stream);

            VertexRange = Read(stream, vpu.UnkBoxLocation, vpu.UnkBoxCount, ReadInt32);
            Indices     = Read(stream, vpu.IndexLocation, vpu.IndexCount, ReadIndex);
            Colors      = Read(stream, vpu.ColorLocation, vpu.ColorCount, ReadColor);
            Vertices    = Read(stream, vpu.VertexLocation, vpu.VertexCount, ReadVertex);

            if (vpu.VertexMixerCount > 0)
            {
                var countPerAmount = Read(stream, vpu.VertexMixerOffset, vpu.VertexMixerCount, ReadInt32);
                VertexWeightedCount = countPerAmount.Sum();

                VertexWeightedIndices = countPerAmount
                                        .Select((count, amount) =>
                {
                    stream.AlignPosition(0x10);
                    return(Enumerable
                           .Range(0, count)
                           .Select(x => Enumerable.Range(0, amount + 1).Select(y => stream.ReadInt32()).ToArray())
                           .ToArray());
                })
                                        .ToArray();
            }

            //Debug.Assert(vpu.VertexCount == Box.Sum());
        }
Beispiel #2
0
        public void Write(Stream stream)
        {
            var entries = new List <Entry>(8);

            AddEntry(entries, HeaderSize, 1);
            AddEntry(entries, CollisionMeshGroupList.Count * Col1Size, 0x10);
            AddEntry(entries, CollisionMeshList.Count * Col2Size, 0x10);
            AddEntry(entries, CollisionList.Count * Col3Size, 4);
            AddEntry(entries, VertexList.Count * Col4Size, 0x10);
            AddEntry(entries, PlaneList.Count * Col5Size, 0x10);
            AddEntry(entries, BoundingBoxList.Count * Col6Size, 0x10);
            AddEntry(entries, SurfaceFlagsList.Count * Col7Size, 4);

            stream.Position = 0;
            BinaryMapping.WriteObject(stream, new Header
            {
                MagicCode = MagicCode,
                Version   = 1,
                Unknown08 = Unknown08,
                Unknown0c = Unknown0c,
                Entries   = entries.ToArray()
            });

            WriteCoctEntry(stream, CollisionMeshGroupList);
            WriteCoctEntry(stream, CollisionMeshList);
            WriteCoctEntry(stream, CollisionList);
            stream.AlignPosition(0x10);
            WriteValueEntry(stream, VertexList, WriteVector4);
            WriteValueEntry(stream, PlaneList, WritePlane);
            WriteValueEntry(stream, BoundingBoxList, WriteBoundingBoxInt16);
            WriteCoctEntry(stream, SurfaceFlagsList);
        }
Beispiel #3
0
 public static void WriteAsFac(Stream stream, IEnumerable <Imgd> images)
 {
     foreach (var image in images)
     {
         image.Write(stream);
         stream.SetLength(stream.AlignPosition(FacAlignment).Position);
     }
 }
Beispiel #4
0
        public byte[] ReadRawRemasteredAsset(string assetName)
        {
            var entry = _entries[assetName];
            var data  = new byte[entry.CompressedLength >= 0 ? entry.CompressedLength : entry.DecompressedLength];

            data = _stream.AlignPosition(0x10).ReadBytes(data.Length);

            return(data);
        }
Beispiel #5
0
        private static void WriteSubModel(Stream stream, SubModel subModel, int baseAddress)
        {
            var header = new SubModelHeader
            {
                Type          = subModel.Type,
                Unk04         = subModel.Unk04,
                Unk08         = subModel.Unk08,
                Unk           = subModel.Unk,
                DmaChainCount = subModel.DmaChains.Count,
            };

            stream.Position += 0x20; // skip header
            stream.Position += subModel.DmaChainCount * 0x20;

            if (subModel.Type == Entity)
            {
                header.UnkDataOffset = (int)stream.Position;
                stream.Write(subModel.UnknownData);

                header.BoneOffset = (int)stream.Position;
                header.BoneCount  = (short)subModel.Bones.Count;
                foreach (var bone in subModel.Bones)
                {
                    WriteBone(stream, bone);
                }
            }
            else if (subModel.Type == Shadow)
            {
                header.UnkDataOffset = 0;
                header.BoneOffset    = 0;
                header.BoneCount     = subModel.BoneCount;
            }
            else
            {
                throw new NotImplementedException($"Submodel type {subModel.Type} not supported.");
            }

            var dmaChainHeaders = subModel.DmaChains.Select(x => WriteDmaChain(stream, x)).ToList();

            stream.SetLength(stream.AlignPosition(0x80).Position);
            header.NextOffset = baseAddress >= 0 ? (int)(baseAddress + stream.Position) : 0;

            stream.Position = 0;
            BinaryMapping.WriteObject(stream, header);
            foreach (var dmaChainHeader in dmaChainHeaders)
            {
                BinaryMapping.WriteObject(stream, dmaChainHeader);
            }
        }
Beispiel #6
0
        public static IEnumerable <Imgd> ReadAsFac(Stream stream)
        {
            stream.SetPosition(0);
            while (true)
            {
                stream.AlignPosition(FacAlignment);
                var subStreamLength = stream.Length - stream.Position;
                if (subStreamLength < HeaderLength)
                {
                    yield break;
                }

                yield return(Imgd.Read(new SubStream(stream, stream.Position, subStreamLength)));
            }
        }
Beispiel #7
0
        public static void Write(Stream stream,
                                 IEnumerable <IEventEntry> eventSet)
        {
            foreach (var item in eventSet)
            {
                var startPosition = stream.Position;
                stream.Position += 4;
                Mapping.WriteObject(stream, item);
                var nextPosition = stream.AlignPosition(2).Position;

                var id     = _typeId[item.GetType()];
                var length = stream.Position - startPosition;
                stream.Position = startPosition;
                stream.Write((short)(length));
                stream.Write((short)id);
                stream.Position = nextPosition;
            }

            stream.Write(Terminator);
        }
Beispiel #8
0
        public static void Write(Stream stream, ICollection <byte[]> entries)
        {
            stream.MustWriteAndSeek();
            stream.Write(entries.Count);

            var accumulator = (entries.Count + 2) * 4;

            foreach (var entry in entries)
            {
                accumulator = Helpers.Align(accumulator, Alignment);
                stream.Write(accumulator);
                accumulator += entry.Length;
            }
            stream.Write(Helpers.Align(accumulator, Alignment));

            foreach (var entry in entries)
            {
                stream.AlignPosition(Alignment);
                stream.Write(entry);
            }
        }
Beispiel #9
0
        public static void Write <TStream>(Stream stream, ICollection <TStream> entries)
            where TStream : Stream
        {
            stream.MustWriteAndSeek();
            stream.Write(entries.Count);

            var accumulator = (entries.Count + 2) * 4;

            foreach (var entry in entries)
            {
                accumulator = Helpers.Align(accumulator, Alignment);
                stream.Write(accumulator);
                accumulator += (int)stream.Length;
            }
            stream.Write(Helpers.Align(accumulator, Alignment));

            foreach (var entry in entries)
            {
                stream.AlignPosition(Alignment);
                entry.FromBegin().CopyTo(stream);
            }
        }
        private byte[] ReadRemasteredAsset(string assetName)
        {
            var header     = _entries[assetName];
            var dataLength = header.CompressedLength >= 0 ? header.CompressedLength : header.DecompressedLength;

            if (dataLength % 16 != 0)
            {
                dataLength += 16 - (dataLength % 16);
            }

            var data = _stream.AlignPosition(0x10).ReadBytes(dataLength);

            _remasteredAssetsRawData.Add(assetName, data.ToArray());

            if (header.CompressedLength > -2)
            {
                for (var i = 0; i < Math.Min(dataLength, 0x100); i += 0x10)
                {
                    EgsEncryption.DecryptChunk(_key, data, i, PASS_COUNT);
                }
            }

            if (header.CompressedLength > -1)
            {
                using var compressedStream = new MemoryStream(data);
                using var deflate          = new DeflateStream(compressedStream.SetPosition(2), CompressionMode.Decompress);

                var decompressedData = new byte[header.DecompressedLength];
                deflate.Read(decompressedData, 0, decompressedData.Length);

                data = decompressedData;
            }

            _remasteredAssetsData.Add(assetName, data.ToArray());

            return(data);
        }
Beispiel #11
0
        public static void Write(this IEnumerable <Entry> entries, Stream stream)
        {
            var myEntries = entries.ToArray();

            stream.Position = 0;
            BinaryMapping.WriteObject(stream, new Header
            {
                MagicCode  = MagicCode,
                Version    = Version,
                EntryCount = (short)myEntries.Length,
                Unused08   = 0,
                Unused0c   = 0
            });

            var dataStartOffset = (int)stream.Position + myEntries.Length * MetaEntrySize;

            foreach (var entry in myEntries)
            {
                BinaryMapping.WriteObject(stream, new MetaEntry
                {
                    DirectoryPointer = entry.DirectoryPointer,
                    Offset           = entry.IsLink ? 0 : dataStartOffset,
                    Length           = entry.IsLink ? 0 : entry.Data.Length,
                    Unused           = 0,
                    Name             = entry.Name
                });

                dataStartOffset += Helpers.Align(entry.Data?.Length ?? 0, Alignment);
            }

            foreach (var entry in myEntries.Where(x => !x.IsLink))
            {
                stream.Write(entry.Data, 0, entry.Data.Length);
                stream.AlignPosition(Alignment);
            }
        }
Beispiel #12
0
        private static void WriteAsMap(Stream stream, M4 mapModel)
        {
            var mapHeader = new SubModelMapHeader
            {
                Type             = Map,
                DmaChainMapCount = mapModel.VifPackets.Count,

                Unk04      = mapModel.unk04,
                Unk08      = mapModel.unk08,
                NextOffset = mapModel.nextOffset,
                va4        = mapModel.va4,
                CountVifPacketRenderingGroup = Convert.ToInt16(mapModel.vifPacketRenderingGroup.Count),
            };

            BinaryMapping.WriteObject(stream, mapHeader);

            var dmaChainMapDescriptorOffset = (int)stream.Position;

            stream.Position += mapModel.VifPackets.Count * 0x10;

            mapHeader.OffsetVifPacketRenderingGroup = (int)stream.Position;
            stream.Position += mapModel.vifPacketRenderingGroup.Count * 4;
            var groupOffsets = new List <int>();

            foreach (var group in mapModel.vifPacketRenderingGroup)
            {
                groupOffsets.Add((int)stream.Position);
                WriteUInt16List(stream, group);
            }

            // capture remapTable offset here
            var remapTableOffsetToOffset = Helpers.Align((int)stream.Position, 4);

            // seek back and fill offsets
            stream.Position = mapHeader.OffsetVifPacketRenderingGroup;
            foreach (var offset in groupOffsets)
            {
                stream.Write(offset);
            }

            // write remapTable here
            stream.Position = remapTableOffsetToOffset;
            mapHeader.OffsetToOffsetDmaChainIndexRemapTable = remapTableOffsetToOffset;
            var remapTableOffset = remapTableOffsetToOffset + 4;

            stream.Write(remapTableOffset);
            WriteUInt16List(stream, mapModel.DmaChainIndexRemapTable);

            stream.AlignPosition(0x10);

            var dmaChainVifOffsets = new List <int>();

            foreach (var dmaChainMap in mapModel.VifPackets)
            {
                var vifPacketIndex = 0;
                dmaChainVifOffsets.Add((int)stream.Position);

                foreach (var packetCount in dmaChainMap.DmaPerVif)
                {
                    BinaryMapping.WriteObject(stream, new DmaTag
                    {
                        Qwc     = packetCount,
                        Address = 0,
                        TagId   = packetCount > 0 ? 1 : 6,
                        Irq     = false,
                    });

                    var packetLength = packetCount * 0x10 + 8;
                    stream.Write(dmaChainMap.VifPacket, vifPacketIndex, packetLength);

                    vifPacketIndex += packetLength;
                }
            }

            stream.AlignPosition(0x80);
            stream.SetLength(stream.Position);

            stream.Position = dmaChainMapDescriptorOffset;
            for (var i = 0; i < mapModel.VifPackets.Count; i++)
            {
                var dmaChainMap = mapModel.VifPackets[i];
                BinaryMapping.WriteObject(stream, new DmaChainMap
                {
                    VifOffset    = dmaChainVifOffsets[i],
                    TextureIndex = dmaChainMap.TextureId,
                    Unk08        = dmaChainMap.Unk08,
                    Unk0a        = dmaChainMap.IsTransparentFlag,
                    Unk0c        = dmaChainMap.Unk0c
                });
            }

            stream.Position = 0;
            BinaryMapping.WriteObject(stream, mapHeader);
        }
Beispiel #13
0
        private static DmaChainHeader WriteDmaChain(Stream stream, DmaChain dmaChain)
        {
            var dmaChainHeader = new DmaChainHeader
            {
                Unk00        = dmaChain.Unk00,
                TextureIndex = dmaChain.TextureIndex,
                Unk08        = dmaChain.Unk08,
                DmaLength    = dmaChain.DmaLength,
            };

            var dmaVifs = dmaChain.DmaVifs;

            var vifPacketOffsets = new List <int>();

            foreach (var dmaVif in dmaVifs)
            {
                vifPacketOffsets.Add((int)stream.Position);
                stream.Write(dmaVif.VifPacket);
            }

            dmaChainHeader.DmaOffset = (int)stream.Position;

            for (var i = 0; i < dmaVifs.Count; i++)
            {
                if (dmaVifs[i].BaseAddress > 0)
                {
                    BinaryMapping.WriteObject(stream, new DmaPacket
                    {
                        DmaTag = new DmaTag
                        {
                            Qwc     = (ushort)(dmaVifs[i].VifPacket.Length / 0x10),
                            TagId   = 3,
                            Irq     = false,
                            Address = vifPacketOffsets[i]
                        },
                        VifCode   = new VifCode {
                        },
                        Parameter = 0
                    });

                    for (var j = 0; j < dmaVifs[i].Alaxi.Length; j++)
                    {
                        BinaryMapping.WriteObject(stream, new DmaPacket
                        {
                            DmaTag = new DmaTag
                            {
                                Qwc     = 4,
                                TagId   = 3,
                                Irq     = false,
                                Address = dmaVifs[i].Alaxi[j]
                            },
                            VifCode   = DefaultVifCode,
                            Parameter = dmaVifs[i].BaseAddress + j * 4
                        });
                    }
                }

                BinaryMapping.WriteObject(stream, CloseDmaPacket);
            }

            var alv1 = new List <int>();

            foreach (var vif in dmaVifs)
            {
                alv1.AddRange(vif.Alaxi);
                alv1.Add(-1);
            }
            alv1.RemoveAt(alv1.Count - 1);

            dmaChainHeader.Count1aOffset = (int)stream.Position;
            stream.Write(alv1.Count);
            foreach (var alvItem in alv1)
            {
                stream.Write(alvItem);
            }

            stream.AlignPosition(0x10);

            return(dmaChainHeader);
        }
Beispiel #14
0
        private static void WriteAsMap(Stream stream, M4 mapModel)
        {
            var mapHeader = new SubModelMapHeader
            {
                Type             = Map,
                DmaChainMapCount = mapModel.VifPackets.Count,

                Unk04      = mapModel.unk04,
                Unk08      = mapModel.unk08,
                NextOffset = mapModel.nextOffset,
                va4        = mapModel.va4,
                Count1     = mapModel.count1, // in a form, ignored by the game engine
            };

            BinaryMapping.WriteObject(stream, mapHeader);

            var dmaChainMapDescriptorOffset = (int)stream.Position;

            stream.Position += mapModel.VifPackets.Count * 0x10;

            mapHeader.Offset1 = (int)stream.Position;
            stream.Position  += mapModel.alb2.Count * 4;
            var alb2Offsets = new List <int>();

            foreach (var alb2 in mapModel.alb2)
            {
                alb2Offsets.Add((int)stream.Position);
                WriteAlb2(stream, alb2);
            }

            var endAlb2Offset = Helpers.Align((int)stream.Position, 4);

            stream.Position = mapHeader.Offset1;
            foreach (var alb2Offset in alb2Offsets)
            {
                stream.Write(alb2Offset);
            }
            stream.Position = endAlb2Offset;

            mapHeader.Offset2 = endAlb2Offset;
            stream.Write(endAlb2Offset + 4 + mapModel.unknownTable.Length * 4);
            stream.Write(mapModel.unknownTable);
            WriteAlb2(stream, mapModel.alb1t2);

            stream.AlignPosition(0x10);

            var dmaChainVifOffsets = new List <int>();

            foreach (var dmaChainMap in mapModel.VifPackets)
            {
                var vifPacketIndex = 0;
                dmaChainVifOffsets.Add((int)stream.Position);

                foreach (var packetCount in dmaChainMap.DmaPerVif)
                {
                    BinaryMapping.WriteObject(stream, new DmaTag
                    {
                        Qwc     = packetCount,
                        Address = 0,
                        TagId   = packetCount > 0 ? 1 : 6,
                        Irq     = false,
                    });

                    var packetLength = packetCount * 0x10 + 8;
                    stream.Write(dmaChainMap.VifPacket, vifPacketIndex, packetLength);

                    vifPacketIndex += packetLength;
                }
            }

            stream.AlignPosition(0x80);
            stream.SetLength(stream.Position);

            stream.Position = dmaChainMapDescriptorOffset;
            for (var i = 0; i < mapModel.VifPackets.Count; i++)
            {
                var dmaChainMap = mapModel.VifPackets[i];
                BinaryMapping.WriteObject(stream, new DmaChainMap
                {
                    VifOffset    = dmaChainVifOffsets[i],
                    TextureIndex = dmaChainMap.TextureId,
                    Unk08        = dmaChainMap.Unk08,
                    Unk0c        = dmaChainMap.Unk0c
                });
            }

            stream.Position = 0;
            BinaryMapping.WriteObject(stream, mapHeader);
        }
Beispiel #15
0
        public void Write(Stream stream)
        {
            var collisionList          = new List <Collision>();
            var collisionMeshList      = new List <RawCollisionMesh>();
            var collisionMeshGroupList = new List <RawCollisionMeshGroup>();

            foreach (var node in CollisionMeshGroupList)
            {
                var start = node.Meshes.Count > 0 ? collisionMeshList.Count : 0;
                collisionMeshGroupList.Add(new RawCollisionMeshGroup
                {
                    Child1             = node.Child1,
                    Child2             = node.Child2,
                    Child3             = node.Child3,
                    Child4             = node.Child4,
                    Child5             = node.Child5,
                    Child6             = node.Child6,
                    Child7             = node.Child7,
                    Child8             = node.Child8,
                    BoundingBox        = node.BoundingBox,
                    CollisionMeshStart = (ushort)start,
                    CollisionMeshEnd   = (ushort)(start + node.Meshes.Count)
                });

                foreach (var mesh in node.Meshes)
                {
                    collisionMeshList.Add(new RawCollisionMesh
                    {
                        BoundingBox    = mesh.BoundingBox,
                        CollisionStart = (ushort)collisionList.Count,
                        CollisionEnd   = (ushort)(collisionList.Count + mesh.Collisions.Count),
                        v10            = mesh.v10,
                        v12            = mesh.v12
                    });

                    collisionList.AddRange(mesh.Collisions);
                }
            }

            var bbCache = new WriteCache <BoundingBoxInt16, string>(x => x.ToString());

            bbCache.AddConstant(BoundingBoxInt16.Invalid, -1);
            foreach (var item in collisionList)
            {
                bbCache.Add(item.BoundingBox);
            }

            var surfaceCache = new WriteCache <SurfaceFlags, int>(x => x.Flags);

            foreach (var item in collisionList)
            {
                surfaceCache.Add(item.SurfaceFlags);
            }

            var planeCache = new WriteCache <Plane, string>(x => x.ToString());

            foreach (var item in collisionList)
            {
                planeCache.Add(item.Plane);
            }

            var entries = new List <Entry>(8);

            AddEntry(entries, HeaderSize, 1);
            AddEntry(entries, CollisionMeshGroupList.Count * Col1Size, 0x10);
            AddEntry(entries, collisionMeshList.Count * Col2Size, 0x10);
            AddEntry(entries, collisionList.Count * Col3Size, 4);
            AddEntry(entries, VertexList.Count * Col4Size, 0x10);
            AddEntry(entries, planeCache.Count * Col5Size, 0x10);
            AddEntry(entries, bbCache.Count * BoundingBoxSize, 0x10);
            AddEntry(entries, surfaceCache.Count * Col7Size, 4);

            stream.Position = 0;
            BinaryMapping.WriteObject(stream, new Header
            {
                MagicCode = MagicCode,
                Version   = 1,
                Unknown08 = Unknown08,
                Unknown0c = Unknown0c,
                Entries   = entries.ToArray()
            });

            WriteCoctEntry(stream, collisionMeshGroupList);
            WriteCoctEntry(stream, collisionMeshList);
            WriteCoctEntry(stream, collisionList
                           .Select(x => new RawCollision
            {
                v00               = x.v00,
                Vertex1           = x.Vertex1,
                Vertex2           = x.Vertex2,
                Vertex3           = x.Vertex3,
                Vertex4           = x.Vertex4,
                PlaneIndex        = planeCache[x.Plane],
                BoundingBoxIndex  = bbCache[x.BoundingBox],
                SurfaceFlagsIndex = surfaceCache[x.SurfaceFlags],
            }));
            stream.AlignPosition(0x10);
            WriteValueEntry(stream, VertexList, WriteVector4);
            WriteValueEntry(stream, planeCache, WritePlane);
            WriteValueEntry(stream, bbCache, WriteBoundingBoxInt16);
            WriteCoctEntry(stream, surfaceCache);
        }
Beispiel #16
0
        private static void Write(Stream stream, InterpolatedMotion motion, bool unkFlag)
        {
            var valuePool    = new PoolValues <float>();
            var keyFramePool = new PoolValues <float>(motion.Timeline.Select(x => x.KeyFrame).Distinct().OrderBy(x => x));
            var tangentPool  = new PoolValues <float>();
            var rawTimeline  = new List <TimelineTableInternal>(motion.Timeline.Count);

            foreach (var item in motion.Timeline)
            {
                rawTimeline.Add(new TimelineTableInternal
                {
                    Time                = (short)(((int)item.Interpolation & 3) | (keyFramePool.GetIndex(item.KeyFrame) << 2)),
                    ValueIndex          = (short)valuePool.GetIndex(item.Value),
                    TangentIndexEaseIn  = (short)tangentPool.GetIndex(item.TangentEaseIn),
                    TangentIndexEaseOut = (short)tangentPool.GetIndex(item.TangentEaseOut),
                });
            }

            var writer = new BinaryWriter(stream);
            var header = new InterpolatedMotionInternal
            {
                BoneCount       = motion.BoneCount,
                TotalFrameCount = motion.TotalFrameCount,
                Unk48           = motion.Unk48,
                BoundingBoxMinX = motion.BoundingBoxMinX,
                BoundingBoxMinY = motion.BoundingBoxMinY,
                BoundingBoxMinZ = motion.BoundingBoxMinZ,
                BoundingBoxMinW = motion.BoundingBoxMinW,
                BoundingBoxMaxX = motion.BoundingBoxMaxX,
                BoundingBoxMaxY = motion.BoundingBoxMaxY,
                BoundingBoxMaxZ = motion.BoundingBoxMaxZ,
                BoundingBoxMaxW = motion.BoundingBoxMaxW,
                FrameLoop       = motion.FrameLoop,
                FrameEnd        = motion.FrameEnd,
                FramePerSecond  = motion.FramePerSecond,
                FrameCount      = motion.FrameCount,
                Unk98           = motion.Unk98,
                Unk9c           = motion.Unk9c,
            };

            stream.Write(new byte[ReservedSize], 0, ReservedSize);
            BinaryMapping.WriteObject(stream, new Header {
            });
            BinaryMapping.WriteObject(stream, new InterpolatedMotionInternal {
            });

            header.StaticPoseCount  = motion.StaticPose.Count;
            header.StaticPoseOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.StaticPose)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            header.ModelBoneAnimationCount  = motion.ModelBoneAnimation.Count;
            header.ModelBoneAnimationOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.ModelBoneAnimation.Select(Map))
            {
                BinaryMapping.WriteObject(stream, item);
            }

            header.IKHelperAnimationCount  = motion.IKHelperAnimation.Count;
            header.IKHelperAnimationOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.IKHelperAnimation.Select(Map))
            {
                BinaryMapping.WriteObject(stream, item);
            }

            header.TimelineOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in rawTimeline)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            stream.AlignPosition(4);
            header.KeyFrameCount  = keyFramePool.Values.Count;
            header.KeyFrameOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in keyFramePool.Values)
            {
                writer.Write(item);
            }

            header.TransformationValueOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in valuePool.Values)
            {
                writer.Write(item);
            }

            header.TangentOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in tangentPool.Values)
            {
                writer.Write(item);
            }

            header.IKChainCount  = motion.IKChains.Count;
            header.IKChainOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.IKChains)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            header.Unk48 = (int)(stream.Position - ReservedSize);

            stream.AlignPosition(0x10);
            header.Table8Offset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.Table8)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            stream.AlignPosition(0x10);
            header.Table7Count  = motion.Table7.Count;
            header.Table7Offset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.Table7)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            header.Table6Count  = motion.Table6.Count;
            header.Table6Offset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.Table6)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            stream.AlignPosition(0x10);
            header.TotalBoneCount = (short)(motion.BoneCount + motion.IKHelpers.Count);
            header.IKHelperOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.IKHelpers)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            header.JointIndexOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.Joints)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            stream.AlignPosition(0x10);
            header.FooterOffset = (int)(stream.Position - ReservedSize);
            BinaryMapping.WriteObject(stream, motion.Footer);

            header.UnknownTable1Offset = (int)(stream.Position - ReservedSize);
            header.UnknownTable1Count  = 0;

            stream.AlignPosition(0x10);
            stream.SetLength(stream.Position);

            stream.SetPosition(ReservedSize);
            BinaryMapping.WriteObject(stream, new Header
            {
                Version   = 0,
                Unk04     = unkFlag ? 1 : 0,
                ByteCount = (int)(stream.Length - ReservedSize),
                Unk0c     = 0,
            });
            BinaryMapping.WriteObject(stream, header);
        }
Beispiel #17
0
        public void Write(Stream stream)
        {
            var collisionList          = new List <Collision>();
            var collisionMeshList      = new List <RawCollisionMesh>();
            var collisionMeshGroupList = new List <RawNode>();

            foreach (var node in Nodes)
            {
                var start = node.Meshes.Count > 0 ? collisionMeshList.Count : 0;
                collisionMeshGroupList.Add(new RawNode
                {
                    Child1             = node.Child1,
                    Child2             = node.Child2,
                    Child3             = node.Child3,
                    Child4             = node.Child4,
                    Child5             = node.Child5,
                    Child6             = node.Child6,
                    Child7             = node.Child7,
                    Child8             = node.Child8,
                    BoundingBox        = node.BoundingBox,
                    CollisionMeshStart = (ushort)start,
                    CollisionMeshEnd   = (ushort)(start + node.Meshes.Count)
                });

                foreach (var mesh in node.Meshes)
                {
                    collisionMeshList.Add(new RawCollisionMesh
                    {
                        BoundingBox    = mesh.BoundingBox,
                        CollisionStart = (ushort)collisionList.Count,
                        CollisionEnd   = (ushort)(collisionList.Count + mesh.Collisions.Count),
                        Visibility     = mesh.Visibility,
                        Group          = mesh.Group
                    });

                    collisionList.AddRange(mesh.Collisions);
                }
            }

            var bbCache = new WriteCache <BoundingBoxInt16, string>(x => x.ToString());

            bbCache.AddConstant(BoundingBoxInt16.Invalid, -1);
            foreach (var item in collisionList)
            {
                bbCache.Add(item.BoundingBox);
            }

            var surfaceCache = new WriteCache <Attributes, int>(x => x.Flags);

            foreach (var item in collisionList)
            {
                surfaceCache.Add(item.Attributes);
            }

            var planeCache = new WriteCache <Plane, string>(x => x.ToString());

            foreach (var item in collisionList)
            {
                planeCache.Add(item.Plane);
            }

            var entries = new List <Entry>(8);

            AddEntry(entries, HeaderSize, 1);
            AddEntry(entries, Nodes.Count * NodeSize, 0x10);
            AddEntry(entries, collisionMeshList.Count * MeshSize, 0x10);
            AddEntry(entries, collisionList.Count * PolygonSize, 4);
            AddEntry(entries, VertexList.Count * Col4Size, 0x10);
            AddEntry(entries, planeCache.Count * Col5Size, 0x10);
            AddEntry(entries, bbCache.Count * BoundingBoxSize, 0x10);
            AddEntry(entries, surfaceCache.Count * AttributesSize, 4);

            stream.Position = 0;
            BinaryMapping.WriteObject(stream, new Header
            {
                MagicCode = MagicCode,
                Version   = 1,
                Depth     = Depth,
                Type      = Type,
                Entries   = entries.ToArray()
            });

            WriteCoctEntry(stream, collisionMeshGroupList);
            WriteCoctEntry(stream, collisionMeshList);
            WriteCoctEntry(stream, collisionList
                           .Select(x => new RawCollision
            {
                Ground           = x.Ground,
                FloorLevel       = x.FloorLevel,
                Vertex1          = x.Vertex1,
                Vertex2          = x.Vertex2,
                Vertex3          = x.Vertex3,
                Vertex4          = x.Vertex4,
                PlaneIndex       = planeCache[x.Plane],
                BoundingBoxIndex = bbCache[x.BoundingBox],
                AttributeIndex   = surfaceCache[x.Attributes],
            }));
            stream.AlignPosition(0x10);
            WriteValueEntry(stream, VertexList, WriteVector4);
            WriteValueEntry(stream, planeCache, WritePlane);
            WriteValueEntry(stream, bbCache, WriteBoundingBoxInt16);
            WriteCoctEntry(stream, surfaceCache);
        }
Beispiel #18
0
        public void Write(Stream stream)
        {
            stream.Position = HeaderLength;
            stream.Write(OffsetData);
            stream.AlignPosition(0x10);

            var texInfo1Offset = (int)stream.Position;

            foreach (var textureInfo in _textureInfo)
            {
                BinaryMapping.WriteObject(stream, new _TextureInfo
                {
                    Data00        = 0x10000006,
                    Data04        = 0x00000000,
                    Data08        = 0x13000000,
                    Data0c        = 0x50000006,
                    Data10        = 0x00000004,
                    Data14        = 0x10000000,
                    Data18        = 0x0000000e,
                    Data1c        = 0x00000000,
                    Data20        = 0x00000000,
                    Data24        = textureInfo.Data24,
                    Data28        = textureInfo.Data28,
                    Data2c        = 0x00000000,
                    Data30        = 0x00000000,
                    Data34        = 0x00000000,
                    Data38        = 0x00000051,
                    Data3c        = 0x00000000,
                    Data40        = textureInfo.Data40,
                    Data44        = textureInfo.Data44,
                    Data48        = 0x00000052,
                    Data4c        = 0x00000000,
                    Data50        = 0x00000000,
                    Data54        = 0x00000000,
                    Data58        = 0x00000053,
                    Data5c        = 0x00000000,
                    Data60        = textureInfo.Data60,
                    Data64        = 0x08000000,
                    Data68        = 0x00000000,
                    Data6c        = 0x00000000,
                    Data70        = textureInfo.Data70,
                    PictureOffset = textureInfo.PictureOffset,
                    Data78        = 0x00000000,
                    Data7c        = textureInfo.Data7c,
                    Data80        = textureInfo.Data80,
                    Data84        = 0x00000000,
                    Data88        = 0x13000000,
                    Data8c        = 0x00000000,
                });
            }

            var texInfo2Offset = (int)stream.Position;

            foreach (var textureInfo in _gsInfo)
            {
                BinaryMapping.WriteObject(stream, new _GsInfo
                {
                    Data00 = 0x0000000010000008,
                    Data08 = 0x5000000813000000,
                    Data10 = 0x1000000000008007,
                    Data18 = 0x000000000000000e,
                    Data20 = 0x0000000000000000,
                    Data28 = 0x000000000000003f,
                    Data30 = textureInfo.Data30,
                    Data38 = 0x0000000000000034,
                    Data40 = textureInfo.Data40,
                    Data48 = 0x0000000000000036,
                    Data50 = textureInfo.Data50,
                    Data58 = 0x0000000000000016,
                    Data60 = textureInfo.Data60,
                    Data68 = 0x0000000000000014,
                    GsTex0 = textureInfo.GsTex0,
                    Data78 = textureInfo.Data78,
                    Data80 = textureInfo.Data80,
                    Data88 = 0x0000000000000008,
                    Data90 = 0x0000000060000000,
                    Data98 = 0x0000000013000000,
                });
            }

            stream.AlignPosition(0x80);

            var pictureOffset = (int)stream.Position;

            stream.Write(PictureData);

            var paletteOffset = (int)stream.Position;

            stream.Write(PaletteData);

            stream.Write(FooterData);

            var writer = new BinaryWriter(stream.SetPosition(0));

            writer.Write(MagicCode);
            writer.Write(PaletteData.Length / 4);
            writer.Write(_textureInfo.Count - 1);
            writer.Write(_gsInfo.Count);
            writer.Write(HeaderLength);
            writer.Write(texInfo1Offset);
            writer.Write(texInfo2Offset);
            writer.Write(pictureOffset);
            writer.Write(paletteOffset);
        }