interpolating between two rotations / quaternions - in DS - source code
mCasual
Posts: 4,607
rotations in Daz studios are expressed as quaternions,
obtained and set using functions like node.getWSRot and node.SetWSRot
or as three euler angles, which are driven by the parameter tab's XRotate, YRotate and ZRotate controllers
a quaternion can be seen as a hinge-vector and a rotation angle
For figure joints, interpolating between two rotations using the three controllers can lead to problems
but interpolating between two rotations using quaternions and the SLERP method leads to good results
here's Daz scripting code for SLERPing between a pose at frame 218 and a pose at frame 228
var tick = 1 * Scene.getTimeStep();
var node = Scene.getPrimarySelection();
var sin = Math.sin;
var frchk = [218, 228]
var fra = frchk[0];
var frb = frchk[1];
var qa = new DzQuat( node.getWSRot( fra * tick ) );
var qb = new DzQuat( node.getWSRot( frb * tick ) );
var d = frb - fra;
for( var i = 1; i < d; i++ )
{
var qc = slerp( qa, qb, i / d );
var t = ( fra + i ) * tick;
node.setWSRot( t, qc )
}
function slerp( q1, q2, t )
{
var ddd = quatDot( q1, q2 );
//dot = cos( angle )
//if (dot < 0) ang > 90 deg, so we invert one of the two
if( ddd < 0 )
{
ddd = -ddd;
q3 = quatScale( q2, -1 );
}
else
{
q3 = q2;
}
var s = 1 - t;
var q1b = quatScale( q1, s );
var q2b = quatScale( q3, t );
if( ddd < 0.95 )
{
var angle = Math.acos( ddd );
var sa = sin( angle )
q1b = quatScale( q1, sin( angle * s ) / sa );
q2b = quatScale( q3, sin( angle * t ) / sa );
}
else
{
q1b = quatScale( q1, s );
q2b = quatScale( q3, t );
}
return( quatAdd( q1b, q2b ) );
}
function quatScale( q, scale)
{
var nq = new DzQuat();
nq.x = q.x * scale;
nq.y = q.y * scale;
nq.z = q.z * scale;
nq.w = q.w * scale;
return( nq );
}
function quatAdd( q, r )
{
var nq = new DzQuat();
nq.x = q.x + r.x;
nq.y = q.y + r.y;
nq.z = q.z + r.z;
nq.w = q.w + r.w;
return( nq );
}
function quatDot( q, r )
{
var qq = new DzVec3( q.x, q.y, q.z );
var rr = new DzVec3( r.x, r.y, r.z );
return( qq.dot( rr ) );
}
Post edited by mCasual on