00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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;
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
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
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
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);
00169
00170
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;
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;
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
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;
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 )
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 }