void SkeletonDebug::SetSkeletonDebug( Ogre::Entity* entity, Ogre::SceneManager* sceneManager, const bool enable, Ogre::Real boneSize, Ogre::Real axisSize) { if (!HasSkeletonDebug(entity)) { GetAxesMaterial(); GetBoneMaterial(); GetAxesMesh(); GetBoneMesh(boneSize); const int numBones = entity->getSkeleton()->getNumBones(); for(unsigned short int iBone = 0; iBone < numBones; ++iBone) { Ogre::Bone* pBone = entity->getSkeleton()->getBone(iBone); if ( !pBone ) { assert(false); continue; } Ogre::Entity *ent; Ogre::TagPoint *tp; // Absolutely HAVE to create bone representations first. Otherwise we // would get the wrong child count because an attached object counts as // a child would be nice to have a function that only gets the children // that are bones... unsigned short numChildren = pBone->numChildren(); if (numChildren == 0) { // There are no children, but we should still represent the bone // Creates a bone of length 1 for leaf bones (bones without children) ent = sceneManager->createEntity(boneName); ent->setCastShadows(false); tp = entity->attachObjectToBone( pBone->getName(), (Ogre::MovableObject*)ent, Ogre::Quaternion(Ogre::Degree(270.0f), Ogre::Vector3::UNIT_Z)); const Ogre::Real modBoneSize = boneSize + boneSize * boneSize * 15.0f; tp->setScale(modBoneSize, boneSize, modBoneSize); } else { for(unsigned short i = 0; i < numChildren; ++i) { if (dynamic_cast<Ogre::Bone*>(pBone->getChild(i))) { Ogre::Vector3 childPosition = pBone->getChild(i)->getPosition(); // If the length is zero, no point in creating the bone representation float length = childPosition.length(); if(length < 0.00001f) continue; Ogre::Quaternion rotation = Ogre::Vector3::UNIT_Y.getRotationTo( childPosition); ent = sceneManager->createEntity(boneName); ent->setCastShadows(false); tp = entity->attachObjectToBone( pBone->getName(), (Ogre::MovableObject*)ent, rotation); const Ogre::Real modBoneSize = boneSize + boneSize * length * 15.0f; tp->setScale(modBoneSize, length, modBoneSize); } } } ent = sceneManager->createEntity(axesName); ent->setCastShadows(false); tp = entity->attachObjectToBone(pBone->getName(), (Ogre::MovableObject*)ent); // Make sure we don't wind up with tiny/giant axes and that one axis doesnt get squashed tp->setScale( (axisSize/entity->getParentSceneNode()->getScale().x), (axisSize/entity->getParentSceneNode()->getScale().y), (axisSize/entity->getParentSceneNode()->getScale().z)); } } if (enable) { ShowSkeletonDebug(entity); } else { HideSkeletonDebug(entity); } }