diff --git a/apps/opencs/view/render/mask.hpp b/apps/opencs/view/render/mask.hpp index 55b7c823f..deeab4996 100644 --- a/apps/opencs/view/render/mask.hpp +++ b/apps/opencs/view/render/mask.hpp @@ -10,9 +10,6 @@ namespace CSVRender /// @copydoc MWRender::VisMask enum Mask { - // internal use within NifLoader, do not change - Mask_UpdateVisitor = 0x1, - // elements that are part of the actual scene Mask_Reference = 0x2, Mask_Pathgrid = 0x4, diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index ed232722d..e50d7b2cd 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -88,8 +88,6 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f) // Add ability to signal osg to show its statistics for debugging purposes mView->addEventHandler(new osgViewer::StatsHandler); - mView->getCamera()->setCullMask(~(Mask_UpdateVisitor)); - viewer.addView(mView); viewer.setDone(false); viewer.realize(); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index f5053cca9..31af55a44 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -20,6 +20,8 @@ #include +#include + #include #include @@ -373,6 +375,7 @@ namespace MWRender mViewer->getCamera()->setCullingMode(cullingMode); mViewer->getCamera()->setCullMask(~(Mask_UpdateVisitor|Mask_SimpleWater)); + NifOsg::Loader::setHiddenNodeMask(Mask_UpdateVisitor); mNearClip = Settings::Manager::getFloat("near clip", "Camera"); mViewDistance = Settings::Manager::getFloat("viewing distance", "Camera"); diff --git a/components/nifosg/controller.cpp b/components/nifosg/controller.cpp index 1842e0017..100aa234a 100644 --- a/components/nifosg/controller.cpp +++ b/components/nifosg/controller.cpp @@ -269,12 +269,14 @@ void UVController::apply(osg::StateSet* stateset, osg::NodeVisitor* nv) } } -VisController::VisController(const Nif::NiVisData *data) +VisController::VisController(const Nif::NiVisData *data, unsigned int mask) : mData(data->mVis) + , mMask(mask) { } VisController::VisController() + : mMask(0) { } @@ -282,6 +284,7 @@ VisController::VisController(const VisController ©, const osg::CopyOp ©o : osg::NodeCallback(copy, copyop) , Controller(copy) , mData(copy.mData) + , mMask(copy.mMask) { } @@ -303,8 +306,7 @@ void VisController::operator() (osg::Node* node, osg::NodeVisitor* nv) if (hasInput()) { bool vis = calculate(getInputValue(nv)); - // Leave 0x1 enabled for UpdateVisitor, so we can make ourselves visible again in the future from this update callback - node->setNodeMask(vis ? ~0 : 0x1); + node->setNodeMask(vis ? ~0 : mMask); } traverse(node, nv); } diff --git a/components/nifosg/controller.hpp b/components/nifosg/controller.hpp index c9bda2e62..ad6ee4d87 100644 --- a/components/nifosg/controller.hpp +++ b/components/nifosg/controller.hpp @@ -234,11 +234,12 @@ namespace NifOsg { private: std::vector mData; + unsigned int mMask; bool calculate(float time) const; public: - VisController(const Nif::NiVisData *data); + VisController(const Nif::NiVisData *data, unsigned int mask); VisController(); VisController(const VisController& copy, const osg::CopyOp& copyop); diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index af8431da7..7d62d1ef1 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -193,6 +193,17 @@ namespace NifOsg return sShowMarkers; } + unsigned int Loader::sHiddenNodeMask = 0; + + void Loader::setHiddenNodeMask(unsigned int mask) + { + sHiddenNodeMask = mask; + } + unsigned int Loader::getHiddenNodeMask() + { + return sHiddenNodeMask; + } + class LoaderImpl { public: @@ -571,8 +582,7 @@ namespace NifOsg if (nifNode->recType == Nif::RC_RootCollisionNode) { skipMeshes = true; - // Leave mask for UpdateVisitor enabled - node->setNodeMask(0x1); + node->setNodeMask(Loader::getHiddenNodeMask()); } // We can skip creating meshes for hidden nodes if they don't have a VisController that @@ -586,8 +596,7 @@ namespace NifOsg if (!hasVisController) skipMeshes = true; // skip child meshes, but still create the child node hierarchy for animating collision shapes - // now hide this node, but leave the mask for UpdateVisitor enabled so that KeyframeController works - node->setNodeMask(0x1); + node->setNodeMask(Loader::getHiddenNodeMask()); } if ((skipMeshes || hasMarkers) && isAnimated) // make sure the empty node is not optimized away so the physicssystem can find it. @@ -753,7 +762,7 @@ namespace NifOsg { if (visctrl->data.empty()) return; - osg::ref_ptr callback(new VisController(visctrl->data.getPtr())); + osg::ref_ptr callback(new VisController(visctrl->data.getPtr(), Loader::getHiddenNodeMask())); setupController(visctrl, callback, animflags); node->addUpdateCallback(callback); } diff --git a/components/nifosg/nifloader.hpp b/components/nifosg/nifloader.hpp index d2d5e7b2d..6168bb474 100644 --- a/components/nifosg/nifloader.hpp +++ b/components/nifosg/nifloader.hpp @@ -74,8 +74,13 @@ namespace NifOsg static bool getShowMarkers(); - private: + /// Set the mask to use for hidden nodes. The default is 0, i.e. updates to those nodes can no longer happen. + /// If you need to run animations or physics for hidden nodes, you may want to set this to a non-zero mask and remove exactly that mask from the camera's cull mask. + static void setHiddenNodeMask(unsigned int mask); + static unsigned int getHiddenNodeMask(); + private: + static unsigned int sHiddenNodeMask; static bool sShowMarkers; };