private Motion(bool isRaw) { IsRaw = isRaw; if (isRaw) { Raw = new RawMotion { Matrices = new List <Matrix4x4[]>(), }; } else { Interpolated = new InterpolatedMotion { Footer = new FooterTable(), IKChains = new List <IKChainTable>(), IKHelperAnimation = new List <BoneAnimationTable>(), IKHelpers = new List <IKHelperTable>(), Joints = new List <JointTable>(), ModelBoneAnimation = new List <BoneAnimationTable>(), StaticPose = new List <StaticPoseTable>(), Table6 = new List <UnknownTable6>(), Table7 = new List <UnknownTable7>(), Table8 = new List <UnknownTable8>(), Timeline = new List <TimelineTable>(), }; } }
private static void Write(Stream stream, RawMotion rawMotion, bool unkFlag) { const int HeaderSize = 0x60; stream.Write(new byte[ReservedSize], 0, ReservedSize); BinaryMapping.WriteObject(stream, new Header { Version = 1, Unk04 = unkFlag ? 1 : 0, ByteCount = HeaderSize + rawMotion.BoneCount * rawMotion.Matrices.Count * Matrix4x4Size + rawMotion.Matrices2.Length * Matrix4x4Size, Unk0c = 0, }); BinaryMapping.WriteObject(stream, new RawMotionInternal { BoneCount = rawMotion.BoneCount, Unk14 = 0, Unk18 = 0, Unk1c = 0, FrameCountPerLoop = (int)(rawMotion.FrameEnd - rawMotion.FrameLoop) * 2, TotalFrameCount = rawMotion.Matrices.Count, Unk28 = rawMotion.Unk28, Unk2c = rawMotion.Matrices2.Length > 0 ? HeaderSize + rawMotion.BoneCount * rawMotion.Matrices.Count * Matrix4x4Size : 0, BoundingBoxMinX = rawMotion.BoundingBoxMinX, BoundingBoxMinY = rawMotion.BoundingBoxMinY, BoundingBoxMinZ = rawMotion.BoundingBoxMinZ, BoundingBoxMinW = rawMotion.BoundingBoxMinW, BoundingBoxMaxX = rawMotion.BoundingBoxMaxX, BoundingBoxMaxY = rawMotion.BoundingBoxMaxY, BoundingBoxMaxZ = rawMotion.BoundingBoxMaxZ, BoundingBoxMaxW = rawMotion.BoundingBoxMaxW, FrameLoop = rawMotion.FrameLoop, FrameEnd = rawMotion.FrameEnd, FramePerSecond = rawMotion.FramePerSecond, FrameCount = rawMotion.FrameCount }); var writer = new BinaryWriter(stream); foreach (var block in rawMotion.Matrices) { for (int i = 0; i < block.Length; i++) { WriteMatrix(writer, block[i]); } } for (int i = 0; i < rawMotion.Matrices2.Length; i++) { WriteMatrix(writer, rawMotion.Matrices2[i]); } writer.Flush(); }
private Motion(Stream stream) { stream.Position += ReservedSize; var header = BinaryMapping.ReadObject <Header>(stream); IsRaw = header.Version == 1; UnkFlag = header.Unk04 != 0; if (IsRaw) { var raw = BinaryMapping.ReadObject <RawMotionInternal>(stream); Raw = new RawMotion { BoneCount = raw.BoneCount, Unk28 = raw.Unk28, Unk2c = raw.Unk2c, BoundingBoxMinX = raw.BoundingBoxMinX, BoundingBoxMinY = raw.BoundingBoxMinY, BoundingBoxMinZ = raw.BoundingBoxMinZ, BoundingBoxMinW = raw.BoundingBoxMinW, BoundingBoxMaxX = raw.BoundingBoxMaxX, BoundingBoxMaxY = raw.BoundingBoxMaxY, BoundingBoxMaxZ = raw.BoundingBoxMaxZ, BoundingBoxMaxW = raw.BoundingBoxMaxW, FrameLoop = raw.FrameLoop, FrameEnd = raw.FrameEnd, FramePerSecond = raw.FramePerSecond, FrameCount = raw.FrameCount }; var reader = new BinaryReader(stream); Raw.Matrices = new List <Matrix4x4[]>(raw.TotalFrameCount); for (var i = 0; i < raw.TotalFrameCount; i++) { var matrices = new Matrix4x4[Raw.BoneCount]; for (var j = 0; j < Raw.BoneCount; j++) { matrices[j] = ReadMatrix(reader); } Raw.Matrices.Add(matrices); } if (raw.Unk2c > 0) { stream.Position = ReservedSize + raw.Unk2c; Raw.Matrices2 = new Matrix4x4[raw.TotalFrameCount]; for (var j = 0; j < Raw.Matrices2.Length; j++) { Raw.Matrices2[j] = ReadMatrix(reader); } } else { Raw.Matrices2 = new Matrix4x4[0]; } } else { var reader = new BinaryReader(stream); var motion = BinaryMapping.ReadObject <InterpolatedMotionInternal>(stream); Interpolated = new InterpolatedMotion { 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.Position = ReservedSize + motion.StaticPoseOffset; Interpolated.StaticPose = Enumerable .Range(0, motion.StaticPoseCount) .Select(x => BinaryMapping.ReadObject <StaticPoseTable>(stream)) .ToList(); stream.Position = ReservedSize + motion.ModelBoneAnimationOffset; Interpolated.ModelBoneAnimation = Enumerable .Range(0, motion.ModelBoneAnimationCount) .Select(x => BinaryMapping.ReadObject <BoneAnimationTableInternal>(stream)) .Select(Map) .ToList(); stream.Position = ReservedSize + motion.IKHelperAnimationOffset; Interpolated.IKHelperAnimation = Enumerable .Range(0, motion.IKHelperAnimationCount) .Select(x => BinaryMapping.ReadObject <BoneAnimationTableInternal>(stream)) .Select(Map) .ToList(); stream.Position = ReservedSize + motion.TimelineOffset; var estimatedTimelineCount = (motion.KeyFrameOffset - motion.TimelineOffset) / 8; var rawTimeline = Enumerable .Range(0, estimatedTimelineCount) .Select(x => BinaryMapping.ReadObject <TimelineTableInternal>(stream)) .ToList(); stream.Position = ReservedSize + motion.KeyFrameOffset; var keyFrames = Enumerable .Range(0, motion.KeyFrameCount) .Select(x => reader.ReadSingle()) .ToList(); stream.Position = ReservedSize + motion.TransformationValueOffset; var estimatedKeyFrameCount = (motion.TangentOffset - motion.TransformationValueOffset) / 4; var transformationValues = Enumerable .Range(0, estimatedKeyFrameCount) .Select(x => reader.ReadSingle()) .ToList(); stream.Position = ReservedSize + motion.TangentOffset; var estimatedTangentCount = (motion.IKChainOffset - motion.TangentOffset) / 4; var tangentValues = Enumerable .Range(0, estimatedTangentCount) .Select(x => reader.ReadSingle()) .ToList(); stream.Position = ReservedSize + motion.IKChainOffset; Interpolated.IKChains = Enumerable .Range(0, motion.IKChainCount) .Select(x => BinaryMapping.ReadObject <IKChainTable>(stream)) .ToList(); stream.Position = ReservedSize + motion.Table8Offset; var estimatedTable8Count = (motion.Table7Offset - motion.Table8Offset) / 0x30; Interpolated.Table8 = Enumerable .Range(0, estimatedTable8Count) .Select(x => BinaryMapping.ReadObject <UnknownTable8>(stream)) .ToList(); stream.Position = ReservedSize + motion.Table7Offset; Interpolated.Table7 = Enumerable .Range(0, motion.Table7Count) .Select(x => BinaryMapping.ReadObject <UnknownTable7>(stream)) .ToList(); stream.Position = ReservedSize + motion.Table6Offset; Interpolated.Table6 = Enumerable .Range(0, motion.Table6Count) .Select(x => BinaryMapping.ReadObject <UnknownTable6>(stream)) .ToList(); stream.Position = ReservedSize + motion.IKHelperOffset; Interpolated.IKHelpers = Enumerable .Range(0, motion.TotalBoneCount - motion.BoneCount) .Select(x => BinaryMapping.ReadObject <IKHelperTable>(stream)) .ToList(); stream.Position = ReservedSize + motion.JointIndexOffset; Interpolated.Joints = Enumerable .Range(0, motion.TotalBoneCount + 1) .Select(x => BinaryMapping.ReadObject <JointTable>(stream)) .ToList(); Interpolated.Timeline = rawTimeline .Select(x => new TimelineTable { Interpolation = (Interpolation)(x.Time & 3), KeyFrame = keyFrames[x.Time >> 2], Value = transformationValues[x.ValueIndex], TangentEaseIn = tangentValues[x.TangentIndexEaseIn], TangentEaseOut = tangentValues[x.TangentIndexEaseOut], }) .ToList(); stream.Position = ReservedSize + motion.FooterOffset; Interpolated.Footer = BinaryMapping.ReadObject <FooterTable>(stream); stream.Position = ReservedSize + motion.UnknownTable1Offset; } }