/* ----------------------------------------------------------------------------- This source file is part of OGRE (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2006 Torus Knot Software Ltd Also see acknowledgements in Readme.html This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt. You may alternatively use this source under the terms of a specific version of the OGRE Unrestricted License provided you have obtained such a license from Torus Knot Software Ltd. ----------------------------------------------------------------------------- */ #include "OgreStableHeaders.h" #include "OgreControllerManager.h" #include "OgreLogManager.h" #include "OgreTextureUnitState.h" #include "OgreRoot.h" namespace Ogre { //----------------------------------------------------------------------- template<> ControllerManager* Singleton::ms_Singleton = 0; ControllerManager* ControllerManager::getSingletonPtr(void) { return ms_Singleton; } ControllerManager& ControllerManager::getSingleton(void) { assert( ms_Singleton ); return ( *ms_Singleton ); } //----------------------------------------------------------------------- ControllerManager::ControllerManager() : mFrameTimeController(new FrameTimeControllerValue()) , mPassthroughFunction(new PassthroughControllerFunction()) , mLastFrameNumber(0) { } //----------------------------------------------------------------------- ControllerManager::~ControllerManager() { clearControllers(); } //----------------------------------------------------------------------- Controller* ControllerManager::createController( const ControllerValueRealPtr& src, const ControllerValueRealPtr& dest, const ControllerFunctionRealPtr& func) { Controller* c = new Controller(src, dest, func); mControllers.insert(c); return c; } //----------------------------------------------------------------------- Controller* ControllerManager::createFrameTimePassthroughController( const ControllerValueRealPtr& dest) { return createController(getFrameTimeSource(), dest, getPassthroughControllerFunction()); } //----------------------------------------------------------------------- void ControllerManager::updateAllControllers(void) { // Only update once per frame unsigned long thisFrameNumber = Root::getSingleton().getCurrentFrameNumber(); if (thisFrameNumber != mLastFrameNumber) { ControllerList::const_iterator ci; for (ci = mControllers.begin(); ci != mControllers.end(); ++ci) { (*ci)->update(); } mLastFrameNumber = thisFrameNumber; } } //----------------------------------------------------------------------- void ControllerManager::clearControllers(void) { ControllerList::iterator ci; for (ci = mControllers.begin(); ci != mControllers.end(); ++ci) { delete *ci; } mControllers.clear(); } //----------------------------------------------------------------------- const ControllerValueRealPtr& ControllerManager::getFrameTimeSource(void) const { return mFrameTimeController; } //----------------------------------------------------------------------- const ControllerFunctionRealPtr& ControllerManager::getPassthroughControllerFunction(void) const { return mPassthroughFunction; } //----------------------------------------------------------------------- Controller* ControllerManager::createTextureAnimator(TextureUnitState* layer, Real sequenceTime) { SharedPtr< ControllerValue > texVal(new TextureFrameControllerValue(layer)); SharedPtr< ControllerFunction > animFunc(new AnimationControllerFunction(sequenceTime)); return createController(mFrameTimeController, texVal, animFunc); } //----------------------------------------------------------------------- Controller* ControllerManager::createTextureUVScroller(TextureUnitState* layer, Real speed) { Controller* ret = 0; if (speed != 0) { SharedPtr< ControllerValue > val; SharedPtr< ControllerFunction > func; // We do both scrolls with a single controller val.bind(new TexCoordModifierControllerValue(layer, true, true)); // Create function: use -speed since we're altering texture coords so they have reverse effect func.bind(new ScaleControllerFunction(-speed, true)); ret = createController(mFrameTimeController, val, func); } return ret; } //----------------------------------------------------------------------- Controller* ControllerManager::createTextureUScroller(TextureUnitState* layer, Real uSpeed) { Controller* ret = 0; if (uSpeed != 0) { SharedPtr< ControllerValue > uVal; SharedPtr< ControllerFunction > uFunc; uVal.bind(new TexCoordModifierControllerValue(layer, true)); // Create function: use -speed since we're altering texture coords so they have reverse effect uFunc.bind(new ScaleControllerFunction(-uSpeed, true)); ret = createController(mFrameTimeController, uVal, uFunc); } return ret; } //----------------------------------------------------------------------- Controller* ControllerManager::createTextureVScroller(TextureUnitState* layer, Real vSpeed) { Controller* ret = 0; if (vSpeed != 0) { SharedPtr< ControllerValue > vVal; SharedPtr< ControllerFunction > vFunc; // Set up a second controller for v scroll vVal.bind(new TexCoordModifierControllerValue(layer, false, true)); // Create function: use -speed since we're altering texture coords so they have reverse effect vFunc.bind(new ScaleControllerFunction(-vSpeed, true)); ret = createController(mFrameTimeController, vVal, vFunc); } return ret; } //----------------------------------------------------------------------- Controller* ControllerManager::createTextureRotater(TextureUnitState* layer, Real speed) { SharedPtr< ControllerValue > val; SharedPtr< ControllerFunction > func; // Target value is texture coord rotation val.bind(new TexCoordModifierControllerValue(layer, false, false, false, false, true)); // Function is simple scale (seconds * speed) // Use -speed since altering texture coords has the reverse visible effect func.bind(new ScaleControllerFunction(-speed, true)); return createController(mFrameTimeController, val, func); } //----------------------------------------------------------------------- Controller* ControllerManager::createTextureWaveTransformer(TextureUnitState* layer, TextureUnitState::TextureTransformType ttype, WaveformType waveType, Real base, Real frequency, Real phase, Real amplitude) { SharedPtr< ControllerValue > val; SharedPtr< ControllerFunction > func; switch (ttype) { case TextureUnitState::TT_TRANSLATE_U: // Target value is a u scroll val.bind(new TexCoordModifierControllerValue(layer, true)); break; case TextureUnitState::TT_TRANSLATE_V: // Target value is a v scroll val.bind(new TexCoordModifierControllerValue(layer, false, true)); break; case TextureUnitState::TT_SCALE_U: // Target value is a u scale val.bind(new TexCoordModifierControllerValue(layer, false, false, true)); break; case TextureUnitState::TT_SCALE_V: // Target value is a v scale val.bind(new TexCoordModifierControllerValue(layer, false, false, false, true)); break; case TextureUnitState::TT_ROTATE: // Target value is texture coord rotation val.bind(new TexCoordModifierControllerValue(layer, false, false, false, false, true)); break; } // Create new wave function for alterations func.bind(new WaveformControllerFunction(waveType, base, frequency, phase, amplitude, true)); return createController(mFrameTimeController, val, func); } //----------------------------------------------------------------------- Controller* ControllerManager::createGpuProgramTimerParam( GpuProgramParameters* params, size_t paramIndex, Real timeFactor) { SharedPtr< ControllerValue > val; SharedPtr< ControllerFunction > func; val.bind(new FloatGpuParameterControllerValue(params, paramIndex)); func.bind(new ScaleControllerFunction(timeFactor, true)); return createController(mFrameTimeController, val, func); } //----------------------------------------------------------------------- void ControllerManager::destroyController(Controller* controller) { ControllerList::iterator i = mControllers.find(controller); if (i != mControllers.end()) { mControllers.erase(i); delete controller; } } //----------------------------------------------------------------------- Real ControllerManager::getTimeFactor(void) const { return static_cast(mFrameTimeController.get())->getTimeFactor(); } //----------------------------------------------------------------------- void ControllerManager::setTimeFactor(Real tf) { static_cast(mFrameTimeController.getPointer())->setTimeFactor(tf); } //----------------------------------------------------------------------- Real ControllerManager::getFrameDelay(void) const { return static_cast(mFrameTimeController.get())->getFrameDelay(); } //----------------------------------------------------------------------- void ControllerManager::setFrameDelay(Real fd) { static_cast(mFrameTimeController.getPointer())->setFrameDelay(fd); } //----------------------------------------------------------------------- Real ControllerManager::getElapsedTime(void) const { return static_cast(mFrameTimeController.get())->getElapsedTime(); } //----------------------------------------------------------------------- void ControllerManager::setElapsedTime(Real elapsedTime) { static_cast(mFrameTimeController.get())->setElapsedTime(elapsedTime); } }