//---------------------------------------------------------------------------- HMatrix KeyframeController::GetRotate (float normTime, int i0, int i1) { HQuaternion q; q.Slerp(normTime, mRotations[i0], mRotations[i1]); HMatrix rot; q.ToRotationMatrix(rot); return rot; }
//---------------------------------------------------------------------------- HQuaternion& HQuaternion::Intermediate (const HQuaternion& q0, const HQuaternion& q1, const HQuaternion& q2) { // assert: Q0, Q1, Q2 all unit-length HQuaternion q1Inv = q1.Conjugate(); HQuaternion p0 = q1Inv*q0; HQuaternion p2 = q1Inv*q2; HQuaternion arg = -0.25f*(p0.Log() + p2.Log()); HQuaternion a = q1*arg.Exp(); *this = a; return *this; }
//---------------------------------------------------------------------------- bool BlendTransformController::Update (double applicationTime) { if (!Controller::Update(applicationTime)) { return false; } mController0->Update(applicationTime); mController1->Update(applicationTime); const Transform& xfrm0 = mController0->GetTransform(); const Transform& xfrm1 = mController1->GetTransform(); float oneMinusWeight = 1.0f - mWeight; // Arithmetic blend of translations. const APoint& trn0 = xfrm0.GetTranslate(); const APoint& trn1 = xfrm1.GetTranslate(); APoint blendTrn = oneMinusWeight*trn0 + mWeight*trn1; mLocalTransform.SetTranslate(blendTrn); if (mRSMatrices) { const HMatrix& rot0 = xfrm0.GetRotate(); const HMatrix& rot1 = xfrm1.GetRotate(); HQuaternion quat0(rot0), quat1(rot1); if (quat0.Dot(quat1) < 0.0f) { quat1 = -quat1; } APoint sca0 = xfrm0.GetScale(); APoint sca1 = xfrm1.GetScale(); HMatrix blendRot; HQuaternion blendQuat; APoint blendSca; if (mGeometricRotation) { blendQuat.Slerp(mWeight, quat0, quat1); } else { blendQuat = oneMinusWeight*quat0 + mWeight*quat1; blendQuat.Normalize(); } blendQuat.ToRotationMatrix(blendRot); mLocalTransform.SetRotate(blendRot); if (mGeometricScale) { for (int i = 0; i < 3; ++i) { float s0 = sca0[i]; float s1 = sca1[i]; if (s0 != 0.0f && s1 != 0.0f) { float sign0 = Mathf::Sign(s0); float sign1 = Mathf::Sign(s1); s0 = Mathf::FAbs(s0); s1 = Mathf::FAbs(s1); float pow0 = Mathf::Pow(s0, oneMinusWeight); float pow1 = Mathf::Pow(s1, mWeight); blendSca[i] = sign0*sign1*pow0*pow1; } else { blendSca[i] = 0.0f; } } } else { blendSca = oneMinusWeight*sca0 + mWeight*sca1; } mLocalTransform.SetScale(blendSca); } else { // Arithemtic blend of matrices. const HMatrix& mat0 = xfrm0.GetMatrix(); const HMatrix& mat1 = xfrm1.GetMatrix(); HMatrix blendMat = oneMinusWeight*mat0 + mWeight*mat1; mLocalTransform.SetMatrix(blendMat); } Spatial* spatial = StaticCast<Spatial>(mObject); spatial->LocalTransform = mLocalTransform; return true; }