From c516e897ee7265c59340305e7ae115c79a449e2f Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Apr 2015 17:29:12 +0200 Subject: [PATCH] Move Controller base classes to SceneUtil, add visitor to assign ControllerSources --- apps/openmw/mwrender/animation.hpp | 2 +- apps/openmw/mwrender/renderingmanager.cpp | 4 +- apps/openmw/mwrender/sky.cpp | 12 +-- components/CMakeLists.txt | 2 +- components/nifosg/controller.cpp | 31 +------ components/nifosg/controller.hpp | 51 +++-------- components/nifosg/nifloader.cpp | 21 +++-- components/sceneutil/controller.cpp | 86 +++++++++++++++++++ components/sceneutil/controller.hpp | 64 ++++++++++++++ ...esetcontroller.cpp => statesetupdater.cpp} | 30 ++++--- ...esetcontroller.hpp => statesetupdater.hpp} | 23 ++--- 11 files changed, 211 insertions(+), 115 deletions(-) create mode 100644 components/sceneutil/controller.cpp create mode 100644 components/sceneutil/controller.hpp rename components/sceneutil/{statesetcontroller.cpp => statesetupdater.cpp} (58%) rename components/sceneutil/{statesetcontroller.hpp => statesetupdater.hpp} (77%) diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index cbded364a..754adec92 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -74,7 +74,7 @@ protected: virtual void setValue(Ogre::Real value); }; - class NullAnimationTime : public NifOsg::ControllerSource + class NullAnimationTime : public SceneUtil::ControllerSource { public: virtual float getValue(osg::NodeVisitor *nv) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index e9a5d302c..ba34cf303 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -13,7 +13,7 @@ #include -#include +#include #include @@ -22,7 +22,7 @@ namespace MWRender { - class StateUpdater : public SceneUtil::StateSetController + class StateUpdater : public SceneUtil::StateSetUpdater { public: virtual void setDefaults(osg::StateSet *stateset) diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index be702a221..a4fd17172 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -37,14 +37,6 @@ namespace { - osg::StateSet* getWritableStateSet(osg::Node* node) - { - osg::StateSet* stateset = node->getOrCreateStateSet(); - osg::ref_ptr cloned = static_cast(stateset->clone(osg::CopyOp::SHALLOW_COPY)); - node->setStateSet(cloned); - return cloned; - } - osg::ref_ptr createAlphaTrackingUnlitMaterial() { osg::ref_ptr mat = new osg::Material; @@ -95,7 +87,7 @@ namespace namespace MWRender { -class AtmosphereUpdater : public SceneUtil::StateSetController +class AtmosphereUpdater : public SceneUtil::StateSetUpdater { public: void setEmissionColor(osg::Vec4f emissionColor) diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 6b1c01644..f61724eeb 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -39,7 +39,7 @@ add_component_dir (resource ) add_component_dir (sceneutil - clone attach lightmanager visitor util statesetcontroller + clone attach lightmanager visitor util statesetupdater controller ) add_component_dir (nif diff --git a/components/nifosg/controller.cpp b/components/nifosg/controller.cpp index 344cb2323..ce004dc79 100644 --- a/components/nifosg/controller.cpp +++ b/components/nifosg/controller.cpp @@ -64,15 +64,6 @@ float ControllerFunction::calculate(float value) } } -FrameTimeSource::FrameTimeSource() -{ -} - -float FrameTimeSource::getValue(osg::NodeVisitor *nv) -{ - return nv->getFrameStamp()->getSimulationTime(); -} - KeyframeController::KeyframeController() { } @@ -207,20 +198,6 @@ void KeyframeController::operator() (osg::Node* node, osg::NodeVisitor* nv) traverse(node, nv); } -Controller::Controller() -{ -} - -bool Controller::hasInput() const -{ - return mSource.get() != NULL; -} - -float Controller::getInputValue(osg::NodeVisitor* nv) -{ - return mFunction->calculate(mSource->getValue(nv)); -} - GeomMorpherController::GeomMorpherController() { } @@ -278,7 +255,7 @@ UVController::UVController(const Nif::NiUVData *data, std::set textureUnits } UVController::UVController(const UVController& copy, const osg::CopyOp& copyop) - : osg::Object(copy, copyop), StateSetController(copy, copyop), Controller(copy) + : osg::Object(copy, copyop), StateSetUpdater(copy, copyop), Controller(copy) , mUTrans(copy.mUTrans) , mVTrans(copy.mVTrans) , mUScale(copy.mUScale) @@ -367,7 +344,7 @@ AlphaController::AlphaController() } AlphaController::AlphaController(const AlphaController ©, const osg::CopyOp ©op) - : StateSetController(copy, copyop), ValueInterpolator(), Controller(copy) + : StateSetUpdater(copy, copyop), ValueInterpolator(), Controller(copy) , mData(copy.mData) { } @@ -394,7 +371,7 @@ MaterialColorController::MaterialColorController() } MaterialColorController::MaterialColorController(const MaterialColorController ©, const osg::CopyOp ©op) - : StateSetController(copy, copyop), Controller(copy) + : StateSetUpdater(copy, copyop), Controller(copy) , mData(copy.mData) { } @@ -423,7 +400,7 @@ FlipController::FlipController() } FlipController::FlipController(const FlipController ©, const osg::CopyOp ©op) - : StateSetController(copy, copyop) + : StateSetUpdater(copy, copyop) , Controller(copy) , mTexSlot(copy.mTexSlot) , mDelta(copy.mDelta) diff --git a/components/nifosg/controller.hpp b/components/nifosg/controller.hpp index 103a72046..3136b3118 100644 --- a/components/nifosg/controller.hpp +++ b/components/nifosg/controller.hpp @@ -8,7 +8,8 @@ #include -#include +#include +#include #include @@ -43,7 +44,6 @@ namespace osgAnimation namespace NifOsg { - // FIXME: Should not be here. We might also want to use this for non-NIF model formats class ValueInterpolator { protected: @@ -76,8 +76,7 @@ namespace NifOsg } }; - // FIXME: Should not be here. We might also want to use this for non-NIF model formats - class ControllerFunction + class ControllerFunction : public SceneUtil::ControllerFunction { private: float mFrequency; @@ -98,35 +97,7 @@ namespace NifOsg float calculate(float value); }; - class ControllerSource - { - public: - virtual float getValue(osg::NodeVisitor* nv) = 0; - }; - - class FrameTimeSource : public ControllerSource - { - public: - FrameTimeSource(); - virtual float getValue(osg::NodeVisitor* nv); - }; - - class Controller - { - public: - Controller(); - - bool hasInput() const; - - float getInputValue(osg::NodeVisitor* nv); - - boost::shared_ptr mSource; - - // The source value gets passed through this function before it's passed on to the DestValue. - boost::shared_ptr mFunction; - }; - - class GeomMorpherController : public osg::Drawable::UpdateCallback, public Controller, public ValueInterpolator + class GeomMorpherController : public osg::Drawable::UpdateCallback, public SceneUtil::Controller, public ValueInterpolator { public: GeomMorpherController(const Nif::NiMorphData* data); @@ -141,7 +112,7 @@ namespace NifOsg std::vector mKeyFrames; }; - class KeyframeController : public osg::NodeCallback, public Controller, public ValueInterpolator + class KeyframeController : public osg::NodeCallback, public SceneUtil::Controller, public ValueInterpolator { public: KeyframeController(const Nif::NiKeyframeData *data); @@ -191,7 +162,7 @@ namespace NifOsg bool mEnabled; }; - class UVController : public SceneUtil::StateSetController, public Controller, public ValueInterpolator + class UVController : public SceneUtil::StateSetUpdater, public SceneUtil::Controller, public ValueInterpolator { public: UVController(); @@ -211,7 +182,7 @@ namespace NifOsg std::set mTextureUnits; }; - class VisController : public osg::NodeCallback, public Controller + class VisController : public osg::NodeCallback, public SceneUtil::Controller { private: std::vector mData; @@ -228,7 +199,7 @@ namespace NifOsg virtual void operator() (osg::Node* node, osg::NodeVisitor* nv); }; - class AlphaController : public SceneUtil::StateSetController, public Controller, public ValueInterpolator + class AlphaController : public SceneUtil::StateSetUpdater, public SceneUtil::Controller, public ValueInterpolator { private: Nif::FloatKeyMapPtr mData; @@ -243,7 +214,7 @@ namespace NifOsg META_Object(NifOsg, AlphaController) }; - class MaterialColorController : public SceneUtil::StateSetController, public Controller, public ValueInterpolator + class MaterialColorController : public SceneUtil::StateSetUpdater, public SceneUtil::Controller, public ValueInterpolator { private: Nif::Vector3KeyMapPtr mData; @@ -258,7 +229,7 @@ namespace NifOsg virtual void apply(osg::StateSet* stateset, osg::NodeVisitor* nv); }; - class FlipController : public SceneUtil::StateSetController, public Controller + class FlipController : public SceneUtil::StateSetUpdater, public SceneUtil::Controller { private: int mTexSlot; @@ -275,7 +246,7 @@ namespace NifOsg virtual void apply(osg::StateSet *stateset, osg::NodeVisitor *nv); }; - class ParticleSystemController : public osg::NodeCallback, public Controller + class ParticleSystemController : public osg::NodeCallback, public SceneUtil::Controller { public: ParticleSystemController(const Nif::NiParticleSystemController* ctrl); diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 8dc286a92..1d7eaba2c 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -719,7 +719,7 @@ namespace NifOsg return skel; } - static void applyNodeProperties(const Nif::Node *nifNode, osg::Node *applyTo, SceneUtil::CompositeStateSetController* composite, Resource::TextureManager* textureManager, std::map& boundTextures, int animflags) + static void applyNodeProperties(const Nif::Node *nifNode, osg::Node *applyTo, SceneUtil::CompositeStateSetUpdater* composite, Resource::TextureManager* textureManager, std::map& boundTextures, int animflags) { const Nif::PropertyList& props = nifNode->props; for (size_t i = 0; i mSource = boost::shared_ptr(new FrameTimeSource); + bool autoPlay = animflags & Nif::NiNode::AnimFlag_AutoPlay; + if (autoPlay) + toSetup->mSource = boost::shared_ptr(new SceneUtil::FrameTimeSource); toSetup->mFunction = boost::shared_ptr(new ControllerFunction(ctrl)); } @@ -825,7 +824,7 @@ namespace NifOsg transformNode->setNodeMask(0x1); } - osg::ref_ptr composite = new SceneUtil::CompositeStateSetController; + osg::ref_ptr composite = new SceneUtil::CompositeStateSetUpdater; applyNodeProperties(nifNode, transformNode, composite, textureManager, boundTextures, animflags); @@ -871,7 +870,7 @@ namespace NifOsg return transformNode; } - static void handleMeshControllers(const Nif::Node *nifNode, SceneUtil::CompositeStateSetController* composite, const std::map &boundTextures, int animflags) + static void handleMeshControllers(const Nif::Node *nifNode, SceneUtil::CompositeStateSetUpdater* composite, const std::map &boundTextures, int animflags) { for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next) { @@ -921,7 +920,7 @@ namespace NifOsg static void handleMaterialControllers(const Nif::Property *materialProperty, osg::Node* node, int animflags) { - osg::ref_ptr composite = new SceneUtil::CompositeStateSetController; + osg::ref_ptr composite = new SceneUtil::CompositeStateSetUpdater; for (Nif::ControllerPtr ctrl = materialProperty->controller; !ctrl.empty(); ctrl = ctrl->next) { if (!(ctrl->flags & Nif::NiNode::ControllerFlag_Active)) @@ -947,7 +946,7 @@ namespace NifOsg node->addUpdateCallback(composite); } - static void handleTextureControllers(const Nif::Property *texProperty, SceneUtil::CompositeStateSetController* composite, Resource::TextureManager* textureManager, osg::StateSet *stateset, int animflags) + static void handleTextureControllers(const Nif::Property *texProperty, SceneUtil::CompositeStateSetUpdater* composite, Resource::TextureManager* textureManager, osg::StateSet *stateset, int animflags) { for (Nif::ControllerPtr ctrl = texProperty->controller; !ctrl.empty(); ctrl = ctrl->next) { @@ -1426,7 +1425,7 @@ namespace NifOsg static void handleProperty(const Nif::Property *property, - osg::Node *node, SceneUtil::CompositeStateSetController* composite, Resource::TextureManager* textureManager, std::map& boundTextures, int animflags) + osg::Node *node, SceneUtil::CompositeStateSetUpdater* composite, Resource::TextureManager* textureManager, std::map& boundTextures, int animflags) { osg::StateSet* stateset = node->getOrCreateStateSet(); diff --git a/components/sceneutil/controller.cpp b/components/sceneutil/controller.cpp new file mode 100644 index 000000000..565d48672 --- /dev/null +++ b/components/sceneutil/controller.cpp @@ -0,0 +1,86 @@ +#include "controller.hpp" + +#include "statesetupdater.hpp" + +#include +#include + +namespace SceneUtil +{ + + + Controller::Controller() + { + } + + bool Controller::hasInput() const + { + return mSource.get() != NULL; + } + + float Controller::getInputValue(osg::NodeVisitor* nv) + { + return mFunction->calculate(mSource->getValue(nv)); + } + + FrameTimeSource::FrameTimeSource() + { + } + + float FrameTimeSource::getValue(osg::NodeVisitor *nv) + { + return nv->getFrameStamp()->getSimulationTime(); + } + + AssignControllerSourcesVisitor::AssignControllerSourcesVisitor() + : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) + { + } + + AssignControllerSourcesVisitor::AssignControllerSourcesVisitor(boost::shared_ptr toAssign) + : mToAssign(toAssign) + , osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) + { + } + + void AssignControllerSourcesVisitor::apply(osg::Node &node) + { + osg::NodeCallback* callback = node.getUpdateCallback(); + while (callback) + { + if (Controller* ctrl = dynamic_cast(callback)) + assign(node, *ctrl); + if (CompositeStateSetUpdater* composite = dynamic_cast(callback)) + { + for (unsigned int i=0; igetNumControllers(); ++i) + { + StateSetUpdater* statesetcontroller = composite->getController(i); + if (Controller* ctrl = dynamic_cast(statesetcontroller)) + assign(node, *ctrl); + } + } + + callback = callback->getNestedCallback(); + } + + traverse(node); + } + + void AssignControllerSourcesVisitor::apply(osg::Geode &geode) + { + for (unsigned int i=0; igetUpdateCallback(); + if (Controller* ctrl = dynamic_cast(callback)) + assign(geode, *ctrl); + } + } + + void AssignControllerSourcesVisitor::assign(osg::Node&, Controller &ctrl) + { + if (!ctrl.mSource.get()) + ctrl.mSource = mToAssign; + } + +} diff --git a/components/sceneutil/controller.hpp b/components/sceneutil/controller.hpp new file mode 100644 index 000000000..de73c7e80 --- /dev/null +++ b/components/sceneutil/controller.hpp @@ -0,0 +1,64 @@ +#ifndef OPENMW_COMPONENTS_SCENEUTIL_CONTROLLER_H +#define OPENMW_COMPONENTS_SCENEUTIL_CONTROLLER_H + +#include + +#include + +namespace SceneUtil +{ + + class ControllerSource + { + public: + virtual float getValue(osg::NodeVisitor* nv) = 0; + }; + + class FrameTimeSource : public ControllerSource + { + public: + FrameTimeSource(); + virtual float getValue(osg::NodeVisitor* nv); + }; + + class ControllerFunction + { + public: + virtual float calculate(float input) = 0; + }; + + class Controller + { + public: + Controller(); + + bool hasInput() const; + + float getInputValue(osg::NodeVisitor* nv); + + boost::shared_ptr mSource; + + // The source value gets passed through this function before it's passed on to the DestValue. + boost::shared_ptr mFunction; + }; + + class AssignControllerSourcesVisitor : public osg::NodeVisitor + { + public: + AssignControllerSourcesVisitor(); + AssignControllerSourcesVisitor(boost::shared_ptr toAssign); + + virtual void apply(osg::Node& node); + virtual void apply(osg::Geode& geode); + + /// Assign the wanted ControllerSource. May be overriden in derived classes. + /// By default assigns the ControllerSource passed to the constructor of this class if no ControllerSource is assigned to that controller yet. + virtual void assign(osg::Node& node, Controller& ctrl); + + private: + boost::shared_ptr mToAssign; + }; + +} + +#endif diff --git a/components/sceneutil/statesetcontroller.cpp b/components/sceneutil/statesetupdater.cpp similarity index 58% rename from components/sceneutil/statesetcontroller.cpp rename to components/sceneutil/statesetupdater.cpp index 079eaf6aa..8ed229aa6 100644 --- a/components/sceneutil/statesetcontroller.cpp +++ b/components/sceneutil/statesetupdater.cpp @@ -1,11 +1,11 @@ -#include "statesetcontroller.hpp" +#include "statesetupdater.hpp" #include namespace SceneUtil { - void StateSetController::operator()(osg::Node* node, osg::NodeVisitor* nv) + void StateSetUpdater::operator()(osg::Node* node, osg::NodeVisitor* nv) { if (!mStateSets[0]) { @@ -28,45 +28,51 @@ namespace SceneUtil traverse(node, nv); } - StateSetController::StateSetController() + StateSetUpdater::StateSetUpdater() { } - StateSetController::StateSetController(const StateSetController ©, const osg::CopyOp ©op) + StateSetUpdater::StateSetUpdater(const StateSetUpdater ©, const osg::CopyOp ©op) : osg::NodeCallback(copy, copyop) { } // ---------------------------------------------------------------------------------- - void CompositeStateSetController::apply(osg::StateSet *stateset, osg::NodeVisitor *nv) + void CompositeStateSetUpdater::apply(osg::StateSet *stateset, osg::NodeVisitor *nv) { for (unsigned int i=0; iapply(stateset, nv); } - void CompositeStateSetController::setDefaults(osg::StateSet *stateset) + void CompositeStateSetUpdater::setDefaults(osg::StateSet *stateset) { for (unsigned int i=0; isetDefaults(stateset); } - CompositeStateSetController::CompositeStateSetController() + CompositeStateSetUpdater::CompositeStateSetUpdater() { } - CompositeStateSetController::CompositeStateSetController(const CompositeStateSetController ©, const osg::CopyOp ©op) - : StateSetController(copy, copyop) - , mCtrls(copy.mCtrls) + CompositeStateSetUpdater::CompositeStateSetUpdater(const CompositeStateSetUpdater ©, const osg::CopyOp ©op) + : StateSetUpdater(copy, copyop) { + for (unsigned int i=0; i(osg::clone(copy.mCtrls[i].get(), copyop))); } - unsigned int CompositeStateSetController::getNumControllers() + unsigned int CompositeStateSetUpdater::getNumControllers() { return mCtrls.size(); } - void CompositeStateSetController::addController(StateSetController *ctrl) + StateSetUpdater* CompositeStateSetUpdater::getController(int i) + { + return mCtrls[i]; + } + + void CompositeStateSetUpdater::addController(StateSetUpdater *ctrl) { mCtrls.push_back(ctrl); } diff --git a/components/sceneutil/statesetcontroller.hpp b/components/sceneutil/statesetupdater.hpp similarity index 77% rename from components/sceneutil/statesetcontroller.hpp rename to components/sceneutil/statesetupdater.hpp index e34332e5f..56f832a08 100644 --- a/components/sceneutil/statesetcontroller.hpp +++ b/components/sceneutil/statesetupdater.hpp @@ -15,14 +15,14 @@ namespace SceneUtil /// the first StateSet is the one we can write to, the second is the one currently in use by the draw traversal of the last frame. /// After a frame is completed the places are swapped. /// @par Must be set as UpdateCallback on a Node. - /// @note Do not add multiple StateSetControllers on the same Node as they will conflict - instead use the CompositeStateSetController. - class StateSetController : public osg::NodeCallback + /// @note Do not add multiple StateSetControllers on the same Node as they will conflict - instead use the CompositeStateSetUpdater. + class StateSetUpdater : public osg::NodeCallback { public: - StateSetController(); - StateSetController(const StateSetController& copy, const osg::CopyOp& copyop); + StateSetUpdater(); + StateSetUpdater(const StateSetUpdater& copy, const osg::CopyOp& copyop); - META_Object(SceneUtil, StateSetController) + META_Object(SceneUtil, StateSetUpdater) virtual void operator()(osg::Node* node, osg::NodeVisitor* nv); @@ -40,17 +40,18 @@ namespace SceneUtil }; /// @brief A variant of the StateSetController that can be made up of multiple controllers all controlling the same target. - class CompositeStateSetController : public StateSetController + class CompositeStateSetUpdater : public StateSetUpdater { public: - CompositeStateSetController(); - CompositeStateSetController(const CompositeStateSetController& copy, const osg::CopyOp& copyop); + CompositeStateSetUpdater(); + CompositeStateSetUpdater(const CompositeStateSetUpdater& copy, const osg::CopyOp& copyop); - META_Object(SceneUtil, CompositeStateSetController) + META_Object(SceneUtil, CompositeStateSetUpdater) unsigned int getNumControllers(); + StateSetUpdater* getController(int i); - void addController(StateSetController* ctrl); + void addController(StateSetUpdater* ctrl); virtual void apply(osg::StateSet* stateset, osg::NodeVisitor* nv); @@ -58,7 +59,7 @@ namespace SceneUtil virtual void setDefaults(osg::StateSet *stateset); - std::vector > mCtrls; + std::vector > mCtrls; }; }