// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . ///////////// // INCLUDE // ///////////// #include "stdpch.h" // First include for pre-compiled headers. // 3D #include "nel/3d/u_particle_system_instance.h" #include "nel/pacs/u_global_position.h" // Client #include "fx_manager.h" #include "time_client.h" #include "pacs_client.h" H_AUTO_DECL(RZ_FXManager) /////////// // USING // /////////// using namespace NLMISC; using namespace NL3D; using namespace NLPACS; using namespace std; //////////// // EXTERN // //////////// extern UScene *Scene; ///////////// // GLOBALS // ///////////// // FX manager. CFXManager FXMngr; ///////////// // MEMBERS // ///////////// ///////////// // METHODS // ///////////// //----------------------------------------------- // CFXManager : // Constructor. //----------------------------------------------- CFXManager::CFXManager() { H_AUTO_USE(RZ_FXManager) _NumFXToRemove = 0; }// CFXManager // //----------------------------------------------- // CFXManager : // Destructor. //----------------------------------------------- CFXManager::~CFXManager() { H_AUTO_USE(RZ_FXManager) reset(); }// CFXManager // //----------------------------------------------- // instantFX : // create an FX that will be removed as soon as possible. //----------------------------------------------- NL3D::UParticleSystemInstance CFXManager::instantFX(const std::string &fxName, float timeOut /* = 0.f*/) { H_AUTO_USE(RZ_FXManager) // Check FX Name. if(fxName.empty()) return 0; NL3D::UParticleSystemInstance fx; fx.cast (Scene->createInstance(fxName)); if(!fx.empty()) { _FX2RemoveList.push_back(CFX2Remove(fx, timeOut)); ++_NumFXToRemove; } return fx; }// instantFX // //----------------------------------------------- // addFX : //----------------------------------------------- void CFXManager::addFX(NL3D::UParticleSystemInstance fx, float timeOut, bool testNoMoreParticles /*= false*/) { H_AUTO_USE(RZ_FXManager) if (fx.empty()) return; _FX2RemoveList.push_back(CFX2Remove(fx, timeOut, testNoMoreParticles)); ++_NumFXToRemove; }// addFX // //----------------------------------------------- // fx2remove : //----------------------------------------------- void CFXManager::fx2remove(NL3D::UParticleSystemInstance fx, float timeOut) { H_AUTO_USE(RZ_FXManager) if(!fx.empty()) { _FX2RemoveList.push_back(CFX2Remove(fx, timeOut)); ++_NumFXToRemove; } }// fx2remove // //----------------------------------------------- // update : //----------------------------------------------- void CFXManager::update() { H_AUTO_USE(RZ_FXManager) // deferred fx while (!_DeferredFXByDate.empty()) { if (T1 < _DeferredFXByDate.begin()->first) break; const CDeferredFX &fx = _DeferredFXByDate.begin()->second; NL3D::UParticleSystemInstance fxInstance = instantFX(fx.FXName, fx.TimeOut); if (!fxInstance.empty()) { fxInstance.setTransformMode(UTransform::DirectMatrix); fxInstance.setMatrix(fx.Matrix); UGlobalPosition gPos; GR->retrievePosition(fx.Matrix.getPos()); UInstanceGroup *clusterSystem = getCluster(gPos); fxInstance.setClusterSystem(clusterSystem); fxInstance.forceInstanciate(); // accurate timing wanted } _DeferredFXByDate.erase(_DeferredFXByDate.begin()); } #ifdef NL_DEBUG nlassert(_NumFXToRemove == _FX2RemoveList.size()); #endif // Try to remove Animation FXs still not removed. std::list::iterator itFx = _FX2RemoveList.begin(); while(itFx != _FX2RemoveList.end()) { // Backup the old iterator std::list::iterator itTmp = itFx; // Iterator on the Next FX. itFx++; // If the FX is not present or valid -> remove the FX. if(!itTmp->Instance.isSystemPresent() || !itTmp->Instance.isValid() || (itTmp->TestNoMoreParticles && !itTmp->Instance.hasParticles()) ) { // Delete the FX. Scene->deleteInstance(itTmp->Instance); // Remove from the list. _FX2RemoveList.erase(itTmp); -- _NumFXToRemove; } else if (itTmp->TimeOut != 0.f) { itTmp->TimeOut -= DT; if (itTmp->TimeOut < 0.f) { // Delete the FX. Scene->deleteInstance(itTmp->Instance); // Remove from the list. _FX2RemoveList.erase(itTmp); -- _NumFXToRemove; } } } }// update // //----------------------------------------------- // reset : //----------------------------------------------- void CFXManager::reset() { H_AUTO_USE(RZ_FXManager) // Remove Animation FXs still not removed. std::list::iterator itFx = _FX2RemoveList.begin(); while(itFx != _FX2RemoveList.end()) { // Delete the FX. if(Scene) Scene->deleteInstance(itFx->Instance); // Next FX itFx++; } // clear FX list _FX2RemoveList.clear(); _DeferredFXByDate.clear(); _NumFXToRemove = 0; } //----------------------------------------------- // deferedFX : //----------------------------------------------- void CFXManager::deferFX(const std::string &fxName, const NLMISC::CMatrix &matrix, float delayInSeconds, float timeOut /*=FX_MANAGER_DEFAULT_TIMEOUT*/) { CDeferredFX fx; fx.FXName = fxName; fx.Matrix = matrix; fx.TimeOut = timeOut; _DeferredFXByDate.insert(std::make_pair(T1 + sint64(1000.f * delayInSeconds), fx)); }