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
Documentation generated on Mon Jun 9 11:45:55 2008 |
Generated with doxygen by Dimitri van Heesch , 1997-2007 |