void AnimationClip::getBoneMapping(const Skeleton& skeleton, AnimationCurveMapping* mapping) const { UINT32 numBones = skeleton.getNumBones(); for(UINT32 i = 0; i < numBones; i++) { const SkeletonBoneInfo& boneInfo = skeleton.getBoneInfo(i); getCurveMapping(boneInfo.name, mapping[i]); } }
//----------------------------------------------------------------------- void Entity::_updateRenderQueue(RenderQueue* queue) { SubEntityList* subEntList; // Check we're not using a manual LOD if (mMeshLodIndex > 0 && mMesh->isLodManual()) { // Use alternate subentities assert((mMeshLodIndex-1) < mLodSubEntityList.size() && "No LOD SubEntityList - did you build the manual LODs after creating the entity?"); // index - 1 as we skip index 0 (original lod) subEntList = mLodSubEntityList[mMeshLodIndex - 1]; } else { subEntList = &mSubEntityList; } // Add each SubEntity to the queue SubEntityList::iterator i, iend; iend = subEntList->end(); for (i = subEntList->begin(); i != iend; ++i) { queue->addRenderable(*i, mRenderQueueID, RENDERABLE_DEFAULT_PRIORITY); } // Since we know we're going to be rendered, take this opportunity to // cache bone matrices & apply world matrix to them if (mMesh->hasSkeleton()) { cacheBoneMatrices(); //--- pass this point, we are sure that the transformation matrix of each bone and tagPoint have been updated // 挂到骨头上的子物体 ChildObjectList::iterator child_itr = mChildObjectList.begin(); ChildObjectList::iterator child_itr_end = mChildObjectList.end(); for( ; child_itr != child_itr_end; child_itr++) { (*child_itr).second->_updateRenderQueue(queue); } } // HACK to display bones // This won't work if the entity is not centered at the origin // TODO work out a way to allow bones to be rendered when Entity not centered if (mDisplaySkeleton && mMesh->hasSkeleton()) { Skeleton* pSkel = mMesh->getSkeleton(); int numBones = pSkel->getNumBones(); for (int b = 0; b < numBones; ++b) { Bone* bone = pSkel->getBone(b); queue->addRenderable(bone, mRenderQueueID); } } }
void Skeleton::fitToTargetSkeleton(const Skeleton &target) { // find root bone int rootId = -1; for(unsigned int i = 0; i < mBones.size(); ++i) { if(mBones[i].parent == -1) { rootId = i; break; } } // is a root in the skeleton if(rootId == -1) { LOG("no root bone found"); return; } // check for consistency if(mBones.size() != target.getNumBones()) { LOG("skeletons does not match"); return; } // init stack with root std::vector<int> ndStack(0); ndStack.push_back(rootId); // level pt int sp = 0; while((unsigned int)sp < ndStack.size()) { Bone& cur = mBones[ndStack[sp]]; for(unsigned int j = 0; j < cur.children.size(); ++j) { ndStack.push_back(cur.children[j]); } sp++; } // apply all rotations according stack order for(unsigned int k = 0; k < ndStack.size(); ++k) { // get current bone unsigned int l = ndStack[k]; Bone& _tB = mBones[l]; // transform rotation from other bone Bone _oB; target.getBone(l, _oB); _tB.R = _oB.R; // offset is the fathers end position if(_tB.parent > -1 && (unsigned int)_tB.parent < mBones.size()) { Bone& _pP = mBones[_tB.parent]; _tB.t = _pP.t + _pP.R.col(1) * _pP.length; } else { // LOG("no t correction for bone " << l); } mJoints[_tB.j0] = _tB.t; mJoints[_tB.j1] = _tB.t + _tB.R.col(1) * _tB.length; } }