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/transform_8cpp-source.html | 1049 +++++++++++++++++++++++++++ 1 file changed, 1049 insertions(+) create mode 100644 docs/doxygen/nel/transform_8cpp-source.html (limited to 'docs/doxygen/nel/transform_8cpp-source.html') diff --git a/docs/doxygen/nel/transform_8cpp-source.html b/docs/doxygen/nel/transform_8cpp-source.html new file mode 100644 index 00000000..343ade81 --- /dev/null +++ b/docs/doxygen/nel/transform_8cpp-source.html @@ -0,0 +1,1049 @@ + + + + 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  
+

transform.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/transform.h"
+00029 #include "3d/skeleton_model.h"
+00030 #include "3d/skip_model.h"
+00031 #include "3d/scene.h"
+00032 #include "3d/root_model.h"
+00033 #include "3d/fast_floor.h"
+00034 
+00035 
+00036 using namespace NLMISC;
+00037 
+00038 
+00039 namespace       NL3D
+00040 {
+00041 
+00042 
+00043 // ***************************************************************************
+00044 void    CTransform::registerBasic()
+00045 {
+00046         CMOT::registerModel( TransformId, 0, CTransform::creator);
+00047         CMOT::registerObs( HrcTravId,                   TransformId, CTransformHrcObs::creator                  );
+00048         CMOT::registerObs( ClipTravId,                  TransformId, CTransformClipObs::creator                 );
+00049         CMOT::registerObs( AnimDetailTravId,    TransformId, CTransformAnimDetailObs::creator   );
+00050         CMOT::registerObs( LightTravId,                 TransformId, CTransformLightObs::creator                );
+00051         CMOT::registerObs( RenderTravId,                TransformId, CTransformRenderObs::creator               );
+00052 }
+00053 
+00054 
+00055 // ***************************************************************************
+00056 CTransform::CTransform()
+00057 {
+00058         _HrcObs= NULL;
+00059         _ClipObs= NULL;
+00060         _LightObs=NULL;
+00061 
+00062         TouchObs.resize(Last);
+00063 
+00064         Visibility= CHrcTrav::Herit;
+00065 
+00066         _LastTransformableMatrixDate= 0;
+00067 
+00068         _FatherSkeletonModel= NULL;
+00069 
+00070         _ClusterSystem = NULL;
+00071 
+00072         _FreezeHRCState= FreezeHRCStateDisabled;
+00073 
+00074         _OrderingLayer = 0;
+00075 
+00076         
+00077         // No logicInfo by default
+00078         _LogicInfo= NULL;
+00079 
+00080         _ForceCLodSticked= false;
+00081 
+00082         // default MeanColor value
+00083         _MeanColor.set(255,255,255,255);
+00084 
+00085 
+00086         // Setup some state.
+00087 
+00088         /*
+00089                 Default are:
+00090                         IsAnimDetailable= 0
+00091                         IsLoadBalancable= 0
+00092                         IsLightable= 0
+00093                         IsRenderable= 0
+00094                         IsTransparent= 0
+00095                         IsOpaque= 1
+00096                         QuadGridClipEnabled= 0.
+00097 
+00098                         IsUserLightable= 1                      // default, the model may be lighted.
+00099                         IsFinalLightable= 0
+00100                         IsNeedUpdateLighting= 0
+00101                         ISNeedUpdateFrozenStaticLightSetup= 0
+00102 
+00103                         IsSkeleton= 0
+00104 
+00105                         IsDeleteChannelMixer = 0;
+00106         */
+00107         _StateFlags= IsOpaque | IsUserLightable;
+00108 }
+00109 
+00110 
+00111 // ***************************************************************************
+00112 void    CTransform::initModel()
+00113 {
+00114         IModel::initModel();
+00115 
+00116         _HrcObs= (CTransformHrcObs*)getObs(HrcTravId);
+00117         _ClipObs= (CTransformClipObs*)getObs(ClipTravId);
+00118         _LightObs= (CTransformLightObs*)getObs(LightTravId);
+00119 }
+00120 
+00121 
+00122 // ***************************************************************************
+00123 CTransform::~CTransform()
+00124 {
+00125         // If still binded to a father skeleton
+00126         if( _FatherSkeletonModel )
+00127         {
+00128                 /* If skinned, cannot detach me from skeleton here because detachSkeletonSon()
+00129                         use some virtual calls of transform: setApplySkin().
+00130                         Hence, It is the deriver job to detach himself from the skeleton.
+00131 
+00132                         NB: test isSkinned(), not isSkinnable(), since isSkinned() is not virtual ....
+00133                         This means that if a Mesh isSkinnable(), but never skinned, it is not asserted here.
+00134                 */
+00135                 if( isSkinned() )
+00136                 {
+00137                         nlstop;
+00138                 }
+00139                 else
+00140                         // Can detach Me. Important for UTransform sticked
+00141                         _FatherSkeletonModel->detachSkeletonSon(this);
+00142         }
+00143 
+00144         // resetLighting, removing me from PointLight Transform list.
+00145         // NB: not done for FrozenStaticLightSetup, because those lights don't owns me.
+00146         resetLighting();
+00147 
+00148         // Must also remove me from the lightingManager.
+00149         // must test _LightObs because of CCluster usage out of mot (thanks to mat!! :) )
+00150         if(_LightObs)
+00151         {
+00152                 CLightTrav      *lightTrav= (CLightTrav*)_LightObs->Trav;
+00153                 _LightedModelIt= lightTrav->LightingManager.eraseStaticLightedModel(_LightedModelIt);
+00154         }
+00155 
+00156         if (getChannelMixerOwnerShip()) delete (CChannelMixer *) _ChannelMixer;
+00157 }
+00158 
+00159 // ***************************************************************************
+00160 void            CTransform::hide()
+00161 {
+00162         // Optim: do nothing if already set (=> not foulTransform() -ed).
+00163         if(Visibility!= CHrcTrav::Hide)
+00164         {
+00165                 foulTransform();
+00166                 Visibility= CHrcTrav::Hide;
+00167         }
+00168 }
+00169 // ***************************************************************************
+00170 void            CTransform::show()
+00171 {
+00172         // Optim: do nothing if already set (=> not foulTransform() -ed).
+00173         if(Visibility!= CHrcTrav::Show)
+00174         {
+00175                 foulTransform();
+00176                 Visibility= CHrcTrav::Show;
+00177         }
+00178 }
+00179 // ***************************************************************************
+00180 void            CTransform::heritVisibility()
+00181 {
+00182         // Optim: do nothing if already set (=> not foulTransform() -ed).
+00183         if(Visibility!= CHrcTrav::Herit)
+00184         {
+00185                 foulTransform();
+00186                 Visibility= CHrcTrav::Herit;
+00187         }
+00188 }
+00189 
+00190 
+00191 // ***************************************************************************
+00192 CTrackDefaultVector             CTransform::DefaultPos( CVector::Null );
+00193 CTrackDefaultVector             CTransform::DefaultRotEuler( CVector::Null );
+00194 CTrackDefaultQuat               CTransform::DefaultRotQuat( NLMISC::CQuat::Identity );
+00195 CTrackDefaultVector             CTransform::DefaultScale( CVector(1,1,1) );
+00196 CTrackDefaultVector             CTransform::DefaultPivot( CVector::Null );
+00197 
+00198 ITrack* CTransform::getDefaultTrack (uint valueId)
+00199 {
+00200         // Cyril: prefer do it here in CTransform, because of CCamera, CLight etc... (which may not need a default value too!!)
+00201 
+00202         // what value ?
+00203         switch (valueId)
+00204         {
+00205         case PosValue:                  return &DefaultPos;
+00206         case RotEulerValue:             return &DefaultRotEuler;
+00207         case RotQuatValue:              return &DefaultRotQuat;
+00208         case ScaleValue:                return &DefaultScale;
+00209         case PivotValue:                return &DefaultPivot;
+00210         }
+00211 
+00212         // No, only ITrnasformable values!
+00213         nlstop;
+00214         // Deriver note: else call BaseClass::getDefaultTrack(valueId);
+00215 
+00216         return NULL;
+00217 
+00218 }
+00219 
+00220 // ***************************************************************************
+00221 void    CTransform::registerToChannelMixer(CChannelMixer *chanMixer, const std::string &prefix)
+00222 {
+00223         if (getChannelMixerOwnerShip() && chanMixer != _ChannelMixer)
+00224         {
+00225                 delete _ChannelMixer;
+00226                 setChannelMixerOwnerShip(false);
+00227         }
+00228 
+00229         // Hey!! we are animated!!
+00230         _ChannelMixer= chanMixer;
+00231 
+00232         // Update flag, if we must be inserted in AnimDetail
+00233         setStateFlag(IsAnimDetailable, _ChannelMixer || getStateFlag(IsForceAnimDetail) );
+00234 
+00235         // If skinned, then must inform skeleton parent that it must recompute skin render/animDetail lists
+00236         if(isSkinned())
+00237         {
+00238                 nlassert(_FatherSkeletonModel);
+00239                 _FatherSkeletonModel->dirtSkinRenderLists();
+00240         }
+00241 
+00242         // For CTransfom, channels are not detailled.
+00243         addValue(chanMixer, PosValue, OwnerBit, prefix, false);
+00244         addValue(chanMixer, RotEulerValue, OwnerBit, prefix, false);
+00245         addValue(chanMixer, RotQuatValue, OwnerBit, prefix, false);
+00246         addValue(chanMixer, ScaleValue, OwnerBit, prefix, false);
+00247         addValue(chanMixer, PivotValue, OwnerBit, prefix, false);
+00248 
+00249         // Deriver note: if necessary, call     BaseClass::registerToChannelMixer(chanMixer, prefix);
+00250 }
+00251 
+00252 
+00253 
+00254 // ***************************************************************************
+00255 void                    CTransform::updateWorldMatrixFromFather()
+00256 {
+00257         // If I am not skinned
+00258         if(!isSkinned())
+00259         {
+00260                 // Compute the HRC WorldMatrix.
+00261                 // if I am not sticked.
+00262                 if(!_FatherSkeletonModel)
+00263                 {
+00264                         // get the normal father worldMatrix in Hrc.
+00265                         CTransform      *fatherTransform= dynamic_cast<CTransform*>(_HrcObs->Trav->getFirstParent(this));
+00266                         // if exist
+00267                         if(fatherTransform)
+00268                         {
+00269                                 const CMatrix &parentWM= fatherTransform->_HrcObs->WorldMatrix;
+00270                                 // combine worldMatrix
+00271                                 _HrcObs->WorldMatrix= parentWM * _HrcObs->LocalMatrix;
+00272                         }
+00273                         else
+00274                                 _HrcObs->WorldMatrix= _HrcObs->LocalMatrix;
+00275                 }
+00276                 else
+00277                 {
+00278                         // get the worldMatrix of the bone if I am sticked.
+00279                         const CMatrix &parentWM= _FatherSkeletonModel->Bones[_FatherBoneId].getWorldMatrix();
+00280                         // combine worldMatrix
+00281                         _HrcObs->WorldMatrix= parentWM * _HrcObs->LocalMatrix;
+00282                 }
+00283         }
+00284 }
+00285 
+00286 
+00287 // ***************************************************************************
+00288 void                    CTransform::freeze()
+00289 {
+00290         // First, validate the model, and all his observers.
+00291         // Frozen state is disabled here (in CTransformHrcObs::update()).
+00292         validate();
+00293 
+00294         // Then flag the frozen state.
+00295         _HrcObs->Frozen= true;
+00296 }
+00297 
+00298 // ***************************************************************************
+00299 void                    CTransform::setDontUnfreezeChildren(bool val)
+00300 {
+00301         _HrcObs->DontUnfreezeChildren = val;
+00302 }
+00303 
+00304 
+00305 // ***************************************************************************
+00306 const CMatrix& CTransform::getWorldMatrix()
+00307 {
+00308         return _HrcObs->WorldMatrix;
+00309 }
+00310 
+00311 // ***************************************************************************
+00312 bool    CTransform::getLastClippedState() const
+00313 {
+00314         return _ClipObs->Visible;
+00315 }
+00316 
+00317 
+00318 
+00319 // ***************************************************************************
+00320 void            CTransform::freezeHRC()
+00321 {
+00322         // if disabled, say we are ready to validate our worldMatrix for long.
+00323         if(_FreezeHRCState==FreezeHRCStateDisabled)
+00324         {
+00325                 _FreezeHRCState= FreezeHRCStateRequest;
+00326                 setStateFlag(QuadGridClipEnabled, true);
+00327         }
+00328 }
+00329 
+00330 
+00331 // ***************************************************************************
+00332 void            CTransform::unfreezeHRC()
+00333 {
+00334         // if this model is no HRC frozen disabled
+00335         if(_FreezeHRCState!=FreezeHRCStateDisabled)
+00336         {
+00337                 // if model correctly frozen.
+00338                 if(_FreezeHRCState == CTransform::FreezeHRCStateEnabled )
+00339                 {
+00340                         // Trick: get the traversal via the HrcObs.
+00341                         CHrcTrav        *hrcTrav= static_cast<CHrcTrav*>(_HrcObs->Trav);
+00342                         // if linked to SkipModelRoot, link this model to root of HRC.
+00343                         if( hrcTrav->getFirstParent(this) == hrcTrav->Scene->getSkipModelRoot() )
+00344                                 hrcTrav->link(NULL, this);
+00345 
+00346                         // Link this object to the validateList.
+00347                         linkToValidateList();
+00348 
+00349                         // if lightable()
+00350                         if( isLightable() )
+00351                         {
+00352                                 CLightTrav      *lightTrav= static_cast<CLightTrav*>(_LightObs->Trav);
+00353                                 // Lighting: must remove the object from the quadGrid.
+00354                                 // NB: works if _LightedModelIt==NULL. result is that _LightedModelIt= NULL.
+00355                                 _LightedModelIt= lightTrav->LightingManager.eraseStaticLightedModel(_LightedModelIt);
+00356                         }
+00357 
+00358                 }
+00359 
+00360                 _FreezeHRCState= FreezeHRCStateDisabled;
+00361                 setStateFlag(QuadGridClipEnabled, false);
+00362         }
+00363 }
+00364 
+00365 
+00366 // ***************************************************************************
+00367 void            CTransform::update()
+00368 {
+00369         IModel::update();
+00370 
+00371         // test if the matrix has been changed in ITransformable.
+00372         if(ITransformable::compareMatrixDate(_LastTransformableMatrixDate))
+00373         {
+00374                 _LastTransformableMatrixDate= ITransformable::getMatrixDate();
+00375                 foul(TransformDirty);
+00376         }
+00377 
+00378         // update the freezeHRC state.
+00379         if(_FreezeHRCState != CTransform::FreezeHRCStateDisabled)
+00380         {
+00381                 // if the model request to be frozen in HRC
+00382                 if(_FreezeHRCState == CTransform::FreezeHRCStateRequest )
+00383                 {
+00384                         // Wait for next Hrc traversal to compute good WorldMatrix for this model and his sons.
+00385                         // Also, next Hrc traversal will insert the model in the LightingManager quadGrid (if lightable)
+00386                         _FreezeHRCState = CTransform::FreezeHRCStateReady;
+00387                 }
+00388                 // if the model is ready to be frozen in HRC, then do it!!
+00389                 else if( _FreezeHRCState == CTransform::FreezeHRCStateReady )
+00390                 {
+00391                         // Trick: get the traversal via the HrcObs.
+00392                         CHrcTrav        *hrcTrav= static_cast<CHrcTrav*>(_HrcObs->Trav);
+00393                         // if linked to root of HRC, link this model to SkipModelRoot.
+00394                         if( hrcTrav->getFirstParent(this) == hrcTrav->getRoot() )
+00395                                 hrcTrav->link(hrcTrav->Scene->getSkipModelRoot(), this);
+00396 
+00397                         // unLink this object from the validateList. NB: the list will still be correclty parsed.
+00398                         unlinkFromValidateList();
+00399 
+00400                         // if lightable, the model is inserted in a quadgrid to update his lighting only when
+00401                         // dynamicLights touch him (since himself is static).
+00402                         if( isLightable() )
+00403                         {
+00404                                 CLightTrav      *lightTrav= static_cast<CLightTrav*>(_LightObs->Trav);
+00405                                 // Lighting: must reinsert the object from the quadGrid.
+00406                                 // NB: works if _LightedModelIt==NULL. result is that _LightedModelIt= NULL.
+00407                                 _LightedModelIt= lightTrav->LightingManager.eraseStaticLightedModel(_LightedModelIt);
+00408                                 // insert in the quadgrid.
+00409                                 _LightedModelIt= lightTrav->LightingManager.insertStaticLightedModel(this);
+00410                         }
+00411 
+00412                         // Now this model won't be tested for validation nor for worldMatrix update. End!!
+00413                         _FreezeHRCState = CTransform::FreezeHRCStateEnabled;
+00414                 }
+00415         }
+00416 }
+00417 
+00418 
+00419 // ***************************************************************************
+00420 void    CTransform::getAABBox(NLMISC::CAABBox &bbox) const
+00421 {
+00422         bbox.setCenter(CVector::Null);
+00423         bbox.setHalfSize(CVector::Null);
+00424 }
+00425 
+00426 
+00427 // ***************************************************************************
+00428 void    CTransform::setLoadBalancingGroup(const std::string &group)
+00429 {
+00430         // get the LoadBalancing observer
+00431         IBaseLoadBalancingObs   *obs= (IBaseLoadBalancingObs*)getObs(LoadBalancingTravId);
+00432         nlassert(obs);
+00433 
+00434         // Get the traversal.
+00435         CLoadBalancingTrav      *trav= (CLoadBalancingTrav*)obs->Trav;
+00436         nlassert(trav);
+00437         // get the group from trav (create if needed), and set it.
+00438         obs->LoadBalancingGroup= trav->getOrCreateGroup(group);
+00439 }
+00440 
+00441 
+00442 // ***************************************************************************
+00443 const std::string &CTransform::getLoadBalancingGroup() const
+00444 {
+00445         // get the LoadBalancing observer
+00446         IBaseLoadBalancingObs   *obs= (IBaseLoadBalancingObs*)getObs(LoadBalancingTravId);
+00447         nlassert(obs);
+00448 
+00449         // get the group name
+00450         return obs->LoadBalancingGroup->Name;
+00451 }
+00452 
+00453 
+00454 // ***************************************************************************
+00455 void            CTransform::setMeanColor(CRGBA color)
+00456 {
+00457         // if the color is different from prec
+00458         if(color!=_MeanColor)
+00459         {
+00460                 // change it.
+00461                 _MeanColor= color;
+00462                 // if skinned or sticked to a skeleton model.
+00463                 if(_FatherSkeletonModel)
+00464                 {
+00465                         // must dirt the vertex color of the lod skeleton because some object color has changed
+00466                         _FatherSkeletonModel->dirtLodVertexColor();
+00467                 }
+00468         }
+00469 }
+00470 
+00471 
+00472 // ***************************************************************************
+00473 void            CTransform::setIsLightable(bool val)
+00474 {
+00475         setStateFlag(IsLightable, val);
+00476         // update IsFinalLightable
+00477         setStateFlag(IsFinalLightable, (getStateFlag(IsLightable) && getStateFlag(IsUserLightable)) );
+00478 }
+00479 // ***************************************************************************
+00480 void            CTransform::setUserLightable(bool enable)
+00481 {
+00482         setStateFlag(IsUserLightable, enable);
+00483         // update IsFinalLightable
+00484         setStateFlag(IsFinalLightable, (getStateFlag(IsLightable) && getStateFlag(IsUserLightable)) );
+00485 }
+00486 
+00487 
+00488 // ***************************************************************************
+00489 void            CTransform::setIsRenderable(bool val)
+00490 {
+00491         setStateFlag(IsRenderable, val);
+00492 }
+00493 
+00494 // ***************************************************************************
+00495 void            CTransform::setIsBigLightable(bool val)
+00496 {
+00497         setStateFlag(IsBigLightable, val);
+00498 }
+00499 // ***************************************************************************
+00500 void            CTransform::setIsSkeleton(bool val)
+00501 {
+00502         setStateFlag(IsSkeleton, val);
+00503 }
+00504 
+00505 // ***************************************************************************
+00506 void            CTransform::setApplySkin(bool state)
+00507 {
+00508         setStateFlag(IsSkinned, state);
+00509 }
+00510 
+00511 // ***************************************************************************
+00512 void            CTransform::setIsForceAnimDetail(bool val)
+00513 {
+00514         setStateFlag(IsForceAnimDetail, val );
+00515 
+00516         // Update flag, if we must be inserted in AnimDetail
+00517         setStateFlag(IsAnimDetailable, _ChannelMixer || getStateFlag(IsForceAnimDetail) );
+00518 
+00519         // If skinned, then must inform skeleton parent that it must recompute skin render/animDetail lists
+00520         if(isSkinned())
+00521         {
+00522                 nlassert(_FatherSkeletonModel);
+00523                 _FatherSkeletonModel->dirtSkinRenderLists();
+00524         }
+00525 }
+00526 // ***************************************************************************
+00527 void            CTransform::setIsLoadbalancable(bool val)
+00528 {
+00529         setStateFlag(IsLoadBalancable, val );
+00530 }
+00531 
+00532 
+00533 // ***************************************************************************
+00534 // ***************************************************************************
+00535 // Observers.
+00536 // ***************************************************************************
+00537 // ***************************************************************************
+00538 
+00539 
+00540 // ***************************************************************************
+00541 void    CTransformHrcObs::update()
+00542 {
+00543         IBaseHrcObs::update();
+00544 
+00545         if(Model->TouchObs[CTransform::TransformDirty])
+00546         {
+00547                 // update the local matrix.
+00548                 LocalMatrix= static_cast<CTransform*>(Model)->getMatrix();
+00549                 IBaseHrcObs::LocalVis= static_cast<CTransform*>(Model)->Visibility;
+00550                 // update the date of the local matrix.
+00551                 LocalDate= static_cast<CHrcTrav*>(Trav)->CurrentDate;
+00552 
+00553                 // The transform has been modified. Hence, it is no more frozen.
+00554                 Frozen= false;
+00555         }
+00556 
+00557 }
+00558 
+00559 
+00560 // ***************************************************************************
+00561 void    CTransformHrcObs::updateWorld(IBaseHrcObs *caller)
+00562 {
+00563         const   CMatrix         *pFatherWM;
+00564         bool                            visFather;
+00565         CTransform                      *transModel= (CTransform*)Model;
+00566 
+00567         // If not root case, link to caller.
+00568         if(caller)
+00569         {
+00570                 pFatherWM= &(caller->WorldMatrix);
+00571                 visFather= caller->WorldVis;
+00572 
+00573                 // If father is not Frozen, so do I.
+00574                 CTransformHrcObs        *hrcTransCaller= dynamic_cast<CTransformHrcObs*>(caller);
+00575 
+00576                 // if caller is a CTransformHrcObs
+00577                 //  and if it is not frozen (for any reason), disable us!
+00578 
+00579                 if (hrcTransCaller && !hrcTransCaller->Frozen && !hrcTransCaller->DontUnfreezeChildren)
+00580                         Frozen= false;
+00581 
+00582                 // if caller is a CTransformHrcObs, may herit his _AncestorSkeletonModel
+00583                 // if caller is ! a CTransformHrcObs, final result undefined.
+00584                 if (hrcTransCaller && hrcTransCaller->_AncestorSkeletonModel)
+00585                         // If my father has an _AncestorSkeletonModel, get it.
+00586                         _AncestorSkeletonModel= hrcTransCaller->_AncestorSkeletonModel;
+00587                 else
+00588                         // else I have an ancestor skel model if I am sticked/binded directly to a skeleton model.
+00589                         _AncestorSkeletonModel= transModel->_FatherSkeletonModel;
+00590 
+00591         }
+00592         // else, default!!
+00593         else
+00594         {
+00595                 pFatherWM= &(CMatrix::Identity);
+00596                 visFather= true;
+00597 
+00598                 // at the root of the hierarchy, we have no parent, hence no FatherSkeletonModel nor _AncestorSkeletonModel.
+00599                 _AncestorSkeletonModel= NULL;
+00600 
+00601                 // NB: Root is Frozen by essence :), so don't modify the frozen state here.
+00602         }
+00603 
+00604         // Combine matrix
+00605         if(LocalDate>WorldDate || (caller && caller->WorldDate>WorldDate) )
+00606         {
+00607                 // Must recompute the world matrix.  ONLY IF I AM NOT SKINNED/STICKED TO A SKELETON in the hierarchy!
+00608                 if( _AncestorSkeletonModel==NULL )
+00609                 {
+00610                         WorldMatrix=  *pFatherWM * LocalMatrix;
+00611                         WorldDate= static_cast<CHrcTrav*>(Trav)->CurrentDate;
+00612 
+00613                         // Add the model to the moving object list
+00614                         if (!Frozen)
+00615                                 static_cast<CHrcTrav*>(Trav)->_MovingObjects.push_back (Model);
+00616                 }
+00617         }
+00618 
+00619         // Update dynamic lighting.
+00620         /*
+00621                 If the model is not frozen in StaticLight, then must update lighting each frame.
+00622                 Even if the object doesn't move, a new dynamic light may enter in its aera. Hence we must test
+00623                 it in the light quadrid. StaticLight-ed Objects don't need it because they are inserted in a special quadgrid, 
+00624                 where dynamics lights touch all StaticLight-ed object to force their computing
+00625 
+00626                 NB: not done if _AncestorSkeletonModel!=NULL. no need because  in this case, 
+00627                 result is driven by the _LightContribution of the _AncestorSkeletonModel.
+00628         */
+00629         if( !transModel->_LightContribution.FrozenStaticLightSetup && _AncestorSkeletonModel==NULL )
+00630         {
+00631                 // if the model is lightable reset lighting
+00632                 if( transModel->isLightable() )
+00633                         transModel->resetLighting();
+00634         }
+00635 
+00636         // Combine visibility.
+00637         switch(LocalVis)
+00638         {
+00639                 case CHrcTrav::Herit: WorldVis= visFather; break;
+00640                 case CHrcTrav::Hide: WorldVis= false; break;
+00641                 case CHrcTrav::Show: WorldVis= true; break;
+00642                 default: break;
+00643         }
+00644 
+00645 
+00646         // If I have an ancestor Skeleton Model, I must be binded in ClipTrav to the SonsOfAncestorSkeletonModelGroup
+00647         updateClipTravForAncestorSkeleton();
+00648 
+00649 }
+00650 
+00651 
+00652 // ***************************************************************************
+00653 void    CTransformHrcObs::updateClipTravForAncestorSkeleton()
+00654 {
+00655         CTransform                      *transModel= (CTransform*)Model;
+00656         CClipTrav                       *clipTrav= (CClipTrav*)transModel->_ClipObs->Trav;
+00657 
+00658         // If I have an ancestor Skeleton Model, I must be binded in ClipTrav to the SonsOfAncestorSkeletonModelGroup
+00659         if(_AncestorSkeletonModel && !ClipLinkedInSonsOfAncestorSkeletonModelGroup)
+00660         {
+00661                 // ClipTrav is a graph, so must unlink from ALL olds models.
+00662                 IModel  *father= clipTrav->getFirstParent(transModel);
+00663                 while(father)
+00664                 {
+00665                         clipTrav->unlink(father, transModel);
+00666                         father= clipTrav->getFirstParent(transModel);
+00667                 }
+00668 
+00669                 // And link to SonsOfAncestorSkeletonModelGroup.
+00670                 clipTrav->link(clipTrav->SonsOfAncestorSkeletonModelGroup, transModel);
+00671 
+00672                 // update the flag.
+00673                 ClipLinkedInSonsOfAncestorSkeletonModelGroup= true;
+00674         }
+00675 
+00676 
+00677         // else I must be binded to the standard Root.
+00678         if(!_AncestorSkeletonModel && ClipLinkedInSonsOfAncestorSkeletonModelGroup)
+00679         {
+00680                 // verify first I am really still linked to the SonsOfAncestorSkeletonModelGroup.
+00681                 // This test is important, because link may have changed for any reason (portals, clipManager....).
+00682                 if( clipTrav->getNumParents(transModel) == 1 &&
+00683                         clipTrav->getFirstParent(transModel)==clipTrav->SonsOfAncestorSkeletonModelGroup )
+00684                 {
+00685                         // yes, unlink from it.
+00686                         clipTrav->unlink(clipTrav->SonsOfAncestorSkeletonModelGroup, transModel);
+00687                         // and now, link to std root.
+00688                         clipTrav->link(clipTrav->getRoot(), transModel);
+00689                 }
+00690 
+00691                 // update the flag
+00692                 ClipLinkedInSonsOfAncestorSkeletonModelGroup= false;
+00693         }
+00694 }
+00695 
+00696 
+00697 // ***************************************************************************
+00698 void    CTransformHrcObs::traverse(IObs *caller)
+00699 {
+00700         // Recompute the matrix, according to caller matrix mode, and local matrix.
+00701         nlassert(!caller || dynamic_cast<IBaseHrcObs*>(caller));
+00702         updateWorld(static_cast<IBaseHrcObs*>(caller));
+00703         // DoIt the sons.
+00704         traverseSons();
+00705 }
+00706 
+00707 
+00708 // ***************************************************************************
+00709 void    CTransformClipObs::traverse(IObs *caller)
+00710 {
+00711         nlassert(!caller || dynamic_cast<IBaseClipObs*>(caller));
+00712 
+00713         CClipTrav               *clipTrav= safe_cast<CClipTrav*>(Trav);
+00714         IBaseClipObs    *callerClipObs= static_cast<IBaseClipObs*>(caller);
+00715         CTransform              *transform= (CTransform*)Model;
+00716 
+00717         if ((Date == clipTrav->CurrentDate) && Visible)
+00718                 return;
+00719         Date = clipTrav->CurrentDate;
+00720 
+00721         // clip: update Visible flag.
+00722         Visible= false;
+00723         // if at least visible.
+00724         if(HrcObs->WorldVis)
+00725         {
+00726                 // If linked to a SkeletonModel anywhere in the hierarchy, don't clip, and use skeleton model clip result.
+00727                 // This works because we are sons of a special node which is not in the clip traversal, and
+00728                 // which is traversed at end of the traversal.
+00729                 if( ((CTransformHrcObs*)HrcObs)->_AncestorSkeletonModel!=NULL )
+00730                 {
+00731                         Visible= ((CTransformHrcObs*)HrcObs)->_AncestorSkeletonModel->isClipVisible();
+00732                         // Special test: if we are sticked to a skeletonModel, and if we are still visible, maybe we don't have to
+00733                         if(Visible && transform->_FatherSkeletonModel)
+00734                         {
+00735                                 // if our skeletonModel father is displayed with a Lod, maybe we are not to be displayed
+00736                                 if(transform->_FatherSkeletonModel->isDisplayedAsLodCharacter())
+00737                                 {
+00738                                         // We are visible only if we where sticked to the skeleton with forceCLod==true.
+00739                                         // This is also true if we are actually a skeletonModel
+00740                                         if(!transform->_ForceCLodSticked)
+00741                                                 // otherWise we are not visible. eg: this is the case of skins and some sticked object
+00742                                                 Visible= false;
+00743                                 }
+00744                         }
+00745                 }
+00746                 // else, clip.
+00747                 else
+00748                         Visible= clip(callerClipObs);
+00749         }
+00750 
+00751         // if visible, add to list.
+00752         if(Visible)
+00753         {
+00754                 // add this observer to the visibility list.
+00755                 clipTrav->addVisibleObs(this);
+00756 
+00757                 // Has not an ancestor skeleton model?
+00758                 if( ((CTransformHrcObs*)HrcObs)->_AncestorSkeletonModel==NULL )
+00759                 {
+00760                         // If needed, insert the model in the lighted list.
+00761                         // don't insert if has an ancestorSkeletonModel, because in this case, result is driven by 
+00762                         // the _LightContribution of the _AncestorSkeletonModel.
+00763                         if( transform->isLightable() )
+00764                                 clipTrav->LightTrav->addLightedObs(transform->_LightObs);
+00765 
+00766                         // If needed, insert the model in the animDetail list.
+00767                         // don't insert if has an ancestoreSkeletonModel, because in this case, this ancestore will 
+00768                         // animDetail through the hierarchy...
+00769                         if( transform->isAnimDetailable() )
+00770                                 clipTrav->AnimDetailTrav->addVisibleObs(safe_cast<CTransformAnimDetailObs*>(AnimDetailObs));
+00771                 }
+00772 
+00773                 // If needed, Add it to the loadBalancing trav
+00774                 if( transform->isLoadBalancable() )
+00775                         clipTrav->LoadBalancingTrav->addVisibleObs(LoadBalancingObs);
+00776 
+00777                 // If needed, insert the model in the render list.
+00778                 if( transform->isRenderable() )
+00779                         clipTrav->RenderTrav->addRenderObs(RenderObs);
+00780         }
+00781 
+00782         // DoIt the sons.
+00783         traverseSons();
+00784 }
+00785 
+00786 
+00787 
+00788 // ***************************************************************************
+00789 void    CTransformAnimDetailObs::updateWorldMatrixFromFather()
+00790 {
+00791         CTransform              *transModel= static_cast<CTransform*>(Model);
+00792 
+00793         // If I have an ancestore Skeleton model
+00794         if(transModel->_HrcObs->_AncestorSkeletonModel)
+00795         {
+00796                 // then must first update my worldMatrix.
+00797                 transModel->updateWorldMatrixFromFather();
+00798         }
+00799 }
+00800 
+00801 // ***************************************************************************
+00802 void    CTransformAnimDetailObs::traverseWithoutUpdateWorldMatrix(IObs *caller)
+00803 {
+00804         CTransform              *transModel= static_cast<CTransform*>(Model);
+00805 
+00806         // AnimDetail behavior: animate only if not clipped.
+00807         // NB: no need to test because of VisibilityList use.
+00808 
+00809         // test if the refptr is NULL or not (RefPtr).
+00810         CChannelMixer   *chanmix= transModel->_ChannelMixer;
+00811         if(chanmix)
+00812         {
+00813                 // eval detail!!
+00814                 chanmix->eval(true, static_cast<CAnimDetailTrav*>(Trav)->CurrentDate);
+00815         }
+00816 }
+00817 
+00818 // ***************************************************************************
+00819 void    CTransformAnimDetailObs::traverse(IObs *caller)
+00820 {
+00821         // First, test if I must update my HrcObs worldMatrix because of the ancestorSkeleton scheme
+00822         updateWorldMatrixFromFather();
+00823 
+00824         // eval channelMixer.
+00825         traverseWithoutUpdateWorldMatrix(caller);
+00826 
+00827         // NB: if want to add something, do it in traverseWithoutUpdateWorldMatrix(), because
+00828         // CSkeletonModel doesn't call CTransformAnimDetailObs::traverse()
+00829 
+00830         // no need to traverseSons. No graph here.
+00831 }
+00832 
+00833 
+00834 // ***************************************************************************
+00835 // ***************************************************************************
+00836 // Lighting.
+00837 // ***************************************************************************
+00838 // ***************************************************************************
+00839 
+00840 
+00841 // ***************************************************************************
+00842 void            CTransform::resetLighting()
+00843 {
+00844         // if the model is already isNeedUpdateLighting, his light setup is reseted.
+00845         // so no need to reset again
+00846         if(isNeedUpdateLighting())
+00847                 return;
+00848 
+00849 
+00850         // For all light not in FrozenStaticLightSetup, remove me from their list
+00851         uint    startLight= 0;
+00852         if(_LightContribution.FrozenStaticLightSetup)
+00853         {
+00854                 startLight= _LightContribution.NumFrozenStaticLight;
+00855         }
+00856 
+00857         // for all light in the list, remove me from their list.
+00858         for(uint i=startLight; i<NL3D_MAX_LIGHT_CONTRIBUTION; i++)
+00859         {
+00860                 CPointLight             *pl= _LightContribution.PointLight[i];
+00861                 // if end of list, break.
+00862                 if(!pl)
+00863                         break;
+00864                 else
+00865                 {
+00866                         // remove me from this light.
+00867                         pl->removeLightedModel(_LightContribution.TransformIterator[i]);
+00868                 }
+00869         }
+00870         // empty the list.
+00871         if(startLight<NL3D_MAX_LIGHT_CONTRIBUTION)
+00872                 _LightContribution.PointLight[startLight]= NULL;
+00873 
+00874 
+00875         // the model needs to update his lighting.
+00876         setStateFlag(IsNeedUpdateLighting, true);
+00877         
+00878 }
+00879 
+00880 
+00881 // ***************************************************************************
+00882 void                    CTransform::freezeStaticLightSetup(CPointLight *pointLight[NL3D_MAX_LIGHT_CONTRIBUTION], 
+00883                 uint numPointLights, uint8 sunContribution, CPointLight *frozenAmbientlight)
+00884 {
+00885         nlassert(numPointLights <= NL3D_MAX_LIGHT_CONTRIBUTION);
+00886 
+00887         // resetLighting() first.
+00888         resetLighting();
+00889 
+00890         // Enable StaticLightSetup.
+00891         _LightContribution.FrozenStaticLightSetup= true;
+00892         _LightContribution.NumFrozenStaticLight= numPointLights;
+00893         _LightContribution.SunContribution= sunContribution;
+00894         // setup the FrozenAmbientLight
+00895         _LightContribution.FrozenAmbientLight= frozenAmbientlight;
+00896         // Setup other pointLights
+00897         uint i;
+00898         for(i=0;i<numPointLights;i++)
+00899         {
+00900                 // set the light
+00901                 _LightContribution.PointLight[i]= pointLight[i];
+00902                 // Enable at max.
+00903                 _LightContribution.Factor[i]= 255;
+00904                 // Compute static AttFactor Later because don't have WorlPosition of the model here!!
+00905                 setStateFlag(IsNeedUpdateFrozenStaticLightSetup, true);
+00906 
+00907                 // Do NOT set the iterator, because it is a staticLight.
+00908         }
+00909         // End the list
+00910         if(i<NL3D_MAX_LIGHT_CONTRIBUTION)
+00911                 _LightContribution.PointLight[i]= NULL;
+00912 }
+00913 
+00914 // ***************************************************************************
+00915 void                    CTransform::unfreezeStaticLightSetup()
+00916 {
+00917         // resetLighting() first.
+00918         resetLighting();
+00919 
+00920         // Disable StaticLightSetup.
+00921         _LightContribution.FrozenStaticLightSetup= false;
+00922         _LightContribution.NumFrozenStaticLight= 0;
+00923         // End the list
+00924         _LightContribution.PointLight[0]= NULL;
+00925         // No more FrozenAmbientLight
+00926         _LightContribution.FrozenAmbientLight= NULL;
+00927 
+00928         // Don't need to update StaticLightSetup since no more exist.
+00929         setStateFlag(IsNeedUpdateFrozenStaticLightSetup, false);
+00930 }
+00931 
+00932 
+00933 // ***************************************************************************
+00934 void    CTransformLightObs::traverse(IObs *caller)
+00935 {
+00936         CTransform              *transform= (CTransform*)Model;
+00937 
+00938         // if the model do not need to update his lighting, just skip.
+00939         if(!transform->isNeedUpdateLighting())
+00940                 return;
+00941 
+00942 
+00943         // If a freezeStaticLightSetup() has been called on this model recently.
+00944         if(transform->isNeedUpdateFrozenStaticLightSetup())
+00945         {
+00946                 // Now, the correct matrix is computed.
+00947                 // get the untransformed bbox from the model.
+00948                 CAABBox         bbox;
+00949                 transform->getAABBox(bbox);
+00950                 // get transformed center pos of bbox
+00951                 CVector worldModelPos= transform->getWorldMatrix() * bbox.getCenter();
+00952 
+00953                 // So we can compute AttFactor for each static light influencing this static object
+00954                 uint    numPointLights= transform->_LightContribution.NumFrozenStaticLight;
+00955                 for(uint i=0;i<numPointLights;i++)
+00956                 {
+00957                         const CPointLight       *pl= transform->_LightContribution.PointLight[i];
+00958                         // don't worry about the precision of floor, because of *255.
+00959                         float   distToModel= (pl->getPosition() - worldModelPos).norm();
+00960                         sint    attFactor= OptFastFloor( 255 * pl->computeLinearAttenuation(worldModelPos, distToModel) );
+00961                         transform->_LightContribution.AttFactor[i]= (uint8)attFactor;
+00962                 }
+00963 
+00964                 // clean.
+00965                 transform->setStateFlag(CTransform::IsNeedUpdateFrozenStaticLightSetup, false);
+00966         }
+00967 
+00968 
+00969         // see CTransformClipObs::clip(), here I am Lightable(), and I have no _AncestorSkeletonModel
+00970         // So I am sure that I really need to recompute my ModelLightContributions.
+00971         ((CLightTrav*)Trav)->LightingManager.computeModelLightContributions(transform,
+00972                 transform->_LightContribution, transform->_LogicInfo);
+00973 
+00974         // done!
+00975         transform->setStateFlag(CTransform::IsNeedUpdateLighting, false);
+00976 }
+00977 
+00978 
+00979 
+00980 }
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1