Merge pull request #2816 from Capostrophic/switchlod

CollisionSwitch and Switch/LOD node fixes
pull/2820/head
Bret Curtis 5 years ago committed by GitHub
commit f51476a3c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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);
@ -478,17 +489,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.
@ -669,6 +671,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);
@ -679,7 +686,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);
@ -689,14 +703,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);
}
}

@ -735,20 +735,6 @@ bool Optimizer::CombineStaticTransformsVisitor::removeTransforms(osg::Node* node
// RemoveEmptyNodes.
////////////////////////////////////////////////////////////////////////////
void Optimizer::RemoveEmptyNodesVisitor::apply(osg::Switch& switchNode)
{
// We should keep all switch child nodes since they reflect different switch states.
for (unsigned int i=0; i<switchNode.getNumChildren(); ++i)
traverse(*switchNode.getChild(i));
}
void Optimizer::RemoveEmptyNodesVisitor::apply(osg::LOD& lod)
{
// don't remove any direct children of the LOD because they are used to define each LOD level.
for (unsigned int i=0; i<lod.getNumChildren(); ++i)
traverse(*lod.getChild(i));
}
void Optimizer::RemoveEmptyNodesVisitor::apply(osg::Group& group)
{
if (group.getNumParents()>0)
@ -787,8 +773,11 @@ void Optimizer::RemoveEmptyNodesVisitor::removeEmptyNodes()
++pitr)
{
osg::Group* parent = *pitr;
parent->removeChild(nodeToRemove.get());
if (parent->getNumChildren()==0 && isOperationPermissibleForObject(parent)) newEmptyGroups.insert(parent);
if (!parent->asSwitch() && !dynamic_cast<osg::LOD*>(parent))
{
parent->removeChild(nodeToRemove.get());
if (parent->getNumChildren()==0 && isOperationPermissibleForObject(parent)) newEmptyGroups.insert(parent);
}
}
}

@ -321,8 +321,6 @@ class Optimizer
BaseOptimizerVisitor(optimizer, REMOVE_REDUNDANT_NODES) {}
virtual void apply(osg::Group& group);
virtual void apply(osg::LOD& lod);
virtual void apply(osg::Switch& switchNode);
void removeEmptyNodes();

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

Loading…
Cancel
Save