Optimize RigGeometry to update skinning in CullCallback

c++11
scrawl 10 years ago
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…
Cancel
Save