Create a gist now

Instantly share code, notes, and snippets.

@Veguard /SQUAD.boo
Last active Oct 31, 2015

What would you like to do?
// SQUAD (Spherical Spline Quaternions, [Shomake 1987]) implementation for Unity by Vegard Myklebust.
// Made available under Creative Commons license CC0. License details can be found here:
// https://creativecommons.org/publicdomain/zero/1.0/legalcode.txt
import UnityEngine
static class SQUAD ():
// Returns a smoothed quaternion along the set of quaternions making up the spline, each quaternion is along an equidistant value in t
def Spline(quaternions as (Quaternion), t as single):
section as int = (quaternions.Length-1) * t
alongLine as single = (quaternions.Length-1) * t - section
if section == 0:
return SplineSegment(quaternions[section], quaternions[section], quaternions[section+1], quaternions[section+2], alongLine)
elif section == quaternions.Length - 2 and section > 0:
return SplineSegment(quaternions[section-1], quaternions[section], quaternions[section+1], quaternions[section+1], alongLine)
elif section >= 1 and section < quaternions.Length - 2:
return SplineSegment(quaternions[section-1], quaternions[section], quaternions[section+1], quaternions[section+2], alongLine)
// Returns a quaternion between q1 and q2 as part of a smooth SQUAD segment
def SplineSegment(q0 as Quaternion, q1 as Quaternion, q2 as Quaternion, q3 as Quaternion, t as single):
qa as Quaternion = Intermediate(q0,q1,q2)
qb as Quaternion = Intermediate(q1,q2,q3)
return SQUAD(q1, qa, qb, q2, t)
// Tries to compute sensible tangent values for the quaternion
def Intermediate(q0 as Quaternion, q1 as Quaternion, q2 as Quaternion):
q1inv as Quaternion = Quaternion.Inverse(q1)
c1 as Quaternion = q1inv * q2
c2 as Quaternion = q1inv * q0
c1.Log()
c2.Log()
c3 as Quaternion = c2 + c1
c3.Scale(-0.25)
c3.Exp()
r as Quaternion = q1 * c3
r.Normalize()
return r
// Returns a smooth approximation between q1 and q2 using t1 and t2 as 'tangents'
def SQUAD(q1 as Quaternion, t1 as Quaternion, t2 as Quaternion, q2 as Quaternion, t as single):
slerpT as single = 2.0 * t * (1.0 - t)
slerp1 as Quaternion = QuaternionExtensions.SlerpNoInvert(q1, q2, t)
slerp2 as Quaternion = QuaternionExtensions.SlerpNoInvert(t1, t2, t)
return QuaternionExtensions.SlerpNoInvert(slerp1, slerp2, slerpT)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment