HBTAvatarMesh.cpp

Go to the documentation of this file.
00001 #include "HBTAvatarMesh.h"
00002 #include "OBT_ASSERT.h"
00003 #include "HBTDataTypes.h"
00004 
00005 using namespace std;
00006 using namespace Ogre;
00007 using namespace HBT ;
00008 
00009 //------------------------------------------------------------
00010 AvatarMesh::AvatarMesh() 
00011 : _pObjectSceneNode( NULL ), 
00012   _meshNode( NULL ), 
00013   _entity( NULL ), 
00014   _hidden( false ),
00015   _initialised( false )
00016 {
00017 }
00018 
00019 //------------------------------------------------------------
00020 void AvatarMesh::close()
00021 {
00022   if( _initialised )
00023   {
00024     hide( true ) ;
00025     _pObjectSceneNode->removeChild( _meshNode->getName() ) ;
00026     _pObjectSceneNode->getParentSceneNode()->removeChild( _pObjectSceneNode->getName() ) ;
00027 
00028     _initialised = false ;
00029   }
00030 }
00031 
00032 //------------------------------------------------------------
00033 AvatarMesh::~AvatarMesh()
00034 {
00035   close() ;
00036 }
00037 
00038 //------------------------------------------------------------
00039 bool AvatarMesh::init( Ogre::SceneManager *ogreSceneManager, 
00040                        const InitialisationSequence *initSequence )
00041 {
00042   OBT_ASSERT( ogreSceneManager && "The Scene Manager is invalid" ) ;
00043   OBT_ASSERT( initSequence->boneNumber.size() == initSequence->postureQuat.size() 
00044            && "The number of bones and quaternion don't match" ) ;
00045 
00046   if( _initialised ) close() ;
00047 
00048   //verification que le nom de l'entitée n'existe pas déjà, si oui on ajout un suffixe
00049   std::string changedName( initSequence->humanName ) ;
00050   std::string sceneMeshName( initSequence->humanName ) ;
00051   
00052   for( unsigned int counter = 0u ;ogreSceneManager->hasSceneNode( changedName ); counter++ )
00053   {
00054     ostringstream buffer ; 
00055     buffer << initSequence->humanName << "_#_" << counter ;
00056     changedName = buffer.str() ;
00057   }
00058 
00059   //on attache l'objet à la scene
00060   _entity = ogreSceneManager->createEntity( changedName, initSequence->meshFile ) ;
00061 
00062   if(initSequence->useShadows)
00063   {
00064     _entity->setCastShadows( true ) ;
00065     _entity->getMesh()->buildEdgeList() ;
00066   }
00067 
00068   //ajout des noeuds de scène
00069   _pObjectSceneNode = ogreSceneManager->getRootSceneNode()->createChildSceneNode( changedName ) ;
00070   _meshNode = _pObjectSceneNode->createChildSceneNode(string("mesh") + changedName) ;
00071   _meshNode->attachObject( _entity ) ;
00072   _meshNode->setInheritOrientation( true ) ;
00073   _meshNode->setPosition( Ogre::Vector3::ZERO ) ;  //position 0 par rapport au noeud root MKM: c'est le noeud root MKM qui prendra en charge toutes les orientations et translations
00074   _meshNode->setOrientation( Ogre::Quaternion::IDENTITY ) ;
00075   _meshNode->setScale( Ogre::Vector3::UNIT_SCALE ) ;
00076   
00077   //contrôle manuel des bones
00078   _nbBones = _entity->getSkeleton()->getNumBones() ;
00079   for( unsigned int i = 0u ; i < _nbBones; i++ )
00080   {
00081     Bone * bone = _entity->getSkeleton()->getBone( i ) ;
00082     bone->setManuallyControlled( true ) ;
00083   }
00084 
00085   //initialisation de la posture et des bones
00086   setScl( initSequence->generalScale ) ;  // global scale
00087   setRot( initSequence->rootQuat ) ;      // root orientation
00088   setPos( initSequence->rootPos ) ;       // root position
00089 
00090   for( unsigned int pos = 0; pos < initSequence->boneNumber.size() ; pos++ )
00091   {
00092     Bone * bone =_entity->getSkeleton()->getBone( initSequence->boneNumber.at( pos ) ) ;
00093     bone->setInheritOrientation( false ) ;
00094 
00095     //il faut multiplier par l'inverse du world orientation de l'entitée car le setOrientation du bones se fait dans le repère de l'entitée en mode inheritOrientation(false)
00096     bone->setOrientation( _sceneNodeInverseQuat * initSequence->postureQuat.at( pos ) ) ;
00097     bone->_update( true, true ) ;
00098   }
00099 
00100   _initialised = true;
00101   return true;
00102 }
00103 
00104 //------------------------------------------------------------
00105 void AvatarMesh::hide( const bool hide )
00106 {
00107   if( _initialised && _hidden != hide)
00108   {
00109     _hidden = hide;
00110     _entity->setVisible( !_hidden ) ;
00111   }
00112 }
00113 
00114 
00115 //------------------------------------------------------------
00116 void AvatarMesh::update( const PostureData& postureData )
00117 {
00118   if( _initialised )
00119   {
00120     setScl(postureData.generalScale) ;  //scale global
00121     setRot(postureData.rootQuat) ;  //orientation du root
00122     setPos(postureData.rootPos+Vector3(0,0,0) ) ;    //position du root
00123 
00124     //on applique l'orientation pour les bones:
00125     for( unsigned int cBone = 0; 
00126          cBone < postureData.quatModified.size() ; cBone ++ )
00127     {
00128       if( postureData.quatModified.at(cBone) )
00129         setBoneOrientation(cBone, postureData.postureQuat.at( cBone ), true ) ;
00130     }
00131   }//fin if initialized
00132 }
00133 
00134 //------------------------------------------------------------
00135 Ogre::Vector3 AvatarMesh::getPos() const
00136 {
00137   Ogre::Vector3 v( Ogre::Vector3::ZERO ) ;
00138   if( _initialised ) 
00139   {
00140     v = _entity->getSkeleton()->getRootBone()->getWorldPosition() ;
00141     Matrix4 sceneNodeTransform ;
00142     _meshNode->getWorldTransforms( &sceneNodeTransform ) ;
00143     v = sceneNodeTransform * v;
00144   }
00145 
00146   return v;
00147 }
00148 
00149 //------------------------------------------------------------
00150 Ogre::Quaternion AvatarMesh::getRot() const
00151 {
00152   
00153   return _initialised ?
00154     _pObjectSceneNode->getWorldOrientation() :
00155     Ogre::Quaternion::IDENTITY ;
00156 }
00157 
00158 //------------------------------------------------------------
00159 Ogre::Vector3 AvatarMesh::getScl() const
00160 {
00161    return  _initialised ? 
00162      _pObjectSceneNode->_getDerivedScale() : 
00163      Ogre::Vector3::UNIT_SCALE ;
00164 }
00165 
00166 //------------------------------------------------------------
00167 void AvatarMesh::setPos( const Ogre::Vector3& pos )
00168 {
00169   assert(_pObjectSceneNode) ;
00170 
00171   Ogre::Vector3 newPos( pos ) ;
00172   Ogre::Vector3 rootBonePos( _entity->getSkeleton()->getRootBone()->getWorldPosition() ) ;
00173   Ogre::Vector3 sceneNodeScale( _pObjectSceneNode->getScale() ) ;
00174   Quaternion sceneNodeOri( _pObjectSceneNode->getWorldOrientation() ) ;
00175 
00176   newPos = newPos - sceneNodeOri * ( rootBonePos * sceneNodeScale ) ;
00177   _pObjectSceneNode->setPosition( newPos ) ;
00178   _pObjectSceneNode->_update( true, true ) ;
00179 }
00180 
00181 //------------------------------------------------------------
00182 void AvatarMesh::setRot( const Ogre::Quaternion& q )
00183 {
00184   OBT_ASSERT( _pObjectSceneNode ) ;
00185   _pObjectSceneNode->setOrientation( q ) ;
00186 
00187   _sceneNodeInverseQuat = _meshNode->getWorldOrientation().Inverse() ;
00188 }
00189 
00190 //------------------------------------------------------------
00191 void AvatarMesh::setScl(const Ogre::Vector3& scl)
00192 {
00193   assert(_pObjectSceneNode) ;
00194   ( (SceneNode*)_pObjectSceneNode)->setScale(scl[0],scl[1],scl[2]) ;
00195 }
00196 
00197 //------------------------------------------------------------  
00198 int AvatarMesh::getBoneID( const string& boneName ) const
00199 {
00200   return !_initialised ? 
00201     _entity->getSkeleton()->getBone( boneName )->getHandle() : -1 ;
00202 }
00203 
00204 //------------------------------------------------------------
00205 unsigned short AvatarMesh::getNbBones() const
00206 {
00207   return _initialised ? _nbBones : 0u ;
00208 }
00209 //------------------------------------------------------------
00210 void AvatarMesh::setBoneOrientation( const int boneID, 
00211                                      const Ogre::Quaternion &q, 
00212                                      const bool inWorldFrame )
00213 {
00214   if( _initialised )
00215   {
00216     Ogre::Quaternion quat( q ) ;
00217     Bone * bone = _entity->getSkeleton()->getBone( boneID ) ;
00218 
00219     if( inWorldFrame )
00220     {
00221       //il faut multiplier par l'inverse du world orientation de l'entitée car il semblerais que le setOrientation du bones se fait dans le repère de l'entitée en mode inheritOrientation(false)
00222       quat = _meshNode->getWorldOrientation().Inverse() * quat;
00223     }
00224 
00225     bone->setOrientation( quat ) ;
00226 
00227     bone->_update( true, true ) ;
00228   }
00229 }
00230 

logo OpenMask

Documentation generated on Mon Jun 9 11:45:55 2008

Generated with doxygen by Dimitri van Heesch ,   1997-2007