public static void LoadCurves(BinaryReaderEx reader, SpuBinary spuBinary) { var numBones = spuBinary.NumBones; foreach (var section in spuBinary.Sections) { var bones = CreateBoneArray(numBones); foreach (var chunk in section.Chunks) { reader.BaseStream.Position = spuBinary.SpuBasePosition + chunk.Offset; for (var i = 0; i < chunk.NumChildren; i++) { var boneId = reader.ReadInt16(Endianness.BigEndian); var type = reader.ReadInt16(Endianness.BigEndian); var count = reader.ReadInt16(Endianness.BigEndian); reader.ReadInt16(); // Skip 2 unused bytes if ((type == 0 && chunk.Flag != 1) || (type != 0 && chunk.Flag == 1)) { throw new InvalidOperationException(String.Format("Flag/Type mismatch? Flag = {0} Type = {1}", chunk.Flag, type)); } AnimatedComponent component = DetermineAnimatedComponent(type); Curves.CurveBase curve; switch (type) { case 0x00: curve = CreateQuaternionCurve(reader, count); break; case 0x04: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: curve = CreateCompressedLinearCurve(reader, component, count); break; case 0x0B: case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: curve = CreateConstantCurve(reader, component, count); break; case 0x11: case 0x12: case 0x13: curve = CreateUncompressedLinearCurve(reader, component, count); break; default: throw new InvalidOperationException("Unknown curve type " + type); } if (curve.CurveValues.Count == 0) { throw new InvalidOperationException("No Curve Values!?"); } AddCurveToBone(bones, boneId, curve); } } for (var i = 0; i < numBones; i++) { var bone = bones[i]; if (bone == null) { continue; } var boneNode = new AnimatedBoneNode(); boneNode.Bone = bone; boneNode.Parent = section; section.Children.Add(boneNode); } } }