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); }
public static string ToValueName(PoolValueName value) => PoolValues.TryGetValue(value, out var a) && !String.IsNullOrEmpty(a.Name) ? a.Name : value.ToString();