diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 54a02c950..75a427c5a 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -113,6 +113,7 @@ namespace // NodeCallback used to have a transform always oriented towards the camera. Can have translation and scale // set just like a regular MatrixTransform, but the rotation set will be overridden in order to face the camera. + // Must be set as a cull callback. class BillboardCallback : public osg::NodeCallback { public: @@ -160,24 +161,34 @@ namespace struct UpdateMorphGeometry : public osg::Drawable::CullCallback { UpdateMorphGeometry() + : mLastFrameNumber(0) { } UpdateMorphGeometry(const UpdateMorphGeometry& copy, const osg::CopyOp& copyop) : osg::Drawable::CullCallback(copy, copyop) + , mLastFrameNumber(0) { } META_Object(NifOsg, UpdateMorphGeometry) - virtual bool cull(osg::NodeVisitor *, osg::Drawable * drw, osg::State *) const + virtual bool cull(osg::NodeVisitor* nv, osg::Drawable * drw, osg::State *) const { osgAnimation::MorphGeometry* geom = static_cast(drw); if (!geom) return false; + + if (mLastFrameNumber == nv->getFrameStamp()->getFrameNumber()) + return false; + mLastFrameNumber = nv->getFrameStamp()->getFrameNumber(); + geom->transformSoftwareMethod(); return false; } + + private: + mutable unsigned int mLastFrameNumber; }; // Callback to return a static bounding box for a MorphGeometry. The idea is to not recalculate the bounding box diff --git a/components/sceneutil/riggeometry.cpp b/components/sceneutil/riggeometry.cpp index 2a67c6ce6..8eb08f546 100644 --- a/components/sceneutil/riggeometry.cpp +++ b/components/sceneutil/riggeometry.cpp @@ -60,7 +60,7 @@ public: RigGeometry::RigGeometry() : mSkeleton(NULL) - , mFirstFrame(true) + , mLastFrameNumber(0) , mBoundsFirstFrame(true) { setCullCallback(new UpdateRigGeometry); @@ -72,7 +72,7 @@ RigGeometry::RigGeometry(const RigGeometry ©, const osg::CopyOp ©op) : osg::Geometry(copy, copyop) , mSkeleton(NULL) , mInfluenceMap(copy.mInfluenceMap) - , mFirstFrame(copy.mFirstFrame) + , mLastFrameNumber(0) , mBoundsFirstFrame(copy.mBoundsFirstFrame) { setSourceGeometry(copy.mSourceGeometry); @@ -206,9 +206,12 @@ void RigGeometry::update(osg::NodeVisitor* nv) return; } - if (!mSkeleton->getActive() && !mFirstFrame) + if (!mSkeleton->getActive() && mLastFrameNumber != 0) return; - mFirstFrame = false; + + if (mLastFrameNumber == nv->getFrameStamp()->getFrameNumber()) + return; + mLastFrameNumber = nv->getFrameStamp()->getFrameNumber(); mSkeleton->updateBoneMatrices(nv); diff --git a/components/sceneutil/riggeometry.hpp b/components/sceneutil/riggeometry.hpp index bd7c586c4..e51fc0cf6 100644 --- a/components/sceneutil/riggeometry.hpp +++ b/components/sceneutil/riggeometry.hpp @@ -64,7 +64,7 @@ namespace SceneUtil BoneSphereMap mBoneSphereMap; - bool mFirstFrame; + unsigned int mLastFrameNumber; bool mBoundsFirstFrame; bool initFromParentSkeleton(osg::NodeVisitor* nv);