1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-08 09:37:53 +00:00

CollisionSwitch and Switch/LOD node fixes

Properly apply transformations to both switch and LOD nodes
Allow both NiSwitchNode and NiLODNode to be the root node
Properly add CollisionSwitch into the scene graph
This commit is contained in:
Capostrophic 2020-04-29 15:50:50 +03:00
parent e4358d1489
commit 63fe02b1ba
2 changed files with 27 additions and 12 deletions

View File

@ -170,6 +170,17 @@ namespace NifOsg
class CollisionSwitch : public osg::MatrixTransform
{
public:
CollisionSwitch() : osg::MatrixTransform()
{
}
CollisionSwitch(const CollisionSwitch& copy, const osg::CopyOp& copyop)
: osg::MatrixTransform(copy, copyop)
{
}
META_Node(NifOsg, CollisionSwitch)
CollisionSwitch(const osg::Matrixf& transformations, bool enabled) : osg::MatrixTransform(transformations)
{
setEnabled(enabled);
@ -472,17 +483,8 @@ namespace NifOsg
osg::ref_ptr<osg::Group> node;
osg::Object::DataVariance dataVariance = osg::Object::UNSPECIFIED;
// TODO: it is unclear how to handle transformations of LOD nodes and controllers for them.
switch (nifNode->recType)
{
case Nif::RC_NiLODNode:
{
const Nif::NiLODNode* niLodNode = static_cast<const Nif::NiLODNode*>(nifNode);
node = handleLodNode(niLodNode);
dataVariance = osg::Object::DYNAMIC;
break;
}
case Nif::RC_NiSwitchNode:
case Nif::RC_NiAutoNormalParticles:
case Nif::RC_NiRotatingParticles:
// Leaf nodes in the NIF hierarchy, so won't be able to dynamically attach children.
@ -663,6 +665,11 @@ namespace NifOsg
&& !nifNode->controller.empty() && node->getDataVariance() == osg::Object::DYNAMIC)
handleNodeControllers(nifNode, static_cast<osg::MatrixTransform*>(node.get()), animflags);
// LOD and Switch nodes must be wrapped by a transform (the current node) to support transformations properly
// and we need to attach their children to the osg::LOD/osg::Switch nodes
// but we must return that transform to the caller of handleNode instead of the actual LOD/Switch nodes.
osg::ref_ptr<osg::Group> currentNode = node;
if (nifNode->recType == Nif::RC_NiSwitchNode)
{
const Nif::NiSwitchNode* niSwitchNode = static_cast<const Nif::NiSwitchNode*>(nifNode);
@ -673,7 +680,14 @@ namespace NifOsg
else if (niSwitchNode->name == Constants::HerbalismLabel && !SceneUtil::hasUserDescription(rootNode, Constants::HerbalismLabel))
rootNode->getOrCreateUserDataContainer()->addDescription(Constants::HerbalismLabel);
node = switchNode;
currentNode = switchNode;
}
else if (nifNode->recType == Nif::RC_NiLODNode)
{
const Nif::NiLODNode* niLodNode = static_cast<const Nif::NiLODNode*>(nifNode);
osg::ref_ptr<osg::LOD> lodNode = handleLodNode(niLodNode);
node->addChild(lodNode);
currentNode = lodNode;
}
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(nifNode);
@ -683,14 +697,14 @@ namespace NifOsg
for (size_t i = 0; i < effects.length(); ++i)
{
if (!effects[i].empty())
handleEffect(effects[i].getPtr(), node, imageManager);
handleEffect(effects[i].getPtr(), currentNode, imageManager);
}
const Nif::NodeList &children = ninode->children;
for(size_t i = 0;i < children.length();++i)
{
if(!children[i].empty())
handleNode(children[i].getPtr(), node, imageManager, boundTextures, animflags, skipMeshes, hasMarkers, isAnimated, textKeys, rootNode);
handleNode(children[i].getPtr(), currentNode, imageManager, boundTextures, animflags, skipMeshes, hasMarkers, isAnimated, textKeys, rootNode);
}
}

View File

@ -131,6 +131,7 @@ void registerSerializers()
"NifOsg::StaticBoundingBoxCallback",
"NifOsg::GeomMorpherController",
"NifOsg::UpdateMorphGeometry",
"NifOsg::CollisionSwitch",
"osgMyGUI::Drawable",
"osg::DrawCallback",
"osgOQ::ClearQueriesCallback",