#include "controller.hpp" #include <algorithm> #include "statesetupdater.hpp" #include <osg/Drawable> #include <osg/Geometry> #include <osg/MatrixTransform> #include <osg/NodeCallback> namespace SceneUtil { Controller::Controller() {} bool Controller::hasInput() const { return mSource.get() != nullptr; } float Controller::getInputValue(osg::NodeVisitor* nv) { if (mFunction) return mFunction->calculate(mSource->getValue(nv)); else return mSource->getValue(nv); } void Controller::setSource(std::shared_ptr<ControllerSource> source) { mSource = std::move(source); } void Controller::setFunction(std::shared_ptr<ControllerFunction> function) { mFunction = std::move(function); } std::shared_ptr<ControllerSource> Controller::getSource() const { return mSource; } std::shared_ptr<ControllerFunction> Controller::getFunction() const { return mFunction; } FrameTimeSource::FrameTimeSource() {} float FrameTimeSource::getValue(osg::NodeVisitor* nv) { return nv->getFrameStamp()->getSimulationTime(); } ControllerVisitor::ControllerVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) { } void ControllerVisitor::apply(osg::Node& node) { applyNode(node); } void ControllerVisitor::apply(osg::MatrixTransform& node) { applyNode(node); } void ControllerVisitor::apply(osg::Geometry& node) { applyNode(node); } void ControllerVisitor::applyNode(osg::Node& node) { osg::Callback* callback = node.getUpdateCallback(); while (callback) { if (Controller* ctrl = dynamic_cast<Controller*>(callback)) visit(node, *ctrl); if (CompositeStateSetUpdater* composite = dynamic_cast<CompositeStateSetUpdater*>(callback)) { for (unsigned int i = 0; i < composite->getNumControllers(); ++i) { StateSetUpdater* statesetcontroller = composite->getController(i); if (Controller* ctrl = dynamic_cast<Controller*>(statesetcontroller)) visit(node, *ctrl); } } callback = callback->getNestedCallback(); } if (node.getNumChildrenRequiringUpdateTraversal() > 0) traverse(node); } AssignControllerSourcesVisitor::AssignControllerSourcesVisitor() : ControllerVisitor() { } AssignControllerSourcesVisitor::AssignControllerSourcesVisitor(std::shared_ptr<ControllerSource> toAssign) : ControllerVisitor() , mToAssign(std::move(toAssign)) { } void AssignControllerSourcesVisitor::visit(osg::Node&, Controller& ctrl) { if (!ctrl.getSource()) ctrl.setSource(mToAssign); } ForceControllerSourcesVisitor::ForceControllerSourcesVisitor() : AssignControllerSourcesVisitor() { } ForceControllerSourcesVisitor::ForceControllerSourcesVisitor(std::shared_ptr<ControllerSource> toAssign) : AssignControllerSourcesVisitor(std::move(toAssign)) { } void ForceControllerSourcesVisitor::visit(osg::Node&, Controller& ctrl) { ctrl.setSource(mToAssign); } FindMaxControllerLengthVisitor::FindMaxControllerLengthVisitor() : SceneUtil::ControllerVisitor() , mMaxLength(0) { } void FindMaxControllerLengthVisitor::visit(osg::Node&, Controller& ctrl) { if (ctrl.getFunction()) mMaxLength = std::max(mMaxLength, ctrl.getFunction()->getMaximum()); } float FindMaxControllerLengthVisitor::getMaxLength() const { return mMaxLength; } }