ArticulatedHierarchyController.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 //
00026 // C++ Implementation: ArticulatedHierarchyController
00027 //
00028 // Description: 
00029 //
00030 //
00031 // Author: Pierre-Jean Bensoussan, Digital Trainers (2008)
00032 //
00033 // Copyright: See COPYING file that comes with this distribution
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             // If the selected articulation is the current activated one it must be disabled
00236             if (activeArticulations[i])
00237             {
00238                 activeArticulations[i] = false;
00239             }
00240             else
00241             {
00242                 // Set all but the new select one articulations as inactive
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         // MouseWheel event won't be stopped by any "release" event, we stop it manually
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                                 // Reference potential initial articulations value for interaction springs 
00385                                 // and Current articulation value at the coresponding artculation
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                             //  while (articulatedObjIt != articulatedObjItEnd)
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 // Register in the Factory  
00419 int ArticulatedHierarchyControllerClass = core::RegisterObject("")
00420 .add< ArticulatedHierarchyController >()
00421 ;
00422 
00423 } // namespace controller
00424 
00425 } // namespace component
00426 
00427 } // namespace sofa

Generated on Sun Nov 23 02:49:37 2008 for Sofa by  doxygen 1.5.7.1