From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/mot_8cpp-source.html | 780 ++++++++++++++++++++++++++++++++++ 1 file changed, 780 insertions(+) create mode 100644 docs/doxygen/nel/mot_8cpp-source.html (limited to 'docs/doxygen/nel/mot_8cpp-source.html') diff --git a/docs/doxygen/nel/mot_8cpp-source.html b/docs/doxygen/nel/mot_8cpp-source.html new file mode 100644 index 00000000..278e2bff --- /dev/null +++ b/docs/doxygen/nel/mot_8cpp-source.html @@ -0,0 +1,780 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

mot.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2000 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 #include "std3d.h"
+00027 
+00028 #include "3d/mot.h"
+00029 #include "nel/misc/debug.h"
+00030 #include "nel/misc/stream.h"
+00031 #include <algorithm>
+00032 #include <list>
+00033 using namespace std;
+00034 using namespace NLMISC;
+00035 
+00036 
+00037 namespace       NL3D
+00038 {
+00039 
+00040 
+00041 // ***************************************************************************
+00042 // ***************************************************************************
+00043 // CMOT static.
+00044 // ***************************************************************************
+00045 // ***************************************************************************
+00046 
+00047 
+00048 // ***************************************************************************
+00049 set<CMOT::CModelEntry>          CMOT::RegModels;
+00050 set<CMOT::CObsEntry>            CMOT::RegObservers;
+00051 
+00052 // ***************************************************************************
+00053 void    CMOT::registerModel(const CClassId &idModel, const CClassId &idModelBase, IModel* (*creator)())
+00054 {
+00055         nlassert(idModel!=CClassId::Null);
+00056         nlassert(creator);
+00057         // idModelBase may be Null...
+00058 
+00059         CModelEntry             e;
+00060         e.BaseModelId= idModelBase;
+00061         e.ModelId= idModel;
+00062         e.Creator= creator;
+00063 
+00064         // Insert/replace e.
+00065         RegModels.erase(e);
+00066         RegModels.insert(e);
+00067 }
+00068 // ***************************************************************************
+00069 void    CMOT::registerObs(const CClassId &idTrav, const CClassId &idModel, IObs* (*creator)())
+00070 {
+00071         nlassert(idTrav!=CClassId::Null);
+00072         nlassert(idModel!=CClassId::Null);
+00073         nlassert(creator);
+00074 
+00075         CObsEntry               e;
+00076         e.ModelId= idModel;
+00077         e.TravId= idTrav;
+00078         e.Creator= creator;
+00079 
+00080         // Insert/replace e.
+00081         RegObservers.erase(e);
+00082         RegObservers.insert(e);
+00083 }
+00084 
+00085 
+00086 // ***************************************************************************
+00087 // ***************************************************************************
+00088 // CMOT.
+00089 // ***************************************************************************
+00090 // ***************************************************************************
+00091 
+00092 
+00093 // ***************************************************************************
+00094 CMOT::CMOT()
+00095 {
+00096         _ValidateModelList= NULL;
+00097 }
+00098 // ***************************************************************************
+00099 CMOT::~CMOT()
+00100 {
+00101         release();
+00102 }
+00103 
+00104 // ***************************************************************************
+00105 void    CMOT::addTrav(ITrav *v)
+00106 {
+00107         nlassert(v);
+00108         CClassId        idTrav= v->getClassId();
+00109         nlassert(idTrav!=CClassId::Null);       
+00110 
+00111         CTravEntry      e;
+00112         e.TravId= idTrav;
+00113         e.Trav= v;
+00114 
+00115         Traversals.push_back(e);
+00116         v->addedToMOT(this);
+00117 }
+00118 // ***************************************************************************
+00119 ITrav   *CMOT::getTrav(const CClassId &idTrav) const 
+00120 {
+00121         std::vector<CTravEntry>::const_iterator it;
+00122 
+00123         for(it= Traversals.begin(); it!= Traversals.end(); it++)
+00124         {
+00125                 if(idTrav== (*it).TravId)
+00126                         return (*it).Trav;
+00127         }
+00128 
+00129         return NULL;
+00130 }
+00131 // ***************************************************************************
+00132 void    CMOT::release()
+00133 {
+00134         // First, release all the models.
+00135         set<IModel*>::iterator  it;
+00136         it= Models.begin();
+00137         while( it!=Models.end())
+00138         {
+00139                 deleteModel(*it);
+00140                 it= Models.begin();
+00141         }
+00142         // No models at all.
+00143         _ValidateModelList= NULL;
+00144 
+00145         // Then release the traversals ptrs.
+00146         Traversals.clear();
+00147 }
+00148 
+00149 
+00150 // ***************************************************************************
+00151 IModel  *CMOT::createModel(const CClassId &idModel)
+00152 {
+00153         nlassert(idModel!=CClassId::Null);
+00154 
+00155         CModelEntry     e;
+00156         e.ModelId= idModel;
+00157         set<CModelEntry>::iterator      itModel;
+00158         itModel= RegModels.find(e);
+00159 
+00160         if(itModel==RegModels.end())
+00161         {
+00162                 nlstop;                 // Warning, CScene::registerBasics () has not been called !
+00163                 return NULL;
+00164         }
+00165         else
+00166         {
+00167                 IModel  *m= (*itModel).Creator();
+00168                 if(!m)  return NULL;
+00169 
+00170                 // Set the owner for the model.
+00171                 m->_OwnerMot= this;
+00172 
+00173                 // create observer for each trav.
+00174                 std::vector<CTravEntry>::const_iterator itTrav;
+00175                 for(itTrav= Traversals.begin(); itTrav!=Traversals.end(); itTrav++)
+00176                 {
+00177                         // Create observer.
+00178                         IObs    *obs= createObs((*itTrav).Trav, idModel);
+00179                         nlassert(obs);
+00180                         // Init model.
+00181                         obs->Model= m;
+00182                         obs->Trav= (*itTrav).Trav;
+00183                         // Attach it to Model.
+00184                         m->Observers.insert(IModel::CObsMap::value_type((*itTrav).TravId, obs));
+00185                         // Attach them to traversal's root.
+00186                         if((*itTrav).Trav->getRoot())
+00187                                 (*itTrav).Trav->link(NULL, m);
+00188                 }
+00189 
+00190                 // After m finished, init the observers.
+00191                 IModel::CObsMap::const_iterator itObs;
+00192                 for(itObs= m->Observers.begin(); itObs!=m->Observers.end(); itObs++)
+00193                 {
+00194                         IObs    *o= (*itObs).second;
+00195                         o->init();
+00196                 }
+00197 
+00198                 // Insert the model into the set.
+00199                 Models.insert(m);
+00200 
+00201                 // By default the model is validate() in CMOT::validateModels().
+00202                 m->linkToValidateList();
+00203 
+00204                 // Once the model is correclty created, finish init him.
+00205                 m->initModel();
+00206 
+00207                 return m;
+00208         }
+00209 }
+00210 // ***************************************************************************
+00211 void    CMOT::deleteModel(IModel *model)
+00212 {
+00213         if(model==NULL)
+00214                 return;
+00215         set<IModel*>::iterator  it= Models.find(model);
+00216         if(it!=Models.end())
+00217         {
+00218                 delete *it;
+00219                 Models.erase(it);
+00220         }
+00221 }
+00222 
+00223 
+00224 // ***************************************************************************
+00225 void    CMOT::validateModels()
+00226 {
+00227         // check all the models which must be checked.
+00228         IModel  *model= _ValidateModelList;
+00229         IModel  *next;
+00230         while( model )
+00231         {
+00232                 // next to validate. get next now, because model->validate() may remove model from the list.
+00233                 next= model->_NextModelToValidate;
+00234 
+00235                 // chek / validate the model.
+00236                 model->validate();
+00237 
+00238                 // next.
+00239                 model= next;
+00240         }
+00241 }
+00242 
+00243 
+00244 // ***************************************************************************
+00245 IObs    *CMOT::createObs(const ITrav *trav, const CClassId &idModel) const
+00246 {
+00247         nlassert(trav);
+00248         CClassId idTrav= trav->getClassId();
+00249         nlassert(idTrav!=CClassId::Null);
+00250 
+00251         if(idModel==CClassId::Null)
+00252         {
+00253                 // Use trav to create default observer.
+00254                 return trav->createDefaultObs();
+00255         }
+00256 
+00257         CObsEntry       e;
+00258         e.TravId= idTrav;
+00259         e.ModelId= idModel;
+00260         std::set<CObsEntry>::iterator   it;
+00261         it= RegObservers.find(e);
+00262 
+00263         if(it==RegObservers.end())
+00264         {
+00265                 // Try the father of the model.
+00266                 CModelEntry     e;
+00267                 e.ModelId= idModel;
+00268                 set<CModelEntry>::iterator      it;
+00269                 it= RegModels.find(e);
+00270 
+00271                 nlassert(it!=RegModels.end());
+00272 
+00273                 return createObs(trav, (*it).BaseModelId);
+00274         }
+00275         else
+00276         {
+00277                 // Register with the specified observer.
+00278                 return (*it).Creator();
+00279         }
+00280 }
+00281 
+00282 
+00283 // ***************************************************************************
+00284 IObs    *CMOT::getModelObs(IModel *m, const NLMISC::CClassId &idTrav) const
+00285 {
+00286         if(!m)
+00287                 return NULL;
+00288         return m->getObs(idTrav);
+00289 }
+00290 
+00291 
+00292 // ***************************************************************************
+00293 // ***************************************************************************
+00294 // ITrav.
+00295 // ***************************************************************************
+00296 // ***************************************************************************
+00297 
+00298 
+00299 // ***************************************************************************
+00300 void    ITrav::setRoot(IModel   *root)
+00301 {
+00302         if(root)
+00303                 Root= root->getObs(getClassId());
+00304         else
+00305                 Root= NULL;
+00306 }
+00307 // ***************************************************************************
+00308 IModel  *ITrav::getRoot() const
+00309 {
+00310         if(Root)
+00311                 return Root->Model;
+00312         else
+00313                 return NULL;
+00314 }
+00315 
+00316 // ***************************************************************************
+00317 void    ITrav::link(IModel *m1, IModel *m2) const
+00318 {
+00319         IObs    *o1,*o2;
+00320 
+00321         nlassert(m2);
+00322         CClassId        travId= getClassId();
+00323 
+00324         if(m1)
+00325         {
+00326                 o1= m1->getObs(travId);
+00327                 nlassert(o1);
+00328         }
+00329         else
+00330         {
+00331                 o1= Root;
+00332                 // If his one is NULL, return.
+00333                 // NB: this may not be an error. eg: in CScene::release(), when all models are deleted, 
+00334                 // a ~CSkeletonModel() call link() to Root, but Root model may have been deleted first!!!
+00335                 if(!o1)
+00336                         return;
+00337         }
+00338         o2= m2->getObs(travId);
+00339         nlassert(o1);
+00340         nlassert(o2);
+00341         o2->addParent(o1);
+00342         o1->addChild(o2);
+00343 }
+00344 // ***************************************************************************
+00345 void    ITrav::unlink(IModel *m1, IModel *m2) const
+00346 {
+00347         IObs    *o1,*o2;
+00348 
+00349         nlassert(m2);
+00350         CClassId        travId= getClassId();
+00351 
+00352         if(m1)
+00353         {
+00354                 o1= m1->getObs(travId);
+00355                 nlassert(o1);
+00356         }
+00357         else
+00358         {
+00359                 o1= Root;
+00360                 // If his one is NULL, return.
+00361                 // NB: this may not be an error. eg: in CScene::release(), when all models are deleted, 
+00362                 // a ~CSkeletonModel() call link() to Root, but Root model may have been deleted first!!!
+00363                 if(!o1)
+00364                         return;
+00365         }
+00366         o2= m2->getObs(travId);
+00367         nlassert(o1);
+00368         nlassert(o2);
+00369         o2->delParent(o1);
+00370         o1->delChild(o2);
+00371 }
+00372 
+00373 // ***************************************************************************
+00374 void    ITrav::moveChildren(IModel *parentFrom, IModel *parentTo) const
+00375 {
+00376         // Make a local list of children (since link() modify the list).
+00377         list<IModel     *>      children;
+00378         for(IModel      *c= getFirstChild(parentFrom); c!=NULL; c= getNextChild(parentFrom))
+00379                 children.push_back(c);
+00380 
+00381         for(list<IModel *>::iterator it= children.begin(); it!= children.end();it++)
+00382         {
+00383                 unlink(parentFrom, *it);
+00384                 link(parentTo, *it);
+00385         }
+00386 }
+00387 // ***************************************************************************
+00388 void    ITrav::copyChildren(IModel *parentFrom, IModel *parentTo) const
+00389 {
+00390         // Make a local list of children (since link() modify the list).
+00391         list<IModel     *>      children;
+00392         for(IModel      *c= getFirstChild(parentFrom); c!=NULL; c= getNextChild(parentFrom))
+00393                 children.push_back(c);
+00394 
+00395         for(list<IModel *>::iterator it= children.begin(); it!= children.end();it++)
+00396         {
+00397                 link(parentTo, *it);
+00398         }
+00399 }
+00400 
+00401 
+00402 // ***************************************************************************
+00403 sint ITrav::getNumChildren (IModel *m) const
+00404 {
+00405         IObs *o = m->getObs(getClassId());
+00406         return o->getNumChildren();
+00407 }
+00408 // ***************************************************************************
+00409 IModel* ITrav::getFirstChild (IModel *m) const
+00410 {
+00411         IObs *o = m->getObs(getClassId());
+00412         IObs *child = o->getFirstChild();
+00413         if (child != NULL)
+00414                 return child->Model;
+00415         return NULL;
+00416 }
+00417 // ***************************************************************************
+00418 IModel* ITrav::getNextChild (IModel *m) const
+00419 {
+00420         IObs *o = m->getObs(getClassId());
+00421         IObs *child = o->getNextChild();
+00422         if (child != NULL)
+00423                 return child->Model;
+00424         return NULL;
+00425 }
+00426 
+00427 // ***************************************************************************
+00428 sint ITrav::getNumParents (IModel *m) const
+00429 {
+00430         IObs *o = m->getObs(getClassId());
+00431         return o->getNumParents();
+00432 }
+00433 // ***************************************************************************
+00434 IModel* ITrav::getFirstParent (IModel *m) const
+00435 {
+00436         IObs *o = m->getObs(getClassId());
+00437         IObs *father = o->getFirstParent();
+00438         if (father != NULL)
+00439                 return father->Model;
+00440         return NULL;
+00441 
+00442 }
+00443 // ***************************************************************************
+00444 IModel* ITrav::getNextParent (IModel *m) const
+00445 {
+00446         IObs *o = m->getObs(getClassId());
+00447         IObs *father = o->getNextParent();
+00448         if (father != NULL)
+00449                 return father->Model;
+00450         return NULL;
+00451 }
+00452 
+00453 
+00454 
+00455 
+00456 // ***************************************************************************
+00457 // ***************************************************************************
+00458 // IModel.
+00459 // ***************************************************************************
+00460 // ***************************************************************************
+00461 
+00462 
+00463 // ***************************************************************************
+00464 IModel::IModel()
+00465 {
+00466         TouchObs.resize(Last);
+00467         LastClassId= 0;
+00468         LastObs= NULL;
+00469 
+00470         _OwnerMot= NULL;
+00471         _PrecModelToValidate= NULL;
+00472         _NextModelToValidate= NULL;
+00473 }
+00474 // ***************************************************************************
+00475 IModel::~IModel()
+00476 {
+00477         // ensure the model is no more linked to the validateList.
+00478         unlinkFromValidateList();
+00479 
+00480         // delte observers.
+00481         CObsMap::iterator       it;
+00482         for(it=Observers.begin();it!=Observers.end();it++)
+00483         {
+00484                 delete (*it).second;
+00485                 (*it).second=NULL;
+00486         }
+00487 }
+00488 // ***************************************************************************
+00489 IObs    *IModel::getObs(const CClassId &idTrav) const 
+00490 {
+00491         CObsMap::const_iterator it;
+00492 
+00493         if(idTrav==LastClassId)
+00494                 return LastObs;
+00495 
+00496         LastClassId= idTrav;
+00497         it= Observers.find(idTrav);
+00498         if(it==Observers.end())
+00499                 LastObs= NULL;
+00500         else
+00501                 LastObs= (*it).second;
+00502 
+00503         return LastObs;
+00504 }
+00505 
+00506 
+00507 // ***************************************************************************
+00508 void    IModel::validate()
+00509 {
+00510         update();
+00511 
+00512         // If the model is newer than observers.
+00513         if(TouchObs[IModel::Dirty])
+00514         {
+00515                 // update all model's observers.
+00516                 IModel::CObsMap::iterator       it;
+00517                 for(it= Observers.begin(); it!= Observers.end(); it++)
+00518                 {
+00519                         IObs    *o= (*it).second;
+00520                         o->update();
+00521                 }
+00522 
+00523                 // Must clear all dirty falgs.
+00524                 cleanTouch();
+00525         }
+00526 }
+00527 
+00528 
+00529 // ***************************************************************************
+00530 void    IModel::linkToValidateList()
+00531 {
+00532         if(!_OwnerMot)
+00533                 return;
+00534 
+00535         // If the model is not already inserted.
+00536         if( ! (_PrecModelToValidate!=NULL  ||  _OwnerMot->_ValidateModelList==this) )
+00537         {
+00538                 // insert it.
+00539                 _NextModelToValidate= _OwnerMot->_ValidateModelList;
+00540                 _PrecModelToValidate= NULL;
+00541                 if(_NextModelToValidate)
+00542                         _NextModelToValidate->_PrecModelToValidate= this;
+00543                 _OwnerMot->_ValidateModelList= this;
+00544         }
+00545 }
+00546 
+00547 
+00548 // ***************************************************************************
+00549 void    IModel::unlinkFromValidateList()
+00550 {
+00551         if(!_OwnerMot)
+00552                 return;
+00553 
+00554         // If the model is inserted.
+00555         if( _PrecModelToValidate!=NULL  ||  _OwnerMot->_ValidateModelList==this )
+00556         {
+00557                 // update prec.
+00558                 if(_PrecModelToValidate)
+00559                         _PrecModelToValidate->_NextModelToValidate= _NextModelToValidate;
+00560                 else
+00561                         _OwnerMot->_ValidateModelList= _NextModelToValidate;
+00562 
+00563                 // update next.
+00564                 if(_NextModelToValidate)
+00565                         _NextModelToValidate->_PrecModelToValidate= _PrecModelToValidate;
+00566 
+00567                 // End.
+00568                 _PrecModelToValidate= NULL;
+00569                 _NextModelToValidate= NULL;
+00570         }
+00571 }
+00572 
+00573 
+00574 
+00575 // ***************************************************************************
+00576 // ***************************************************************************
+00577 // IObs.
+00578 // ***************************************************************************
+00579 // ***************************************************************************
+00580 
+00581 
+00582 
+00583 // ***************************************************************************
+00584 IObs::IObs()
+00585 {
+00586         Model= NULL;
+00587         Trav= NULL;
+00588 
+00589         NumFathers= 0;
+00590         NumSons= 0;
+00591         CurSonIt= SonList.end();
+00592         CurFatherIt= FatherList.end();
+00593 }
+00594 // ***************************************************************************
+00595 IObs::~IObs()
+00596 {
+00597         ItObsList       it;
+00598 
+00599         // delete map of Its.
+00600         SonMap.clear();
+00601         FatherMap.clear();
+00602 
+00603         // Delete link from fathers.
+00604         for(it= FatherList.begin(); it!=FatherList.end(); it++)
+00605         {
+00606                 IObs    *father= (*it);
+00607                 // Must use delChild() since don't know what father is.
+00608                 father->delChild(this);
+00609         }
+00610 
+00611         // Delete link from sons.
+00612         for(it= SonList.begin(); it!=SonList.end(); it++)
+00613         {
+00614                 IObs    *son= (*it);
+00615                 // Must use delParent() since don't know what son is.
+00616                 son->delParent(this);
+00617         }
+00618 
+00619         // And so delete lists.
+00620         SonList.clear();
+00621         FatherList.clear();
+00622         NumFathers= 0;
+00623         NumSons= 0;
+00624 }
+00625 // ***************************************************************************
+00626 IObs    *IObs::getObs(const CClassId &idTrav) const
+00627 {
+00628         return Model->getObs(idTrav);
+00629 }
+00630 
+00631 
+00632 // ***************************************************************************
+00633 void    IObs::addChild(IObs *son)
+00634 {
+00635         nlassert(son);
+00636 
+00637         // insert (if not exist).
+00638         ItObsMap        it= SonMap.find(son);
+00639         if(it==SonMap.end())
+00640         {
+00641                 // insert in the map and in the list.
+00642                 SonMap[son]= SonList.insert(SonList.end(), son);
+00643                 NumSons++;
+00644         }
+00645 }
+00646 // ***************************************************************************
+00647 void    IObs::delChild(IObs *son)
+00648 {
+00649         nlassert(son);
+00650 
+00651         // Just erase (if possible).
+00652         ItObsMap        it= SonMap.find(son);
+00653         if(it!=SonMap.end())
+00654         {
+00655                 // erase from list, then from mapt
+00656                 SonList.erase(it->second);
+00657                 SonMap.erase(it);
+00658                 NumSons--;
+00659         }
+00660 }
+00661 // ***************************************************************************
+00662 void    IObs::addParent(IObs *father)
+00663 {
+00664         nlassert(father);
+00665 
+00666         if(isTreeNode())
+00667         {
+00668                 // Must test if father is already linked.
+00669                 ItObsMap        itMap;
+00670                 itMap= FatherMap.find(father);
+00671                 if(itMap!=FatherMap.end())
+00672                         return;         // father is already a parent of this.
+00673 
+00674                 // Tree node, so delete fathers, and fathers links to me.
+00675                 for(ItObsList it= FatherList.begin(); it!=FatherList.end();it++)
+00676                 {
+00677                         // Must use delChild() since don't know what father is.
+00678                         (*it)->delChild(this);
+00679                 }
+00680                 FatherMap.clear();
+00681                 FatherList.clear();
+00682         }
+00683 
+00684         // insert (if not exist).
+00685         ItObsMap        it= FatherMap.find(father);
+00686         if(it==FatherMap.end())
+00687         {
+00688                 // insert in the map and in the list.
+00689                 FatherMap[father]= FatherList.insert(FatherList.end(), father);
+00690                 NumFathers++;
+00691         }
+00692 }
+00693 // ***************************************************************************
+00694 void    IObs::delParent(IObs *father)
+00695 {
+00696         nlassert(father);
+00697 
+00698         // Just erase (if possible).
+00699         ItObsMap        it= FatherMap.find(father);
+00700         if(it!=FatherMap.end())
+00701         {
+00702                 // erase from list, then from mapt
+00703                 FatherList.erase(it->second);
+00704                 FatherMap.erase(it);
+00705                 NumFathers--;
+00706         }
+00707 }
+00708 
+00709 
+00710 
+00711 }
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1