mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-22 11:09:40 +00:00
Merge pull request #2816 from Capostrophic/switchlod
CollisionSwitch and Switch/LOD node fixes
This commit is contained in:
commit
f51476a3c5
4 changed files with 32 additions and 30 deletions
|
@ -170,6 +170,17 @@ namespace NifOsg
|
||||||
class CollisionSwitch : public osg::MatrixTransform
|
class CollisionSwitch : public osg::MatrixTransform
|
||||||
{
|
{
|
||||||
public:
|
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)
|
CollisionSwitch(const osg::Matrixf& transformations, bool enabled) : osg::MatrixTransform(transformations)
|
||||||
{
|
{
|
||||||
setEnabled(enabled);
|
setEnabled(enabled);
|
||||||
|
@ -478,17 +489,8 @@ namespace NifOsg
|
||||||
osg::ref_ptr<osg::Group> node;
|
osg::ref_ptr<osg::Group> node;
|
||||||
osg::Object::DataVariance dataVariance = osg::Object::UNSPECIFIED;
|
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)
|
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_NiAutoNormalParticles:
|
||||||
case Nif::RC_NiRotatingParticles:
|
case Nif::RC_NiRotatingParticles:
|
||||||
// Leaf nodes in the NIF hierarchy, so won't be able to dynamically attach children.
|
// 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)
|
&& !nifNode->controller.empty() && node->getDataVariance() == osg::Object::DYNAMIC)
|
||||||
handleNodeControllers(nifNode, static_cast<osg::MatrixTransform*>(node.get()), animflags);
|
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)
|
if (nifNode->recType == Nif::RC_NiSwitchNode)
|
||||||
{
|
{
|
||||||
const Nif::NiSwitchNode* niSwitchNode = static_cast<const Nif::NiSwitchNode*>(nifNode);
|
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))
|
else if (niSwitchNode->name == Constants::HerbalismLabel && !SceneUtil::hasUserDescription(rootNode, Constants::HerbalismLabel))
|
||||||
rootNode->getOrCreateUserDataContainer()->addDescription(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);
|
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)
|
for (size_t i = 0; i < effects.length(); ++i)
|
||||||
{
|
{
|
||||||
if (!effects[i].empty())
|
if (!effects[i].empty())
|
||||||
handleEffect(effects[i].getPtr(), node, imageManager);
|
handleEffect(effects[i].getPtr(), currentNode, imageManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Nif::NodeList &children = ninode->children;
|
const Nif::NodeList &children = ninode->children;
|
||||||
for(size_t i = 0;i < children.length();++i)
|
for(size_t i = 0;i < children.length();++i)
|
||||||
{
|
{
|
||||||
if(!children[i].empty())
|
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.
|
// 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)
|
void Optimizer::RemoveEmptyNodesVisitor::apply(osg::Group& group)
|
||||||
{
|
{
|
||||||
if (group.getNumParents()>0)
|
if (group.getNumParents()>0)
|
||||||
|
@ -787,10 +773,13 @@ void Optimizer::RemoveEmptyNodesVisitor::removeEmptyNodes()
|
||||||
++pitr)
|
++pitr)
|
||||||
{
|
{
|
||||||
osg::Group* parent = *pitr;
|
osg::Group* parent = *pitr;
|
||||||
|
if (!parent->asSwitch() && !dynamic_cast<osg::LOD*>(parent))
|
||||||
|
{
|
||||||
parent->removeChild(nodeToRemove.get());
|
parent->removeChild(nodeToRemove.get());
|
||||||
if (parent->getNumChildren()==0 && isOperationPermissibleForObject(parent)) newEmptyGroups.insert(parent);
|
if (parent->getNumChildren()==0 && isOperationPermissibleForObject(parent)) newEmptyGroups.insert(parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_redundantNodeList.clear();
|
_redundantNodeList.clear();
|
||||||
_redundantNodeList.swap(newEmptyGroups);
|
_redundantNodeList.swap(newEmptyGroups);
|
||||||
|
|
|
@ -321,8 +321,6 @@ class Optimizer
|
||||||
BaseOptimizerVisitor(optimizer, REMOVE_REDUNDANT_NODES) {}
|
BaseOptimizerVisitor(optimizer, REMOVE_REDUNDANT_NODES) {}
|
||||||
|
|
||||||
virtual void apply(osg::Group& group);
|
virtual void apply(osg::Group& group);
|
||||||
virtual void apply(osg::LOD& lod);
|
|
||||||
virtual void apply(osg::Switch& switchNode);
|
|
||||||
|
|
||||||
void removeEmptyNodes();
|
void removeEmptyNodes();
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,7 @@ void registerSerializers()
|
||||||
"NifOsg::StaticBoundingBoxCallback",
|
"NifOsg::StaticBoundingBoxCallback",
|
||||||
"NifOsg::GeomMorpherController",
|
"NifOsg::GeomMorpherController",
|
||||||
"NifOsg::UpdateMorphGeometry",
|
"NifOsg::UpdateMorphGeometry",
|
||||||
|
"NifOsg::CollisionSwitch",
|
||||||
"osgMyGUI::Drawable",
|
"osgMyGUI::Drawable",
|
||||||
"osg::DrawCallback",
|
"osg::DrawCallback",
|
||||||
"osgOQ::ClearQueriesCallback",
|
"osgOQ::ClearQueriesCallback",
|
||||||
|
|
Loading…
Reference in a new issue