bool TbsAnimObj::GetDecompAffine( TimeValue t, INode* pNode, AffineParts* ap, Point3* rotAxis, float* rotAngle ) { Matrix3 tm = pNode->GetNodeTM(t) * Inverse(pNode->GetParentTM(t)); decomp_affine(tm, ap); Point3 vRotAxis; float fRotAngle; if( rotAngle != NULL && rotAngle != NULL ) { AngAxisFromQ(ap->q, rotAngle, *rotAxis); } return true; }
bool bgAnimMax::GetDecompAffine(TimeValue time, INode* pNode, AffineParts* pAP, Point3* pRotAxis, float* pRotAngle) { Matrix3 tm = pNode->GetNodeTM(time) * Inverse(pNode->GetParentTM(time)); decomp_affine(tm, pAP); Point3 vRotAxis; float fRotAngle; if (pRotAngle != NULL && pRotAngle != NULL) { AngAxisFromQ(pAP->q, pRotAngle, *pRotAxis); } return true; }
/** * This method will check if there is any animation connected to the node. * It will run from start to end of animation range and if the position, * rotation or scale has been changed during this, it will return true. */ BOOL OSGExp::hasAnimation(INode* node){ TimeValue start = _ip->GetAnimRange().Start(); TimeValue end = _ip->GetAnimRange().End(); TimeValue t; int delta = GetTicksPerFrame(); Matrix3 tm; AffineParts ap; Point3 firstPos; float rotAngle, firstRotAngle; Point3 rotAxis, firstRotAxis; Point3 firstScaleFactor; //return TRUE; for (t=start; t<=end; t+=delta) { tm = node->GetNodeTM(t) * Inverse(node->GetParentTM(t)); decomp_affine(tm, &ap); AngAxisFromQ(ap.q, &rotAngle, rotAxis); // If any point, rotation or scale in the t'th frame has // changes from the start frame then we have an animation. if (t != start){ if(!Util::isPoint3Equal(ap.t, firstPos) || !Util::isPoint3Equal(rotAxis, firstRotAxis) || fabs(rotAngle - firstRotAngle) > ALMOST_ZERO || !Util::isPoint3Equal(ap.k, firstScaleFactor)){ return TRUE; } } else { firstPos = ap.t; firstRotAngle = rotAngle; firstRotAxis = rotAxis; firstScaleFactor = ap.k; } } return FALSE; }
/** * This method will sample the node at each frame to get any possible change * of position, rotation and scaling. The posible changes is inserted into an * OSG AnimationPath and returned. */ osg::AnimationPath* OSGExp::sampleNode(INode* node){ // Create the animation path. osg::AnimationPath* animationPath = new osg::AnimationPath(); animationPath->setLoopMode(osg::AnimationPath::LOOP); TimeValue start = _ip->GetAnimRange().Start(); TimeValue end = _ip->GetAnimRange().End(); int val; if (node->GetUserPropInt("startFrame",val)) start= val; if (node->GetUserPropInt("endFrame",val)) end= val; TimeValue t; int delta = GetTicksPerFrame(); Matrix3 tm; AffineParts ap; for (t=start; t<=end; t+=delta) { tm = node->GetNodeTM(t) * Inverse(node->GetParentTM(t)); decomp_affine(tm, &ap); Point3 pos = ap.t; Point3 sca = ap.k; // Note: OSG wants absolute rotations Quat rot = ap.q; // Convert from Max's left-handed rotation to right-handed float ang; Point3 axis; AngAxisFromQ(rot, &ang, axis); ang = -ang; rot = QFromAngAxis(ang, axis); // Insert the sample point into animation path addControlPoint(animationPath, (t/(float)TIME_TICKSPERSEC), pos, rot, sca); } return animationPath; }
BOOL AsciiExp::CheckForAnimation(INode* node, BOOL& bPos, BOOL& bRot, BOOL& bScale) { TimeValue start = ip->GetAnimRange().Start(); TimeValue end = ip->GetAnimRange().End(); TimeValue t; int delta = GetTicksPerFrame(); Matrix3 tm; AffineParts ap; Point3 firstPos; float rotAngle, firstRotAngle = 0.0f; Point3 rotAxis, firstRotAxis; Point3 firstScaleFactor; bPos = bRot = bScale = FALSE; for (t=start; t<=end; t+=delta) { tm = node->GetNodeTM(t) * Inverse(node->GetParentTM(t)); decomp_affine(tm, &ap); AngAxisFromQ(ap.q, &rotAngle, rotAxis); if (t != start) { if (!bPos) { if (!EqualPoint3(ap.t, firstPos)) { bPos = TRUE; } } // MAX 2.x: // We examine the rotation angle to see if the rotation component // has changed. // Although not entierly true, it should work. // It is rare that the rotation axis is animated without // the rotation angle being somewhat affected. // MAX 3.x: // The above did not work, I have a repro scene that doesn't export a rotation track // because of this. I fixed it to also compare the axis. if (!bRot) { if (fabs(rotAngle - firstRotAngle) > ALMOST_ZERO) { bRot = TRUE; } else if (!EqualPoint3(rotAxis, firstRotAxis)) { bRot = TRUE; } } if (!bScale) { if (!EqualPoint3(ap.k, firstScaleFactor)) { bScale = TRUE; } } } else { firstPos = ap.t; firstRotAngle = rotAngle; firstRotAxis = rotAxis; firstScaleFactor = ap.k; } // No need to continue looping if all components are animated if (bPos && bRot && bScale) break; } return bPos || bRot || bScale; }