Skip to content

Instantly share code, notes, and snippets.

@apkd
Created September 10, 2017 13:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apkd/e98ff927aec4b29e0f64e7f78b01d69a to your computer and use it in GitHub Desktop.
Save apkd/e98ff927aec4b29e0f64e7f78b01d69a to your computer and use it in GitHub Desktop.
using UnityEngine;
public static partial class QuaternionExtensions
{
/// <summary>
/// Gradually changes a quaternion towards a desired goal over time.
/// The quaternion is smoothed by some spring-damper like function, which will never overshoot.
/// </summary>
/// <param name="current">Current rotation to interpolate from.</param>
/// <param name="target">Target rotation to interpolate to.</param>
/// <param name="velocity">Temporary rotation velocity coefficient, modified in each function iteration.</param>
/// <param name="time">Time of interpolation.</param>
/// <returns>Result of the iteration.</returns>
public static Quaternion SmoothDamp(this Quaternion current, Quaternion target, ref Quaternion velocity, float time)
{
var dot = Quaternion.Dot(current, target);
var scale = dot > 0f ? 1f : -1f;
target.x *= scale;
target.y *= scale;
target.z *= scale;
target.w *= scale;
var result = new Vector4(
x: Mathf.SmoothDamp(current.x, target.x, ref velocity.x, time),
y: Mathf.SmoothDamp(current.y, target.y, ref velocity.y, time),
z: Mathf.SmoothDamp(current.z, target.z, ref velocity.z, time),
w: Mathf.SmoothDamp(current.w, target.w, ref velocity.w, time)
).normalized;
var dt = 1f / Time.deltaTime;
velocity.x = (result.x - current.x) * dt;
velocity.y = (result.y - current.y) * dt;
velocity.z = (result.z - current.z) * dt;
velocity.w = (result.w - current.w) * dt;
return new Quaternion(result.x, result.y, result.z, result.w);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment