ArticulatedHierarchyController.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <sofa/component/controller/ArticulatedHierarchyController.h>
00038 #include <sofa/defaulttype/VecTypes.h>
00039
00040 #include <sofa/core/ObjectFactory.h>
00041 #include <sofa/core/objectmodel/BaseContext.h>
00042 #include <sofa/core/objectmodel/KeypressedEvent.h>
00043 #include <sofa/core/objectmodel/MouseEvent.h>
00044 #include <sofa/simulation/common/AnimateBeginEvent.h>
00045 #include <sofa/simulation/common/MechanicalVisitor.h>
00046 #include <sofa/simulation/common/UpdateMappingVisitor.h>
00047
00048 #include <sofa/simulation/tree/GNode.h>
00049
00050 #include <cctype>
00051
00052 namespace sofa
00053 {
00054
00055 namespace component
00056 {
00057
00058 namespace controller
00059 {
00060
00061 using namespace sofa::helper;
00062 using sofa::core::componentmodel::behavior::MechanicalState;
00063 using sofa::component::controller::ArticulatedHierarchyContainer;
00064
00065
00066 ArticulatedHierarchyController::ArticulatedHierarchyController()
00067 : articulationsIndices( initData(&articulationsIndices, "articulationsIndices", "Indices of articulations controlled by the keyboard") )
00068 , bindingKeys( initData(&bindingKeys, "bindingKeys", "Keys to press to control the articulations" ) )
00069 , angleDelta( initData(&angleDelta, 0.01, "angleDelta", "Angle incrementation due to each user interaction" ) )
00070 , propagateUserInteraction( initData(&propagateUserInteraction, false, "propagateUserInteraction", "Says wether or not the user interaction is local on the articulations, or must be propagated to children recursively" ) )
00071 {
00072 m_artCenterVec.resize(0);
00073 }
00074
00075
00076
00077 void ArticulatedHierarchyController::init()
00078 {
00079 dumpArticulationsAndBindingKeys();
00080
00081 activeArticulations.resize(bindingKeys.getValue().size());
00082 propagationChain = false;
00083
00084 sofa::simulation::tree::GNode* curNode = dynamic_cast<sofa::simulation::tree::GNode*>(this->getContext());
00085 if (curNode)
00086 curNode->getTreeObjects<ArticulatedHierarchyContainer::ArticulationCenter, ArtCenterVec >(&m_artCenterVec);
00087
00088 resetControler();
00089 }
00090
00091
00092
00093 void ArticulatedHierarchyController::buildPropagationArticulationsChain(void)
00094 {
00095 ArtCenterVecIt artCenterIt;
00096 ArtCenterVecIt artCenterItEnd;
00097
00098 ArtVecIt artIt;
00099 ArtVecIt artItEnd;
00100
00101 ArticulatedHierarchyContainer::ArticulationCenter *activeArticulationCenter = NULL;
00102 ArticulatedHierarchyContainer::ArticulationCenter::Articulation *activeArticulation = NULL;
00103
00104 for (unsigned int i=0; i<articulationsIndices.getValue().size(); i++)
00105 {
00106 int activeArticulationIndex = articulationsIndices.getValue()[i];
00107
00108 artCenterIt = m_artCenterVec.begin();
00109 artCenterItEnd = m_artCenterVec.end();
00110
00111 while ((artCenterIt != artCenterItEnd) && (activeArticulationCenter == NULL))
00112 {
00113 artIt = (*artCenterIt)->articulations.begin();
00114 artItEnd = (*artCenterIt)->articulations.end();
00115 while (artIt != artItEnd)
00116 {
00117 if ((*artIt)->articulationIndex.getValue() == activeArticulationIndex)
00118 {
00119 activeArticulationCenter = *artCenterIt;
00120 activeArticulation = *artIt;
00121 break;
00122 }
00123 ++artIt;
00124 }
00125 ++artCenterIt;
00126 }
00127
00128 std::vector< int > propagationArticulationsArray;
00129
00130 if ((activeArticulation != NULL) && (activeArticulationCenter != NULL))
00131 {
00132 buildArray(propagationArticulationsArray, activeArticulation, activeArticulationCenter);
00133 }
00134
00135 articulationsPropagationChains.insert(std::make_pair(activeArticulationIndex, propagationArticulationsArray));
00136
00137 activeArticulation = NULL;
00138 activeArticulationCenter = NULL;
00139 }
00140 }
00141
00142
00143
00144 void ArticulatedHierarchyController::buildArray(std::vector< int > &artIndices, ArticulatedHierarchyContainer::ArticulationCenter::Articulation *artRef, ArticulatedHierarchyContainer::ArticulationCenter *artCenterParent)
00145 {
00146 ArtCenterVecIt artCenterIt = m_artCenterVec.begin();
00147 ArtCenterVecIt artCenterItEnd = m_artCenterVec.end();
00148
00149 bool childFound = false;
00150 while (artCenterIt != artCenterItEnd)
00151 {
00152 if ((*artCenterIt)->parentIndex.getValue() == artCenterParent->childIndex.getValue())
00153 {
00154 ArtVecIt artIt = (*artCenterIt)->articulations.begin();
00155 ArtVecIt artItEnd = (*artCenterIt)->articulations.end();
00156
00157 while (artIt != artItEnd)
00158 {
00159 if (((*artIt)->rotation.getValue() == artRef->rotation.getValue())
00160 && ((*artIt)->translation.getValue() == artRef->translation.getValue())
00161 && ((*artIt)->axis.getValue() == artRef->axis.getValue()))
00162 {
00163 artIndices.push_back((*artIt)->articulationIndex.getValue());
00164 childFound = true;
00165 buildArray(artIndices,artRef,*artCenterIt);
00166 break;
00167 }
00168 ++artIt;
00169 }
00170 }
00171
00172 if (childFound) break;
00173 ++artCenterIt;
00174 }
00175 }
00176
00177
00178
00179 void ArticulatedHierarchyController::dumpActiveArticulations(void) const
00180 {
00181 vector<bool>::const_iterator it = activeArticulations.begin();
00182 vector<bool>::const_iterator itEnd = activeArticulations.end();
00183 int i=0;
00184 while (it != itEnd)
00185 {
00186 if (*it)
00187 std::cout << "-------------> Articulation " << articulationsIndices.getValue()[i] << " active\n";
00188 else
00189 std::cout << "-------------> Articulation " << articulationsIndices.getValue()[i] << " inactive\n";
00190
00191 ++it;
00192 i++;
00193 }
00194 }
00195
00196
00197
00198 void ArticulatedHierarchyController::dumpArticulationsAndBindingKeys(void) const
00199 {
00200 std::cout << "ARTICULATIONS_KEYBOARD_CONTROLER : Controled Articulations & Binding Keys\n";
00201
00202 vector<int>::const_iterator articulationsIndicesIt = articulationsIndices.getValue().begin();
00203 vector<int>::const_iterator articulationsIndicesItEnd = articulationsIndices.getValue().end();
00204
00205 vector<char>::const_iterator bindinKeysIt = bindingKeys.getValue().begin();
00206 vector<char>::const_iterator bindinKeysItEnd = bindingKeys.getValue().end();
00207
00208 while (articulationsIndicesIt != articulationsIndicesItEnd)
00209 {
00210 std::cout << "Articulation " << *articulationsIndicesIt << " controlled with key " << *bindinKeysIt << std::endl;
00211 ++articulationsIndicesIt;
00212 ++bindinKeysIt;
00213 if (bindinKeysIt == bindinKeysItEnd)
00214 break;
00215 }
00216 }
00217
00218
00219
00220 void ArticulatedHierarchyController::updateActiveArticulationsIndices(const char keyChar)
00221 {
00222 unsigned int numKeys = bindingKeys.getValue().size();
00223
00224 if (numKeys != 0)
00225 {
00226 unsigned int i = 0;
00227 for (; i < numKeys; i++)
00228 {
00229 if (bindingKeys.getValue()[i] == (isupper(bindingKeys.getValue()[i]) ? toupper(keyChar) : tolower(keyChar)))
00230 break;
00231 }
00232
00233 if ((i < numKeys)&&(i < articulationsIndices.getValue().size()))
00234 {
00235
00236 if (activeArticulations[i])
00237 {
00238 activeArticulations[i] = false;
00239 }
00240 else
00241 {
00242
00243 vector<bool>::iterator it = activeArticulations.begin();
00244 vector<bool>::iterator itEnd = activeArticulations.end();
00245 while (it != itEnd)
00246 {
00247 *it = false;
00248 ++it;
00249 }
00250
00251 activeArticulations[i] = true;
00252 }
00253 }
00254 }
00255
00256 dumpActiveArticulations();
00257 }
00258
00259
00260
00261 void ArticulatedHierarchyController::onKeyPressedEvent(core::objectmodel::KeypressedEvent *kev)
00262 {
00263 updateActiveArticulationsIndices(kev->getKey());
00264 }
00265
00266
00267
00268 void ArticulatedHierarchyController::onMouseEvent(core::objectmodel::MouseEvent *mev)
00269 {
00270 switch (mev->getState())
00271 {
00272 case sofa::core::objectmodel::MouseEvent::LeftPressed :
00273 signFactor = 1;
00274 mouseMode = BtLeft;
00275 break;
00276
00277 case sofa::core::objectmodel::MouseEvent::LeftReleased :
00278 mouseMode = None;
00279 break;
00280
00281 case sofa::core::objectmodel::MouseEvent::RightPressed :
00282 signFactor = -1;
00283 mouseMode = BtRight;
00284 break;
00285
00286 case sofa::core::objectmodel::MouseEvent::RightReleased :
00287 mouseMode = None;
00288 break;
00289
00290 case sofa::core::objectmodel::MouseEvent::Wheel :
00291 signFactor = 2 * abs(mev->getWheelDelta()) / mev->getWheelDelta();
00292 mouseMode = Wheel;
00293 break;
00294
00295 case sofa::core::objectmodel::MouseEvent::Reset :
00296 resetControler();
00297 break;
00298
00299 default :
00300 break;
00301 }
00302 }
00303
00304
00305
00306 void ArticulatedHierarchyController::onBeginAnimationStep()
00307 {
00308 applyController();
00309 }
00310
00311
00312
00313 void ArticulatedHierarchyController::resetControler(void)
00314 {
00315 vector<bool>::iterator it = activeArticulations.begin();
00316 vector<bool>::iterator itEnd = activeArticulations.end();
00317 while (it != itEnd)
00318 {
00319 *it = false;
00320 ++it;
00321 }
00322
00323 mouseMode = None;
00324 }
00325
00326
00327
00328 void ArticulatedHierarchyController::applyController(void)
00329 {
00330 if (mouseMode != None)
00331 {
00332 if ((!propagationChain) && (propagateUserInteraction.getValue()))
00333 {
00334 buildPropagationArticulationsChain();
00335 propagationChain = true;
00336 }
00337
00338
00339 if (mouseMode == Wheel) mouseMode=None;
00340
00341 int articulationIndex;
00342 unsigned int i = 0;
00343 for (; i<activeArticulations.size(); i++)
00344 {
00345 if (activeArticulations[i])
00346 {
00347 articulationIndex = articulationsIndices.getValue()[i];
00348 break;
00349 }
00350 }
00351
00352 if (i < activeArticulations.size())
00353 {
00354 std::vector< int > articulationPropagationChain;
00355 std::map< int, sofa::helper::vector< int > >::iterator iter = articulationsPropagationChains.find(articulationIndex);
00356 if( iter != articulationsPropagationChains.end())
00357 articulationPropagationChain = iter->second;
00358
00359 double distributedAngleDelta = angleDelta.getValue() / (double)(articulationPropagationChain.size() + 1);
00360
00361 for (unsigned int j=0; j<articulationPropagationChain.size()+1; j++)
00362 {
00363 ArtCenterVecIt artCenterIt = m_artCenterVec.begin();
00364 ArtCenterVecIt artCenterItEnd = m_artCenterVec.end();
00365
00366 bool articulationFound = false;
00367
00368 while ((artCenterIt != artCenterItEnd) && (!articulationFound))
00369 {
00370 ArtVecIt it = (*artCenterIt)->articulations.begin();
00371 ArtVecIt itEnd = (*artCenterIt)->articulations.end();
00372 while (it != itEnd)
00373 {
00374 if ((*it)->articulationIndex.getValue() == articulationIndex)
00375 {
00376 std::vector< MechanicalState<sofa::defaulttype::Vec1dTypes>* > articulatedObjects;
00377
00378 sofa::simulation::tree::GNode* curNode = dynamic_cast<sofa::simulation::tree::GNode*>(this->getContext());
00379 if (curNode)
00380 curNode->getTreeObjects<MechanicalState<sofa::defaulttype::Vec1dTypes>, std::vector< MechanicalState<sofa::defaulttype::Vec1dTypes>* > >(&articulatedObjects);
00381
00382 if (!articulatedObjects.empty())
00383 {
00384
00385
00386
00387 std::vector< MechanicalState<sofa::defaulttype::Vec1dTypes>* >::iterator articulatedObjIt = articulatedObjects.begin();
00388 std::vector< MechanicalState<sofa::defaulttype::Vec1dTypes>* >::iterator articulatedObjItEnd = articulatedObjects.end();
00389
00390
00391 {
00392 (*(*articulatedObjIt)->getX())[(*it)->articulationIndex.getValue()].x() += signFactor * distributedAngleDelta;
00393 (*(*articulatedObjIt)->getXfree())[(*it)->articulationIndex.getValue()].x() += signFactor * distributedAngleDelta;
00394 ++articulatedObjIt;
00395 }
00396 }
00397
00398 articulationFound = true;
00399 break;
00400 }
00401 ++it;
00402 }
00403 ++artCenterIt;
00404 }
00405
00406 if (j < articulationPropagationChain.size())
00407 articulationIndex = articulationPropagationChain[j];
00408 }
00409
00410 static_cast<sofa::simulation::tree::GNode*>(this->getContext())->execute<sofa::simulation::MechanicalPropagatePositionAndVelocityVisitor>();
00411 static_cast<sofa::simulation::tree::GNode*>(this->getContext())->execute<sofa::simulation::UpdateMappingVisitor>();
00412 }
00413 }
00414 }
00415
00416 SOFA_DECL_CLASS(ArticulatedHierarchyController)
00417
00418
00419 int ArticulatedHierarchyControllerClass = core::RegisterObject("")
00420 .add< ArticulatedHierarchyController >()
00421 ;
00422
00423 }
00424
00425 }
00426
00427 }