# 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_instance_user.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000, 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_instance_user.h"
00029 #include "3d/particle_system.h"
00030 #include "3d/particle_system_shape.h"
00031 #include "3d/ps_emitter.h"
00032 
00033 
00034 namespace NL3D {
00035 
00036 
00037 //===================================================================
00038 CParticleSystemInstanceUser::CParticleSystemInstanceUser(CScene *scene, IModel *model) 
00039                                                                 : CTransformUser(scene, model), _Invalidated(false)
00040 {
00041         NL3D_MEM_PS_INSTANCE                    
00042         CParticleSystemModel *psm = NLMISC::safe_cast<CParticleSystemModel *>(_Transform);
00043         psm->registerPSModelObserver(this);
00044 }
00045 
00046 //===================================================================
00047 void                            CParticleSystemInstanceUser::getShapeAABBox(NLMISC::CAABBox &bbox) const
00048 {
00049         NL3D_MEM_PS_INSTANCE                    
00050         CParticleSystemModel *psm = NLMISC::safe_cast<CParticleSystemModel *>(_Transform);
00051         psm->getAABBox(bbox);
00052 }
00053 
00054 //===================================================================
00055 CParticleSystemInstanceUser::~CParticleSystemInstanceUser()
00056 {       
00057         NL3D_MEM_PS_INSTANCE                    
00058         CParticleSystemModel *psm = NLMISC::safe_cast<CParticleSystemModel *>(_Transform);
00059         psm->removePSModelObserver(this);               
00060 }
00061 
00062 //===================================================================
00063 bool            CParticleSystemInstanceUser::isSystemPresent(void) const
00064 {
00065         NL3D_MEM_PS_INSTANCE                    
00066         if (_Invalidated) return false; // the system is not even valid
00067         CParticleSystemModel *psm = NLMISC::safe_cast<CParticleSystemModel *>(_Transform);
00068         return psm->getPS() != NULL;
00069 }
00070 
00071 //===================================================================
00072 bool            CParticleSystemInstanceUser::getSystemBBox(NLMISC::CAABBox &bbox)
00073 {
00074         NL3D_MEM_PS_INSTANCE                    
00075         if (_Invalidated) return false;
00076         CParticleSystemModel *psm = NLMISC::safe_cast<CParticleSystemModel *>(_Transform);
00077         if (!psm->getPS()) return false;
00078         psm->getPS()->computeBBox(bbox);
00079         return true;
00080 }
00081 
00082 //===================================================================
00083 void            CParticleSystemInstanceUser::setUserParam(uint index, float value)
00084 {       
00085         if (index >= MaxPSUserParam)
00086         {
00087                 nlwarning("invalid user param index");
00088                 return;
00089         }       
00090         CParticleSystemModel *psm = NLMISC::safe_cast<CParticleSystemModel *>(_Transform);
00091         // psm->getPS()->setUserParam(index, value);
00092         IAnimatedValue *av = psm->getValue(CParticleSystemModel::PSParam0 + index);
00093         NLMISC::safe_cast<CAnimatedValueFloat *>(av)->Value = value;
00094         psm->touch(CParticleSystemModel::PSParam0 + index, CParticleSystemModel::OwnerBit);     
00095 }
00096 
00097 //===================================================================
00098 float           CParticleSystemInstanceUser::getUserParam(uint index) const
00099 {
00100         NL3D_MEM_PS_INSTANCE                    
00101         if (index >= MaxPSUserParam)
00102         {
00103                 nlwarning("invalid user param index");
00104                 return 0.f;
00105         }
00106         CParticleSystemModel *psm = NLMISC::safe_cast<CParticleSystemModel *>(_Transform) ;
00107         //return psm->getPS()->getUserParam(index) ;
00108         IAnimatedValue *av = psm->getValue(CParticleSystemModel::PSParam0 + index);
00109         return NLMISC::safe_cast<CAnimatedValueFloat *>(av)->Value;
00110 }
00111 
00112 //===================================================================
00113 bool            CParticleSystemInstanceUser::isValid(void) const
00114 {
00115         NL3D_MEM_PS_INSTANCE                    
00116         return !_Invalidated;
00117 }
00118 
00119 //===================================================================
00120 void            CParticleSystemInstanceUser::registerPSObserver(IPSObserver *observer)
00121 {
00122         NL3D_MEM_PS_INSTANCE                    
00123         nlassert(!isPSObserver(observer));
00124         _Observers.push_back(observer);
00125 }
00126 
00127 //===================================================================
00128 bool            CParticleSystemInstanceUser::isPSObserver(IPSObserver *observer)
00129 {
00130         NL3D_MEM_PS_INSTANCE                    
00131         return std::find(_Observers.begin(), _Observers.end(), observer) != _Observers.end();
00132 }
00133 
00134 
00135 //===================================================================
00136 void            CParticleSystemInstanceUser::removePSObserver(IPSObserver *observer)
00137 {
00138         NL3D_MEM_PS_INSTANCE                    
00139         nlassert(isPSObserver(observer));
00140         _Observers.erase(std::find(_Observers.begin(), _Observers.end(), observer));
00141 }
00142 
00143 
00144 //===================================================================
00145 void            CParticleSystemInstanceUser::invalidPS(CParticleSystemModel *psm)
00146 {
00147         NL3D_MEM_PS_INSTANCE                    
00148         // the instance pointer is invalid now
00149         _Invalidated = true;
00150         std::vector<IPSObserver *> obserCopy(_Observers.begin(), _Observers.end());
00151         for (std::vector<IPSObserver *>::iterator it = _Observers.begin(); it != _Observers.end(); ++it)
00152         {
00153                 (*it)->systemDestroyed(this);
00154         }
00155 }
00156 
00157 //===================================================================
00158 uint                            CParticleSystemInstanceUser::getNumMaterials() const
00159 {
00160         NL3D_MEM_PS_INSTANCE                    
00161         return 0;
00162 }
00163 
00164 //===================================================================
00165 UInstanceMaterial       &CParticleSystemInstanceUser::getMaterial(uint materialId)
00166 {
00167         NL3D_MEM_PS_INSTANCE                    
00168         nlassert(0); // no material for a particle system
00169 
00170         // return dummy object
00171         return *(UInstanceMaterial *) NULL;
00172 }
00173 
00174 
00175 //===================================================================
00176 static inline uint32 IDToLittleEndian(uint32 input)
00177 {
00178         NL3D_MEM_PS_INSTANCE                    
00179         #ifdef NL_LITTLE_ENDIAN
00180                 return input;
00181         #else
00182                 return ((input & (0xff<<24))>>24)
00183                                 | ((input & (0xff<<16))>>8)
00184                                 | ((input & (0xff<<8))<<8)
00185                                 | ((input & 0xff)<<24);
00186         #endif
00187 }
00188 
00189 //===================================================================
00190 bool    CParticleSystemInstanceUser::emit(uint32 anId, uint quantity)
00191 {
00192         NL3D_MEM_PS_INSTANCE                    
00193         const uint32 id = IDToLittleEndian(anId);
00194         nlassert(isSystemPresent());
00195         CParticleSystem *ps = (NLMISC::safe_cast<CParticleSystemModel *>(_Transform))->getPS();
00196         uint numLb  = ps->getNumLocatedBindableByExternID(id);
00197         if (numLb == 0) return false; // INVALID ID !!
00198         for (uint k = 0; k < numLb; ++k)
00199         {
00200                 CPSLocatedBindable *lb = ps->getLocatedBindableByExternID(id, k);               
00201                 if (lb->getType() == PSEmitter)
00202                 {
00203                         CPSEmitter *e = NLMISC::safe_cast<CPSEmitter *>(lb);
00204                         nlassert(e->getOwner());
00205                         uint nbInstances = e->getOwner()->getSize();
00206                         for (uint l = 0; l < nbInstances; ++l)
00207                         {
00208                                 e->singleEmit(l, quantity);
00209                         }
00210                 }
00211         }
00212         return true;
00213 }
00214 
00215 
00216 
00217 //===================================================================
00218 bool CParticleSystemInstanceUser::removeByID(uint32 anId)
00219 {
00220         NL3D_MEM_PS_INSTANCE                    
00221         const uint32 id = IDToLittleEndian(anId);
00222         if (!isSystemPresent()) return false;
00223         CParticleSystem *ps = (NLMISC::safe_cast<CParticleSystemModel *>(_Transform))->getPS();
00224         uint numLb  = ps->getNumLocatedBindableByExternID(id);
00225         if (numLb == 0) return false; // INVALID ID !!
00226         for (uint k = 0; k < numLb; ++k)
00227         {
00228                 CPSLocatedBindable *lb = ps->getLocatedBindableByExternID(id, k);
00229                 CPSLocated *owner = lb->getOwner();
00230                 nlassert(owner);
00231                 uint nbInstances  =  owner->getSize();
00232                 for (uint l = 0; l < nbInstances; ++l)
00233                 {
00234                         owner->deleteElement(0);
00235                 }               
00236         }
00237         return true;
00238 }
00239 
00240 //===================================================================
00241 void            CParticleSystemInstanceUser::changeMRMDistanceSetup(float distanceFinest, float distanceMiddle, float distanceCoarsest)
00242 {
00243         NL3D_MEM_PS_INSTANCE                    
00244         // no-op.
00245 }
00246 
00247 
00248 //===================================================================
00249 uint CParticleSystemInstanceUser::getNumID() const
00250 {
00251         NL3D_MEM_PS_INSTANCE                    
00252         if (!isSystemPresent()) return 0;
00253         CParticleSystem *ps = (NLMISC::safe_cast<CParticleSystemModel *>(_Transform))->getPS();
00254         return ps->getNumID();
00255 }
00256 
00257 //===================================================================
00258 uint32 CParticleSystemInstanceUser::getID(uint index) const
00259 {
00260         NL3D_MEM_PS_INSTANCE                    
00261         if (!isSystemPresent()) return 0;
00262         CParticleSystem *ps = (NLMISC::safe_cast<CParticleSystemModel *>(_Transform))->getPS();
00263         return ps->getID(index);
00264 }
00265 
00266 //===================================================================
00267 bool CParticleSystemInstanceUser::getIDs(std::vector<uint32> &dest) const
00268 {
00269         NL3D_MEM_PS_INSTANCE                    
00270         if (!isSystemPresent()) return false;
00271         CParticleSystem *ps = (NLMISC::safe_cast<CParticleSystemModel *>(_Transform))->getPS();
00272         ps->getIDs(dest);
00273         return true;
00274 }
00275 
00276 
00277 //===================================================================
00278 void            CParticleSystemInstanceUser::setShapeDistMax(float distMax)
00279 {
00280         NL3D_MEM_PS_INSTANCE                    
00281         CParticleSystemModel *psm = NLMISC::safe_cast<CParticleSystemModel *>(_Transform);
00282         if(psm && psm->Shape)
00283         {
00284                 psm->Shape->setDistMax(distMax);
00285         }
00286 }
00287 
00288 //===================================================================
00289 float           CParticleSystemInstanceUser::getShapeDistMax() const
00290 {
00291         NL3D_MEM_PS_INSTANCE
00292         CParticleSystemModel *psm = NLMISC::safe_cast<CParticleSystemModel *>(_Transform);
00293         if(psm && psm->Shape)
00294         {
00295                 return psm->Shape->getDistMax();
00296         }
00297         else
00298                 return -1;
00299 }
00300 
00301 //===================================================================
00302 bool CParticleSystemInstanceUser::setActive(uint32 anId, bool active)
00303 {
00304         NL3D_MEM_PS_INSTANCE
00305         const uint32 id = IDToLittleEndian(anId);
00306         if (!isSystemPresent()) return false;
00307         CParticleSystem *ps = (NLMISC::safe_cast<CParticleSystemModel *>(_Transform))->getPS();
00308         uint numLb  = ps->getNumLocatedBindableByExternID(id);
00309         if (numLb == 0) return false; // INVALID ID !!
00310         for (uint k = 0; k < numLb; ++k)
00311         {
00312                 CPSLocatedBindable *lb = ps->getLocatedBindableByExternID(id, k);
00313                 lb->setActive(active);          
00314         }
00315         return true;
00316 }
00317 
00318 
00319 //===================================================================
00320 bool CParticleSystemInstanceUser::activateEmitters(bool active)
00321 {       
00322         NL3D_MEM_PS_INSTANCE
00323         if (!isSystemPresent()) return false;
00324         CParticleSystem *ps = (NLMISC::safe_cast<CParticleSystemModel *>(_Transform))->getPS();
00325         for(uint k = 0; k < ps->getNbProcess(); ++k)
00326         {
00327                 CPSLocated *loc = dynamic_cast<CPSLocated *>(ps->getProcess(k));
00328                 if (loc)
00329                 {
00330                         for(uint l = 0; l < loc->getNbBoundObjects(); ++l)
00331                         {
00332                                 if (loc->getBoundObject(l)->getType() == PSEmitter)     
00333                                         loc->getBoundObject(l)->setActive(active);
00334                         }
00335                 }
00336         }
00337         return true;
00338 }
00339 
00340 //===================================================================
00341 bool CParticleSystemInstanceUser::hasParticles() const
00342 {
00343         NL3D_MEM_PS_INSTANCE
00344         if (!isSystemPresent()) return false;
00345         CParticleSystem *ps = (NLMISC::safe_cast<CParticleSystemModel *>(_Transform))->getPS();
00346         return ps->hasParticles();
00347 }
00348 
00349 //===================================================================
00350 bool CParticleSystemInstanceUser::hasEmmiters() const
00351 {
00352         NL3D_MEM_PS_INSTANCE
00353         if (!isSystemPresent()) return false;
00354         CParticleSystem *ps = (NLMISC::safe_cast<CParticleSystemModel *>(_Transform))->getPS();
00355         return ps->hasEmitters();
00356 }
00357 //===================================================================
00358 bool CParticleSystemInstanceUser::isShared() const
00359 {
00360         NL3D_MEM_PS_INSTANCE
00361         CParticleSystemModel *psm = NLMISC::safe_cast<CParticleSystemModel *>(_Transform);
00362         if(psm->Shape)
00363         {
00364                 return NLMISC::safe_cast<CParticleSystemShape *>((IShape *) psm->Shape)->isShared();
00365         }       
00366         return false;
00367 }
00368 
00369 //===================================================================
00370 void UParticleSystemInstance::setGlobalUserParamValue(const std::string &name, float value)
00371 {
00372         NL3D_MEM_PS_INSTANCE
00373         if (name.empty())
00374         {
00375                 nlwarning("invalid name");
00376                 return;
00377         }
00378         CParticleSystem::setGlobalValue(name, value);
00379 }
00380 
00381 //===================================================================
00382 float UParticleSystemInstance::getGlobalUserParamValue(const std::string &name)
00383 {
00384         NL3D_MEM_PS_INSTANCE
00385         if (name.empty())
00386         {
00387                 nlwarning("invalid name");
00388                 return 0.f;
00389         }
00390         return CParticleSystem::getGlobalValue(name);
00391 }
00392 
00393 //===================================================================
00394 void UParticleSystemInstance::setGlobalVectorValue(const std::string &name,const NLMISC::CVector &v)
00395 {
00396         NL3D_MEM_PS_INSTANCE
00397         if (name.empty())
00398         {
00399                 nlwarning("invalid name");
00400         }
00401         CParticleSystem::setGlobalVectorValue(name, v);
00402 }
00403 
00404 //===================================================================
00405 NLMISC::CVector UParticleSystemInstance::getGlobalVectorValue(const std::string &name)
00406 {
00407         NL3D_MEM_PS_INSTANCE
00408         if (name.empty())
00409         {
00410                 nlwarning("invalid name");
00411                 return NLMISC::CVector::Null;
00412         }
00413         else return CParticleSystem::getGlobalVectorValue(name);
00414 }
00415 
00416 //===================================================================
00417 void            CParticleSystemInstanceUser::enableAsyncTextureMode(bool enable) 
00418 {
00419         NL3D_MEM_PS_INSTANCE
00420 }
00421 
00422 //===================================================================
00423 bool            CParticleSystemInstanceUser::getAsyncTextureMode() const 
00424 {
00425         NL3D_MEM_PS_INSTANCE
00426         return false;
00427 }
00428 
00429 //===================================================================
00430 void            CParticleSystemInstanceUser::startAsyncTextureLoading() 
00431 {
00432         NL3D_MEM_PS_INSTANCE
00433 }
00434 
00435 //===================================================================
00436 bool            CParticleSystemInstanceUser::isAsyncTextureReady() 
00437 {
00438         NL3D_MEM_PS_INSTANCE
00439         return true;
00440 }
00441 void            CParticleSystemInstanceUser::setAsyncTextureDistance(float dist)
00442 {
00443         NL3D_MEM_PS_INSTANCE
00444 }
00445 float           CParticleSystemInstanceUser::getAsyncTextureDistance() const
00446 {
00447         return 0;
00448 }
00449 void            CParticleSystemInstanceUser::setAsyncTextureDirty(bool flag)
00450 {
00451 }
00452 bool            CParticleSystemInstanceUser::isAsyncTextureDirty() const
00453 {
00454         return false;
00455 }
00456 
00457 //===================================================================
00458 void CParticleSystemInstanceUser::bypassGlobalUserParamValue(uint userParamIndex, bool byPass /*=true*/)
00459 {
00460         NL3D_MEM_PS_INSTANCE
00461         if (userParamIndex >= MaxPSUserParam)
00462         {
00463                 nlwarning("invalid user param index");
00464                 return;
00465         }
00466         CParticleSystemModel *psm = NLMISC::safe_cast<CParticleSystemModel *>(_Transform);
00467         psm->bypassGlobalUserParamValue(userParamIndex, byPass);
00468 }
00469 
00470 //===================================================================
00471 bool CParticleSystemInstanceUser::isGlobalUserParamValueBypassed(uint userParamIndex) const
00472 {
00473         NL3D_MEM_PS_INSTANCE
00474         if (userParamIndex >= MaxPSUserParam)
00475         {
00476                 nlwarning("invalid user param index");
00477                 return 0.f;
00478         }
00479         CParticleSystemModel *psm = NLMISC::safe_cast<CParticleSystemModel *>(_Transform);
00480         return isGlobalUserParamValueBypassed(userParamIndex);
00481 }
00482 
00483 } // NL3D