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
pull/2816/head
Capostrophic 5 years ago
parent e4358d1489
commit 63fe02b1ba

@ -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);
}
}

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

Loading…
Cancel
Save