converts remaining osg::NodeCallback (#3147)

With this PR we convert remaining instantiations of the deprecated osg::NodeCallback in Open MW to SceneUtil::NodeCallback.
pull/3150/head
Bo Svensson 3 years ago committed by GitHub
parent 8e9851c97c
commit b2af81bc18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -87,22 +87,22 @@ namespace
std::vector<osg::ref_ptr<osg::Node> > mToRemove; std::vector<osg::ref_ptr<osg::Node> > mToRemove;
}; };
class DayNightCallback : public osg::NodeCallback class DayNightCallback : public SceneUtil::NodeCallback<DayNightCallback, osg::Switch*>
{ {
public: public:
DayNightCallback() : mCurrentState(0) DayNightCallback() : mCurrentState(0)
{ {
} }
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::Switch* node, osg::NodeVisitor* nv)
{ {
unsigned int state = MWBase::Environment::get().getWorld()->getNightDayMode(); unsigned int state = MWBase::Environment::get().getWorld()->getNightDayMode();
const unsigned int newState = node->asGroup()->getNumChildren() > state ? state : 0; const unsigned int newState = node->getNumChildren() > state ? state : 0;
if (newState != mCurrentState) if (newState != mCurrentState)
{ {
mCurrentState = newState; mCurrentState = newState;
node->asSwitch()->setSingleChildOn(mCurrentState); node->setSingleChildOn(mCurrentState);
} }
traverse(node, nv); traverse(node, nv);
@ -472,20 +472,18 @@ namespace MWRender
} }
} }
class ResetAccumRootCallback : public osg::NodeCallback class ResetAccumRootCallback : public SceneUtil::NodeCallback<ResetAccumRootCallback, osg::MatrixTransform*>
{ {
public: public:
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::MatrixTransform* transform, osg::NodeVisitor* nv)
{ {
osg::MatrixTransform* transform = static_cast<osg::MatrixTransform*>(node);
osg::Matrix mat = transform->getMatrix(); osg::Matrix mat = transform->getMatrix();
osg::Vec3f position = mat.getTrans(); osg::Vec3f position = mat.getTrans();
position = osg::componentMultiply(mResetAxes, position); position = osg::componentMultiply(mResetAxes, position);
mat.setTrans(position); mat.setTrans(position);
transform->setMatrix(mat); transform->setMatrix(mat);
traverse(node, nv); traverse(transform, nv);
} }
void setAccumulate(const osg::Vec3f& accumulate) void setAccumulate(const osg::Vec3f& accumulate)

@ -6,6 +6,7 @@
#include <components/sceneutil/controller.hpp> #include <components/sceneutil/controller.hpp>
#include <components/sceneutil/textkeymap.hpp> #include <components/sceneutil/textkeymap.hpp>
#include <components/sceneutil/util.hpp> #include <components/sceneutil/util.hpp>
#include <components/sceneutil/nodecallback.hpp>
#include <vector> #include <vector>
@ -506,7 +507,7 @@ public:
bool canBeHarvested() const override; bool canBeHarvested() const override;
}; };
class UpdateVfxCallback : public osg::NodeCallback class UpdateVfxCallback : public SceneUtil::NodeCallback<UpdateVfxCallback>
{ {
public: public:
UpdateVfxCallback(EffectParams& params) UpdateVfxCallback(EffectParams& params)
@ -519,7 +520,7 @@ public:
bool mFinished; bool mFinished;
EffectParams mParams; EffectParams mParams;
void operator()(osg::Node* node, osg::NodeVisitor* nv) override; void operator()(osg::Node* node, osg::NodeVisitor* nv);
private: private:
double mStartingTime; double mStartingTime;

@ -5,6 +5,7 @@
#include <components/misc/mathutil.hpp> #include <components/misc/mathutil.hpp>
#include <components/sceneutil/positionattitudetransform.hpp> #include <components/sceneutil/positionattitudetransform.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include <components/sceneutil/nodecallback.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
@ -25,7 +26,7 @@
namespace namespace
{ {
class UpdateRenderCameraCallback : public osg::NodeCallback class UpdateRenderCameraCallback : public SceneUtil::NodeCallback<UpdateRenderCameraCallback, osg::Camera*>
{ {
public: public:
UpdateRenderCameraCallback(MWRender::Camera* cam) UpdateRenderCameraCallback(MWRender::Camera* cam)
@ -33,12 +34,10 @@ public:
{ {
} }
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::Camera* cam, osg::NodeVisitor* nv)
{ {
osg::Camera* cam = static_cast<osg::Camera*>(node);
// traverse first to update animations, in case the camera is attached to an animated node // traverse first to update animations, in case the camera is attached to an animated node
traverse(node, nv); traverse(cam, nv);
mCamera->updateCamera(cam); mCamera->updateCamera(cam);
} }

@ -12,7 +12,7 @@
namespace osg namespace osg
{ {
class Camera; class Camera;
class NodeCallback; class Callback;
class Node; class Node;
} }
@ -82,7 +82,7 @@ namespace MWRender
void updatePosition(); void updatePosition();
float getCameraDistanceCorrection() const; float getCameraDistanceCorrection() const;
osg::ref_ptr<osg::NodeCallback> mUpdateCallback; osg::ref_ptr<osg::Callback> mUpdateCallback;
// Used to rotate player to the direction of view after exiting preview or vanity mode. // Used to rotate player to the direction of view after exiting preview or vanity mode.
osg::Vec3f mDeferredRotation; osg::Vec3f mDeferredRotation;

@ -22,6 +22,7 @@
#include <components/sceneutil/lightmanager.hpp> #include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/shadow.hpp> #include <components/sceneutil/shadow.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include <components/sceneutil/nodecallback.hpp>
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
@ -36,7 +37,7 @@
namespace MWRender namespace MWRender
{ {
class DrawOnceCallback : public osg::NodeCallback class DrawOnceCallback : public SceneUtil::NodeCallback<DrawOnceCallback>
{ {
public: public:
DrawOnceCallback () DrawOnceCallback ()
@ -45,7 +46,7 @@ namespace MWRender
{ {
} }
void operator () (osg::Node* node, osg::NodeVisitor* nv) override void operator () (osg::Node* node, osg::NodeVisitor* nv)
{ {
if (!mRendered) if (!mRendered)
{ {
@ -523,7 +524,7 @@ namespace MWRender
rebuild(); rebuild();
} }
class UpdateCameraCallback : public osg::NodeCallback class UpdateCameraCallback : public SceneUtil::NodeCallback<UpdateCameraCallback, osg::Camera*>
{ {
public: public:
UpdateCameraCallback(osg::ref_ptr<const osg::Node> nodeToFollow, const osg::Vec3& posOffset, const osg::Vec3& lookAtOffset) UpdateCameraCallback(osg::ref_ptr<const osg::Node> nodeToFollow, const osg::Vec3& posOffset, const osg::Vec3& lookAtOffset)
@ -533,12 +534,10 @@ namespace MWRender
{ {
} }
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::Camera* cam, osg::NodeVisitor* nv)
{ {
osg::Camera* cam = static_cast<osg::Camera*>(node);
// Update keyframe controllers in the scene graph first... // Update keyframe controllers in the scene graph first...
traverse(node, nv); traverse(cam, nv);
// Now update camera utilizing the updated head position // Now update camera utilizing the updated head position
osg::NodePathList nodepaths = mNodeToFollow->getParentalNodePaths(); osg::NodePathList nodepaths = mNodeToFollow->getParentalNodePaths();

@ -16,6 +16,7 @@
#include <components/sceneutil/workqueue.hpp> #include <components/sceneutil/workqueue.hpp>
#include <components/sceneutil/util.hpp> #include <components/sceneutil/util.hpp>
#include <components/sceneutil/nodecallback.hpp>
#include <components/esm/globalmap.hpp> #include <components/esm/globalmap.hpp>
@ -62,7 +63,7 @@ namespace
} }
class CameraUpdateGlobalCallback : public osg::NodeCallback class CameraUpdateGlobalCallback : public SceneUtil::NodeCallback<CameraUpdateGlobalCallback, osg::Camera*>
{ {
public: public:
CameraUpdateGlobalCallback(MWRender::GlobalMap* parent) CameraUpdateGlobalCallback(MWRender::GlobalMap* parent)
@ -71,14 +72,14 @@ namespace
{ {
} }
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::Camera* node, osg::NodeVisitor* nv)
{ {
if (mRendered) if (mRendered)
{ {
if (mParent->copyResult(static_cast<osg::Camera*>(node), nv->getTraversalNumber())) if (mParent->copyResult(node, nv->getTraversalNumber()))
{ {
node->setNodeMask(0); node->setNodeMask(0);
mParent->markForRemoval(static_cast<osg::Camera*>(node)); mParent->markForRemoval(node);
} }
return; return;
} }

@ -20,6 +20,7 @@
#include <components/sceneutil/shadow.hpp> #include <components/sceneutil/shadow.hpp>
#include <components/sceneutil/util.hpp> #include <components/sceneutil/util.hpp>
#include <components/sceneutil/lightmanager.hpp> #include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/nodecallback.hpp>
#include <components/files/memorystream.hpp> #include <components/files/memorystream.hpp>
#include <components/resource/scenemanager.hpp> #include <components/resource/scenemanager.hpp>
@ -35,7 +36,7 @@
namespace namespace
{ {
class CameraLocalUpdateCallback : public osg::NodeCallback class CameraLocalUpdateCallback : public SceneUtil::NodeCallback<CameraLocalUpdateCallback, osg::Camera*>
{ {
public: public:
CameraLocalUpdateCallback(MWRender::LocalMap* parent) CameraLocalUpdateCallback(MWRender::LocalMap* parent)
@ -44,7 +45,7 @@ namespace
{ {
} }
void operator()(osg::Node* node, osg::NodeVisitor*) override void operator()(osg::Camera* node, osg::NodeVisitor*)
{ {
if (mRendered) if (mRendered)
node->setNodeMask(0); node->setNodeMask(0);
@ -52,12 +53,11 @@ namespace
if (!mRendered) if (!mRendered)
{ {
mRendered = true; mRendered = true;
mParent->markForRemoval(static_cast<osg::Camera*>(node)); mParent->markForRemoval(node);
} }
// Note, we intentionally do not traverse children here. The map camera's scene data is the same as the master camera's, // Note, we intentionally do not traverse children here. The map camera's scene data is the same as the master camera's,
// so it has been updated already. // so it has been updated already.
//traverse(node, nv);
} }
private: private:

@ -148,44 +148,6 @@ public:
float getValue(osg::NodeVisitor* nv) override; float getValue(osg::NodeVisitor* nv) override;
}; };
// --------------------------------------------------------------------------------
/// Subclass RotateController to add a Z-offset for sneaking in first person mode.
/// @note We use inheritance instead of adding another controller, so that we do not have to compute the worldOrient twice.
/// @note Must be set on a MatrixTransform.
class NeckController : public RotateController
{
public:
NeckController(osg::Node* relativeTo)
: RotateController(relativeTo)
{
}
void setOffset(const osg::Vec3f& offset)
{
mOffset = offset;
}
void operator()(osg::Node* node, osg::NodeVisitor* nv) override
{
osg::MatrixTransform* transform = static_cast<osg::MatrixTransform*>(node);
osg::Matrix matrix = transform->getMatrix();
osg::Quat worldOrient = getWorldOrientation(node);
osg::Quat orient = worldOrient * mRotate * worldOrient.inverse() * matrix.getRotate();
matrix.setRotate(orient);
matrix.setTrans(matrix.getTrans() + worldOrient.inverse() * mOffset);
transform->setMatrix(matrix);
traverse(node,nv);
}
private:
osg::Vec3f mOffset;
};
// -------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------
HeadAnimationTime::HeadAnimationTime(const MWWorld::Ptr& reference) HeadAnimationTime::HeadAnimationTime(const MWWorld::Ptr& reference)
@ -954,7 +916,7 @@ void NpcAnimation::addControllers()
if (found != mNodeMap.end()) if (found != mNodeMap.end())
{ {
osg::MatrixTransform* node = found->second.get(); osg::MatrixTransform* node = found->second.get();
mFirstPersonNeckController = new NeckController(mObjectRoot.get()); mFirstPersonNeckController = new RotateController(mObjectRoot.get());
node->addUpdateCallback(mFirstPersonNeckController); node->addUpdateCallback(mFirstPersonNeckController);
mActiveControllers.emplace_back(node, mFirstPersonNeckController); mActiveControllers.emplace_back(node, mFirstPersonNeckController);
} }

@ -24,7 +24,7 @@ namespace MWSound
namespace MWRender namespace MWRender
{ {
class NeckController; class RotateController;
class HeadAnimationTime; class HeadAnimationTime;
class NpcAnimation : public ActorAnimation, public WeaponAnimation, public MWWorld::InventoryStoreListener class NpcAnimation : public ActorAnimation, public WeaponAnimation, public MWWorld::InventoryStoreListener
@ -96,7 +96,7 @@ private:
void setRenderBin(); void setRenderBin();
osg::ref_ptr<NeckController> mFirstPersonNeckController; osg::ref_ptr<RotateController> mFirstPersonNeckController;
static bool isFirstPersonPart(const ESM::BodyPart* bodypart); static bool isFirstPersonPart(const ESM::BodyPart* bodypart);
static bool isFemalePart(const ESM::BodyPart* bodypart); static bool isFemalePart(const ESM::BodyPart* bodypart);

@ -10,6 +10,7 @@
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include <components/sceneutil/util.hpp> #include <components/sceneutil/util.hpp>
#include <components/sceneutil/nodecallback.hpp>
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include "vismask.hpp" #include "vismask.hpp"
@ -33,7 +34,7 @@ namespace
return geom; return geom;
} }
class CullCallback : public osg::NodeCallback class CullCallback : public SceneUtil::NodeCallback<CullCallback, osg::Node*, osgUtil::CullVisitor*>
{ {
public: public:
CullCallback() CullCallback()
@ -41,12 +42,11 @@ namespace
{ {
} }
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::Node* node, osgUtil::CullVisitor* cv)
{ {
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(nv);
osgUtil::RenderStage* renderStage = cv->getCurrentRenderStage(); osgUtil::RenderStage* renderStage = cv->getCurrentRenderStage();
unsigned int frame = nv->getTraversalNumber(); unsigned int frame = cv->getTraversalNumber();
if (frame != mLastFrameNumber) if (frame != mLastFrameNumber)
{ {
mLastFrameNumber = frame; mLastFrameNumber = frame;
@ -56,7 +56,7 @@ namespace
if (!postProcessor) if (!postProcessor)
{ {
Log(Debug::Error) << "Failed retrieving user data for master camera: FBO setup failed"; Log(Debug::Error) << "Failed retrieving user data for master camera: FBO setup failed";
traverse(node, nv); traverse(node, cv);
return; return;
} }
@ -71,7 +71,7 @@ namespace
} }
} }
traverse(node, nv); traverse(node, cv);
} }
private: private:

@ -22,21 +22,27 @@ void RotateController::setRotate(const osg::Quat &rotate)
mRotate = rotate; mRotate = rotate;
} }
void RotateController::operator()(osg::Node *node, osg::NodeVisitor *nv) void RotateController::setOffset(const osg::Vec3f& offset)
{
mOffset = offset;
}
void RotateController::operator()(osg::MatrixTransform *node, osg::NodeVisitor *nv)
{ {
if (!mEnabled) if (!mEnabled)
{ {
traverse(node, nv); traverse(node, nv);
return; return;
} }
osg::MatrixTransform* transform = static_cast<osg::MatrixTransform*>(node); osg::Matrix matrix = node->getMatrix();
osg::Matrix matrix = transform->getMatrix();
osg::Quat worldOrient = getWorldOrientation(node); osg::Quat worldOrient = getWorldOrientation(node);
osg::Quat worldOrientInverse = worldOrient.inverse();
osg::Quat orient = worldOrient * mRotate * worldOrient.inverse() * matrix.getRotate(); osg::Quat orient = worldOrient * mRotate * worldOrientInverse * matrix.getRotate();
matrix.setRotate(orient); matrix.setRotate(orient);
matrix.setTrans(matrix.getTrans() + worldOrientInverse * mOffset);
transform->setMatrix(matrix); node->setMatrix(matrix);
traverse(node,nv); traverse(node,nv);
} }

@ -1,31 +1,36 @@
#ifndef OPENMW_MWRENDER_ROTATECONTROLLER_H #ifndef OPENMW_MWRENDER_ROTATECONTROLLER_H
#define OPENMW_MWRENDER_ROTATECONTROLLER_H #define OPENMW_MWRENDER_ROTATECONTROLLER_H
#include <osg/NodeCallback> #include <components/sceneutil/nodecallback.hpp>
#include <osg/Quat> #include <osg/Quat>
namespace osg
{
class MatrixTransform;
}
namespace MWRender namespace MWRender
{ {
/// Applies a rotation in \a relativeTo's space. /// Applies a rotation in \a relativeTo's space.
/// @note Assumes that the node being rotated has its "original" orientation set every frame by a different controller. /// @note Assumes that the node being rotated has its "original" orientation set every frame by a different controller.
/// The rotation is then applied on top of that orientation. /// The rotation is then applied on top of that orientation.
/// @note Must be set on a MatrixTransform. class RotateController : public SceneUtil::NodeCallback<RotateController, osg::MatrixTransform*>
class RotateController : public osg::NodeCallback
{ {
public: public:
RotateController(osg::Node* relativeTo); RotateController(osg::Node* relativeTo);
void setEnabled(bool enabled); void setEnabled(bool enabled);
void setOffset(const osg::Vec3f& offset);
void setRotate(const osg::Quat& rotate); void setRotate(const osg::Quat& rotate);
void operator()(osg::Node* node, osg::NodeVisitor* nv) override; void operator()(osg::MatrixTransform* node, osg::NodeVisitor* nv);
protected: protected:
osg::Quat getWorldOrientation(osg::Node* node); osg::Quat getWorldOrientation(osg::Node* node);
bool mEnabled; bool mEnabled;
osg::Vec3f mOffset;
osg::Quat mRotate; osg::Quat mRotate;
osg::Node* mRelativeTo; osg::Node* mRelativeTo;
}; };

@ -44,6 +44,7 @@
#include <components/sceneutil/controller.hpp> #include <components/sceneutil/controller.hpp>
#include <components/sceneutil/visitor.hpp> #include <components/sceneutil/visitor.hpp>
#include <components/sceneutil/shadow.hpp> #include <components/sceneutil/shadow.hpp>
#include <components/sceneutil/nodecallback.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
@ -301,13 +302,11 @@ public:
return osg::BoundingSphere(osg::Vec3f(0,0,0), 0); return osg::BoundingSphere(osg::Vec3f(0,0,0), 0);
} }
class CullCallback : public osg::NodeCallback class CullCallback : public SceneUtil::NodeCallback<CullCallback, osg::Node*, osgUtil::CullVisitor*>
{ {
public: public:
void operator() (osg::Node* node, osg::NodeVisitor* nv) override void operator() (osg::Node* node, osgUtil::CullVisitor* cv)
{ {
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(nv);
// XXX have to remove unwanted culling plane of the water reflection camera // XXX have to remove unwanted culling plane of the water reflection camera
// Remove all planes that aren't from the standard frustum // Remove all planes that aren't from the standard frustum
@ -336,7 +335,7 @@ public:
cv->getProjectionCullingStack().back().pushCurrentMask(); cv->getProjectionCullingStack().back().pushCurrentMask();
cv->getCurrentCullingSet().pushCurrentMask(); cv->getCurrentCullingSet().pushCurrentMask();
traverse(node, nv); traverse(node, cv);
cv->getProjectionCullingStack().back().popCurrentMask(); cv->getProjectionCullingStack().back().popCurrentMask();
cv->getCurrentCullingSet().popCurrentMask(); cv->getCurrentCullingSet().popCurrentMask();
@ -398,7 +397,7 @@ private:
/// @note Must be added as cull callback. /// @note Must be added as cull callback.
/// @note Meant to be used on a node that is child of a CameraRelativeTransform. /// @note Meant to be used on a node that is child of a CameraRelativeTransform.
/// The current view point must be retrieved by the CameraRelativeTransform since we can't get it anymore once we are in camera-relative space. /// The current view point must be retrieved by the CameraRelativeTransform since we can't get it anymore once we are in camera-relative space.
class UnderwaterSwitchCallback : public osg::NodeCallback class UnderwaterSwitchCallback : public SceneUtil::NodeCallback<UnderwaterSwitchCallback>
{ {
public: public:
UnderwaterSwitchCallback(CameraRelativeTransform* cameraRelativeTransform) UnderwaterSwitchCallback(CameraRelativeTransform* cameraRelativeTransform)
@ -414,7 +413,7 @@ public:
return mEnabled && viewPoint.z() < mWaterLevel; return mEnabled && viewPoint.z() < mWaterLevel;
} }
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::Node* node, osg::NodeVisitor* nv)
{ {
if (isUnderwater()) if (isUnderwater())
return; return;
@ -717,7 +716,7 @@ private:
} }
}; };
class OcclusionCallback : public osg::NodeCallback class OcclusionCallback
{ {
public: public:
OcclusionCallback(osg::ref_ptr<osg::OcclusionQueryNode> oqnVisible, osg::ref_ptr<osg::OcclusionQueryNode> oqnTotal) OcclusionCallback(osg::ref_ptr<osg::OcclusionQueryNode> oqnVisible, osg::ref_ptr<osg::OcclusionQueryNode> oqnTotal)
@ -760,7 +759,7 @@ private:
}; };
/// SunFlashCallback handles fading/scaling of a node depending on occlusion query result. Must be attached as a cull callback. /// SunFlashCallback handles fading/scaling of a node depending on occlusion query result. Must be attached as a cull callback.
class SunFlashCallback : public OcclusionCallback class SunFlashCallback : public OcclusionCallback, public SceneUtil::NodeCallback<SunFlashCallback, osg::Node*, osgUtil::CullVisitor*>
{ {
public: public:
SunFlashCallback(osg::ref_ptr<osg::OcclusionQueryNode> oqnVisible, osg::ref_ptr<osg::OcclusionQueryNode> oqnTotal) SunFlashCallback(osg::ref_ptr<osg::OcclusionQueryNode> oqnVisible, osg::ref_ptr<osg::OcclusionQueryNode> oqnTotal)
@ -769,10 +768,8 @@ private:
{ {
} }
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::Node* node, osgUtil::CullVisitor* cv)
{ {
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(nv);
float visibleRatio = getVisibleRatio(cv->getCurrentCamera()); float visibleRatio = getVisibleRatio(cv->getCurrentCamera());
osg::ref_ptr<osg::StateSet> stateset; osg::ref_ptr<osg::StateSet> stateset;
@ -811,7 +808,7 @@ private:
cv->pushModelViewMatrix(new osg::RefMatrix(modelView), osg::Transform::RELATIVE_RF); cv->pushModelViewMatrix(new osg::RefMatrix(modelView), osg::Transform::RELATIVE_RF);
traverse(node, nv); traverse(node, cv);
cv->popModelViewMatrix(); cv->popModelViewMatrix();
@ -832,7 +829,7 @@ private:
/// SunGlareCallback controls a full-screen glare effect depending on occlusion query result and the angle between sun and camera. /// SunGlareCallback controls a full-screen glare effect depending on occlusion query result and the angle between sun and camera.
/// Must be attached as a cull callback to the node above the glare node. /// Must be attached as a cull callback to the node above the glare node.
class SunGlareCallback : public OcclusionCallback class SunGlareCallback : public OcclusionCallback, public SceneUtil::NodeCallback<SunGlareCallback, osg::Node*, osgUtil::CullVisitor*>
{ {
public: public:
SunGlareCallback(osg::ref_ptr<osg::OcclusionQueryNode> oqnVisible, osg::ref_ptr<osg::OcclusionQueryNode> oqnTotal, SunGlareCallback(osg::ref_ptr<osg::OcclusionQueryNode> oqnVisible, osg::ref_ptr<osg::OcclusionQueryNode> oqnTotal,
@ -854,10 +851,8 @@ private:
mColor[i] = std::min(1.f, mColor[i]); mColor[i] = std::min(1.f, mColor[i]);
} }
void operator ()(osg::Node* node, osg::NodeVisitor* nv) override void operator ()(osg::Node* node, osgUtil::CullVisitor* cv)
{ {
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(nv);
float angleRadians = getAngleToSunInRadians(*cv->getCurrentRenderStage()->getInitialViewMatrix()); float angleRadians = getAngleToSunInRadians(*cv->getCurrentRenderStage()->getInitialViewMatrix());
float visibleRatio = getVisibleRatio(cv->getCurrentCamera()); float visibleRatio = getVisibleRatio(cv->getCurrentCamera());
@ -885,7 +880,7 @@ private:
stateset->setAttributeAndModes(mat, osg::StateAttribute::ON); stateset->setAttributeAndModes(mat, osg::StateAttribute::ON);
cv->pushStateSet(stateset); cv->pushStateSet(stateset);
traverse(node, nv); traverse(node, cv);
cv->popStateSet(); cv->popStateSet();
} }
} }

@ -58,20 +58,17 @@ namespace MWRender
/// To use, simply create the scene as subgraph of this node, then do setPlane(const osg::Plane& plane); /// To use, simply create the scene as subgraph of this node, then do setPlane(const osg::Plane& plane);
class ClipCullNode : public osg::Group class ClipCullNode : public osg::Group
{ {
class PlaneCullCallback : public osg::NodeCallback class PlaneCullCallback : public SceneUtil::NodeCallback<PlaneCullCallback, osg::Node*, osgUtil::CullVisitor*>
{ {
public: public:
/// @param cullPlane The culling plane (in world space). /// @param cullPlane The culling plane (in world space).
PlaneCullCallback(const osg::Plane* cullPlane) PlaneCullCallback(const osg::Plane* cullPlane)
: osg::NodeCallback() : mCullPlane(cullPlane)
, mCullPlane(cullPlane)
{ {
} }
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::Node* node, osgUtil::CullVisitor* cv)
{ {
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(nv);
osg::Polytope::PlaneList origPlaneList = cv->getProjectionCullingStack().back().getFrustum().getPlaneList(); osg::Polytope::PlaneList origPlaneList = cv->getProjectionCullingStack().back().getFrustum().getPlaneList();
osg::Plane plane = *mCullPlane; osg::Plane plane = *mCullPlane;
@ -83,7 +80,7 @@ class ClipCullNode : public osg::Group
cv->getProjectionCullingStack().back().getFrustum().add(plane); cv->getProjectionCullingStack().back().getFrustum().add(plane);
traverse(node, nv); traverse(node, cv);
// undo // undo
cv->getProjectionCullingStack().back().getFrustum().set(origPlaneList); cv->getProjectionCullingStack().back().getFrustum().set(origPlaneList);
@ -93,7 +90,7 @@ class ClipCullNode : public osg::Group
const osg::Plane* mCullPlane; const osg::Plane* mCullPlane;
}; };
class FlipCallback : public osg::NodeCallback class FlipCallback : public SceneUtil::NodeCallback<FlipCallback, osg::Node*, osgUtil::CullVisitor*>
{ {
public: public:
FlipCallback(const osg::Plane* cullPlane) FlipCallback(const osg::Plane* cullPlane)
@ -101,9 +98,8 @@ class ClipCullNode : public osg::Group
{ {
} }
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::Node* node, osgUtil::CullVisitor* cv)
{ {
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(nv);
osg::Vec3d eyePoint = cv->getEyePoint(); osg::Vec3d eyePoint = cv->getEyePoint();
osg::RefMatrix* modelViewMatrix = new osg::RefMatrix(*cv->getModelViewMatrix()); osg::RefMatrix* modelViewMatrix = new osg::RefMatrix(*cv->getModelViewMatrix());
@ -123,7 +119,7 @@ class ClipCullNode : public osg::Group
modelViewMatrix->preMultTranslate(mCullPlane->getNormal() * clipFudge); modelViewMatrix->preMultTranslate(mCullPlane->getNormal() * clipFudge);
cv->pushModelViewMatrix(modelViewMatrix, osg::Transform::RELATIVE_RF); cv->pushModelViewMatrix(modelViewMatrix, osg::Transform::RELATIVE_RF);
traverse(node, nv); traverse(node, cv);
cv->popModelViewMatrix(); cv->popModelViewMatrix();
} }
@ -166,31 +162,28 @@ private:
/// This callback on the Camera has the effect of a RELATIVE_RF_INHERIT_VIEWPOINT transform mode (which does not exist in OSG). /// This callback on the Camera has the effect of a RELATIVE_RF_INHERIT_VIEWPOINT transform mode (which does not exist in OSG).
/// We want to keep the View Point of the parent camera so we will not have to recreate LODs. /// We want to keep the View Point of the parent camera so we will not have to recreate LODs.
class InheritViewPointCallback : public osg::NodeCallback class InheritViewPointCallback : public SceneUtil::NodeCallback<InheritViewPointCallback, osg::Node*, osgUtil::CullVisitor*>
{ {
public: public:
InheritViewPointCallback() {} InheritViewPointCallback() {}
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::Node* node, osgUtil::CullVisitor* cv)
{ {
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(nv);
osg::ref_ptr<osg::RefMatrix> modelViewMatrix = new osg::RefMatrix(*cv->getModelViewMatrix()); osg::ref_ptr<osg::RefMatrix> modelViewMatrix = new osg::RefMatrix(*cv->getModelViewMatrix());
cv->popModelViewMatrix(); cv->popModelViewMatrix();
cv->pushModelViewMatrix(modelViewMatrix, osg::Transform::ABSOLUTE_RF_INHERIT_VIEWPOINT); cv->pushModelViewMatrix(modelViewMatrix, osg::Transform::ABSOLUTE_RF_INHERIT_VIEWPOINT);
traverse(node, nv); traverse(node, cv);
} }
}; };
/// Moves water mesh away from the camera slightly if the camera gets too close on the Z axis. /// Moves water mesh away from the camera slightly if the camera gets too close on the Z axis.
/// The offset works around graphics artifacts that occurred with the GL_DEPTH_CLAMP when the camera gets extremely close to the mesh (seen on NVIDIA at least). /// The offset works around graphics artifacts that occurred with the GL_DEPTH_CLAMP when the camera gets extremely close to the mesh (seen on NVIDIA at least).
/// Must be added as a Cull callback. /// Must be added as a Cull callback.
class FudgeCallback : public osg::NodeCallback class FudgeCallback : public SceneUtil::NodeCallback<FudgeCallback, osg::Node*, osgUtil::CullVisitor*>
{ {
public: public:
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::Node* node, osgUtil::CullVisitor* cv)
{ {
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(nv);
const float fudge = 0.2; const float fudge = 0.2;
if (std::abs(cv->getEyeLocal().z()) < fudge) if (std::abs(cv->getEyeLocal().z()) < fudge)
{ {
@ -203,11 +196,11 @@ public:
modelViewMatrix->preMultTranslate(osg::Vec3f(0,0,diff)); modelViewMatrix->preMultTranslate(osg::Vec3f(0,0,diff));
cv->pushModelViewMatrix(modelViewMatrix, osg::Transform::RELATIVE_RF); cv->pushModelViewMatrix(modelViewMatrix, osg::Transform::RELATIVE_RF);
traverse(node, nv); traverse(node, cv);
cv->popModelViewMatrix(); cv->popModelViewMatrix();
} }
else else
traverse(node, nv); traverse(node, cv);
} }
}; };

@ -6,7 +6,7 @@
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <osg/Vec3f> #include <osg/Vec3f>
#include <osg/Camera> #include <osg/Vec3d>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
@ -16,6 +16,7 @@ namespace osg
class PositionAttitudeTransform; class PositionAttitudeTransform;
class Geometry; class Geometry;
class Node; class Node;
class Callback;
} }
namespace osgUtil namespace osgUtil
@ -72,7 +73,7 @@ namespace MWRender
bool mInterior; bool mInterior;
osg::Callback* mCullCallback; osg::Callback* mCullCallback;
osg::ref_ptr<osg::NodeCallback> mShaderWaterStateSetUpdater; osg::ref_ptr<osg::Callback> mShaderWaterStateSetUpdater;
osg::Vec3f getSceneNodeCoordinates(int gridX, int gridY); osg::Vec3f getSceneNodeCoordinates(int gridX, int gridY);
void updateVisible(); void updateVisible();

@ -20,6 +20,7 @@
#include <components/sceneutil/controller.hpp> #include <components/sceneutil/controller.hpp>
#include <components/sceneutil/visitor.hpp> #include <components/sceneutil/visitor.hpp>
#include <components/sceneutil/lightmanager.hpp> #include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/nodecallback.hpp>
#include "../mwworld/manualref.hpp" #include "../mwworld/manualref.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
@ -161,7 +162,7 @@ namespace MWWorld
} }
/// Rotates an osg::PositionAttitudeTransform over time. /// Rotates an osg::PositionAttitudeTransform over time.
class RotateCallback : public osg::NodeCallback class RotateCallback : public SceneUtil::NodeCallback<RotateCallback, osg::PositionAttitudeTransform*>
{ {
public: public:
RotateCallback(const osg::Vec3f& axis = osg::Vec3f(0,-1,0), float rotateSpeed = osg::PI*2) RotateCallback(const osg::Vec3f& axis = osg::Vec3f(0,-1,0), float rotateSpeed = osg::PI*2)
@ -170,14 +171,12 @@ namespace MWWorld
{ {
} }
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::PositionAttitudeTransform* node, osg::NodeVisitor* nv)
{ {
osg::PositionAttitudeTransform* transform = static_cast<osg::PositionAttitudeTransform*>(node);
double time = nv->getFrameStamp()->getSimulationTime(); double time = nv->getFrameStamp()->getSimulationTime();
osg::Quat orient = osg::Quat(time * mRotateSpeed, mAxis); osg::Quat orient = osg::Quat(time * mRotateSpeed, mAxis);
transform->setAttitude(orient); node->setAttitude(orient);
traverse(node, nv); traverse(node, nv);
} }

@ -15,6 +15,7 @@
#include <components/resource/imagemanager.hpp> #include <components/resource/imagemanager.hpp>
#include <components/shader/shadermanager.hpp> #include <components/shader/shadermanager.hpp>
#include <components/sceneutil/nodecallback.hpp>
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
@ -51,7 +52,7 @@ class Drawable : public osg::Drawable {
public: public:
// Stage 0: update widget animations and controllers. Run during the Update traversal. // Stage 0: update widget animations and controllers. Run during the Update traversal.
class FrameUpdate : public osg::Drawable::UpdateCallback class FrameUpdate : public SceneUtil::NodeCallback<FrameUpdate>
{ {
public: public:
FrameUpdate() FrameUpdate()
@ -64,9 +65,8 @@ public:
mRenderManager = renderManager; mRenderManager = renderManager;
} }
void update(osg::NodeVisitor*, osg::Drawable*) override void operator()(osg::Node*, osg::NodeVisitor*)
{ {
if (mRenderManager)
mRenderManager->update(); mRenderManager->update();
} }
@ -75,7 +75,7 @@ public:
}; };
// Stage 1: collect draw calls. Run during the Cull traversal. // Stage 1: collect draw calls. Run during the Cull traversal.
class CollectDrawCalls : public osg::Drawable::CullCallback class CollectDrawCalls : public SceneUtil::NodeCallback<CollectDrawCalls>
{ {
public: public:
CollectDrawCalls() CollectDrawCalls()
@ -88,13 +88,9 @@ public:
mRenderManager = renderManager; mRenderManager = renderManager;
} }
bool cull(osg::NodeVisitor*, osg::Drawable*, osg::State*) const override void operator()(osg::Node*, osg::NodeVisitor*)
{ {
if (!mRenderManager)
return false;
mRenderManager->collectDrawCalls(); mRenderManager->collectDrawCalls();
return false;
} }
private: private:

@ -72,7 +72,7 @@ KeyframeController::KeyframeController()
KeyframeController::KeyframeController(const KeyframeController &copy, const osg::CopyOp &copyop) KeyframeController::KeyframeController(const KeyframeController &copy, const osg::CopyOp &copyop)
: SceneUtil::KeyframeController(copy, copyop) : SceneUtil::KeyframeController(copy, copyop)
, SceneUtil::NodeCallback<KeyframeController>(copy, copyop) , SceneUtil::NodeCallback<KeyframeController, NifOsg::MatrixTransform*>(copy, copyop)
, mRotations(copy.mRotations) , mRotations(copy.mRotations)
, mXRotations(copy.mXRotations) , mXRotations(copy.mXRotations)
, mYRotations(copy.mYRotations) , mYRotations(copy.mYRotations)
@ -134,16 +134,15 @@ osg::Vec3f KeyframeController::getTranslation(float time) const
return osg::Vec3f(); return osg::Vec3f();
} }
void KeyframeController::operator() (osg::Node* node, osg::NodeVisitor* nv) void KeyframeController::operator() (NifOsg::MatrixTransform* node, osg::NodeVisitor* nv)
{ {
if (hasInput()) if (hasInput())
{ {
NifOsg::MatrixTransform* trans = static_cast<NifOsg::MatrixTransform*>(node); osg::Matrix mat = node->getMatrix();
osg::Matrix mat = trans->getMatrix();
float time = getInputValue(nv); float time = getInputValue(nv);
Nif::Matrix3& rot = trans->mRotationScale; Nif::Matrix3& rot = node->mRotationScale;
bool setRot = false; bool setRot = false;
if(!mRotations.empty()) if(!mRotations.empty())
@ -169,7 +168,7 @@ void KeyframeController::operator() (osg::Node* node, osg::NodeVisitor* nv)
for (int j=0;j<3;++j) for (int j=0;j<3;++j)
rot.mValues[i][j] = mat(j,i); // NB column/row major difference rot.mValues[i][j] = mat(j,i); // NB column/row major difference
float& scale = trans->mScale; float& scale = node->mScale;
if(!mScales.empty()) if(!mScales.empty())
scale = mScales.interpKey(time); scale = mScales.interpKey(time);
@ -180,7 +179,7 @@ void KeyframeController::operator() (osg::Node* node, osg::NodeVisitor* nv)
if(!mTranslations.empty()) if(!mTranslations.empty())
mat.setTrans(mTranslations.interpKey(time)); mat.setTrans(mTranslations.interpKey(time));
trans->setMatrix(mat); node->setMatrix(mat);
} }
traverse(node, nv); traverse(node, nv);
@ -191,8 +190,8 @@ GeomMorpherController::GeomMorpherController()
} }
GeomMorpherController::GeomMorpherController(const GeomMorpherController &copy, const osg::CopyOp &copyop) GeomMorpherController::GeomMorpherController(const GeomMorpherController &copy, const osg::CopyOp &copyop)
: osg::Drawable::UpdateCallback(copy, copyop) : Controller(copy)
, Controller(copy) , SceneUtil::NodeCallback<GeomMorpherController, SceneUtil::MorphGeometry*>(copy, copyop)
, mKeyFrames(copy.mKeyFrames) , mKeyFrames(copy.mKeyFrames)
{ {
} }
@ -218,9 +217,8 @@ GeomMorpherController::GeomMorpherController(const Nif::NiGeomMorpherController*
} }
} }
void GeomMorpherController::update(osg::NodeVisitor *nv, osg::Drawable *drawable) void GeomMorpherController::operator()(SceneUtil::MorphGeometry* node, osg::NodeVisitor *nv)
{ {
SceneUtil::MorphGeometry* morphGeom = static_cast<SceneUtil::MorphGeometry*>(drawable);
if (hasInput()) if (hasInput())
{ {
if (mKeyFrames.size() <= 1) if (mKeyFrames.size() <= 1)
@ -233,11 +231,11 @@ void GeomMorpherController::update(osg::NodeVisitor *nv, osg::Drawable *drawable
if (!(*it).empty()) if (!(*it).empty())
val = it->interpKey(input); val = it->interpKey(input);
SceneUtil::MorphGeometry::MorphTarget& target = morphGeom->getMorphTarget(i); SceneUtil::MorphGeometry::MorphTarget& target = node->getMorphTarget(i);
if (target.getWeight() != val) if (target.getWeight() != val)
{ {
target.setWeight(val); target.setWeight(val);
morphGeom->dirty(); node->dirty();
} }
} }
} }
@ -312,7 +310,7 @@ VisController::VisController()
} }
VisController::VisController(const VisController &copy, const osg::CopyOp &copyop) VisController::VisController(const VisController &copy, const osg::CopyOp &copyop)
: osg::NodeCallback(copy, copyop) : SceneUtil::NodeCallback<VisController>(copy, copyop)
, Controller(copy) , Controller(copy)
, mData(copy.mData) , mData(copy.mData)
, mMask(copy.mMask) , mMask(copy.mMask)
@ -353,14 +351,14 @@ RollController::RollController(const Nif::NiFloatInterpolator* interpolator)
} }
RollController::RollController(const RollController &copy, const osg::CopyOp &copyop) RollController::RollController(const RollController &copy, const osg::CopyOp &copyop)
: osg::NodeCallback(copy, copyop) : SceneUtil::NodeCallback<RollController, osg::MatrixTransform*>(copy, copyop)
, Controller(copy) , Controller(copy)
, mData(copy.mData) , mData(copy.mData)
, mStartingTime(copy.mStartingTime) , mStartingTime(copy.mStartingTime)
{ {
} }
void RollController::operator() (osg::Node* node, osg::NodeVisitor* nv) void RollController::operator() (osg::MatrixTransform* node, osg::NodeVisitor* nv)
{ {
traverse(node, nv); traverse(node, nv);
@ -371,15 +369,14 @@ void RollController::operator() (osg::Node* node, osg::NodeVisitor* nv)
mStartingTime = newTime; mStartingTime = newTime;
float value = mData.interpKey(getInputValue(nv)); float value = mData.interpKey(getInputValue(nv));
osg::MatrixTransform* transform = static_cast<osg::MatrixTransform*>(node); osg::Matrix matrix = node->getMatrix();
osg::Matrix matrix = transform->getMatrix();
// Rotate around "roll" axis. // Rotate around "roll" axis.
// Note: in original game rotation speed is the framerate-dependent in a very tricky way. // Note: in original game rotation speed is the framerate-dependent in a very tricky way.
// Do not replicate this behaviour until we will really need it. // Do not replicate this behaviour until we will really need it.
// For now consider controller's current value as an angular speed in radians per 1/60 seconds. // For now consider controller's current value as an angular speed in radians per 1/60 seconds.
matrix = osg::Matrix::rotate(value * duration * 60.f, 0, 0, 1) * matrix; matrix = osg::Matrix::rotate(value * duration * 60.f, 0, 0, 1) * matrix;
transform->setMatrix(matrix); node->setMatrix(matrix);
} }
} }
@ -545,29 +542,28 @@ ParticleSystemController::ParticleSystemController()
} }
ParticleSystemController::ParticleSystemController(const ParticleSystemController &copy, const osg::CopyOp &copyop) ParticleSystemController::ParticleSystemController(const ParticleSystemController &copy, const osg::CopyOp &copyop)
: osg::NodeCallback(copy, copyop) : SceneUtil::NodeCallback<ParticleSystemController, osgParticle::ParticleProcessor*>(copy, copyop)
, Controller(copy) , Controller(copy)
, mEmitStart(copy.mEmitStart) , mEmitStart(copy.mEmitStart)
, mEmitStop(copy.mEmitStop) , mEmitStop(copy.mEmitStop)
{ {
} }
void ParticleSystemController::operator() (osg::Node* node, osg::NodeVisitor* nv) void ParticleSystemController::operator() (osgParticle::ParticleProcessor* node, osg::NodeVisitor* nv)
{ {
osgParticle::ParticleProcessor* emitter = static_cast<osgParticle::ParticleProcessor*>(node);
if (hasInput()) if (hasInput())
{ {
float time = getInputValue(nv); float time = getInputValue(nv);
emitter->getParticleSystem()->setFrozen(false); node->getParticleSystem()->setFrozen(false);
emitter->setEnabled(time >= mEmitStart && time < mEmitStop); node->setEnabled(time >= mEmitStart && time < mEmitStop);
} }
else else
emitter->getParticleSystem()->setFrozen(true); node->getParticleSystem()->setFrozen(true);
traverse(node, nv); traverse(node, nv);
} }
PathController::PathController(const PathController &copy, const osg::CopyOp &copyop) PathController::PathController(const PathController &copy, const osg::CopyOp &copyop)
: osg::NodeCallback(copy, copyop) : SceneUtil::NodeCallback<PathController, osg::MatrixTransform*>(copy, copyop)
, Controller(copy) , Controller(copy)
, mPath(copy.mPath) , mPath(copy.mPath)
, mPercent(copy.mPercent) , mPercent(copy.mPercent)
@ -592,7 +588,7 @@ float PathController::getPercent(float time) const
return percent; return percent;
} }
void PathController::operator() (osg::Node* node, osg::NodeVisitor* nv) void PathController::operator() (osg::MatrixTransform* node, osg::NodeVisitor* nv)
{ {
if (mPath.empty() || mPercent.empty() || !hasInput()) if (mPath.empty() || mPercent.empty() || !hasInput())
{ {
@ -600,14 +596,13 @@ void PathController::operator() (osg::Node* node, osg::NodeVisitor* nv)
return; return;
} }
osg::MatrixTransform* trans = static_cast<osg::MatrixTransform*>(node); osg::Matrix mat = node->getMatrix();
osg::Matrix mat = trans->getMatrix();
float time = getInputValue(nv); float time = getInputValue(nv);
float percent = getPercent(time); float percent = getPercent(time);
osg::Vec3f pos(mPath.interpKey(percent)); osg::Vec3f pos(mPath.interpKey(percent));
mat.setTrans(pos); mat.setTrans(pos);
trans->setMatrix(mat); node->setMatrix(mat);
traverse(node, nv); traverse(node, nv);
} }

@ -15,19 +15,27 @@
#include <osg/Texture2D> #include <osg/Texture2D>
#include <osg/StateSet>
#include <osg/NodeCallback>
#include <osg/Drawable>
namespace osg namespace osg
{ {
class Material; class Material;
class MatrixTransform;
}
namespace osgParticle
{
class ParticleProcessor;
}
namespace SceneUtil
{
class MorphGeometry;
} }
namespace NifOsg namespace NifOsg
{ {
class MatrixTransform;
// interpolation of keyframes // interpolation of keyframes
template <typename MapT> template <typename MapT>
class ValueInterpolator class ValueInterpolator
@ -208,8 +216,7 @@ namespace NifOsg
float getMaximum() const override; float getMaximum() const override;
}; };
/// Must be set on a SceneUtil::MorphGeometry. class GeomMorpherController : public SceneUtil::Controller, public SceneUtil::NodeCallback<GeomMorpherController, SceneUtil::MorphGeometry*>
class GeomMorpherController : public osg::Drawable::UpdateCallback, public SceneUtil::Controller
{ {
public: public:
GeomMorpherController(const Nif::NiGeomMorpherController* ctrl); GeomMorpherController(const Nif::NiGeomMorpherController* ctrl);
@ -218,13 +225,13 @@ namespace NifOsg
META_Object(NifOsg, GeomMorpherController) META_Object(NifOsg, GeomMorpherController)
void update(osg::NodeVisitor* nv, osg::Drawable* drawable) override; void operator()(SceneUtil::MorphGeometry*, osg::NodeVisitor*);
private: private:
std::vector<FloatInterpolator> mKeyFrames; std::vector<FloatInterpolator> mKeyFrames;
}; };
class KeyframeController : public SceneUtil::KeyframeController, public SceneUtil::NodeCallback<KeyframeController> class KeyframeController : public SceneUtil::KeyframeController, public SceneUtil::NodeCallback<KeyframeController, NifOsg::MatrixTransform*>
{ {
public: public:
// This is used if there's no interpolator but there is data (Morrowind meshes). // This is used if there's no interpolator but there is data (Morrowind meshes).
@ -242,7 +249,7 @@ namespace NifOsg
osg::Vec3f getTranslation(float time) const override; osg::Vec3f getTranslation(float time) const override;
void operator() (osg::Node*, osg::NodeVisitor*); void operator() (NifOsg::MatrixTransform*, osg::NodeVisitor*);
private: private:
QuaternionInterpolator mRotations; QuaternionInterpolator mRotations;
@ -277,7 +284,7 @@ namespace NifOsg
std::set<int> mTextureUnits; std::set<int> mTextureUnits;
}; };
class VisController : public osg::NodeCallback, public SceneUtil::Controller class VisController : public SceneUtil::NodeCallback<VisController>, public SceneUtil::Controller
{ {
private: private:
std::vector<Nif::NiVisData::VisData> mData; std::vector<Nif::NiVisData::VisData> mData;
@ -292,10 +299,10 @@ namespace NifOsg
META_Object(NifOsg, VisController) META_Object(NifOsg, VisController)
void operator() (osg::Node* node, osg::NodeVisitor* nv) override; void operator() (osg::Node* node, osg::NodeVisitor* nv);
}; };
class RollController : public osg::NodeCallback, public SceneUtil::Controller class RollController : public SceneUtil::NodeCallback<RollController, osg::MatrixTransform*>, public SceneUtil::Controller
{ {
private: private:
FloatInterpolator mData; FloatInterpolator mData;
@ -307,7 +314,7 @@ namespace NifOsg
RollController() = default; RollController() = default;
RollController(const RollController& copy, const osg::CopyOp& copyop); RollController(const RollController& copy, const osg::CopyOp& copyop);
void operator() (osg::Node* node, osg::NodeVisitor* nv) override; void operator() (osg::MatrixTransform* node, osg::NodeVisitor* nv);
META_Object(NifOsg, RollController) META_Object(NifOsg, RollController)
}; };
@ -378,7 +385,7 @@ namespace NifOsg
void apply(osg::StateSet *stateset, osg::NodeVisitor *nv) override; void apply(osg::StateSet *stateset, osg::NodeVisitor *nv) override;
}; };
class ParticleSystemController : public osg::NodeCallback, public SceneUtil::Controller class ParticleSystemController : public SceneUtil::NodeCallback<ParticleSystemController, osgParticle::ParticleProcessor*>, public SceneUtil::Controller
{ {
public: public:
ParticleSystemController(const Nif::NiParticleSystemController* ctrl); ParticleSystemController(const Nif::NiParticleSystemController* ctrl);
@ -387,14 +394,14 @@ namespace NifOsg
META_Object(NifOsg, ParticleSystemController) META_Object(NifOsg, ParticleSystemController)
void operator() (osg::Node* node, osg::NodeVisitor* nv) override; void operator() (osgParticle::ParticleProcessor* node, osg::NodeVisitor* nv);
private: private:
float mEmitStart; float mEmitStart;
float mEmitStop; float mEmitStop;
}; };
class PathController : public osg::NodeCallback, public SceneUtil::Controller class PathController : public SceneUtil::NodeCallback<PathController, osg::MatrixTransform*>, public SceneUtil::Controller
{ {
public: public:
PathController(const Nif::NiPathController* ctrl); PathController(const Nif::NiPathController* ctrl);
@ -403,7 +410,7 @@ namespace NifOsg
META_Object(NifOsg, PathController) META_Object(NifOsg, PathController)
void operator() (osg::Node*, osg::NodeVisitor*) override; void operator() (osg::MatrixTransform*, osg::NodeVisitor*);
private: private:
Vec3Interpolator mPath; Vec3Interpolator mPath;

@ -109,24 +109,21 @@ namespace
// NodeCallback used to have a node always oriented towards the camera. The node can have translation and scale // NodeCallback used to have a node always oriented towards the camera. The node can have translation and scale
// set just like a regular MatrixTransform, but the rotation set will be overridden in order to face the camera. // set just like a regular MatrixTransform, but the rotation set will be overridden in order to face the camera.
// Must be set as a cull callback. class BillboardCallback : public SceneUtil::NodeCallback<BillboardCallback, osg::Node*, osgUtil::CullVisitor*>
class BillboardCallback : public osg::NodeCallback
{ {
public: public:
BillboardCallback() BillboardCallback()
{ {
} }
BillboardCallback(const BillboardCallback& copy, const osg::CopyOp& copyop) BillboardCallback(const BillboardCallback& copy, const osg::CopyOp& copyop)
: osg::NodeCallback(copy, copyop) : SceneUtil::NodeCallback<BillboardCallback, osg::Node*, osgUtil::CullVisitor*>(copy, copyop)
{ {
} }
META_Object(NifOsg, BillboardCallback) META_Object(NifOsg, BillboardCallback)
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::Node* node, osgUtil::CullVisitor* cv)
{ {
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(nv);
osg::Matrix modelView = *cv->getModelViewMatrix(); osg::Matrix modelView = *cv->getModelViewMatrix();
// attempt to preserve scale // attempt to preserve scale
@ -143,7 +140,7 @@ namespace
cv->pushModelViewMatrix(new osg::RefMatrix(modelView), osg::Transform::RELATIVE_RF); cv->pushModelViewMatrix(new osg::RefMatrix(modelView), osg::Transform::RELATIVE_RF);
traverse(node, nv); traverse(node, cv);
cv->popModelViewMatrix(); cv->popModelViewMatrix();
} }

@ -68,19 +68,17 @@ void ParticleSystem::drawImplementation(osg::RenderInfo& renderInfo) const
osgParticle::ParticleSystem::drawImplementation(renderInfo); osgParticle::ParticleSystem::drawImplementation(renderInfo);
} }
void InverseWorldMatrix::operator()(osg::Node *node, osg::NodeVisitor *nv) void InverseWorldMatrix::operator()(osg::MatrixTransform *node, osg::NodeVisitor *nv)
{ {
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR) if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{ {
osg::NodePath path = nv->getNodePath(); osg::NodePath path = nv->getNodePath();
path.pop_back(); path.pop_back();
osg::MatrixTransform* trans = static_cast<osg::MatrixTransform*>(node);
osg::Matrix mat = osg::computeLocalToWorld( path ); osg::Matrix mat = osg::computeLocalToWorld( path );
mat.orthoNormalize(mat); // don't undo the scale mat.orthoNormalize(mat); // don't undo the scale
mat.invert(mat); mat.invert(mat);
trans->setMatrix(mat); node->setMatrix(mat);
} }
traverse(node,nv); traverse(node,nv);
} }

@ -8,7 +8,7 @@
#include <osgParticle/Placer> #include <osgParticle/Placer>
#include <osgParticle/Counter> #include <osgParticle/Counter>
#include <osg/NodeCallback> #include <components/sceneutil/nodecallback.hpp>
#include "controller.hpp" // ValueInterpolator #include "controller.hpp" // ValueInterpolator
@ -57,20 +57,20 @@ namespace NifOsg
// Node callback used to set the inverse of the parent's world matrix on the MatrixTransform // Node callback used to set the inverse of the parent's world matrix on the MatrixTransform
// that the callback is attached to. Used for certain particle systems, // that the callback is attached to. Used for certain particle systems,
// so that the particles do not move with the node they are attached to. // so that the particles do not move with the node they are attached to.
class InverseWorldMatrix : public osg::NodeCallback class InverseWorldMatrix : public SceneUtil::NodeCallback<InverseWorldMatrix, osg::MatrixTransform*>
{ {
public: public:
InverseWorldMatrix() InverseWorldMatrix()
{ {
} }
InverseWorldMatrix(const InverseWorldMatrix& copy, const osg::CopyOp& op) InverseWorldMatrix(const InverseWorldMatrix& copy, const osg::CopyOp& copyop)
: osg::Object(), osg::NodeCallback() : osg::Object(copy, copyop), SceneUtil::NodeCallback<InverseWorldMatrix, osg::MatrixTransform*>(copy, copyop)
{ {
} }
META_Object(NifOsg, InverseWorldMatrix) META_Object(NifOsg, InverseWorldMatrix)
void operator()(osg::Node* node, osg::NodeVisitor* nv) override; void operator()(osg::MatrixTransform* node, osg::NodeVisitor* nv);
}; };
class ParticleShooter : public osgParticle::Shooter class ParticleShooter : public osgParticle::Shooter

@ -2,6 +2,7 @@
#include <components/vfs/manager.hpp> #include <components/vfs/manager.hpp>
#include <osg/Stats>
#include <osgAnimation/Animation> #include <osgAnimation/Animation>
#include <osgAnimation/BasicAnimationManager> #include <osgAnimation/BasicAnimationManager>
#include <osgAnimation/Channel> #include <osgAnimation/Channel>

@ -40,16 +40,14 @@
namespace namespace
{ {
class InitWorldSpaceParticlesCallback : public osg::NodeCallback class InitWorldSpaceParticlesCallback : public SceneUtil::NodeCallback<InitWorldSpaceParticlesCallback, osgParticle::ParticleSystem*>
{ {
public: public:
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osgParticle::ParticleSystem* node, osg::NodeVisitor* nv)
{ {
osgParticle::ParticleSystem* partsys = static_cast<osgParticle::ParticleSystem*>(node);
// HACK: Ignore the InverseWorldMatrix transform the particle system is attached to // HACK: Ignore the InverseWorldMatrix transform the particle system is attached to
if (partsys->getNumParents() && partsys->getParent(0)->getNumParents()) if (node->getNumParents() && node->getParent(0)->getNumParents())
transformInitialParticles(partsys, partsys->getParent(0)->getParent(0)); transformInitialParticles(node, node->getParent(0)->getParent(0));
node->removeUpdateCallback(this); node->removeUpdateCallback(this);
} }

@ -26,7 +26,7 @@ namespace SceneUtil
mType = type; mType = type;
} }
void LightController::operator ()(osg::Node* node, osg::NodeVisitor* nv) void LightController::operator ()(SceneUtil::LightSource* node, osg::NodeVisitor* nv)
{ {
double time = nv->getFrameStamp()->getSimulationTime(); double time = nv->getFrameStamp()->getSimulationTime();
if (mStartTime == 0) if (mStartTime == 0)
@ -38,7 +38,7 @@ namespace SceneUtil
if (mType == LT_Normal) if (mType == LT_Normal)
{ {
static_cast<SceneUtil::LightSource*>(node)->getLight(nv->getTraversalNumber())->setDiffuse(mDiffuseColor); node->getLight(nv->getTraversalNumber())->setDiffuse(mDiffuseColor);
traverse(node, nv); traverse(node, nv);
return; return;
} }
@ -62,8 +62,7 @@ namespace SceneUtil
mPhase = mPhase <= 0.5f ? 1.f : 0.25f; mPhase = mPhase <= 0.5f ? 1.f : 0.25f;
} }
auto* lightSource = static_cast<SceneUtil::LightSource*>(node); node->getLight(nv->getTraversalNumber())->setDiffuse(mDiffuseColor * mBrightness * node->getActorFade());
lightSource->getLight(nv->getTraversalNumber())->setDiffuse(mDiffuseColor * mBrightness * lightSource->getActorFade());
traverse(node, nv); traverse(node, nv);
} }

@ -1,15 +1,16 @@
#ifndef OPENMW_COMPONENTS_SCENEUTIL_LIGHTCONTROLLER_H #ifndef OPENMW_COMPONENTS_SCENEUTIL_LIGHTCONTROLLER_H
#define OPENMW_COMPONENTS_SCENEUTIL_LIGHTCONTROLLER_H #define OPENMW_COMPONENTS_SCENEUTIL_LIGHTCONTROLLER_H
#include <osg/NodeCallback> #include <components/sceneutil/nodecallback.hpp>
#include <osg/Vec4f> #include <osg/Vec4f>
namespace SceneUtil namespace SceneUtil
{ {
class LightSource;
/// @brief Controller class to handle a pulsing and/or flickering light /// @brief Controller class to handle a pulsing and/or flickering light
/// @note Must be set on a SceneUtil::LightSource. class LightController : public SceneUtil::NodeCallback<LightController, SceneUtil::LightSource*>
class LightController : public osg::NodeCallback
{ {
public: public:
enum LightType { enum LightType {
@ -26,7 +27,7 @@ namespace SceneUtil
void setDiffuse(const osg::Vec4f& color); void setDiffuse(const osg::Vec4f& color);
void operator()(osg::Node* node, osg::NodeVisitor* nv) override; void operator()(SceneUtil::LightSource* node, osg::NodeVisitor* nv);
private: private:
LightType mType; LightType mType;

@ -650,23 +650,21 @@ namespace SceneUtil
} }
}; };
class LightManagerCullCallback : public osg::NodeCallback class LightManagerCullCallback : public SceneUtil::NodeCallback<LightManagerCullCallback, LightManager*, osgUtil::CullVisitor*>
{ {
public: public:
LightManagerCullCallback(LightManager* lightManager) : mLightManager(lightManager), mLastFrameNumber(0) {} LightManagerCullCallback() : mLastFrameNumber(0) {}
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(LightManager* node, osgUtil::CullVisitor* cv)
{ {
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(nv);
if (mLastFrameNumber != cv->getTraversalNumber()) if (mLastFrameNumber != cv->getTraversalNumber())
{ {
mLastFrameNumber = cv->getTraversalNumber(); mLastFrameNumber = cv->getTraversalNumber();
if (mLightManager->getLightingMethod() == LightingMethod::SingleUBO) if (node->getLightingMethod() == LightingMethod::SingleUBO)
{ {
auto stateset = mLightManager->getStateSet(); auto stateset = node->getStateSet();
auto bo = mLightManager->getLightBuffer(mLastFrameNumber); auto bo = node->getLightBuffer(mLastFrameNumber);
#if OSG_VERSION_GREATER_OR_EQUAL(3,5,7) #if OSG_VERSION_GREATER_OR_EQUAL(3,5,7)
osg::ref_ptr<osg::UniformBufferBinding> ubb = new osg::UniformBufferBinding(static_cast<int>(Resource::SceneManager::UBOBinding::LightBuffer), bo->getData(), 0, bo->getData()->getTotalDataSize()); osg::ref_ptr<osg::UniformBufferBinding> ubb = new osg::UniformBufferBinding(static_cast<int>(Resource::SceneManager::UBOBinding::LightBuffer), bo->getData(), 0, bo->getData()->getTotalDataSize());
@ -676,23 +674,23 @@ namespace SceneUtil
stateset->setAttributeAndModes(ubb, osg::StateAttribute::ON); stateset->setAttributeAndModes(ubb, osg::StateAttribute::ON);
} }
auto sun = mLightManager->getSunlight(); auto sun = node->getSunlight();
if (sun) if (sun)
{ {
// we must defer uploading the transformation to view-space position to deal with different cameras (e.g. reflection RTT). // we must defer uploading the transformation to view-space position to deal with different cameras (e.g. reflection RTT).
if (mLightManager->getLightingMethod() == LightingMethod::PerObjectUniform) if (node->getLightingMethod() == LightingMethod::PerObjectUniform)
{ {
osg::Matrixf lightMat; osg::Matrixf lightMat;
configurePosition(lightMat, sun->getPosition()); configurePosition(lightMat, sun->getPosition());
configureAmbient(lightMat, sun->getAmbient()); configureAmbient(lightMat, sun->getAmbient());
configureDiffuse(lightMat, sun->getDiffuse()); configureDiffuse(lightMat, sun->getDiffuse());
configureSpecular(lightMat, sun->getSpecular()); configureSpecular(lightMat, sun->getSpecular());
mLightManager->setSunlightBuffer(lightMat, mLastFrameNumber); node->setSunlightBuffer(lightMat, mLastFrameNumber);
} }
else else
{ {
auto buf = mLightManager->getLightBuffer(mLastFrameNumber); auto buf = node->getLightBuffer(mLastFrameNumber);
buf->setCachedSunPos(sun->getPosition()); buf->setCachedSunPos(sun->getPosition());
buf->setAmbient(0, sun->getAmbient()); buf->setAmbient(0, sun->getAmbient());
@ -702,11 +700,10 @@ namespace SceneUtil
} }
} }
traverse(node, nv); traverse(node, cv);
} }
private: private:
LightManager* mLightManager;
size_t mLastFrameNumber; size_t mLastFrameNumber;
}; };
@ -899,7 +896,7 @@ namespace SceneUtil
getOrCreateStateSet()->addUniform(new osg::Uniform("PointLightCount", 0)); getOrCreateStateSet()->addUniform(new osg::Uniform("PointLightCount", 0));
addCullCallback(new LightManagerCullCallback(this)); addCullCallback(new LightManagerCullCallback());
} }
LightManager::LightManager(const LightManager &copy, const osg::CopyOp &copyop) LightManager::LightManager(const LightManager &copy, const osg::CopyOp &copyop)

@ -6,23 +6,19 @@
#include <osg/Texture2D> #include <osg/Texture2D>
#include <osgUtil/CullVisitor> #include <osgUtil/CullVisitor>
#include <components/sceneutil/nodecallback.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
namespace SceneUtil namespace SceneUtil
{ {
// RTTNode's cull callback class CullCallback : public SceneUtil::NodeCallback<CullCallback, RTTNode*, osgUtil::CullVisitor*>
class CullCallback : public osg::NodeCallback
{ {
public: public:
CullCallback(RTTNode* group)
: mGroup(group) {}
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(RTTNode* node, osgUtil::CullVisitor* cv)
{ {
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(nv); node->cull(cv);
mGroup->cull(cv);
} }
RTTNode* mGroup;
}; };
RTTNode::RTTNode(uint32_t textureWidth, uint32_t textureHeight, int renderOrderNum, bool doPerViewMapping) RTTNode::RTTNode(uint32_t textureWidth, uint32_t textureHeight, int renderOrderNum, bool doPerViewMapping)
@ -31,7 +27,7 @@ namespace SceneUtil
, mRenderOrderNum(renderOrderNum) , mRenderOrderNum(renderOrderNum)
, mDoPerViewMapping(doPerViewMapping) , mDoPerViewMapping(doPerViewMapping)
{ {
addCullCallback(new CullCallback(this)); addCullCallback(new CullCallback);
setCullingActive(false); setCullingActive(false);
} }

@ -68,7 +68,7 @@ namespace SceneUtil
} }
StateSetUpdater::StateSetUpdater(const StateSetUpdater &copy, const osg::CopyOp &copyop) StateSetUpdater::StateSetUpdater(const StateSetUpdater &copy, const osg::CopyOp &copyop)
: osg::NodeCallback(copy, copyop) : SceneUtil::NodeCallback<StateSetUpdater>(copy, copyop)
{ {
} }

@ -1,7 +1,7 @@
#ifndef OPENMW_COMPONENTS_SCENEUTIL_STATESETCONTROLLER_H #ifndef OPENMW_COMPONENTS_SCENEUTIL_STATESETCONTROLLER_H
#define OPENMW_COMPONENTS_SCENEUTIL_STATESETCONTROLLER_H #define OPENMW_COMPONENTS_SCENEUTIL_STATESETCONTROLLER_H
#include <osg/NodeCallback> #include <components/sceneutil/nodecallback.hpp>
#include <map> #include <map>
#include <array> #include <array>
@ -28,7 +28,7 @@ namespace SceneUtil
/// @note When used as a CullCallback, StateSetUpdater will have no effect on leaf nodes such as osg::Geometry and must be used on branch nodes only. /// @note When used as a CullCallback, StateSetUpdater will have no effect on leaf nodes such as osg::Geometry and must be used on branch nodes only.
/// @note Do not add the same StateSetUpdater to multiple nodes. /// @note Do not add the same StateSetUpdater to multiple nodes.
/// @note Do not add multiple StateSetUpdaters on the same Node as they will conflict - instead use the CompositeStateSetUpdater. /// @note Do not add multiple StateSetUpdaters on the same Node as they will conflict - instead use the CompositeStateSetUpdater.
class StateSetUpdater : public osg::NodeCallback class StateSetUpdater : public SceneUtil::NodeCallback<StateSetUpdater>
{ {
public: public:
StateSetUpdater(); StateSetUpdater();
@ -36,7 +36,7 @@ namespace SceneUtil
META_Object(SceneUtil, StateSetUpdater) META_Object(SceneUtil, StateSetUpdater)
void operator()(osg::Node* node, osg::NodeVisitor* nv) override; void operator()(osg::Node* node, osg::NodeVisitor* nv);
/// Apply state - to override in derived classes /// Apply state - to override in derived classes
/// @note Due to the double buffering approach you *have* to apply all state /// @note Due to the double buffering approach you *have* to apply all state

@ -19,6 +19,7 @@
#include <components/resource/scenemanager.hpp> #include <components/resource/scenemanager.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/sceneutil/nodecallback.hpp>
#ifndef GL_DEPTH32F_STENCIL8_NV #ifndef GL_DEPTH32F_STENCIL8_NV
#define GL_DEPTH32F_STENCIL8_NV 0x8DAC #define GL_DEPTH32F_STENCIL8_NV 0x8DAC
@ -174,8 +175,7 @@ void GlowUpdater::setDuration(float duration)
} }
// Allows camera to render to a color and floating point depth texture with a multisampled framebuffer. // Allows camera to render to a color and floating point depth texture with a multisampled framebuffer.
// Must be set on a camera's cull callback. class AttachMultisampledDepthColorCallback : public SceneUtil::NodeCallback<AttachMultisampledDepthColorCallback, osg::Node*, osgUtil::CullVisitor*>
class AttachMultisampledDepthColorCallback : public osg::NodeCallback
{ {
public: public:
AttachMultisampledDepthColorCallback(osg::Texture2D* colorTex, osg::Texture2D* depthTex, int samples, int colorSamples) AttachMultisampledDepthColorCallback(osg::Texture2D* colorTex, osg::Texture2D* depthTex, int samples, int colorSamples)
@ -195,14 +195,14 @@ public:
mFbo->setAttachment(osg::Camera::DEPTH_BUFFER, osg::FrameBufferAttachment(depthTex)); mFbo->setAttachment(osg::Camera::DEPTH_BUFFER, osg::FrameBufferAttachment(depthTex));
} }
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::Node* node, osgUtil::CullVisitor* cv)
{ {
osgUtil::RenderStage* renderStage = static_cast<osgUtil::CullVisitor*>(nv)->getCurrentRenderStage(); osgUtil::RenderStage* renderStage = cv->getCurrentRenderStage();
renderStage->setMultisampleResolveFramebufferObject(mFbo); renderStage->setMultisampleResolveFramebufferObject(mFbo);
renderStage->setFrameBufferObject(mMsaaFbo); renderStage->setFrameBufferObject(mMsaaFbo);
traverse(node, nv); traverse(node, cv);
} }
private: private:

@ -4,7 +4,6 @@
#include <osg/Matrix> #include <osg/Matrix>
#include <osg/BoundingSphere> #include <osg/BoundingSphere>
#include <osg/Camera> #include <osg/Camera>
#include <osg/NodeCallback>
#include <osg/Texture2D> #include <osg/Texture2D>
#include <osg/Vec4f> #include <osg/Vec4f>
#include <osg/Depth> #include <osg/Depth>

@ -4,13 +4,14 @@
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <osg/Referenced> #include <osg/Referenced>
#include <osg/Vec3f> #include <osg/Vec3f>
#include <osg/NodeCallback>
#include <atomic> #include <atomic>
#include <limits> #include <limits>
#include <memory> #include <memory>
#include <set> #include <set>
#include <components/sceneutil/nodecallback.hpp>
#include "defs.hpp" #include "defs.hpp"
#include "cellborder.hpp" #include "cellborder.hpp"
@ -45,7 +46,7 @@ namespace Terrain
class ChunkManager; class ChunkManager;
class CompositeMapRenderer; class CompositeMapRenderer;
class HeightCullCallback : public osg::NodeCallback class HeightCullCallback : public SceneUtil::NodeCallback<HeightCullCallback>
{ {
public: public:
void setLowZ(float z) void setLowZ(float z)
@ -75,7 +76,7 @@ namespace Terrain
return mMask; return mMask;
} }
void operator()(osg::Node* node, osg::NodeVisitor* nv) override void operator()(osg::Node* node, osg::NodeVisitor* nv)
{ {
if (mLowZ <= mHighZ) if (mLowZ <= mHighZ)
traverse(node, nv); traverse(node, nv);

Loading…
Cancel
Save