From 323547bd9c2f5d70fe13bf879259606792642868 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Thu, 13 Jan 2022 17:13:38 +0100 Subject: [PATCH] Improved HeadTarget.RotationX --- .../Scripts/Targets/HeadTarget.cs | 30 +++++++++++++++++-- Samples/Sites.meta | 8 ----- Samples/Visitors.meta | 8 ----- package.json | 4 +-- 4 files changed, 30 insertions(+), 20 deletions(-) delete mode 100644 Samples/Sites.meta delete mode 100644 Samples/Visitors.meta diff --git a/Runtime/HumanoidFree/Scripts/Targets/HeadTarget.cs b/Runtime/HumanoidFree/Scripts/Targets/HeadTarget.cs index f80ed97..d77156e 100644 --- a/Runtime/HumanoidFree/Scripts/Targets/HeadTarget.cs +++ b/Runtime/HumanoidFree/Scripts/Targets/HeadTarget.cs @@ -1017,9 +1017,12 @@ namespace Passer.Humanoid { /// Sets the rotation of the head around the X axis public void RotationX(float angle) { - Vector3 angles = (Quaternion.Inverse(humanoid.transform.rotation) * transform.rotation).eulerAngles; + Quaternion localTargetRotation = Quaternion.Inverse(humanoid.transform.rotation) * transform.rotation; + GetSwingTwist(Vector3.right, localTargetRotation, out Quaternion swing, out Quaternion twist); + float xAngle = angle * maxXangle; - transform.rotation = humanoid.transform.rotation * Quaternion.Euler(xAngle, angles.y, angles.z); + Quaternion newLocalTargetRotation = Quaternion.AngleAxis(xAngle, Vector3.right) * swing; + transform.rotation = humanoid.transform.rotation * newLocalTargetRotation; } /// Sets the rotation of the head around the Y axis @@ -1029,6 +1032,29 @@ namespace Passer.Humanoid { transform.rotation = humanoid.transform.rotation * Quaternion.Euler(angles.x, yAngle, angles.z); } + public static Quaternion GetRotationAround(Vector3 axis, Quaternion rotation) { + Vector3 ra = new Vector3(rotation.x, rotation.y, rotation.z); // rotation axis + Vector3 p = Vector3.Project(ra, axis); // return projection v1 on to v2 (parallel component) + Quaternion twist = new Quaternion(p.x, p.y, p.z, rotation.w); + twist = Normalize(twist); + return twist; + } + + public static Quaternion Normalize(Quaternion q) { + float length = Mathf.Sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w); + if (length == 0) + return Quaternion.identity; + + float scale = 1.0f / length; + Quaternion q1 = new Quaternion(q.x * scale, q.y * scale, q.z * scale, q.w * scale); + return q1; + } + + public static void GetSwingTwist(Vector3 axis, Quaternion rotation, out Quaternion swing, out Quaternion twist) { + twist = GetRotationAround(axis, rotation); + swing = rotation * Quaternion.Inverse(twist); + } + #endregion #region Tools diff --git a/Samples/Sites.meta b/Samples/Sites.meta deleted file mode 100644 index 1879ab5..0000000 --- a/Samples/Sites.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a1d84f5cb24b89d4db7c1d3b83949a69 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/Visitors.meta b/Samples/Visitors.meta deleted file mode 100644 index 27edab5..0000000 --- a/Samples/Visitors.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 03517ba7d9815ac47985f7ce3a768240 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/package.json b/package.json index c05d011..f01cbf6 100644 --- a/package.json +++ b/package.json @@ -24,12 +24,12 @@ { "displayName": "Sites", "description": "Example sites which can be visited with a Visitor", - "path": "Samples/Sites" + "path": "Samples~/Sites" }, { "displayName": "Visitors", "description": "The default Visitors which can browse sites", - "path": "Samples/Visitors" + "path": "Samples~/Visitors" } ] } \ No newline at end of file