From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../nel/particle__system__model_8cpp-source.html | 824 +++++++++++++++++++++ 1 file changed, 824 insertions(+) create mode 100644 docs/doxygen/nel/particle__system__model_8cpp-source.html (limited to 'docs/doxygen/nel/particle__system__model_8cpp-source.html') diff --git a/docs/doxygen/nel/particle__system__model_8cpp-source.html b/docs/doxygen/nel/particle__system__model_8cpp-source.html new file mode 100644 index 00000000..88c5c582 --- /dev/null +++ b/docs/doxygen/nel/particle__system__model_8cpp-source.html @@ -0,0 +1,824 @@ + + + + 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  
+

particle_system_model.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2001 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 "nel/misc/debug.h"
+00029 #include "nel/misc/common.h"
+00030 #include "nel/misc/hierarchical_timer.h"
+00031 #include "3d/particle_system_model.h"
+00032 #include "3d/particle_system_shape.h"
+00033 #include "3d/particle_system.h"
+00034 #include "3d/scene.h"
+00035 #include "3d/anim_detail_trav.h"
+00036 #include "3d/clip_trav.h"
+00037 #include "3d/render_trav.h"
+00038 #include "3d/skeleton_model.h"
+00039 
+00040 
+00041 
+00042 #include "cluster.h" // ask trap
+00043 
+00044 
+00045 
+00046 
+00047 namespace NL3D {
+00048 
+00051 CParticleSystemModel::CParticleSystemModel() : _AutoGetEllapsedTime(true),
+00052                                                                                            _ParticleSystem(NULL),
+00053                                                                                            _Scene(NULL),
+00054                                                                                            _EllapsedTime(0.01f),
+00055                                                                                            _EllapsedTimeRatio(1.f),
+00056                                                                                            _ToolDisplayEnabled(false),
+00057                                                                                            _TransparencyStateTouched(true),
+00058                                                                                            _EditionMode(false),
+00059                                                                                            _Invalidated(false),
+00060                                                                                            _InsertedInVisibleList(false),
+00061                                                                                            _InClusterAndVisible(false),
+00062                                                                                            _BypassGlobalUserParam(0)
+00063 {
+00064         setOpacity(false);
+00065         setTransparency(true);
+00066         IAnimatable::resize(AnimValueLast);
+00067         _TriggerAnimatedValue.Value = true;
+00068 
+00069         // AnimDetail behavior: Must be traversed in AnimDetail, even if no channel mixer registered
+00070         CTransform::setIsForceAnimDetail(true);
+00071 }
+00072 
+00073 
+00075 void CParticleSystemModel::setEditionMode(bool enable /*= true*/)
+00076 { 
+00077         if (enable)
+00078         {
+00080                 if (!_ParticleSystem)
+00081                 {
+00082                         nlassert(_Scene);
+00083                         nlassert(Shape);
+00084                         reallocRsc();
+00085                 }
+00086         }
+00087         _EditionMode = enable; 
+00088 }
+00089 
+00091 void CParticleSystemModel::registerPSModelObserver(IPSModelObserver *obs)
+00092 {
+00093         nlassert(!isPSModelObserver(obs)); // this observer has already been registered
+00094         _Observers.push_back(obs);
+00095 }
+00096 
+00098 void CParticleSystemModel::removePSModelObserver(IPSModelObserver *obs)
+00099 {       
+00100         nlassert(isPSModelObserver(obs)); // the observer must have been registered
+00101         std::vector<IPSModelObserver *>::iterator it = std::find(_Observers.begin(), _Observers.end(), obs);
+00102         _Observers.erase(it);
+00103 }
+00104 
+00105 
+00107 bool CParticleSystemModel::isPSModelObserver(IPSModelObserver *obs)
+00108 {
+00109         return std::find(_Observers.begin(), _Observers.end(), obs) != _Observers.end();
+00110 }
+00111 
+00112 
+00114 void CParticleSystemModel::registerBasic()
+00115 {
+00116         // register the model and his observers
+00117         CMOT::registerModel(ParticleSystemModelId, TransformShapeId, CParticleSystemModel::creator);    
+00118         CMOT::registerObs(AnimDetailTravId, ParticleSystemModelId, CParticleSystemDetailObs::creator);
+00119         CMOT::registerObs(ClipTravId, ParticleSystemModelId, CParticleSystemClipObs::creator);
+00120         CMOT::registerObs(RenderTravId, ParticleSystemModelId, CParticleSystemRenderObs::creator);
+00121 }
+00122 
+00124 void CParticleSystemModel::updateOpacityInfos(void)
+00125 {
+00126         nlassert(_ParticleSystem);
+00127         if (!_TransparencyStateTouched) return;
+00128         nlassert(_ParticleSystem);
+00129         setOpacity(_ParticleSystem->hasOpaqueObjects() || _ToolDisplayEnabled);
+00130         setTransparency(_ParticleSystem->hasTransparentObjects());
+00131         _TransparencyStateTouched = false;
+00132 }
+00133 
+00134 
+00136 void CParticleSystemModel::getAABBox(NLMISC::CAABBox &bbox) const
+00137 {
+00138         if (_ParticleSystem)
+00139         {
+00140                 _ParticleSystem->computeBBox(bbox);
+00141         }
+00142         else
+00143         {
+00144                 NLMISC::safe_cast<CParticleSystemShape *>((IShape *) Shape)->getAABBox(bbox);
+00145         }
+00146 }
+00147 
+00149 CParticleSystemModel::~CParticleSystemModel()
+00150 {       
+00151         nlassert(_Scene);
+00152         if (_ParticleSystem)
+00153         {
+00154                 _Scene->getParticleSystemManager().removeSystemModel(_ModelHandle);             
+00155         }
+00156         // Auto detach me from skeleton. Must do it here, not in ~CTransform().
+00157         if(_FatherSkeletonModel)
+00158         {
+00159                 // detach me from the skeleton.
+00160                 // Observers hierarchy is modified.
+00161                 _FatherSkeletonModel->detachSkeletonSon(this);
+00162                 nlassert(_FatherSkeletonModel==NULL);
+00163         }
+00164 }
+00165 
+00166 
+00169 void CParticleSystemModel::reallocRsc()
+00170 {
+00171         nlassert(_ParticleSystem == NULL);
+00172         _ParticleSystem = NLMISC::safe_cast<CParticleSystemShape *>((IShape *) Shape)->instanciatePS(*_Scene);
+00173         nlassert(_ParticleSystem);
+00174         nlassert(_Scene);
+00175         CParticleSystemManager &psmgt = _Scene->getParticleSystemManager();
+00176         _ModelHandle = psmgt.addSystemModel(this);
+00177         if (_ParticleSystem->getAnimType() == CParticleSystem::AnimAlways)
+00178         {
+00179                 _AnimatedModelHandle = psmgt.addPermanentlyAnimatedSystem(this);
+00180         }
+00181         // touch user params animated value. If the system rsc have been released before, this force to restore them
+00182         for (uint k = 0; k < MaxPSUserParam; ++k)
+00183         {               
+00184                 touch((uint)CParticleSystemModel::PSParam0 + k, OwnerBit);
+00185         }
+00186 }
+00187 
+00189 void CParticleSystemModel::releasePSPointer()
+00190 {
+00191         if (_ParticleSystem.getNbRef() == 1)
+00192         {       
+00193                 // Backup user params (in animated value) so that they will be restored when the system is recreated
+00194                 for (uint k = 0; k < MaxPSUserParam; ++k)
+00195                 {
+00196                         
+00197                         _UserParam[k].Value = _ParticleSystem->getUserParam(k);                                 
+00198                 }
+00199         }
+00200         //
+00201         _ParticleSystem = NULL; // one less ref with the smart ptr 
+00202 }
+00203 
+00205 bool CParticleSystemModel::refreshRscDeletion(const std::vector<CPlane> &worldFrustumPyramid,  const NLMISC::CVector &viewerPos)
+00206 {
+00207         if (_EditionMode) return false;
+00216         nlassert(_ParticleSystem);      
+00217         CParticleSystemShape            *shape = NLMISC::safe_cast<CParticleSystemShape *>((IShape *) Shape);
+00218         
+00219         /* NLMISC::CVector sysPos = getTransformMode() == DirectMatrix ?
+00220                                                          getMatrix().getPos()                       :
+00221                                                          getPos(); */
+00222 
+00223         NLMISC::CVector sysPos = getWorldMatrix().getPos();
+00224         
+00225         NLMISC::CVector v = sysPos - viewerPos;
+00227         const float dist2 = v * v;
+00228         
+00229         if (dist2 > shape->_MaxViewDist * shape->_MaxViewDist) // too far ?
+00230         {
+00231                 if (_AnimatedModelHandle.Valid)
+00232                 {
+00233                         _Scene->getParticleSystemManager().removePermanentlyAnimatedSystem(_AnimatedModelHandle);
+00234                         _AnimatedModelHandle.Valid = false;
+00235                 }               
+00236                 releasePSPointer();
+00237                 if (shape->_DestroyModelWhenOutOfRange)
+00238                 {                       
+00239                         _Invalidated = true;
+00240                 }               
+00241                 return true;            
+00242         }
+00243 
+00245         if (shape->_DestroyWhenOutOfFrustum)
+00246         {
+00247                 if (checkAgainstPyramid(worldFrustumPyramid) == false)
+00248                 {
+00249                         if (_AnimatedModelHandle.Valid)
+00250                         {
+00251                                 _Scene->getParticleSystemManager().removePermanentlyAnimatedSystem(_AnimatedModelHandle);
+00252                                 _AnimatedModelHandle.Valid = false;
+00253                         }
+00254 
+00255                         if (shape->_DestroyModelWhenOutOfRange)
+00256                         {                                                       
+00257                                 _Invalidated = true;
+00258                         }
+00259                         releasePSPointer();
+00260                         return true;
+00261                 }
+00262         }
+00263 
+00264         return false;
+00265 }               
+00266 
+00268 void CParticleSystemModel::releaseRsc()
+00269 {
+00270         if (!_ParticleSystem) return;
+00271 
+00272         if (_AnimatedModelHandle.Valid)
+00273         {
+00274                 _Scene->getParticleSystemManager().removePermanentlyAnimatedSystem(_AnimatedModelHandle);
+00275                 _AnimatedModelHandle.Valid = false;
+00276         }       
+00277         nlassert(_Scene);
+00278         _Scene->getParticleSystemManager().removeSystemModel(_ModelHandle);
+00279 }
+00280 
+00282 void CParticleSystemModel::releaseRscAndInvalidate()
+00283 {
+00284 
+00285         if (!_ParticleSystem) return;
+00286 
+00287         if (_AnimatedModelHandle.Valid)
+00288         {
+00289                 _Scene->getParticleSystemManager().removePermanentlyAnimatedSystem(_AnimatedModelHandle);
+00290                 _AnimatedModelHandle.Valid = false;
+00291         }       
+00292         releasePSPointer();
+00293         _Invalidated = true;
+00294 
+00295         nlassert(_Scene);
+00296         _Scene->getParticleSystemManager().removeSystemModel(_ModelHandle);
+00297 
+00298         static std::vector<IPSModelObserver *> copyVect;
+00299         copyVect.resize(_Observers.size());
+00300         std::copy(_Observers.begin(), _Observers.end(), copyVect.begin());
+00301         
+00302         for (std::vector<IPSModelObserver *>::iterator it = copyVect.begin(); it != copyVect.end(); ++it)
+00303         {
+00304                 (*it)->invalidPS(this); // if this crash, then you forgot to call removePSModelObserver !
+00305         }
+00306 }
+00307 
+00309 IAnimatedValue* CParticleSystemModel::getValue (uint valueId)
+00310 {
+00311         nlassert(valueId < AnimValueLast);
+00312         if (valueId < OwnerBit) return CTransformShape::getValue(valueId);      
+00313         if (valueId < PSTrigger)
+00314         {
+00315         
+00316                 return &_UserParam[valueId - (uint)  PSParam0];
+00317         }
+00318         return &_TriggerAnimatedValue;
+00319 }
+00320 
+00322 const char *CParticleSystemModel::getPSParamName (uint valueId)
+00323 {       
+00324         nlassert(valueId < AnimValueLast);
+00325         const char *name[] = { "PSParam0", "PSParam1", "PSParam2", "PSParam3" };        
+00326         return name[valueId - (uint) PSParam0];
+00327 }
+00328 
+00330 const char *CParticleSystemModel::getValueName (uint valueId) const 
+00331 { 
+00332         nlassert(valueId < AnimValueLast);
+00333         if (valueId < OwnerBit) return CTransformShape::getValueName(valueId);
+00334         if (valueId < PSTrigger) return getPSParamName(valueId); 
+00335         return "PSTrigger";
+00336 }
+00337 
+00339 ITrack* CParticleSystemModel::getDefaultTrack (uint valueId)
+00340 {
+00341         nlassert(valueId < AnimValueLast);
+00342         nlassert(Shape);
+00343 
+00344         CParticleSystemShape *pss = NLMISC::safe_cast<CParticleSystemShape *>((IShape *) Shape);
+00345 
+00346         switch (valueId)
+00347         {
+00348                 case PosValue:                  return pss->getDefaultPos();            
+00349                 case RotQuatValue:              return pss->getDefaultRotQuat();
+00350                 case ScaleValue:                return pss->getDefaultScale();          
+00351         }
+00352         if (valueId < OwnerBit) return CTransformShape::getDefaultTrack(valueId); // delegate to parent
+00353 
+00354         // this value belong to us
+00355         if (valueId < PSTrigger) 
+00356         {
+00357                 return pss->getUserParamDefaultTrack(valueId - (uint) PSParam0);
+00358         }
+00359         return pss->getDefaultTriggerTrack();
+00360 }
+00361 
+00363         void CParticleSystemModel::registerToChannelMixer(CChannelMixer *chanMixer, const std::string &prefix /* =std::string() */)
+00364 {
+00365         CTransformShape::registerToChannelMixer(chanMixer, prefix);
+00366         addValue(chanMixer, PSParam0, OwnerBit, prefix, true);
+00367         addValue(chanMixer, PSParam1, OwnerBit, prefix, true);
+00368         addValue(chanMixer, PSParam2, OwnerBit, prefix, true);
+00369         addValue(chanMixer, PSParam3, OwnerBit, prefix, true);  
+00370         addValue(chanMixer, PSTrigger, OwnerBit, prefix, true); 
+00371 }
+00372 
+00373 
+00375 float CParticleSystemModel::getNumTriangles (float distance)
+00376 {
+00377         if (!_ParticleSystem) return 0;
+00378         return (float) _ParticleSystem->getWantedNumTris(distance);
+00379 }
+00380 
+00382 bool CParticleSystemModel::checkAgainstPyramid(const std::vector<CPlane>        &pyramid) const
+00383 {               
+00384         nlassert(_ParticleSystem)
+00385         NLMISC::CAABBox bbox;
+00386         _ParticleSystem->computeBBox(bbox);             
+00387         const CMatrix           &mat = getMatrix();
+00388         
+00389         // Transform the pyramid in Object space.       
+00390         for(sint i=0; i < (sint) pyramid.size(); i++)
+00391         {       
+00392                 // test wether the bbox is entirely in the neg side of the plane
+00393                 if (!bbox.clipBack(pyramid[i]  * mat  )) 
+00394                 {
+00395                         return false;                   
+00396                 }
+00397         }
+00398         return true;
+00399 
+00400 }
+00401 
+00403 // CParticleSystemDetailObs implementation  //
+00405 
+00407 void    CParticleSystemDetailObs::traverse(IObs *caller)
+00408 {    
+00409         CTransformAnimDetailObs::traverse(caller);      
+00410         CParticleSystemModel *psm= NLMISC::safe_cast<CParticleSystemModel *>(Model);
+00411         CParticleSystem *ps = psm->getPS();
+00412         if (psm->_Invalidated) return;
+00413         if (psm->getVisibility() == CHrcTrav::Hide) return;
+00414         
+00415         
+00416         if (!psm->_EditionMode && !psm->_InClusterAndVisible)
+00417         {
+00418                 CParticleSystemShape            *pss = NLMISC::safe_cast<CParticleSystemShape *>((IShape *)psm->Shape);
+00419                 if (pss->_DestroyWhenOutOfFrustum)
+00420                 {
+00421                         if (pss->_DestroyModelWhenOutOfRange)
+00422                         {
+00423                                 psm->releaseRscAndInvalidate();                 
+00424                         }
+00425                         else // remove rsc but do not invalidate the system
+00426                         {
+00427                                 psm->releaseRsc();
+00428                         }
+00429                         return;
+00430                 }
+00431                 if (!ps) return;
+00432         }       
+00433 
+00434         // check for trigger. If the trigger is false, and there is a system instanciated, we delete it.
+00435         if (!psm->_EditionMode)
+00436         {
+00437                 if (!psm->_TriggerAnimatedValue.Value)
+00438                 {                                                                       
+00439                         // system is off, or hasn't been instanciated now...
+00440                         if (ps)
+00441                         {
+00442                                 psm->releaseRsc();                              
+00443                         }
+00444                         return;
+00445                 }
+00446         }
+00447 
+00448         // the system or its center is in the view frustum, but it may not have been instanciated from its shape now
+00449         if (!ps)
+00450         {
+00451                 nlassert(psm->_Scene);
+00452                 nlassert(psm->Shape);
+00453                 psm->reallocRsc();
+00454                 ps = psm->_ParticleSystem;
+00455         }
+00456 
+00457         CClipTrav                       *trav= (CClipTrav*) ClipObs->Trav;
+00458         
+00459         if (psm->_InClusterAndVisible ||  ps->getAnimType() == CParticleSystem::AnimInCluster)
+00460         {               
+00461                 bool animate = true;
+00462                 if (ps->isSharingEnabled()) 
+00463                 {
+00464                         if (ps->_LastUpdateDate == trav->CurrentDate)
+00465                         {
+00466                                 animate = false;                                
+00467                         }
+00468                         else
+00469                         {
+00470                                 ps->_LastUpdateDate = trav->CurrentDate;
+00471                         }
+00472                 }
+00473                 else
+00474                 {
+00475                         ps->_LastUpdateDate = trav->CurrentDate;
+00476                 }       
+00477                 ps->_LastUpdateDate = trav->CurrentDate;
+00478                 if (animate)
+00479                 {
+00480                         const CMatrix           &mat= HrcObs->WorldMatrix;       
+00481                         ps->setSysMat(mat);
+00482                         ps->setViewMat(trav->ViewMatrix);
+00483                         psm->updateOpacityInfos();
+00484 
+00485                         //ps->setSysMat(psm->getWorldMatrix());
+00486                         nlassert(ps->getScene());       
+00487 
+00488 
+00489                         // setup the number of faces we allow
+00490                         ps->setNumTris((uint) psm->getNumTrianglesAfterLoadBalancing());
+00491 
+00492 
+00493                         // set the global user param that are bypassed
+00494                         nlctassert(MaxPSUserParam < 8); // there should be less than 8 parameters because of mask stored in a byte
+00495                         ps->_BypassGlobalUserParam = psm->_BypassGlobalUserParam;
+00496 
+00497                         // setup system user parameters for parameters that have been touched
+00498                         for (uint k = 0; k < MaxPSUserParam; ++k)
+00499                         {
+00500                                 if (psm->isTouched((uint)CParticleSystemModel::PSParam0 + k))
+00501                                 {
+00502                                         ps->setUserParam(k, psm->_UserParam[k].Value);
+00503                                         psm->clearFlag((uint)CParticleSystemModel::PSParam0 + k);
+00504                                 }
+00505                         }
+00506 
+00507                         if (ps->getAnimType() != CParticleSystem::AnimAlways) // if the animation is always perfomed, then its done by the particle system manager
+00508                         {
+00509                                 if (psm->isAutoGetEllapsedTimeEnabled())
+00510                                 {
+00511                                         psm->setEllapsedTime(ps->getScene()->getEllapsedTime() * psm->getEllapsedTimeRatio());
+00512                                 }
+00513                                 TAnimationTime delay = psm->getEllapsedTime();
+00514                                 // animate particles                            
+00515                                 ps->step(CParticleSystem::Anim, delay);                                 
+00516                         }
+00517                 }
+00518         }               
+00519         
+00520 
+00521         // add a render obs if in cluster & not hidden
+00522         if (psm->_InClusterAndVisible)
+00523         {
+00524                 trav->RenderTrav->addRenderObs(ClipObs->RenderObs);
+00525         }
+00526 }
+00527 
+00528 
+00529 
+00531 // CParticleSystemRenderObs implementation  //
+00533 void    CParticleSystemRenderObs::traverse(IObs *caller)
+00534 {
+00535 
+00536         
+00537 
+00538 /*
+00539         if (!psm->_OutOfFrustum)
+00540         {*/
+00541                 CTransformShapeRenderObs::traverse(caller);
+00542         //}
+00543 }
+00544 
+00545 
+00546 /*
+00547  * CParticleSystemClipObs implementation              
+00548  * IMPORTANT : the Visible attribute is interpreted as 'in traversed clusters'. We need this because we want
+00549  * to know when a p.s is in clusters, but not visible. As a matter of fact we may need to have system that are animated
+00550  * as long as in cluster, but not visible. 
+00551  */
+00552         
+00553 void    CParticleSystemClipObs::traverse(IObs *caller)
+00554 {
+00555         H_AUTO ( NL3D_Particles_Clip );
+00556 
+00557 //          CTransformClipObs::traverse(caller);
+00558                 traverseSons();
+00559                 nlassert(!caller || dynamic_cast<IBaseClipObs*>(caller));
+00560                 CParticleSystemModel            *m= (CParticleSystemModel*)Model;       
+00561                 if (m->_Invalidated) return;            
+00562                 CClipTrav                       *trav= (CClipTrav*)Trav;
+00563                 
+00564 
+00565                 if (Date != trav->CurrentDate) 
+00566                 {
+00567                         m->_InsertedInVisibleList = false;
+00568                         m->_InClusterAndVisible = false;
+00569                         Date = trav->CurrentDate;
+00570                 }
+00571                 if (m->_InClusterAndVisible) return; // already visible
+00572                 
+00573 
+00574                 CParticleSystem *ps = m->_ParticleSystem;
+00575 
+00576                 
+00577                 if (ps) // system instanciated
+00578                 {
+00579                         // if there are no more particles, no need to even clip..
+00580                         if (checkDestroyCondition(ps, m)) return;
+00581                 }
+00582                 
+00583                 // special case : system sticked to a skeleton
+00584                 if( ((CTransformHrcObs*)HrcObs)->_AncestorSkeletonModel!=NULL )
+00585                 {
+00586                         bool visible = ((CTransformHrcObs*)HrcObs)->_AncestorSkeletonModel->isClipVisible();
+00587                         // Special test: if we are sticked to a skeletonModel, and if we are still visible, maybe we don't have to
+00588                         if(Visible && m->_FatherSkeletonModel)
+00589                         {
+00590                                 CClipTrav               *clipTrav= NLMISC::safe_cast<CClipTrav*>(Trav);
+00591 
+00592                                 // if our skeletonModel father is displayed with a Lod, maybe we are not to be displayed
+00593                                 if(m->_FatherSkeletonModel->isDisplayedAsLodCharacter())
+00594                                 {
+00595                                         // We are visible only if we where sticked to the skeleton with forceCLod==true.
+00596                                         // This is also true if we are actually a skeletonModel
+00597                                         if(!m->getShowWhenLODSticked())
+00598                                                 // otherWise we are not visible. eg: this is the case of skins and some sticked object
+00599                                                 visible = false;
+00600                                 }
+00601                         }
+00602                         //
+00603                         if (visible)
+00604                         {                               
+00605                                 Visible = true;
+00606                                 insertInVisibleList();                          
+00607                                 m->_InClusterAndVisible = true;
+00608                                 return;
+00609                         }
+00610                         else // not visible, may need animation however..
+00611                         {                               
+00612                                 if (!ps) // no resc allocated
+00613                                 {
+00614                                         CParticleSystemShape            *pss= NLMISC::safe_cast<CParticleSystemShape *>((IShape *)m->Shape);
+00615                                         nlassert(pss);
+00616                                         // invalidate the system if too far
+00617                                         const CVector pos = m->getMatrix().getPos();            
+00618                                         const CVector d = pos - trav->CamPos;
+00619                                         if (d * d > pss->_MaxViewDist * pss->_MaxViewDist) 
+00620                                         {
+00621                                                 Visible = false;                                        
+00622                                                 if (pss->_DestroyModelWhenOutOfRange)
+00623                                                 {
+00624                                                         m->_Invalidated = true;                                 
+00625                                                 }                                                                                                       
+00626                                         }
+00627                                 }
+00628                                 else
+00629                                 {                               
+00630                                         // NB : The test to see wether the system is not too far is performed by the particle system manager                                    
+00631                                         if (!m->_EditionMode)
+00632                                         {
+00633                                                 Visible = true;     // system near, but maybe not in cluster..
+00634                                                 insertInVisibleList();
+00635                                         }                                       
+00636                                 }
+00637                         }
+00638                         return;                         
+00639                 }
+00640 
+00641 
+00642                 //
+00643                 const std::vector<CPlane>       &pyramid= trav->WorldPyramid;   
+00648                 // now the pyramid is directly expressed in the world
+00649                 const CMatrix           &mat= HrcObs->WorldMatrix;       
+00650 
+00651                                 
+00652                 // Transform the pyramid in Object space.
+00653 
+00654                 
+00655                 if(!ps) 
+00656                 {
+00657                         CParticleSystemShape            *pss= NLMISC::safe_cast<CParticleSystemShape *>((IShape *)m->Shape);
+00658                         nlassert(pss);
+00659 
+00660                         // the system wasn't present the last time, we use its center to see if it's back in the view frustum,
+00661                         // or if it is near enough.
+00662                         // if this is the case, we say it isn't clipped, so it will be reinstanciated from the shape
+00663                         // during the DetailAnimTraversal
+00664 
+00665                         const CVector pos = m->getMatrix().getPos();
+00666                 
+00667                         const CVector d = pos - trav->CamPos;
+00668 
+00669 
+00670                         // check wether system not too far              
+00671                         if (d * d > pss->_MaxViewDist * pss->_MaxViewDist) 
+00672                         {
+00673                                 Visible = false;                                        
+00674                                 if (pss->_DestroyModelWhenOutOfRange)
+00675                                 {
+00676                                         m->_Invalidated = true;                                 
+00677                                 }                                                       
+00678                                 return;
+00679                         }               
+00680 
+00681                         // test the shape to see wether we have a precomputed bbox
+00682                         if (!pss->_UsePrecomputedBBox)
+00683                         {                                                               
+00686                                 for(sint i=0; i < (sint)pyramid.size(); i++)
+00687                                 {                                       
+00688                                         if ( (pyramid[i]   *  mat  ).d > 0.0f )  // in its basis, the system is at the center
+00689 
+00690                                         {                                               
+00691                                                 Visible = true;
+00692                                                 insertInVisibleList();
+00693                                                 return;
+00694                                         }
+00695                                 }       
+00696                                 
+00697                                 Visible = true;
+00698                                 insertInVisibleList();                          
+00699                                 m->_InClusterAndVisible = true;
+00700                                 return;                                         
+00701                         }
+00702                         else
+00703                         {
+00706                                 for(sint i=0; i < (sint)pyramid.size(); i++)
+00707                                 {                                       
+00708                                         if ( !pss->_PrecomputedBBox.clipBack(pyramid[i]  * mat  ) ) 
+00709                                         {
+00710                                                 
+00711                                                 Visible = true;
+00712                                                 insertInVisibleList();
+00713                                                 return;                                 
+00714                                         }
+00715                                 }                       
+00716 
+00717                                 Visible = true;
+00718                                 insertInVisibleList();
+00719                                 m->_InClusterAndVisible = true;
+00720                                 return;
+00721                                 
+00722                         }
+00723                 }
+00724                 
+00725                 //=========================================================================================================
+00726                 // the system is already instanciated
+00727                 
+00728                 nlassert(ps);                                           
+00730                 if (m->checkAgainstPyramid(pyramid) == false)
+00731                 {
+00732                         if (!m->_EditionMode)
+00733                         {
+00734                                 // system near, but maybe not in cluster..      
+00735                                 Visible = true;
+00736                                 insertInVisibleList();
+00737                         }                               
+00738                         return;
+00739                 }
+00740                 
+00741 
+00742                 Visible = true;
+00743                 insertInVisibleList();
+00744                 m->_InClusterAndVisible = true;
+00745 }
+00746 
+00747 //===================================================================
+00748 bool CParticleSystemClipObs::checkDestroyCondition(CParticleSystem *ps, CParticleSystemModel *m)
+00749 {
+00750         nlassert(ps && m);
+00751         if (!m->_EditionMode)
+00752         {
+00756                 if (ps->getAnimType() != CParticleSystem::AnimAlways)
+00757                 {
+00758                         // test deletion condition (no more particle, no more particle and emitters)
+00759                         if (ps->getDestroyCondition() != CParticleSystem::none)
+00760                         {
+00761                                 if (ps->getSystemDate() > ps->getDelayBeforeDeathConditionTest())
+00762                                 {
+00763                                         switch (ps->getDestroyCondition())
+00764                                         {
+00765                                                 case CParticleSystem::noMoreParticles:
+00766                                                         if (!ps->hasParticles())
+00767                                                         {                                                       
+00768                                                                 m->releaseRscAndInvalidate();
+00769                                                                 return true;
+00770                                                         }
+00771                                                         break;
+00772                                                 case CParticleSystem::noMoreParticlesAndEmitters:
+00773                                                         if (!ps->hasParticles() && !ps->hasEmitters())
+00774                                                         {
+00775                                                                 m->releaseRscAndInvalidate();
+00776                                                                 return true;
+00777                                                         }
+00778                                                         break;
+00779                                                 default: break;
+00780                                         }
+00781                                 }
+00782                         }
+00783                 }
+00784         }
+00785         return false;
+00786 }
+00787 
+00788 //===================================================================
+00789 void CParticleSystemModel::bypassGlobalUserParamValue(uint userParamIndex,bool byPass /*=true*/)
+00790 {
+00791         nlctassert(MaxPSUserParam < 8); // there should be less than 8 parameters because of mask stored in a byte
+00792         nlassert(userParamIndex < MaxPSUserParam);
+00793         if (byPass) _BypassGlobalUserParam |= (1 << userParamIndex);
+00794         else _BypassGlobalUserParam &= ~(1 << userParamIndex);
+00795 }
+00796 
+00797 //===================================================================
+00798 bool CParticleSystemModel::isGlobalUserParamValueBypassed(uint userParamIndex) const
+00799 {
+00800         nlctassert(MaxPSUserParam < 8); // there should be less than 8 parameters because of mask stored in a byte
+00801         nlassert(userParamIndex < MaxPSUserParam);
+00802         return (_BypassGlobalUserParam & (1 << userParamIndex)) != 0;
+00803 }
+00804 
+00805 
+00806 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1