mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-25 15:35:23 +00:00
Optimize RigGeometry to update skinning in CullCallback
This commit is contained in:
parent
e5e1013c51
commit
304d7e544f
@ -362,6 +362,56 @@ namespace
|
||||
}
|
||||
};
|
||||
|
||||
struct FindNearestParentSkeleton : public osg::NodeVisitor
|
||||
{
|
||||
osg::ref_ptr<osgAnimation::Skeleton> _root;
|
||||
FindNearestParentSkeleton() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_PARENTS) {}
|
||||
void apply(osg::Transform& node)
|
||||
{
|
||||
if (_root.valid())
|
||||
return;
|
||||
_root = dynamic_cast<osgAnimation::Skeleton*>(&node);
|
||||
traverse(node);
|
||||
}
|
||||
};
|
||||
|
||||
// RigGeometry is skinned from a CullCallback to prevent unnecessary updates of culled rig geometries.
|
||||
// Note: this assumes only one cull thread is using the given RigGeometry, there would be a race condition otherwise.
|
||||
struct UpdateRigGeometry : public osg::Drawable::CullCallback
|
||||
{
|
||||
virtual bool cull(osg::NodeVisitor *, osg::Drawable * drw, osg::State *) const
|
||||
{
|
||||
osgAnimation::RigGeometry* geom = static_cast<osgAnimation::RigGeometry*>(drw);
|
||||
if (!geom)
|
||||
return false;
|
||||
if (!geom->getSkeleton() && !geom->getParents().empty())
|
||||
{
|
||||
FindNearestParentSkeleton finder;
|
||||
if (geom->getParents().size() > 1)
|
||||
osg::notify(osg::WARN) << "A RigGeometry should not have multi parent ( " << geom->getName() << " )" << std::endl;
|
||||
geom->getParents()[0]->accept(finder);
|
||||
|
||||
if (!finder._root.valid())
|
||||
{
|
||||
osg::notify(osg::WARN) << "A RigGeometry did not find a parent skeleton for RigGeometry ( " << geom->getName() << " )" << std::endl;
|
||||
return false;
|
||||
}
|
||||
geom->buildVertexInfluenceSet();
|
||||
geom->setSkeleton(finder._root.get());
|
||||
}
|
||||
|
||||
if (!geom->getSkeleton())
|
||||
return false;
|
||||
|
||||
if (geom->getNeedToComputeMatrix())
|
||||
geom->computeMatrixFromRootSkeleton();
|
||||
|
||||
geom->update();
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class RigBoundingBoxCallback : public osg::Drawable::ComputeBoundingBoxCallback
|
||||
{
|
||||
public:
|
||||
@ -1284,6 +1334,10 @@ namespace NifOsg
|
||||
}
|
||||
rig->setInfluenceMap(map);
|
||||
|
||||
// Override default update using cull callback instead for efficiency.
|
||||
rig->setUpdateCallback(NULL);
|
||||
rig->setCullCallback(new UpdateRigGeometry);
|
||||
|
||||
osg::ref_ptr<osg::MatrixTransform> trans(new osg::MatrixTransform);
|
||||
trans->setUpdateCallback(new InvertBoneMatrix());
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user