diff --git a/components/sceneutil/riggeometry.cpp b/components/sceneutil/riggeometry.cpp index 50e47e289..2a67c6ce6 100644 --- a/components/sceneutil/riggeometry.cpp +++ b/components/sceneutil/riggeometry.cpp @@ -5,8 +5,6 @@ #include -#include - #include #include "skeleton.hpp" @@ -65,8 +63,6 @@ RigGeometry::RigGeometry() , mFirstFrame(true) , mBoundsFirstFrame(true) { - initWorkQueue(); - setCullCallback(new UpdateRigGeometry); setUpdateCallback(new UpdateRigBounds); setSupportsDisplayList(false); @@ -79,21 +75,9 @@ RigGeometry::RigGeometry(const RigGeometry ©, const osg::CopyOp ©op) , mFirstFrame(copy.mFirstFrame) , mBoundsFirstFrame(copy.mBoundsFirstFrame) { - initWorkQueue(); - setSourceGeometry(copy.mSourceGeometry); } -void RigGeometry::initWorkQueue() -{ - static int numCpu = OpenThreads::GetNumberOfProcessors(); - if (numCpu > 1) - { - static WorkQueue sWorkQueue(1); - mWorkQueue = &sWorkQueue; - } -} - void RigGeometry::setSourceGeometry(osg::ref_ptr sourceGeometry) { mSourceGeometry = sourceGeometry; @@ -214,31 +198,22 @@ void accummulateMatrix(const osg::Matrixf& invBindMatrix, const osg::Matrixf& ma ptrresult[14] += ptr[14] * weight; } -class UpdateSkinningWorkItem : public WorkItem +void RigGeometry::update(osg::NodeVisitor* nv) { -public: - UpdateSkinningWorkItem(RigGeometry* rig, const osg::Matrixf& geomToSkelMatrix, RigGeometry::BoneMatrixMap boneMatrices) - : mRig(rig) - , mGeomToSkelMatrix(geomToSkelMatrix) - , mBoneMatrices(boneMatrices) + if (!mSkeleton) { + if (!initFromParentSkeleton(nv)) + return; } - virtual void doWork() - { - mRig->updateSkinning(mGeomToSkelMatrix, mBoneMatrices); + if (!mSkeleton->getActive() && !mFirstFrame) + return; + mFirstFrame = false; - mTicket->signalDone(); - } + mSkeleton->updateBoneMatrices(nv); -private: - RigGeometry* mRig; - osg::Matrixf mGeomToSkelMatrix; - RigGeometry::BoneMatrixMap mBoneMatrices; -}; + osg::Matrixf geomToSkel = getGeomToSkelMatrix(nv); -void RigGeometry::updateSkinning(const osg::Matrixf& geomToSkel, RigGeometry::BoneMatrixMap boneMatrices) -{ // skinning osg::Vec3Array* positionSrc = static_cast(mSourceGeometry->getVertexArray()); osg::Vec3Array* normalSrc = static_cast(mSourceGeometry->getNormalArray()); @@ -258,7 +233,7 @@ void RigGeometry::updateSkinning(const osg::Matrixf& geomToSkel, RigGeometry::Bo Bone* bone = weightIt->first.first; const osg::Matrix& invBindMatrix = weightIt->first.second; float weight = weightIt->second; - const osg::Matrixf& boneMatrix = boneMatrices.at(bone); + const osg::Matrixf& boneMatrix = bone->mMatrixInSkeletonSpace; accummulateMatrix(invBindMatrix, boneMatrix, weight, resultMat); } resultMat = resultMat * geomToSkel; @@ -275,45 +250,6 @@ void RigGeometry::updateSkinning(const osg::Matrixf& geomToSkel, RigGeometry::Bo normalDst->dirty(); } -void RigGeometry::update(osg::NodeVisitor* nv) -{ - if (!mSkeleton) - { - if (!initFromParentSkeleton(nv)) - return; - } - - if (!mSkeleton->getActive() && !mFirstFrame) - return; - mFirstFrame = false; - - mSkeleton->updateBoneMatrices(nv); - - BoneMatrixMap boneMatrices; - for (BoneSphereMap::const_iterator it = mBoneSphereMap.begin(); it != mBoneSphereMap.end(); ++it) - boneMatrices[it->first] = it->first->mMatrixInSkeletonSpace; - - if (mWorkQueue) - { - // shouldn't happen, unless the CullCallback was a false positive, i.e. the Drawable's parent wasn't culled, but the Drawable *is* culled - if (mWorkTicket) - mWorkTicket->waitTillDone(); - - osg::Matrixf geomToSkel = getGeomToSkelMatrix(nv); - - // actual skinning update moved to a background thread - WorkItem* item = new UpdateSkinningWorkItem(this, geomToSkel, boneMatrices); - // keep the work ticket so we can synchronize in drawImplementation() - mWorkTicket = item->getTicket(); - - mWorkQueue->addWorkItem(item); - } - else - { - updateSkinning(getGeomToSkelMatrix(nv), boneMatrices); - } -} - void RigGeometry::updateBounds(osg::NodeVisitor *nv) { if (!mSkeleton) @@ -343,46 +279,6 @@ void RigGeometry::updateBounds(osg::NodeVisitor *nv) getParent(i)->dirtyBound(); } -void RigGeometry::drawImplementation(osg::RenderInfo &renderInfo) const -{ - if (mWorkTicket) - { - mWorkTicket->waitTillDone(); - mWorkTicket = NULL; - } - osg::Geometry::drawImplementation(renderInfo); -} - -void RigGeometry::compileGLObjects(osg::RenderInfo &renderInfo) const -{ - if (mWorkTicket) - { - mWorkTicket->waitTillDone(); - mWorkTicket = NULL; - } - osg::Geometry::compileGLObjects(renderInfo); -} - -void RigGeometry::accept(osg::PrimitiveFunctor &pf) const -{ - if (mWorkTicket) - { - mWorkTicket->waitTillDone(); - mWorkTicket = NULL; - } - osg::Geometry::accept(pf); -} - -void RigGeometry::accept(osg::PrimitiveIndexFunctor &pf) const -{ - if (mWorkTicket) - { - mWorkTicket->waitTillDone(); - mWorkTicket = NULL; - } - osg::Geometry::accept(pf); -} - osg::Matrixf RigGeometry::getGeomToSkelMatrix(osg::NodeVisitor *nv) { osg::NodePath path; diff --git a/components/sceneutil/riggeometry.hpp b/components/sceneutil/riggeometry.hpp index 4dd8e8013..bd7c586c4 100644 --- a/components/sceneutil/riggeometry.hpp +++ b/components/sceneutil/riggeometry.hpp @@ -7,16 +7,12 @@ namespace SceneUtil { - class WorkQueue; - class WorkTicket; - class Skeleton; class Bone; /// @brief Mesh skinning implementation. /// @note A RigGeometry may be attached directly to a Skeleton, or somewhere below a Skeleton. /// Note though that the RigGeometry ignores any transforms below the Skeleton, so the attachment point is not that important. - /// @note You must use a double buffering scheme for queuing the drawing of RigGeometries, see FrameSwitch, or set their DataVariance to DYNAMIC class RigGeometry : public osg::Geometry { public: @@ -45,23 +41,10 @@ namespace SceneUtil // Called automatically by our CullCallback void update(osg::NodeVisitor* nv); - // Called by the worker thread - typedef std::map BoneMatrixMap; - void updateSkinning(const osg::Matrixf& geomToSkelMatrix, BoneMatrixMap boneMatrices); - // Called automatically by our UpdateCallback void updateBounds(osg::NodeVisitor* nv); - // Overriding a bunch of Drawable methods to synchronize access to our vertex array - virtual void drawImplementation(osg::RenderInfo& renderInfo) const; - virtual void compileGLObjects(osg::RenderInfo& renderInfo) const; - virtual void accept(osg::PrimitiveFunctor& pf) const; - virtual void accept(osg::PrimitiveIndexFunctor& pf) const; - private: - mutable osg::ref_ptr mWorkTicket; - WorkQueue* mWorkQueue; - osg::ref_ptr mSourceGeometry; Skeleton* mSkeleton; @@ -87,8 +70,6 @@ namespace SceneUtil bool initFromParentSkeleton(osg::NodeVisitor* nv); osg::Matrixf getGeomToSkelMatrix(osg::NodeVisitor* nv); - - void initWorkQueue(); }; }