2020-07-27 23:13:43 +00:00
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
2022-03-03 03:46:33 +00:00
|
|
|
|
namespace QSB.Utility;
|
|
|
|
|
|
|
|
|
|
public static class QuaternionHelper
|
2020-07-27 23:13:43 +00:00
|
|
|
|
{
|
2022-03-03 03:46:33 +00:00
|
|
|
|
// Stolen from here: https://gist.github.com/maxattack/4c7b4de00f5c1b95a33b
|
|
|
|
|
public static Quaternion SmoothDamp(Quaternion rot, Quaternion target, ref Quaternion deriv, float time)
|
2020-12-02 21:23:01 +00:00
|
|
|
|
{
|
2022-03-03 03:46:33 +00:00
|
|
|
|
if (Time.deltaTime < Mathf.Epsilon)
|
2020-12-02 21:23:01 +00:00
|
|
|
|
{
|
2022-03-03 03:46:33 +00:00
|
|
|
|
return rot;
|
|
|
|
|
}
|
2022-02-17 04:00:57 +00:00
|
|
|
|
|
2022-03-03 03:46:33 +00:00
|
|
|
|
// account for double-cover
|
|
|
|
|
var dot = Quaternion.Dot(rot, target);
|
|
|
|
|
var multi = dot > 0f ? 1f : -1f;
|
|
|
|
|
target.x *= multi;
|
|
|
|
|
target.y *= multi;
|
|
|
|
|
target.z *= multi;
|
|
|
|
|
target.w *= multi;
|
|
|
|
|
// smooth damp (nlerp approx)
|
|
|
|
|
var result = new Vector4(
|
|
|
|
|
Mathf.SmoothDamp(rot.x, target.x, ref deriv.x, time),
|
|
|
|
|
Mathf.SmoothDamp(rot.y, target.y, ref deriv.y, time),
|
|
|
|
|
Mathf.SmoothDamp(rot.z, target.z, ref deriv.z, time),
|
|
|
|
|
Mathf.SmoothDamp(rot.w, target.w, ref deriv.w, time)
|
|
|
|
|
).normalized;
|
2021-02-19 13:23:14 +00:00
|
|
|
|
|
2022-03-03 03:46:33 +00:00
|
|
|
|
// ensure deriv is tangent
|
|
|
|
|
var derivError = Vector4.Project(new Vector4(deriv.x, deriv.y, deriv.z, deriv.w), result);
|
|
|
|
|
deriv.x -= derivError.x;
|
|
|
|
|
deriv.y -= derivError.y;
|
|
|
|
|
deriv.z -= derivError.z;
|
|
|
|
|
deriv.w -= derivError.w;
|
2021-02-19 13:23:14 +00:00
|
|
|
|
|
2022-03-03 03:46:33 +00:00
|
|
|
|
return new Quaternion(result.x, result.y, result.z, result.w);
|
2020-12-02 21:23:01 +00:00
|
|
|
|
}
|
2022-02-25 06:04:54 +00:00
|
|
|
|
}
|