mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-30 09:06:43 +00:00
Revert "Use the WorkQueue to update skinning"
This reverts commit d52d0d9640
.
Moving to branch
This commit is contained in:
parent
9c86d4f8bc
commit
a1e74a35a2
2 changed files with 10 additions and 133 deletions
|
@ -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 ©, const osg::CopyOp ©op)
|
||||||
, 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…
Reference in a new issue