Im running into a bug while trying to create a pose store tool in 3ds max. For some reason when i peform the slerp function on a rotation from one transform to the next it will occasionally add an extra 360 rotation.
I have a video showing how it happens here https://vimeo.com/44279808 . The password is slerp
This is a bit of code I wrote years ago to do just this. The function you are potentially looking for is the quatSlerp
fn quatDotProduct quatDotA quatDotB =
(
quatDotA.w*quatDotB.w + quatDotA.x*quatDotB.x + quatDotA.y*quatDotB.y + quatDotA.z*quatDotB.z
)
fn quatMultiply theMultiplier theQuat =
(
local returnQuat = (quat 0 0 0 1)
returnQuat.w = theMultiplier * theQuat.w
returnQuat.x = theMultiplier * theQuat.x
returnQuat.y = theMultiplier * theQuat.y
returnQuat.z = theMultiplier * theQuat.z
return returnQuat
)
fn quatAdd quatAddA quatAddB =
(
local returnQuat = (quat 0 0 0 1)
returnQuat.w = quatAddA.w + quatAddB.w
returnQuat.x = quatAddA.x + quatAddB.x
returnQuat.y = quatAddA.y + quatAddB.y
returnQuat.z = quatAddA.z + quatAddB.z
return returnQuat
)
fn quatSubtract quatAddA quatAddB =
(
local returnQuat = (quat 0 0 0 1)
returnQuat.w = quatAddA.w - quatAddB.w
returnQuat.x = quatAddA.x - quatAddB.x
returnQuat.y = quatAddA.y - quatAddB.y
returnQuat.z = quatAddA.z - quatAddB.z
return returnQuat
)
fn quatSlerp quatA quatB ratio =
(
local quat1 = (quat 0 0 0 1) --declare as quats
local quat2 = (quat 0 0 0 1)
local ca = (quatDotProduct quatA quatB )
if ca < 0.0 then
(
ca = -ca
quat1.w = -quatA.w
quat1.x = -quatA.x
quat1.y = -quatA.y
quat1.z = -quatA.z
)
else
(
quat1 = copy quatA
)
if ((1.0 - ca) > 0.00000012) then --smallest maxscript number?
(
angle = acos(ca)
sa = sin(angle)
s1 = sin((1.0 - ratio) * angle) / sa
s2 = sin(ratio * angle) / sa
)
else
(
s1 = 1.0 - ratio
s2 = ratio
)
quat1 = (quatMultiply s1 quat1)
quat2 = (quatMultiply s2 quatB)
return (quatAdd quat1 quat2)
)
--returns a number in 0.0 to 1.0 representing how similar the two quaternions are. "Identity-tude"
--1.0 is identical, and 0.0 is exactly opposite (180 degrees off on one axis for example)
--Honestly I don't know how kosher this methodology is...
--The two quatslerps herein are used to "normalize" the quaternions.
fn quatDelta quatA quatB =
(
quatDotProduct (quatslerp quatA (quat 0 0 0 1) 0.0) (quatslerp quatB (quat 0 0 0 1) 0.0)
)
Thanks this fixed my problem.
fn quatAdd quatAddA quatAddB =
(
local returnQuat = (quat 0 0 0 1)
returnQuat.w = quatAddA.w + quatAddB.w
returnQuat.x = quatAddA.x + quatAddB.x
returnQuat.y = quatAddA.y + quatAddB.y
returnQuat.z = quatAddA.z + quatAddB.z
return returnQuat
)
Um, what is this code supposed to do?