void AnimController::setBonePose( PyramidObject *node ) { PyramidObject *childNode = (PyramidObject *)node; PyramidObject *parentNode = (PyramidObject *)node->getParent(); if( parentNode == GraphicsObjMan::getMainTree()->getRoot() ) return; if (parentNode != 0 && childNode != 0) { // Now get the world matrices Vect start(0.0f,0.0f,0.0f); parentNode->transform(); Vect ptA = start * parentNode->getWorld(); childNode->transform(); Vect ptB = start * childNode->getWorld(); // direction between the anchor points of the respective bones Vect dir = -(ptB - ptA); // length of the bone 0 float mag = dir.mag(); // Set the orientation and length for bone 0 Matrix S( SCALE, BONE_WIDTH, BONE_WIDTH, mag); Quat Q( ROT_ORIENT, dir.getNorm(), Vect( 0.0f, 1.0f, 0.0f) ); Matrix T( TRANS, ptB ); Matrix BoneOrient = S * Q * T; childNode->setBoneOrientation( BoneOrient ); } }
void Skeleton::setBonePose(GraphicsObject * node, FrameBucket* pResult) { // need this value for Scale Vector - would it change in derived classes? const float BONE_WIDTH = 2.0f; // Now get the world matrices - we know nodes are PyramidObjects for Skeleton // this casting may not be needed if we create a new AnimationObject to pass in instead of GraphicsObject PyramidObject *childNode = (PyramidObject *)node; PyramidObject *parentNode = (PyramidObject *)node->getParent(); // Get the manager GraphicsObjectManager *goMgr = GraphicsObjectManager::getInstance(); PCSTree* tree = goMgr->getTree(); PCSNode* root = tree->getRoot(); // for bone Bip01 - it is the anchor point, no need to set its pose when its parent is dummy root node if(parentNode == root) return; if( parentNode != 0 && childNode != 0 ) { // starting point Vect start(0.0f,0.0f,0.0f); // calling transform first to evaluate an up-to-date world, then get starting point in World coords // ***ORDER*** do this for parent first, then child - in transform, p1 will get parent's world matrix parentNode->transform(pResult); Vect ptA = start * parentNode->getWorld(); childNode->transform(pResult); Vect ptB = start * childNode->getWorld(); // At this point, we have the two bones initial positions in world space // Now get the direction between two anchor points of respective bones, and direction Vect dir = -(ptB- ptA); float mag = dir.mag(); // used to flip pyramids to point outward Matrix T_flip(TRANS, 0.0f, 0.0f, 1.0f); // rotates it to Z axis Matrix R_flip( ROT_X, 180.0f * MATH_PI_180); Matrix S( SCALE, BONE_WIDTH, BONE_WIDTH, mag); Quat Q( ROT_ORIENT, dir.getNorm(), Vect( 0.0f, 1.0f, 0.0f) ); Matrix T(TRANS, ptB); Matrix BoneOrient = S * Q * T; // Matrix BoneOrient = R_flip * T_flip * S * Q * T ; // Matrix BoneOrient = S * Q ; // Matrix BoneOrient = S; childNode->setBoneOrientation(BoneOrient); } /* deal with last node, when there isn't a terminal node - does this help in any way? // copy orientation matrix from grandparent to set Parent's orientation if( parentNode != 0 && childNode == 0 ) { // get the parent's parent -> grandParent GraphicsObject *grandParentNode = (GraphicsObject *)parentNode->getParent(); Matrix BoneOrient = grandParentNode->getBoneOrientation(); parentNode->setBoneOrientation( BoneOrient ); // should be childNode now??? } */ }