mirror of
https://github.com/LazyDuchess/OpenTS2.git
synced 2025-01-22 08:11:47 -05:00
Fix rotation conversion to quaternions in animations
This commit is contained in:
parent
2475f1a8a5
commit
380b83ad7f
9 changed files with 61 additions and 18 deletions
|
@ -265,7 +265,7 @@ namespace OpenTS2.Components
|
|||
tip = tip,
|
||||
target = Scenegraph.BoneCRC32ToTransform[target.TranslationCrc],
|
||||
targetPositionWeight = 1.0f,
|
||||
targetRotationWeight = 0.0f,
|
||||
targetRotationWeight = 1.0f,
|
||||
hintWeight = 1.0f,
|
||||
};
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using OpenTS2.Common.Utils;
|
||||
using OpenTS2.Files.Formats.DBPF.Scenegraph.Block;
|
||||
using OpenTS2.Files.Formats.DBPF.Types;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Animations.Rigging;
|
||||
|
||||
|
@ -103,15 +104,41 @@ namespace OpenTS2.Content.DBPF.Scenegraph
|
|||
{
|
||||
if (channel.Type == AnimResourceConstBlock.ChannelType.EulerRotation)
|
||||
{
|
||||
var curveX =
|
||||
new AnimationCurve(CreateKeyFramesForComponent(channel.DurationTicks, channel.Components[0]));
|
||||
clip.SetCurve(relativePathToBone, typeof(Transform), "localEulerAngles.x", curveX);
|
||||
var curveY =
|
||||
new AnimationCurve(CreateKeyFramesForComponent(channel.DurationTicks, channel.Components[1]));
|
||||
clip.SetCurve(relativePathToBone, typeof(Transform), "localEulerAngles.y", curveY);
|
||||
var curveZ =
|
||||
new AnimationCurve(CreateKeyFramesForComponent(channel.DurationTicks, channel.Components[2]));
|
||||
clip.SetCurve(relativePathToBone, typeof(Transform), "localEulerAngles.z", curveZ);
|
||||
var xFrames = CreateKeyFramesForComponent(channel.DurationTicks, channel.Components[0]);
|
||||
var yFrames = CreateKeyFramesForComponent(channel.DurationTicks, channel.Components[1]);
|
||||
var zFrames = CreateKeyFramesForComponent(channel.DurationTicks, channel.Components[2]);
|
||||
var curveX = new AnimationCurve(xFrames);
|
||||
var curveY = new AnimationCurve(yFrames);
|
||||
var curveZ = new AnimationCurve(zFrames);
|
||||
|
||||
var quatX = new Keyframe[xFrames.Length];
|
||||
var quatY = new Keyframe[xFrames.Length];
|
||||
var quatZ = new Keyframe[xFrames.Length];
|
||||
var quatW = new Keyframe[xFrames.Length];
|
||||
|
||||
// Convert from xyz euler rotations to quaternions.
|
||||
for (var i = 0; i < curveX.keys.Length; i++)
|
||||
{
|
||||
var xFrame = curveX.keys[i];
|
||||
var t = xFrame.time;
|
||||
var (y, z) = (curveY.Evaluate(t), curveZ.Evaluate(t));
|
||||
var quat = QuaternionSerializer.FromSims2EulerRotationDegrees(xFrame.value, y, z);
|
||||
|
||||
quatX[i] = new Keyframe(t, quat.x);
|
||||
quatY[i] = new Keyframe(t, quat.y);
|
||||
quatZ[i] = new Keyframe(t, quat.z);
|
||||
quatW[i] = new Keyframe(t, quat.w);
|
||||
}
|
||||
|
||||
curveX = new AnimationCurve(quatX);
|
||||
curveY = new AnimationCurve(quatY);
|
||||
curveZ = new AnimationCurve(quatZ);
|
||||
var curveW = new AnimationCurve(quatW);
|
||||
|
||||
clip.SetCurve(relativePathToBone, typeof(Transform), "localRotation.x", curveX);
|
||||
clip.SetCurve(relativePathToBone, typeof(Transform), "localRotation.y", curveY);
|
||||
clip.SetCurve(relativePathToBone, typeof(Transform), "localRotation.z", curveZ);
|
||||
clip.SetCurve(relativePathToBone, typeof(Transform), "localRotation.w", curveW);
|
||||
}
|
||||
else if (channel.Type == AnimResourceConstBlock.ChannelType.TransformXYZ)
|
||||
{
|
||||
|
|
|
@ -61,14 +61,14 @@ namespace OpenTS2.Files.Formats.DBPF
|
|||
}
|
||||
|
||||
var position = Vector3Serializer.Deserialize(reader);
|
||||
var rotation = QuaterionSerialzier.Deserialize(reader);
|
||||
var rotation = QuaternionSerializer.Deserialize(reader);
|
||||
|
||||
var numBones = reader.ReadUInt32();
|
||||
for (var i = 0; i < numBones; i++)
|
||||
{
|
||||
var boneName = reader.ReadVariableLengthPascalString();
|
||||
var bonePosition = Vector3Serializer.Deserialize(reader);
|
||||
var boneRotation = QuaterionSerialzier.Deserialize(reader);
|
||||
var boneRotation = QuaternionSerializer.Deserialize(reader);
|
||||
}
|
||||
|
||||
return new LotObjectAsset.LotObject(resourceName, position, rotation);
|
||||
|
|
|
@ -142,7 +142,7 @@ namespace OpenTS2.Files.Formats.DBPF
|
|||
var objectVersion = reader.ReadByte();
|
||||
|
||||
var positionOffset = Vector3Serializer.Deserialize(reader);
|
||||
var modelOrientation = QuaterionSerialzier.Deserialize(reader);
|
||||
var modelOrientation = QuaternionSerializer.Deserialize(reader);
|
||||
// unknown
|
||||
var unknown = Vector3Serializer.Deserialize(reader);
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace OpenTS2.Files.Formats.DBPF.Scenegraph.Block
|
|||
Quaternion jointOrientation = Quaternion.identity;
|
||||
if (blockTypeInfo.Version > 3)
|
||||
{
|
||||
jointOrientation = QuaterionSerialzier.Deserialize(reader);
|
||||
jointOrientation = QuaternionSerializer.Deserialize(reader);
|
||||
}
|
||||
|
||||
return new BoneDataExtensionBlock(blockTypeInfo, headingOffsetAxis, mirrorAxis, stretchAxis, stretchFactor,
|
||||
|
|
|
@ -84,7 +84,7 @@ namespace OpenTS2.Files.Formats.DBPF.Scenegraph.Block
|
|||
return new DataListValue<DataListValue[]>(name, items);
|
||||
case 8:
|
||||
// quanterion
|
||||
return new DataListValue<Quaternion>(name, QuaterionSerialzier.Deserialize(reader));
|
||||
return new DataListValue<Quaternion>(name, QuaternionSerializer.Deserialize(reader));
|
||||
case 9:
|
||||
// bytes
|
||||
var len = reader.ReadUInt32();
|
||||
|
|
|
@ -278,7 +278,7 @@ namespace OpenTS2.Files.Formats.DBPF.Scenegraph.Block
|
|||
var bindPoses = new GeometryDataContainerBlock.BindPose[reader.ReadUInt32()];
|
||||
for (var i = 0; i < bindPoses.Length; i++)
|
||||
{
|
||||
var rotation = QuaterionSerialzier.Deserialize(reader);
|
||||
var rotation = QuaternionSerializer.Deserialize(reader);
|
||||
var position = Vector3Serializer.Deserialize(reader);
|
||||
bindPoses[i] = new GeometryDataContainerBlock.BindPose(position, rotation);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace OpenTS2.Files.Formats.DBPF.Scenegraph.Block
|
|||
var compositionTree = CompositionTreeNodeBlock.Deserialize(reader);
|
||||
|
||||
var transform = Vector3Serializer.Deserialize(reader);
|
||||
var rotation = QuaterionSerialzier.Deserialize(reader);
|
||||
var rotation = QuaternionSerializer.Deserialize(reader);
|
||||
var boneId = reader.ReadUInt32();
|
||||
return new TransformNodeBlock(blockTypeInfo, compositionTree, transform, rotation, boneId);
|
||||
}
|
||||
|
|
|
@ -3,11 +3,27 @@ using UnityEngine;
|
|||
|
||||
namespace OpenTS2.Files.Formats.DBPF.Types
|
||||
{
|
||||
public class QuaterionSerialzier
|
||||
public static class QuaternionSerializer
|
||||
{
|
||||
public static Quaternion Deserialize(IoBuffer reader)
|
||||
{
|
||||
return new Quaternion(reader.ReadFloat(), reader.ReadFloat(), reader.ReadFloat(), reader.ReadFloat());
|
||||
}
|
||||
|
||||
public static Quaternion FromSims2EulerRotationDegrees(float x, float y, float z)
|
||||
{
|
||||
var sx = Mathf.Sin(x * 0.5f * Mathf.Deg2Rad);
|
||||
var cx = Mathf.Cos(x * 0.5f * Mathf.Deg2Rad);
|
||||
var sy = Mathf.Sin(y * 0.5f * Mathf.Deg2Rad);
|
||||
var cy = Mathf.Cos(y * 0.5f * Mathf.Deg2Rad);
|
||||
var sz = Mathf.Sin(z * 0.5f * Mathf.Deg2Rad);
|
||||
var cz = Mathf.Cos(z * 0.5f * Mathf.Deg2Rad);
|
||||
|
||||
var quatX = (cz * (cy * sx)) - (sz * (cx * sy));
|
||||
var quatY = (cz * (cx * sy)) + (sz * (cy * sx));
|
||||
var quatZ = (sz * (cx * cy)) - (cz * (sx * sy));
|
||||
var quatW = (cz * (cx * cy)) + (sz * (sx * sy));
|
||||
return new Quaternion(quatX, quatY, quatZ, quatW);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue