Revert "Use the WorkQueue to update skinning"

This reverts commit d52d0d9640.

Moving to branch
c++11
scrawl 10 years ago
parent 9c86d4f8bc
commit a1e74a35a2

@ -5,8 +5,6 @@
#include <cstdlib> #include <cstdlib>
#include <components/sceneutil/workqueue.hpp>
#include <osg/MatrixTransform> #include <osg/MatrixTransform>
#include "skeleton.hpp" #include "skeleton.hpp"
@ -65,8 +63,6 @@ RigGeometry::RigGeometry()
, mFirstFrame(true) , mFirstFrame(true)
, mBoundsFirstFrame(true) , mBoundsFirstFrame(true)
{ {
initWorkQueue();
setCullCallback(new UpdateRigGeometry); setCullCallback(new UpdateRigGeometry);
setUpdateCallback(new UpdateRigBounds); setUpdateCallback(new UpdateRigBounds);
setSupportsDisplayList(false); setSupportsDisplayList(false);
@ -79,21 +75,9 @@ RigGeometry::RigGeometry(const RigGeometry &copy, const osg::CopyOp &copyop)
, mFirstFrame(copy.mFirstFrame) , mFirstFrame(copy.mFirstFrame)
, mBoundsFirstFrame(copy.mBoundsFirstFrame) , mBoundsFirstFrame(copy.mBoundsFirstFrame)
{ {
initWorkQueue();
setSourceGeometry(copy.mSourceGeometry); 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<osg::Geometry> sourceGeometry) void RigGeometry::setSourceGeometry(osg::ref_ptr<osg::Geometry> sourceGeometry)
{ {
mSourceGeometry = sourceGeometry; mSourceGeometry = sourceGeometry;
@ -214,31 +198,22 @@ void accummulateMatrix(const osg::Matrixf& invBindMatrix, const osg::Matrixf& ma
ptrresult[14] += ptr[14] * weight; ptrresult[14] += ptr[14] * weight;
} }
class UpdateSkinningWorkItem : public WorkItem void RigGeometry::update(osg::NodeVisitor* nv)
{ {
public: if (!mSkeleton)
UpdateSkinningWorkItem(RigGeometry* rig, const osg::Matrixf& geomToSkelMatrix, RigGeometry::BoneMatrixMap boneMatrices)
: mRig(rig)
, mGeomToSkelMatrix(geomToSkelMatrix)
, mBoneMatrices(boneMatrices)
{ {
if (!initFromParentSkeleton(nv))
return;
} }
virtual void doWork() if (!mSkeleton->getActive() && !mFirstFrame)
{ return;
mRig->updateSkinning(mGeomToSkelMatrix, mBoneMatrices); mFirstFrame = false;
mTicket->signalDone(); mSkeleton->updateBoneMatrices(nv);
}
private: osg::Matrixf geomToSkel = getGeomToSkelMatrix(nv);
RigGeometry* mRig;
osg::Matrixf mGeomToSkelMatrix;
RigGeometry::BoneMatrixMap mBoneMatrices;
};
void RigGeometry::updateSkinning(const osg::Matrixf& geomToSkel, RigGeometry::BoneMatrixMap boneMatrices)
{
// skinning // skinning
osg::Vec3Array* positionSrc = static_cast<osg::Vec3Array*>(mSourceGeometry->getVertexArray()); osg::Vec3Array* positionSrc = static_cast<osg::Vec3Array*>(mSourceGeometry->getVertexArray());
osg::Vec3Array* normalSrc = static_cast<osg::Vec3Array*>(mSourceGeometry->getNormalArray()); osg::Vec3Array* normalSrc = static_cast<osg::Vec3Array*>(mSourceGeometry->getNormalArray());
@ -258,7 +233,7 @@ void RigGeometry::updateSkinning(const osg::Matrixf& geomToSkel, RigGeometry::Bo
Bone* bone = weightIt->first.first; Bone* bone = weightIt->first.first;
const osg::Matrix& invBindMatrix = weightIt->first.second; const osg::Matrix& invBindMatrix = weightIt->first.second;
float weight = weightIt->second; float weight = weightIt->second;
const osg::Matrixf& boneMatrix = boneMatrices.at(bone); const osg::Matrixf& boneMatrix = bone->mMatrixInSkeletonSpace;
accummulateMatrix(invBindMatrix, boneMatrix, weight, resultMat); accummulateMatrix(invBindMatrix, boneMatrix, weight, resultMat);
} }
resultMat = resultMat * geomToSkel; resultMat = resultMat * geomToSkel;
@ -275,45 +250,6 @@ void RigGeometry::updateSkinning(const osg::Matrixf& geomToSkel, RigGeometry::Bo
normalDst->dirty(); 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) void RigGeometry::updateBounds(osg::NodeVisitor *nv)
{ {
if (!mSkeleton) if (!mSkeleton)
@ -343,46 +279,6 @@ void RigGeometry::updateBounds(osg::NodeVisitor *nv)
getParent(i)->dirtyBound(); 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::Matrixf RigGeometry::getGeomToSkelMatrix(osg::NodeVisitor *nv)
{ {
osg::NodePath path; osg::NodePath path;

@ -7,16 +7,12 @@
namespace SceneUtil namespace SceneUtil
{ {
class WorkQueue;
class WorkTicket;
class Skeleton; class Skeleton;
class Bone; class Bone;
/// @brief Mesh skinning implementation. /// @brief Mesh skinning implementation.
/// @note A RigGeometry may be attached directly to a Skeleton, or somewhere below a Skeleton. /// @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 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 class RigGeometry : public osg::Geometry
{ {
public: public:
@ -45,23 +41,10 @@ namespace SceneUtil
// Called automatically by our CullCallback // Called automatically by our CullCallback
void update(osg::NodeVisitor* nv); void update(osg::NodeVisitor* nv);
// Called by the worker thread
typedef std::map<Bone*, osg::Matrixf> BoneMatrixMap;
void updateSkinning(const osg::Matrixf& geomToSkelMatrix, BoneMatrixMap boneMatrices);
// Called automatically by our UpdateCallback // Called automatically by our UpdateCallback
void updateBounds(osg::NodeVisitor* nv); 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: private:
mutable osg::ref_ptr<WorkTicket> mWorkTicket;
WorkQueue* mWorkQueue;
osg::ref_ptr<osg::Geometry> mSourceGeometry; osg::ref_ptr<osg::Geometry> mSourceGeometry;
Skeleton* mSkeleton; Skeleton* mSkeleton;
@ -87,8 +70,6 @@ namespace SceneUtil
bool initFromParentSkeleton(osg::NodeVisitor* nv); bool initFromParentSkeleton(osg::NodeVisitor* nv);
osg::Matrixf getGeomToSkelMatrix(osg::NodeVisitor* nv); osg::Matrixf getGeomToSkelMatrix(osg::NodeVisitor* nv);
void initWorkQueue();
}; };
} }

Loading…
Cancel
Save