From 81615c1ae5ac4055ffbe8c6239ebdf6b8b7fb029 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 6 Apr 2013 00:18:36 -0700 Subject: [PATCH] Add a custom GrowFade particle affector --- CMakeLists.txt | 1 + libs/openengine/ogre/particles.cpp | 146 +++++++++++++++++++++++++++++ libs/openengine/ogre/particles.hpp | 17 ++++ libs/openengine/ogre/renderer.cpp | 15 +++ libs/openengine/ogre/renderer.hpp | 2 + 5 files changed, 181 insertions(+) create mode 100644 libs/openengine/ogre/particles.cpp create mode 100644 libs/openengine/ogre/particles.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e1b8e32e5e..b6a1017906 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,7 @@ set(LIBDIR ${CMAKE_SOURCE_DIR}/libs) set(OENGINE_OGRE ${LIBDIR}/openengine/ogre/renderer.cpp ${LIBDIR}/openengine/ogre/fader.cpp + ${LIBDIR}/openengine/ogre/particles.cpp ${LIBDIR}/openengine/ogre/selectionbuffer.cpp ) set(OENGINE_GUI diff --git a/libs/openengine/ogre/particles.cpp b/libs/openengine/ogre/particles.cpp new file mode 100644 index 0000000000..3453b7f3d7 --- /dev/null +++ b/libs/openengine/ogre/particles.cpp @@ -0,0 +1,146 @@ +#include "particles.hpp" + +#include +#include +#include +#include + +class GrowFadeAffector : public Ogre::ParticleAffector +{ +public: + /** Command object for grow_time (see Ogre::ParamCommand).*/ + class CmdGrowTime : public Ogre::ParamCommand + { + public: + Ogre::String doGet(const void *target) const + { + const GrowFadeAffector *self = static_cast(target); + return Ogre::StringConverter::toString(self->getGrowTime()); + } + void doSet(void *target, const Ogre::String &val) + { + GrowFadeAffector *self = static_cast(target); + self->setGrowTime(Ogre::StringConverter::parseReal(val)); + } + }; + + /** Command object for fade_time (see Ogre::ParamCommand).*/ + class CmdFadeTime : public Ogre::ParamCommand + { + public: + Ogre::String doGet(const void *target) const + { + const GrowFadeAffector *self = static_cast(target); + return Ogre::StringConverter::toString(self->getFadeTime()); + } + void doSet(void *target, const Ogre::String &val) + { + GrowFadeAffector *self = static_cast(target); + self->setFadeTime(Ogre::StringConverter::parseReal(val)); + } + }; + + /** Default constructor. */ + GrowFadeAffector(Ogre::ParticleSystem *psys) : ParticleAffector(psys) + { + mGrowTime = 0.0f; + mFadeTime = 0.0f; + + mType = "GrowFade"; + + // Init parameters + if(createParamDictionary("GrowFadeAffector")) + { + Ogre::ParamDictionary *dict = getParamDictionary(); + + Ogre::String grow_title("grow_time"); + Ogre::String fade_title("fade_time"); + Ogre::String grow_descr("Time from begin to reach full size."); + Ogre::String fade_descr("Time from end to shrink."); + + dict->addParameter(Ogre::ParameterDef(grow_title, grow_descr, Ogre::PT_REAL), &msGrowCmd); + dict->addParameter(Ogre::ParameterDef(fade_title, fade_descr, Ogre::PT_REAL), &msFadeCmd); + } + } + + /** See Ogre::ParticleAffector. */ + void _initParticle(Ogre::Particle *particle) + { + const Ogre::Real life_time = particle->totalTimeToLive; + Ogre::Real particle_time = particle->timeToLive; + + Ogre::Real width = mParent->getDefaultWidth(); + Ogre::Real height = mParent->getDefaultHeight(); + if(life_time-particle_time < mGrowTime) + { + Ogre::Real scale = (life_time-particle_time) / mGrowTime; + width *= scale; + height *= scale; + } + if(particle_time < mFadeTime) + { + Ogre::Real scale = particle_time / mFadeTime; + width *= scale; + height *= scale; + } + particle->setDimensions(width, height); + } + + /** See Ogre::ParticleAffector. */ + void _affectParticles(Ogre::ParticleSystem *psys, Ogre::Real timeElapsed) + { + Ogre::ParticleIterator pi = psys->_getIterator(); + while (!pi.end()) + { + Ogre::Particle *p = pi.getNext(); + const Ogre::Real life_time = p->totalTimeToLive; + Ogre::Real particle_time = p->timeToLive; + + Ogre::Real width = mParent->getDefaultWidth(); + Ogre::Real height = mParent->getDefaultHeight(); + if(life_time-particle_time < mGrowTime) + { + Ogre::Real scale = (life_time-particle_time) / mGrowTime; + width *= scale; + height *= scale; + } + if(particle_time < mFadeTime) + { + Ogre::Real scale = particle_time / mFadeTime; + width *= scale; + height *= scale; + } + p->setDimensions(width, height); + } + } + + void setGrowTime(Ogre::Real time) + { + mGrowTime = time; + } + Ogre::Real getGrowTime() const + { return mGrowTime; } + + void setFadeTime(Ogre::Real time) + { + mFadeTime = time; + } + Ogre::Real getFadeTime() const + { return mFadeTime; } + + static CmdGrowTime msGrowCmd; + static CmdFadeTime msFadeCmd; + +protected: + Ogre::Real mGrowTime; + Ogre::Real mFadeTime; +}; +GrowFadeAffector::CmdGrowTime GrowFadeAffector::msGrowCmd; +GrowFadeAffector::CmdFadeTime GrowFadeAffector::msFadeCmd; + +Ogre::ParticleAffector *GrowFadeAffectorFactory::createAffector(Ogre::ParticleSystem *psys) +{ + Ogre::ParticleAffector *p = new GrowFadeAffector(psys); + mAffectors.push_back(p); + return p; +} diff --git a/libs/openengine/ogre/particles.hpp b/libs/openengine/ogre/particles.hpp new file mode 100644 index 0000000000..d466bb0308 --- /dev/null +++ b/libs/openengine/ogre/particles.hpp @@ -0,0 +1,17 @@ +#ifndef OENGINE_OGRE_PARTICLES_H +#define OENGINE_OGRE_PARTICLES_H + +#include + +/** Factory class for GrowFadeAffector. */ +class GrowFadeAffectorFactory : public Ogre::ParticleAffectorFactory +{ + /** See Ogre::ParticleAffectorFactory */ + Ogre::String getName() const + { return "GrowFade"; } + + /** See Ogre::ParticleAffectorFactory */ + Ogre::ParticleAffector *createAffector(Ogre::ParticleSystem *psys); +}; + +#endif /* OENGINE_OGRE_PARTICLES_H */ diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index 05760ffa98..c9e91968f5 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -1,5 +1,6 @@ #include "renderer.hpp" #include "fader.hpp" +#include "particles.hpp" #include "OgreRoot.h" #include "OgreRenderWindow.h" @@ -8,6 +9,8 @@ #include "OgreTextureManager.h" #include "OgreTexture.h" #include "OgreHardwarePixelBuffer.h" +#include +#include "OgreParticleAffectorFactory.h" #include @@ -24,6 +27,7 @@ using namespace Ogre; using namespace OEngine::Render; + #if defined(__APPLE__) && !defined(__LP64__) CustomRoot::CustomRoot(const Ogre::String& pluginFileName, @@ -106,6 +110,11 @@ void OgreRenderer::loadPlugins() void OgreRenderer::unloadPlugins() { + std::vector::iterator ai; + for(ai = mAffectorFactories.begin();ai != mAffectorFactories.end();ai++) + OGRE_DELETE (*ai); + mAffectorFactories.clear(); + #ifdef ENABLE_PLUGIN_GL delete mGLPlugin; mGLPlugin = NULL; @@ -197,6 +206,12 @@ void OgreRenderer::configure(const std::string &logPath, Files::loadOgrePlugin(pluginDir, "Plugin_CgProgramManager", *mRoot); Files::loadOgrePlugin(pluginDir, "Plugin_ParticleFX", *mRoot); + Ogre::ParticleAffectorFactory *affector; + affector = OGRE_NEW GrowFadeAffectorFactory(); + Ogre::ParticleSystemManager::getSingleton().addAffectorFactory(affector); + mAffectorFactories.push_back(affector); + + RenderSystem* rs = mRoot->getRenderSystemByName(renderSystem); if (rs == 0) throw std::runtime_error ("RenderSystem with name " + renderSystem + " not found, make sure the plugins are loaded"); diff --git a/libs/openengine/ogre/renderer.hpp b/libs/openengine/ogre/renderer.hpp index 251dc9c54d..ea46f5ae62 100644 --- a/libs/openengine/ogre/renderer.hpp +++ b/libs/openengine/ogre/renderer.hpp @@ -40,6 +40,7 @@ namespace Ogre class SceneManager; class Camera; class Viewport; + class ParticleAffectorFactory; } namespace OEngine @@ -94,6 +95,7 @@ namespace OEngine Ogre::D3D9Plugin* mD3D9Plugin; #endif Fader* mFader; + std::vector mAffectorFactories; bool logging; public: