int CalSkeleton::getBoneLines(float *pLines) { int nrLines; nrLines = 0; rde::vector<CalBone *>::iterator iteratorBone; for(iteratorBone = m_vectorBone.begin(); iteratorBone != m_vectorBone.end(); ++iteratorBone) { int parentId; parentId = (*iteratorBone)->getCoreBone()->getParentId(); if(parentId != -1) { CalBone *pParent; pParent = m_vectorBone[parentId]; const CalVector& translation = (*iteratorBone)->getTranslationAbsolute(); const CalVector& translationParent = pParent->getTranslationAbsolute(); *pLines++ = translationParent[0]; *pLines++ = translationParent[1]; *pLines++ = translationParent[2]; *pLines++ = translation[0]; *pLines++ = translation[1]; *pLines++ = translation[2]; nrLines++; } } return nrLines; }
void IKCharacter::pullWorldPositions( int root_id, int leaf_id ) { CalVector root_pos; if ( auto_root_follow ) { // get root pos int skel_root_id = skeleton->getCoreSkeleton()->getVectorRootCoreBoneId()[0]; root_pos = skeleton->getBone(skel_root_id)->getTranslationAbsolute(); } // work from the leaves down to the root deque<int> queue; if ( leaf_id == -1 ) queue.insert( queue.begin(), leaf_bones.begin(), leaf_bones.end() ); else queue.push_back( leaf_id ); while ( !queue.empty() ) { int id = queue.front(); queue.pop_front(); CalBone* bone = skeleton->getBone(id); world_positions[id] = bone->getTranslationAbsolute() - root_pos; int parent_id = bone->getCoreBone()->getParentId(); if ( parent_id != -1 && id != root_id ) queue.push_back( parent_id ); } }
void CalBone::calculateState() { // check if the bone was not touched by any active animation if(m_accumulatedWeight == 0.0f) { // set the bone to the initial skeleton state m_translation = m_pCoreBone->getTranslation(); m_rotation = m_pCoreBone->getRotation(); } // get parent bone id int parentId; parentId = m_pCoreBone->getParentId(); if(parentId == -1) { // no parent, this means absolute state == relative state m_translationAbsolute = m_translation; m_rotationAbsolute = m_rotation; } else { // get the parent bone CalBone *pParent; pParent = m_pSkeleton->getBone(parentId); // transform relative state with the absolute state of the parent m_translationAbsolute = m_translation; m_translationAbsolute *= pParent->getRotationAbsolute(); m_translationAbsolute += pParent->getTranslationAbsolute(); m_rotationAbsolute = m_rotation; m_rotationAbsolute *= pParent->getRotationAbsolute(); } // calculate the bone space transformation m_translationBoneSpace = m_pCoreBone->getTranslationBoneSpace(); m_translationBoneSpace *= m_rotationAbsolute; m_translationBoneSpace += m_translationAbsolute; m_rotationBoneSpace = m_pCoreBone->getRotationBoneSpace(); m_rotationBoneSpace *= m_rotationAbsolute; // Generate the vertex transform. If I ever add support for bone-scaling // to Cal3D, this step will become significantly more complex. m_transformMatrix = m_rotationBoneSpace; // calculate all child bones std::list<int>::iterator iteratorChildId; for(iteratorChildId = m_pCoreBone->getListChildId().begin(); iteratorChildId != m_pCoreBone->getListChildId().end(); ++iteratorChildId) { m_pSkeleton->getBone(*iteratorChildId)->calculateState(); } }
///////////////////////////////////// // Purpose: get the relative translation // of given boneID // Output: pLoc set // Return: none ///////////////////////////////////// void IgfxObject::BoneGetTransAbs(s32 boneID, Vec3D *pLoc) { if(m_pCalModel) { CalSkeleton *pSkel = m_pCalModel->getSkeleton(); CalBone *pBone = pSkel->getBone(boneID); CalVector cVec = pBone->getTranslationAbsolute(); pLoc->x = cVec.x; pLoc->y = cVec.y; pLoc->z = cVec.z; } }
core::matrix4 CCal3DSceneNode::getBoneMatrix( s32 boneId ) const { if ( calModel == 0 ) return core::matrix4(); CalSkeleton* skeleton = calModel->getSkeleton(); CalBone* bone = skeleton->getBone(boneId); CalQuaternion rot = bone->getRotationAbsolute(); CalVector pos = bone->getTranslationAbsolute(); // Note: Swap Y and Z to convert to Irrlicht coordinates core::quaternion quat = core::quaternion( rot.x, rot.y, rot.z, rot.w ); core::vector3df v = core::vector3df( pos.x, pos.y, pos.z ); core::matrix4 mat = quat.getMatrix(); mat.setTranslation(v); return mat; }
void IKCharacter::pullWorldPositions( int root_id, int leaf_id ) { deque<int> queue; if ( leaf_id == -1 ) queue.insert( queue.begin(), leaf_bones.begin(), leaf_bones.end() ); else queue.push_back( leaf_id ); // work backwards up the tree while ( !queue.empty() ) { int id = queue.front(); queue.pop_front(); CalBone* bone = skeleton->getBone(id); world_positions[id] = bone->getTranslationAbsolute(); int parent_id = bone->getCoreBone()->getParentId(); if ( parent_id != -1 && id != root_id ) queue.push_back( parent_id ); } }
void IKCharacter::draw( int bone_id, float scale, bool additional_drawing ) { CalBone* bone = skeleton->getBone( bone_id ); int parent_id = bone->getCoreBone()->getParentId(); if ( parent_id != -1 ) { // current CalBone* parent = skeleton->getBone( parent_id ); glBegin( GL_LINES ); CalVector v = parent->getTranslationAbsolute(); v*=scale; CalVector c = v; glVertex3f( v.x, v.y, v.z ); v = bone->getTranslationAbsolute(); v*=scale; c += v; c /= 2.0f; glVertex3f( v.x, v.y, v.z ); glEnd(); // world glPushAttrib( GL_CURRENT_BIT ); glColor3f( 0.1f, 0.8f, 0.1f ); glBegin( GL_LINES ); v = world_positions[parent_id]; v*=scale; glVertex3f( v.x, v.y, v.z ); v = world_positions[bone_id]; v*=scale; glVertex3f( v.x, v.y, v.z ); glEnd(); glPopAttrib(); if ( additional_drawing ) { glPushAttrib( GL_CURRENT_BIT ); glBegin( GL_LINES ); // core glColor3f( (parent_id==debug_bone)?1.0f:0.3f, 0.3f, 0.5f ); v = parent->getCoreBone()->getTranslationAbsolute(); v*=scale; glVertex3f( v.x, v.y, v.z ); v = bone->getCoreBone()->getTranslationAbsolute(); v*=scale; glVertex3f( v.x, v.y, v.z ); glEnd(); // draw rotation glPushMatrix(); CalVector root = bone->getCoreBone()->getTranslationAbsolute(); glTranslatef( root.x, root.y, root.z ); CalVector rot; rot.set( 0, 0.1f*scale, 0 ); rot *= bone->getCoreBone()->getRotationAbsolute(); ofEnableAlphaBlending(); glColor4f( 0.2f, 0.2f, 0.8f, 0.2f ); glBegin( GL_TRIANGLES ); //glVertex3f( 0,0,0 ); glVertex3f( rot.x, rot.y, rot.z ); rot *= debug_cached_rotations[bone_id]; glVertex3f( rot.x, rot.y, rot.z ); glEnd(); glColor4f( 0.2f, 0.2f, 0.8f, 0.8f ); rot.set( 0, 0.1f*scale, 0 ); rot *= bone->getCoreBone()->getRotationAbsolute(); glBegin( GL_LINES ); glVertex3f( 0,0,0 ); glVertex3f( rot.x, rot.y, rot.z ); rot *= debug_cached_rotations[bone_id]; glVertex3f( 0,0,0 ); glVertex3f( rot.x, rot.y, rot.z ); glEnd(); ofDisableAlphaBlending(); glPopMatrix(); CalVector u( 0, 0.1f*scale, 0); u *= bone->getRotationAbsolute(); CalVector r( 0.1f*scale, 0, 0 ); r *= bone->getRotationAbsolute(); CalVector f( 0, 0, 0.1f*scale ); f *= bone->getRotationAbsolute(); // right blue glPushMatrix(); root = bone->getTranslationAbsolute(); glTranslatef( root.x, root.y, root.z ); glBegin( GL_LINES ); glColor3f( 0, 0, 1 ); glVertex3f( 0,0,0 ); glVertex3f( r.x, r.y, r.z ); // up red glColor3f( 1, 0, 0 ); glVertex3f( 0,0,0 ); glVertex3f( u.x, u.y, u.z ); // forward green glColor3f( 0, 1, 0 ); glVertex3f( 0,0,0 ); glVertex3f( f.x, f.y, f.z ); glEnd(); glPopMatrix(); // right blue glPushMatrix(); root = world_positions[bone_id]; glTranslatef( root.x, root.y, root.z ); glBegin( GL_LINES ); glColor3f( 0, 0, 1 ); glVertex3f( 0,0,0 ); glVertex3f( r.x, r.y, r.z ); // up red glColor3f( 1, 0, 0 ); glVertex3f( 0,0,0 ); glVertex3f( u.x, u.y, u.z ); // forward green glColor3f( 0, 1, 0 ); glVertex3f( 0,0,0 ); glVertex3f( f.x, f.y, f.z ); glEnd(); glPopMatrix(); glPopAttrib(); } } list<int> children = bone->getCoreBone()->getListChildId(); for ( list<int>::iterator it = children.begin(); it != children.end(); ++it ) { draw( *it, scale, additional_drawing ); } }