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/particle__system_8cpp-source.html | 1046 ++++++++++++++++++++ 1 file changed, 1046 insertions(+) create mode 100644 docs/doxygen/nel/particle__system_8cpp-source.html (limited to 'docs/doxygen/nel/particle__system_8cpp-source.html') diff --git a/docs/doxygen/nel/particle__system_8cpp-source.html b/docs/doxygen/nel/particle__system_8cpp-source.html new file mode 100644 index 00000000..e0b36fe4 --- /dev/null +++ b/docs/doxygen/nel/particle__system_8cpp-source.html @@ -0,0 +1,1046 @@ + + + + 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.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 "3d/particle_system.h"
+00029 #include "3d/ps_located.h"
+00030 #include "3d/driver.h"
+00031 #include "3d/vertex_buffer.h"
+00032 #include "3d/material.h"
+00033 #include "3d/primitive_block.h"
+00034 #include "3d/nelu.h"
+00035 #include "3d/ps_util.h"
+00036 #include "3d/ps_particle.h"
+00037 #include "3d/ps_sound.h"
+00038 #include "3d/particle_system_shape.h"
+00039 #include "nel/misc/aabbox.h"
+00040 #include "nel/misc/file.h"
+00041 #include "nel/misc/stream.h"
+00042 
+00043 
+00044 
+00045 
+00046 namespace NL3D 
+00047 {
+00048 
+00049 uint32                                                                          CParticleSystem::NbParticlesDrawn = 0;
+00050 UPSSoundServer *                                                        CParticleSystem::_SoundServer = NULL;
+00051 CParticleSystem::TGlobalValuesMap                       CParticleSystem::_GlobalValuesMap;
+00052 CParticleSystem::TGlobalVectorValuesMap         CParticleSystem::_GlobalVectorValuesMap;
+00053 
+00054 
+00056 // CPaticleSystem implementation //
+00058 
+00059 
+00061 const float PSDefaultMaxViewDist = 300.f;
+00062 
+00063 /*
+00064  * Constructor
+00065  */
+00066 CParticleSystem::CParticleSystem() : _Driver(NULL),
+00067                                                                          _FontGenerator(NULL),
+00068                                                                          _FontManager(NULL),
+00069                                                                          _Date(0),
+00070                                                                          _LastUpdateDate(-1),
+00071                                                                          _CurrEditedElementLocated(NULL),
+00072                                                                          _CurrEditedElementIndex(0),
+00073                                                                          _Scene(NULL),
+00074                                                                          _TimeThreshold(0.15f),
+00075                                                                          _SystemDate(0.f),
+00076                                                                          _MaxNbIntegrations(2),                                                                  
+00077                                                                          _LODRatio(0.5f),                                                                        
+00078                                                                          _OneMinusCurrentLODRatio(0),
+00079                                                                          _MaxViewDist(PSDefaultMaxViewDist),
+00080                                                                          _InvMaxViewDist(1.f / PSDefaultMaxViewDist),
+00081                                                                          _InvCurrentViewDist(1.f / PSDefaultMaxViewDist),
+00082                                                                          _DieCondition(none),
+00083                                                                          _DelayBeforeDieTest(0.2f),                                                                                                                                             
+00084                                                                          _MaxNumFacesWanted(0),
+00085                                                                          _AnimType(AnimInCluster),
+00086                                                                          _UserParamGlobalValue(NULL),
+00087                                                                          _BypassGlobalUserParam(0),
+00088                                                                          _PresetBehaviour(UserBehaviour),                                                                        
+00089                                                                          _AutoLODStartDistPercent(0.3f),
+00090                                                                          _AutoLODDegradationExponent(1),                                                                                                                                                 
+00091                                                                          _ColorAttenuationScheme(NULL),
+00092                                                                          _GlobalColor(NLMISC::CRGBA::White),
+00093                                                                          _ComputeBBox(true),
+00094                                                                          _BBoxTouched(true),
+00095                                                                          _AccurateIntegration(true),
+00096                                                                          _CanSlowDown(true),
+00097                                                                          _DestroyModelWhenOutOfRange(false),
+00098                                                                          _DestroyWhenOutOfFrustum(false),
+00099                                                                          _Sharing(false),
+00100                                                                          _AutoLOD(false),
+00101                                                                          _KeepEllapsedTimeForLifeUpdate(false),
+00102                                                                          _AutoLODSkipParticles(false),
+00103                                                                          _EnableLoadBalancing(true),
+00104                                                                          _InverseEllapsedTime(0.f),
+00105                                                                          _CurrentDeltaPos(NLMISC::CVector::Null),
+00106                                                                          _DeltaPos(NLMISC::CVector::Null)
+00107 
+00108 {
+00109         std::fill(_UserParam, _UserParam + MaxPSUserParam, 0);  
+00110 }
+00111 
+00112 
+00115 void CParticleSystem::stopSound()
+00116 {
+00117         for (uint k = 0; k < this->getNbProcess(); ++k)
+00118         {
+00119                 CPSLocated *psl = dynamic_cast<NL3D::CPSLocated *>(this->getProcess(k));
+00120                 if (psl)
+00121                 {
+00122                         for (uint l = 0; l < psl->getNbBoundObjects(); ++l)
+00123                         {
+00124                                 if (psl->getBoundObject(l)->getType() == PSSound)
+00125                                 {
+00126                                         static_cast<CPSSound *>(psl->getBoundObject(l))->stopSound();
+00127 
+00128                                 }
+00129                         }
+00130                 }
+00131         }       
+00132 }
+00133 
+00135 void CParticleSystem::reactivateSound()
+00136 {
+00137         for (uint k = 0; k < this->getNbProcess(); ++k)
+00138         {
+00139                 CPSLocated *psl = dynamic_cast<NL3D::CPSLocated *>(this->getProcess(k));
+00140                 if (psl)
+00141                 {
+00142                         for (uint l = 0; l < psl->getNbBoundObjects(); ++l)
+00143                         {
+00144                                 if (psl->getBoundObject(l)->getType() == NL3D::PSSound)
+00145                                 {
+00146                                         static_cast<CPSSound *>(psl->getBoundObject(l))->reactivateSound();
+00147                                 }
+00148                         }
+00149                 }
+00150         }
+00151 }
+00152 
+00153 
+00155 void CParticleSystem::enableLoadBalancing(bool enabled /*=true*/)
+00156 {
+00157         if (enabled)
+00158         {
+00159                 notifyMaxNumFacesChanged();
+00160         }
+00161         _EnableLoadBalancing = enabled;
+00162 }
+00163 
+00165 void CParticleSystem::notifyMaxNumFacesChanged(void)
+00166 {
+00167         if (!_EnableLoadBalancing) return;
+00168         _MaxNumFacesWanted = 0; 
+00169         for (TProcessVect::iterator it = _ProcessVect.begin(); it != _ProcessVect.end(); ++it)
+00170         {                               
+00171                 _MaxNumFacesWanted += (*it)->querryMaxWantedNumFaces();
+00172         }
+00173 }
+00174 
+00175 
+00177 float CParticleSystem::getWantedNumTris(float dist)
+00178 {
+00179         if (!_EnableLoadBalancing) return 0; // no contribution to the load balancing
+00180         if (dist > _MaxViewDist) return 0;
+00181         float retValue = ((1.f - dist * _InvMaxViewDist) * _MaxNumFacesWanted); 
+00183         return retValue;
+00184 }
+00185 
+00186 
+00188 void CParticleSystem::setNumTris(uint numFaces)
+00189 {
+00190         if (_EnableLoadBalancing)
+00191         {       
+00192                 float modelDist = (_SysMat.getPos() - _InvertedViewMat.getPos()).norm();
+00193                 /*uint numFaceWanted = (uint) getWantedNumTris(modelDist);*/
+00194 
+00195                 const float epsilon = 10E-5f;
+00196 
+00197 
+00198                 uint wantedNumTri = (uint) getWantedNumTris(modelDist);
+00199                 if (numFaces >= wantedNumTri || wantedNumTri == 0 || _MaxNumFacesWanted == 0 || modelDist < epsilon)
+00200                 { 
+00201                         _InvCurrentViewDist = _InvMaxViewDist;
+00202                 }
+00203                 else
+00204                 {
+00205                         
+00206                         _InvCurrentViewDist = (_MaxNumFacesWanted - numFaces) / ( _MaxNumFacesWanted * modelDist);
+00207                 }
+00208         }
+00209         else
+00210         {
+00211                 // always take full detail when there's no load balancing
+00212                 _InvCurrentViewDist = _InvMaxViewDist;
+00213         }
+00214 }
+00215 
+00216 
+00219 CParticleSystem::~CParticleSystem()
+00220 {
+00221         for (TProcessVect::iterator it = _ProcessVect.begin(); it != _ProcessVect.end(); ++it)
+00222         {
+00223                 delete *it;
+00224         }
+00225         delete _ColorAttenuationScheme;
+00226         delete _UserParamGlobalValue;
+00227 }
+00228 
+00230 void CParticleSystem::setViewMat(const NLMISC::CMatrix &m)
+00231 {
+00232         _ViewMat = m;
+00233         _InvertedViewMat = m.inverted();
+00234 }                               
+00235 
+00237 bool CParticleSystem::hasEmitters(void) const
+00238 {
+00239         for (TProcessVect::const_iterator it = _ProcessVect.begin(); it != _ProcessVect.end(); ++it)
+00240         {
+00241                 if ((*it)->hasEmitters()) return true;
+00242         }
+00243         return false;
+00244 }
+00245 
+00247 bool CParticleSystem::hasParticles(void) const
+00248 {
+00249         for (TProcessVect::const_iterator it = _ProcessVect.begin(); it != _ProcessVect.end(); ++it)
+00250         {
+00251                 if ((*it)->hasParticles()) return true;
+00252         }
+00253         return false;
+00254 }
+00255 
+00257 void CParticleSystem::stepLocated(TPSProcessPass pass, TAnimationTime et, TAnimationTime realEt)
+00258 {       
+00259         for (TProcessVect::iterator it = _ProcessVect.begin(); it != _ProcessVect.end(); ++it)
+00260         {
+00261                 (*it)->step(pass, et, realEt);
+00262         }       
+00263 }
+00264 
+00265 
+00267 inline void CParticleSystem::updateLODRatio()
+00268 {
+00269         // temp
+00270         CVector sysPos = _SysMat.getPos();
+00271         CVector obsPos = _InvertedViewMat.getPos();
+00272         const CVector d = _SysMat.getPos() - _InvertedViewMat.getPos();         
+00273         _OneMinusCurrentLODRatio = 1.f - (d.norm() * _InvCurrentViewDist);
+00274         NLMISC::clamp(_OneMinusCurrentLODRatio, 0.f, 1.f);
+00275 }
+00276 
+00278 inline void CParticleSystem::updateColor()
+00279 {
+00280         if (_ColorAttenuationScheme)
+00281         {
+00282                 float ratio = 1.00f - _OneMinusCurrentLODRatio;
+00283                 _GlobalColor =  _ColorAttenuationScheme->get(ratio > 0.f ? ratio : 0.f);
+00284         }
+00285 }
+00286 
+00287 
+00288 /*
+00289 static void displaySysPos(IDriver *drv, const CVector &pos, CRGBA col)
+00290 {
+00291         if (!drv) return;       
+00292         drv->setupModelMatrix(CMatrix::Identity);
+00293         CPSUtil::displayArrow(drv, pos, CVector::K, 1.f, CRGBA::White, col);
+00294 }
+00295 */
+00296 
+00298 void CParticleSystem::step(TPass pass, TAnimationTime ellapsedTime)
+00299 {               
+00300         switch (pass)
+00301         {
+00302                 case SolidRender:
+00304                         if (_Sharing)
+00305                         {
+00306                                 updateLODRatio();
+00307                         }
+00308                         // update time
+00309                         ++_Date;        
+00310                         // update global color
+00311                         updateColor();
+00312                         stepLocated(PSSolidRender, ellapsedTime, ellapsedTime);
+00313 
+00314                 break;
+00315                 case BlendRender:                       
+00317                         if (_Sharing)
+00318                         {
+00319                                 updateLODRatio();
+00320                         }
+00321                         // update time
+00322                         ++_Date; 
+00323                         // update global color
+00324                         updateColor();                  
+00325                         stepLocated(PSBlendRender, ellapsedTime, ellapsedTime);
+00326                 break;
+00327                 case ToolRender:
+00328                         stepLocated(PSToolRender, ellapsedTime, ellapsedTime);
+00329                 break;
+00330                 case Anim:
+00331                 {
+00332                         // update user param from global value if needed, unless this behaviour is bypassed has indicated by a flag in _BypassGlobalUserParam
+00333                         if (_UserParamGlobalValue)
+00334                         {
+00335                                 nlctassert(MaxPSUserParam < 8); // there should be less than 8 parameters because of mask stored in a byte                      
+00336                                 uint8 bypassMask = 1;
+00337                                 for(uint k = 0; k < MaxPSUserParam; ++k)
+00338                                 {
+00339                                         if (_UserParamGlobalValue[k] && !(_BypassGlobalUserParam & bypassMask)) // if there is a global value for this param and if the update is not bypassed
+00340                                         {
+00341                                                 _UserParam[k] = _UserParamGlobalValue[k]->second;                                               
+00342                                         }
+00343                                         bypassMask <<= 1;
+00344                                 }
+00345                         }
+00346                         //
+00347                         _BBoxTouched = true;
+00348                         TAnimationTime et = ellapsedTime;
+00349                         uint nbPass = 1;
+00350                         if (_AccurateIntegration)
+00351                         {
+00352                                 if (et > _TimeThreshold)
+00353                                 {
+00354                                         nbPass = (uint32) ceilf(et / _TimeThreshold);
+00355                                         if (nbPass > _MaxNbIntegrations)
+00356                                         { 
+00357                                                 nbPass = _MaxNbIntegrations;
+00358                                                 if (_CanSlowDown)
+00359                                                 {
+00360                                                         et = _TimeThreshold;
+00361                                                         nlassert(_TimeThreshold != 0);
+00362                                                         _InverseEllapsedTime = 1.f / (_TimeThreshold * nbPass);
+00363                                                 }
+00364                                                 else
+00365                                                 {
+00366                                                         et = ellapsedTime / nbPass;
+00367                                                         _InverseEllapsedTime = ellapsedTime != 0 ? 1.f / ellapsedTime : 0.f;
+00368                                                 }                                               
+00369                                         }
+00370                                         else
+00371                                         {
+00372                                                 et = ellapsedTime / nbPass;
+00373                                                 _InverseEllapsedTime = ellapsedTime != 0 ? 1.f / ellapsedTime : 0.f;
+00374                                         }
+00375                                 }
+00376                                 else
+00377                                 {
+00378                                         _InverseEllapsedTime = ellapsedTime != 0 ? 1.f / ellapsedTime : 0.f;
+00379                                 }
+00380                         }
+00381                         else
+00382                         {
+00383                                 _InverseEllapsedTime = ellapsedTime != 0 ? 1.f / ellapsedTime : 0.f;
+00384                         }
+00385                         updateLODRatio();
+00386 
+00387                         // set start position. Used by emitters that emit from Local basis to world
+00388                         _CurrentDeltaPos = -_DeltaPos;
+00389                         //displaySysPos(_Driver, _CurrentDeltaPos + _OldSysMat.getPos(), CRGBA::Red);
+00390                         // process passes
+00391                         float realEt = _KeepEllapsedTimeForLifeUpdate ? (ellapsedTime / nbPass)
+00392                                                                                                                   : et;                 
+00393                         do
+00394                         {                                       
+00395                                 // position of the system at the end of the integration
+00396                                 _CurrentDeltaPos += _DeltaPos * (et * _InverseEllapsedTime);
+00397                                 //displaySysPos(_Driver, _CurrentDeltaPos + _OldSysMat.getPos(), CRGBA::Blue);
+00398                                 // the order of the following is important...
+00399                                 stepLocated(PSCollision, et,  realEt);
+00400                                 for (TProcessVect::iterator it = _ProcessVect.begin(); it != _ProcessVect.end(); ++it)
+00401                                 {
+00402                                         (*it)->updateLife(realEt);
+00403                                         (*it)->step(PSMotion, et, realEt);                                      
+00404                                 }
+00405                                 _SystemDate += realEt;
+00406                                 stepLocated(PSEmit, et,  realEt);                               
+00407                         }
+00408                         while (--nbPass);
+00409                         
+00410                         // perform parametric motion if present
+00411                         for (TProcessVect::iterator it = _ProcessVect.begin(); it != _ProcessVect.end(); ++it)
+00412                         {
+00413                                 if ((*it)->isParametricMotionEnabled()) (*it)->performParametricMotion(_SystemDate, ellapsedTime, realEt);
+00414                         }                               
+00415                         
+00416                 }
+00417         }                       
+00418 }
+00419 
+00420 
+00421 
+00423 void CParticleSystem::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
+00424 {               
+00425         sint version =  f.serialVersion(12);
+00426         // version 12: global userParams
+00427         // version 11: enable load balancing flag 
+00428         // version 9: Sharing flag added
+00429         //            Auto-lod parameters
+00430         //            New integration flag
+00431         //                        Global color attenuation
+00432         // version 8: Replaced the attribute '_PerformMotionWhenOutOfFrustum' by a _AnimType field which allow more precise control
+00433 
+00434         //f.serial(_ViewMat);
+00435         f.serial(_SysMat);
+00436         f.serial(_Date);
+00437         if (f.isReading())
+00438         {
+00439                 delete _ColorAttenuationScheme;
+00440                 // delete previous multimap
+00441                 _LBMap.clear();
+00442                 // delete previously attached process
+00443                 for (TProcessVect::iterator it = _ProcessVect.begin(); it != _ProcessVect.end(); ++it)
+00444                 {
+00445                         delete (*it);
+00446                 }
+00447 
+00448                 _ProcessVect.clear();
+00449 
+00450                 f.serialContPolyPtr(_ProcessVect);              
+00451         
+00452                 _InvSysMat = _SysMat.inverted();
+00453                 _FontGenerator = NULL;
+00454                 _FontManager = NULL;
+00455                 delete _UserParamGlobalValue;
+00456                 _UserParamGlobalValue = NULL;
+00457                 _BypassGlobalUserParam = 0;
+00458         }
+00459         else
+00460         {
+00461                 f.serialContPolyPtr(_ProcessVect);      
+00462         }
+00463         
+00464         if (version > 1) // name of the system
+00465         {
+00466                 f.serial(_Name);
+00467         }
+00468 
+00469         if (version > 2) // infos about integration, and LOD
+00470         {
+00471                 f.serial(_AccurateIntegration);
+00472                 if (_AccurateIntegration) f.serial(_CanSlowDown, _TimeThreshold, _MaxNbIntegrations);
+00473                 f.serial(_InvMaxViewDist, _LODRatio);   
+00474                 _MaxViewDist = 1.f / _InvMaxViewDist;
+00475                 _InvCurrentViewDist = _InvMaxViewDist;
+00476         }
+00477 
+00478         if (version > 3) // tell wether the system must compute his bbox, hold a precomputed bbox
+00479         {
+00480                 f.serial(_ComputeBBox);
+00481                 if (!_ComputeBBox)
+00482                 {
+00483                         f.serial(_PreComputedBBox);
+00484                 }
+00485         }
+00486 
+00487         if (version > 4) // lifetime informations
+00488         {
+00489                 f.serial(_DestroyModelWhenOutOfRange);
+00490                 f.serialEnum(_DieCondition);
+00491                 if (_DieCondition != none)
+00492                 {
+00493                         f.serial(_DelayBeforeDieTest);
+00494                 }
+00495         }       
+00496 
+00497         if (version > 5)
+00498         {
+00499                 f.serial(_DestroyWhenOutOfFrustum);
+00500         }
+00501 
+00502         if (version > 6 && version < 8)
+00503         {
+00504                 bool performMotionWOOF;
+00505                 if (f.isReading())
+00506                 {
+00507                         f.serial(performMotionWOOF);
+00508                         performMotionWhenOutOfFrustum(performMotionWOOF);
+00509                 }
+00510                 else
+00511                 {
+00512                         performMotionWOOF = doesPerformMotionWhenOutOfFrustum();
+00513                         f.serial(performMotionWOOF);
+00514                 }
+00515         }
+00516 
+00517         if (version > 7)
+00518         {
+00519                 f.serialEnum(_AnimType);
+00520                 f.serialEnum(_PresetBehaviour);
+00521         }
+00522 
+00523         if (version > 8)
+00524         {
+00525                 f.serial(_Sharing);
+00526                 f.serial(_AutoLOD);
+00527                 if (_AutoLOD)
+00528                 {
+00529                         f.serial(_AutoLODStartDistPercent, _AutoLODDegradationExponent);
+00530                         f.serial(_AutoLODSkipParticles);
+00531                 }
+00532                 f.serial(_KeepEllapsedTimeForLifeUpdate);
+00533                 f.serialPolyPtr(_ColorAttenuationScheme);
+00534         }
+00535 
+00536         if (version >= 11)
+00537         {
+00538                 f.serial(_EnableLoadBalancing);
+00539         }
+00540 
+00541         if (version >= 12)
+00542         {
+00543                 // serial infos about global user params
+00544                 nlctassert(MaxPSUserParam < 8); // In this version mask of used global user params are stored in a byte..               
+00545                 if (f.isReading())
+00546                 {                       
+00547                         uint8 mask;
+00548                         f.serial(mask);
+00549                         if (mask)
+00550                         {               
+00551                                 std::string globalValueName;
+00552                                 uint8 testMask = 1;
+00553                                 for(uint k = 0; k < MaxPSUserParam; ++k)
+00554                                 {                                       
+00555                                         if (mask & testMask)
+00556                                         {                                               
+00557                                                 f.serial(globalValueName);
+00558                                                 bindGlobalValueToUserParam(globalValueName.c_str(), k);
+00559                                         }
+00560                                         testMask <<= 1;
+00561                                 }
+00562                         }
+00563                 }
+00564                 else
+00565                 {
+00566                         uint8 mask = 0;
+00567                         if (_UserParamGlobalValue)
+00568                         {
+00569                                 for(uint k = 0; k < MaxPSUserParam; ++k)
+00570                                 {
+00571                                         if (_UserParamGlobalValue[k]) mask |= (1 << k);
+00572                                 }
+00573                         }
+00574                         f.serial(mask);
+00575                         if (_UserParamGlobalValue)
+00576                         {
+00577                                 for(uint k = 0; k < MaxPSUserParam; ++k)
+00578                                 {                               
+00579                                         if (_UserParamGlobalValue[k]) 
+00580                                         {
+00581                                                 std::string valueName = _UserParamGlobalValue[k]->first;        
+00582                                                 f.serial(valueName);
+00583                                         }
+00584                                 }
+00585                         }
+00586                 }               
+00587         }       
+00588 
+00589         if (f.isReading())
+00590         {
+00591                 notifyMaxNumFacesChanged();
+00592         }
+00593 }
+00594 
+00595 
+00597 void CParticleSystem::attach(CParticleSystemProcess *ptr)
+00598 {
+00599         nlassert(std::find(_ProcessVect.begin(), _ProcessVect.end(), ptr) == _ProcessVect.end() );
+00600         //nlassert(ptr->getOwner() == NULL); // deja attache a un autre systeme
+00601         _ProcessVect.push_back(ptr);
+00602         ptr->setOwner(this);
+00603         notifyMaxNumFacesChanged();
+00604 }
+00605 
+00607 void CParticleSystem::remove(CParticleSystemProcess *ptr)
+00608 {
+00609         TProcessVect::iterator it = std::find(_ProcessVect.begin(), _ProcessVect.end(), ptr);
+00610         nlassert(it != _ProcessVect.end() );    
+00611         _ProcessVect.erase(it);
+00612         delete ptr;
+00613 }
+00614 
+00616 void CParticleSystem::computeBBox(NLMISC::CAABBox &aabbox)
+00617 {
+00618         if (!_ComputeBBox || !_BBoxTouched)
+00619         {
+00620                 aabbox = _PreComputedBBox;
+00621                 return;
+00622         }
+00623 
+00624         bool foundOne = false;
+00625         NLMISC::CAABBox tmpBox;
+00626         for (TProcessVect::const_iterator it = _ProcessVect.begin(); it != _ProcessVect.end(); ++it)
+00627         {
+00628                 if ((*it)->computeBBox(tmpBox))
+00629                 {
+00630                         if (!(*it)->isInSystemBasis())
+00631                         {
+00632                                 // rotate the aabbox so that it is in the correct basis
+00633                                 tmpBox = NLMISC::CAABBox::transformAABBox(_InvSysMat, tmpBox);
+00634                         }
+00635                         if (foundOne)
+00636                         {
+00637                                 aabbox = NLMISC::CAABBox::computeAABBoxUnion(aabbox, tmpBox);
+00638                         }
+00639                         else
+00640                         {
+00641                                 aabbox = tmpBox;
+00642                                 foundOne = true;
+00643                         }
+00644                 }
+00645         }
+00646 
+00647         if (!foundOne)
+00648         {
+00649                 aabbox.setCenter(NLMISC::CVector::Null);
+00650                 aabbox.setHalfSize(NLMISC::CVector::Null);
+00651         }
+00652         
+00653         _BBoxTouched = false;
+00654         _PreComputedBBox = aabbox;
+00655 }
+00656 
+00658 void CParticleSystem::setSysMat(const CMatrix &m)
+00659 {
+00660         if (_SystemDate != 0.f)
+00661         {       
+00662                 _OldSysMat = _SysMat; // _sysMat is relevant if at least one call to setSysMat has been performed before
+00663                 _DeltaPos  = m.getPos() -  _OldSysMat.getPos();
+00664         }
+00665         else
+00666         {
+00667                 _DeltaPos = NLMISC::CVector::Null;
+00668                 _OldSysMat = m;
+00669         }
+00670         _SysMat = m;
+00671         _InvSysMat = _SysMat.inverted();
+00672 }
+00673 
+00675 bool CParticleSystem::hasOpaqueObjects(void) const
+00676 {
+00678         for (TProcessVect::const_iterator it = _ProcessVect.begin(); it != _ProcessVect.end(); ++it)
+00679         {
+00680                 if (dynamic_cast<CPSLocated *>(*it))
+00681                 {
+00682                         for (uint k = 0; k < ((CPSLocated *) *it)->getNbBoundObjects(); ++k)
+00683                         {
+00684                                 CPSLocatedBindable *lb = ((CPSLocated *) *it)->getBoundObject(k);
+00685                                 if (lb->getType() == PSParticle)
+00686                                 {
+00687                                         if (((CPSParticle *) lb)->hasOpaqueFaces()) return true;
+00688                                 }
+00689                         }
+00690                 }
+00691         }
+00692         return false;
+00693 }
+00694 
+00696 bool CParticleSystem::hasTransparentObjects(void) const
+00697 {
+00699         for (TProcessVect::const_iterator it = _ProcessVect.begin(); it != _ProcessVect.end(); ++it)
+00700         {
+00701                 if (dynamic_cast<CPSLocated *>(*it))
+00702                 {
+00703                         for (uint k = 0; k < ((CPSLocated *) *it)->getNbBoundObjects(); ++k)
+00704                         {
+00705                                 CPSLocatedBindable *lb = ((CPSLocated *) *it)->getBoundObject(k);
+00706                                 if (lb->getType() == PSParticle)
+00707                                 {
+00708                                         if (((CPSParticle *) lb)->hasTransparentFaces()) return true;
+00709                                 }
+00710                         }
+00711                 }
+00712         }
+00713         return false;
+00714 }
+00715 
+00717 void CParticleSystem::getLODVect(NLMISC::CVector &v, float &offset,  bool systemBasis)
+00718 {
+00719         if (!systemBasis)
+00720         {
+00721                 v = _InvCurrentViewDist * _InvertedViewMat.getJ();
+00722                 offset = - _InvertedViewMat.getPos() * v;
+00723         }
+00724         else
+00725         {
+00726                 const CVector tv = _InvSysMat.mulVector(_InvertedViewMat.getJ());
+00727                 const CVector org = _InvSysMat * _InvertedViewMat.getPos();
+00728                 v = _InvCurrentViewDist * tv;
+00729                 offset = - org * v;
+00730         }
+00731 }
+00732 
+00734 TPSLod CParticleSystem::getLOD(void) const
+00735 {
+00736         const float dist = fabsf(_InvCurrentViewDist * (_SysMat.getPos() - _InvertedViewMat.getPos()) * _InvertedViewMat.getJ());
+00737         return dist > _LODRatio ? PSLod2 : PSLod1;
+00738 }
+00739 
+00740 
+00742 void CParticleSystem::registerLocatedBindableExternID(uint32 id, CPSLocatedBindable *lb)
+00743 {
+00744         nlassert(lb);
+00745         nlassert(lb->getOwner() && lb->getOwner()->getOwner() == this); // the located bindable must belong to that system
+00746         #ifdef NL_DEBUG         
+00747                 // check that this lb hasn't been inserted yet
+00748                 TLBMap::iterator lbd = _LBMap.lower_bound(id), ubd = _LBMap.upper_bound(id);
+00749                 nlassert(std::find(lbd, ubd, TLBMap::value_type (id, lb)) == ubd);
+00750                 nlassert(std::find(lbd, ubd, TLBMap::value_type (id, lb)) == ubd );
+00751 
+00752         #endif
+00753                 _LBMap.insert(TLBMap::value_type (id, lb) );
+00754 }
+00755 
+00757 void CParticleSystem::unregisterLocatedBindableExternID(CPSLocatedBindable *lb)
+00758 {
+00759         nlassert(lb);   
+00760         nlassert(lb->getOwner() && lb->getOwner()->getOwner() == this); // the located bindable must belong to that system
+00761         uint32 id = lb->getExternID();
+00762         if (!id) return;
+00763         TLBMap::iterator lbd = _LBMap.lower_bound(id), ubd = _LBMap.upper_bound(id);
+00764         TLBMap::iterator el = std::find(lbd, ubd, TLBMap::value_type (id, lb));
+00765         nlassert(el != ubd); 
+00766         _LBMap.erase(el);
+00767 }
+00768 
+00770 uint CParticleSystem::getNumLocatedBindableByExternID(uint32 id) const
+00771 {
+00772         return _LBMap.count(id);
+00773 }
+00774 
+00776 CPSLocatedBindable *CParticleSystem::getLocatedBindableByExternID(uint32 id, uint index)
+00777 {
+00778         if (index >= _LBMap.count(id))
+00779         {
+00780                 return NULL;
+00781         }
+00782         TLBMap::const_iterator el = _LBMap.lower_bound(id);
+00783         uint left = index;
+00784         while (left--) ++el;
+00785         return  el->second;
+00786 
+00787 }
+00788 
+00790 const CPSLocatedBindable *CParticleSystem::getLocatedBindableByExternID(uint32 id, uint index) const
+00791 {
+00792         if (index >= _LBMap.count(id))
+00793         {
+00794                 return NULL;
+00795         }
+00796         TLBMap::const_iterator el = _LBMap.lower_bound(id);
+00797         uint left = index;
+00798         while (left--) ++el;
+00799         return  el->second;
+00800 }
+00801 
+00803 void CParticleSystem::merge(CParticleSystemShape *pss)
+00804 {
+00805         nlassert(pss);  
+00806         CParticleSystem *duplicate = pss->instanciatePS(*this->_Scene); // duplicate the p.s. to merge
+00807         // now we transfer the located of the duplicated ps to this object...
+00808         for (TProcessVect::iterator it = duplicate->_ProcessVect.begin(); it != duplicate->_ProcessVect.end(); ++it)
+00809         {               
+00810                 attach(*it);            
+00811         }
+00812         duplicate->_ProcessVect.clear();
+00813         delete duplicate;
+00814 }
+00815 
+00817 void CParticleSystem::activatePresetBehaviour(TPresetBehaviour behaviour)
+00818 {
+00819 
+00820         switch(behaviour)
+00821         {
+00822                 case EnvironmentFX:
+00823                         setDestroyModelWhenOutOfRange(false);
+00824                         setDestroyCondition(none);
+00825                         destroyWhenOutOfFrustum(false);
+00826                         setAnimType(AnimVisible);
+00827                 break;
+00828                 case RunningEnvironmentFX:
+00829                         setDestroyModelWhenOutOfRange(false);
+00830                         setDestroyCondition(none);
+00831                         destroyWhenOutOfFrustum(false);
+00832                         setAnimType(AnimInCluster);
+00833                 break;
+00834                 case SpellFX:
+00835                         setDestroyModelWhenOutOfRange(true);
+00836                         setDestroyCondition(noMoreParticles);
+00837                         destroyWhenOutOfFrustum(false);
+00838                         setAnimType(AnimAlways);
+00839                 break;
+00840                 case LoopingSpellFX:
+00841                         setDestroyModelWhenOutOfRange(true);
+00842                         setDestroyCondition(noMoreParticles);
+00843                         destroyWhenOutOfFrustum(false);
+00844                         setAnimType(AnimInCluster);
+00845                 break;
+00846                 case MinorFX:
+00847                         setDestroyModelWhenOutOfRange(true);
+00848                         setDestroyCondition(noMoreParticles);
+00849                         destroyWhenOutOfFrustum(true);
+00850                         setAnimType(AnimVisible);
+00851                 break;          
+00852                 default: break;
+00853         }
+00854         _PresetBehaviour = behaviour;
+00855 }
+00856 
+00857 
+00859 CParticleSystemProcess *CParticleSystem::detach(uint index)
+00860 {
+00861         nlassert(index < _ProcessVect.size());
+00862         CParticleSystemProcess *proc = _ProcessVect[index];     
+00863         // release references other process may have to this system
+00864         for(TProcessVect::iterator it = _ProcessVect.begin(); it != _ProcessVect.end(); ++it)
+00865         {
+00866                 (*it)->releaseRefTo(proc);
+00867         }
+00868         // erase from the vector
+00869         _ProcessVect.erase(_ProcessVect.begin() + index);
+00870         proc->setOwner(NULL);
+00871         // not part of this system any more     
+00872         return proc;
+00873 }
+00874 
+00876 bool CParticleSystem::isProcess(CParticleSystemProcess *process) const
+00877 {
+00878         for(TProcessVect::const_iterator it = _ProcessVect.begin(); it != _ProcessVect.end(); ++it)
+00879         {
+00880                 if (*it == process) return true;
+00881         }
+00882         return false;
+00883 }
+00884 
+00886 uint CParticleSystem::getIndexOf(const CParticleSystemProcess *process) const
+00887 {
+00888         for(uint k = 0; k < _ProcessVect.size(); ++k)
+00889         {
+00890                 if (_ProcessVect[k] == process) return k;
+00891         }
+00892         nlassert(0); // not a process of this system
+00893         return 0; // for warning
+00894 }
+00895 
+00897 uint CParticleSystem::getNumID() const
+00898 {
+00899         return _LBMap.size();
+00900 }
+00901 
+00903 uint32 CParticleSystem::getID(uint index) const
+00904 {
+00905         TLBMap::const_iterator it = _LBMap.begin();
+00906         for(uint k = 0; k < index; ++k)
+00907         {
+00908                 if (it == _LBMap.end()) return 0;
+00909                 ++it;
+00910         }
+00911         return it->first;
+00912 }
+00913 
+00915 void CParticleSystem::getIDs(std::vector<uint32> &dest) const
+00916 {
+00917         dest.resize(_LBMap.size());
+00918         uint k = 0;
+00919         for(TLBMap::const_iterator it = _LBMap.begin(); it != _LBMap.end(); ++it)
+00920         {
+00921                 dest[k] = it->first;
+00922                 ++k;
+00923         }
+00924 }
+00925 
+00927 void CParticleSystem::interpolatePosDelta(NLMISC::CVector &dest,TAnimationTime deltaT)
+00928 {
+00929         dest = _CurrentDeltaPos - (deltaT * _InverseEllapsedTime) * _DeltaPos;
+00930 }
+00931 
+00933 void CParticleSystem::bindGlobalValueToUserParam(const std::string &globalValueName, uint userParamIndex)
+00934 {
+00935         nlassert(userParamIndex < MaxPSUserParam);
+00936         if (globalValueName.empty()) // disable a user param global value
+00937         {
+00938                 if (!_UserParamGlobalValue) return;
+00939                 _UserParamGlobalValue[userParamIndex] = NULL;
+00940                 for(uint k = 0; k < MaxPSUserParam; ++k)
+00941                 {
+00942                         if (_UserParamGlobalValue[k] != NULL) return;
+00943                 }
+00944                 // no more entry used
+00945                 delete _UserParamGlobalValue;
+00946                 _UserParamGlobalValue = NULL;
+00947         }
+00948         else // enable a user param global value
+00949         {
+00950                 if (!_UserParamGlobalValue) 
+00951                 {
+00952                         // no table has been allocated yet, so create one
+00953                         _UserParamGlobalValue = new const TGlobalValuesMap::value_type *[MaxPSUserParam];
+00954                         std::fill(_UserParamGlobalValue, _UserParamGlobalValue + MaxPSUserParam, (TGlobalValuesMap::value_type *) NULL);
+00955                 }
+00956                 // has the global value be created yet ?
+00957                 TGlobalValuesMap::const_iterator it = _GlobalValuesMap.find(globalValueName);
+00958                 if (it != _GlobalValuesMap.end())
+00959                 {
+00960                         // yes, make a reference on it
+00961                         _UserParamGlobalValue[userParamIndex] = &(*it);
+00962                 }
+00963                 else
+00964                 {
+00965                         // create a new entry
+00966                         std::pair<TGlobalValuesMap::iterator, bool> itPair = _GlobalValuesMap.insert(TGlobalValuesMap::value_type(globalValueName, 0.f));
+00967                         _UserParamGlobalValue[userParamIndex] = &(*(itPair.first));
+00968                 }
+00969         }
+00970 }
+00971 
+00973 void CParticleSystem::setGlobalValue(const std::string &name, float value)
+00974 {
+00975         nlassert(!name.empty());
+00976         NLMISC::clamp(value, 0.f, 1.f);
+00977         _GlobalValuesMap[name] = value;
+00978 }
+00979 
+00981 float CParticleSystem::getGlobalValue(const std::string &name)
+00982 {
+00983         TGlobalValuesMap::const_iterator it = _GlobalValuesMap.find(name);
+00984         if (it != _GlobalValuesMap.end()) return it->second;
+00985         return 0.f; // not a known value
+00986 }
+00987 
+00989 std::string CParticleSystem::getGlobalValueName(uint userParamIndex) const
+00990 {
+00991         nlassert(userParamIndex < MaxPSUserParam);
+00992         if (!_UserParamGlobalValue) return "";
+00993         if (!_UserParamGlobalValue[userParamIndex]) return "";
+00994         return _UserParamGlobalValue[userParamIndex]->first;
+00995 }
+00996 
+00998 void CParticleSystem::setGlobalVectorValue(const std::string &name, const NLMISC::CVector &value)
+00999 {
+01000         nlassert(!name.empty());
+01001         _GlobalVectorValuesMap[name] = value;   
+01002 }
+01003 
+01004 
+01006 NLMISC::CVector CParticleSystem::getGlobalVectorValue(const std::string &name)
+01007 {
+01008         nlassert(!name.empty());
+01009         TGlobalVectorValuesMap::const_iterator it = _GlobalVectorValuesMap.find(name);
+01010         if (it != _GlobalVectorValuesMap.end()) return it->second;
+01011         return NLMISC::CVector::Null; // not a known value      
+01012 }
+01013 
+01015 CParticleSystem::CGlobalVectorValueHandle CParticleSystem::getGlobalVectorValueHandle(const std::string &name)
+01016 {
+01017         nlassert(!name.empty());        
+01018         TGlobalVectorValuesMap::iterator it = _GlobalVectorValuesMap.find(name);
+01019         if (it == _GlobalVectorValuesMap.end())
+01020         {
+01021                 it = _GlobalVectorValuesMap.insert(TGlobalVectorValuesMap::value_type(name, NLMISC::CVector::Null)).first;              
+01022         }
+01023         CGlobalVectorValueHandle handle;
+01024         handle._Value = &it->second;    
+01025         handle._Name = &it->first;
+01026         return handle;
+01027 }
+01028 
+01029 
+01030 
+01031 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1