mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-28 21:07:59 +03:00
Move skinning code to SceneUtil
This commit is contained in:
parent
9246a668b9
commit
eaa4316ff8
7 changed files with 15 additions and 15 deletions
155
components/sceneutil/skeleton.cpp
Normal file
155
components/sceneutil/skeleton.cpp
Normal file
|
@ -0,0 +1,155 @@
|
|||
#include "skeleton.hpp"
|
||||
|
||||
#include <osg/Transform>
|
||||
#include <osg/MatrixTransform>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace SceneUtil
|
||||
{
|
||||
|
||||
class InitBoneCacheVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
InitBoneCacheVisitor(std::map<std::string, std::pair<osg::NodePath, osg::MatrixTransform*> >& cache)
|
||||
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
||||
, mCache(cache)
|
||||
{
|
||||
}
|
||||
|
||||
void apply(osg::Transform &node)
|
||||
{
|
||||
osg::MatrixTransform* bone = node.asMatrixTransform();
|
||||
if (!bone)
|
||||
return;
|
||||
|
||||
mCache[bone->getName()] = std::make_pair(getNodePath(), bone);
|
||||
|
||||
traverse(node);
|
||||
}
|
||||
private:
|
||||
std::map<std::string, std::pair<osg::NodePath, osg::MatrixTransform*> >& mCache;
|
||||
};
|
||||
|
||||
Skeleton::Skeleton()
|
||||
: mBoneCacheInit(false)
|
||||
, mNeedToUpdateBoneMatrices(true)
|
||||
, mLastFrameNumber(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Skeleton::Skeleton(const Skeleton ©, const osg::CopyOp ©op)
|
||||
: osg::Group(copy, copyop)
|
||||
, mBoneCacheInit(false)
|
||||
, mNeedToUpdateBoneMatrices(true)
|
||||
, mLastFrameNumber(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Bone* Skeleton::getBone(const std::string &name)
|
||||
{
|
||||
if (!mBoneCacheInit)
|
||||
{
|
||||
InitBoneCacheVisitor visitor(mBoneCache);
|
||||
accept(visitor);
|
||||
mBoneCacheInit = true;
|
||||
}
|
||||
|
||||
BoneCache::iterator found = mBoneCache.find(name);
|
||||
if (found == mBoneCache.end())
|
||||
return NULL;
|
||||
|
||||
// find or insert in the bone hierarchy
|
||||
|
||||
if (!mRootBone.get())
|
||||
{
|
||||
mRootBone.reset(new Bone);
|
||||
}
|
||||
|
||||
const osg::NodePath& path = found->second.first;
|
||||
Bone* bone = mRootBone.get();
|
||||
for (osg::NodePath::const_iterator it = path.begin(); it != path.end(); ++it)
|
||||
{
|
||||
osg::MatrixTransform* matrixTransform = dynamic_cast<osg::MatrixTransform*>(*it);
|
||||
if (!matrixTransform)
|
||||
continue;
|
||||
|
||||
Bone* child = NULL;
|
||||
for (unsigned int i=0; i<bone->mChildren.size(); ++i)
|
||||
{
|
||||
if (bone->mChildren[i]->mNode == *it)
|
||||
{
|
||||
child = bone->mChildren[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!child)
|
||||
{
|
||||
child = new Bone;
|
||||
bone->mChildren.push_back(child);
|
||||
mNeedToUpdateBoneMatrices = true;
|
||||
}
|
||||
bone = child;
|
||||
|
||||
bone->mNode = matrixTransform;
|
||||
}
|
||||
|
||||
return bone;
|
||||
}
|
||||
|
||||
void Skeleton::updateBoneMatrices(osg::NodeVisitor* nv)
|
||||
{
|
||||
if (nv->getFrameStamp()->getFrameNumber() != mLastFrameNumber)
|
||||
mNeedToUpdateBoneMatrices = true;
|
||||
|
||||
mLastFrameNumber = nv->getFrameStamp()->getFrameNumber();
|
||||
|
||||
if (mNeedToUpdateBoneMatrices)
|
||||
{
|
||||
if (mRootBone.get())
|
||||
{
|
||||
for (unsigned int i=0; i<mRootBone->mChildren.size(); ++i)
|
||||
mRootBone->mChildren[i]->update(NULL);
|
||||
}
|
||||
else
|
||||
std::cerr << "no root bone" << std::endl;
|
||||
|
||||
mNeedToUpdateBoneMatrices = false;
|
||||
}
|
||||
}
|
||||
|
||||
Bone::Bone()
|
||||
: mNode(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
Bone::~Bone()
|
||||
{
|
||||
for (unsigned int i=0; i<mChildren.size(); ++i)
|
||||
delete mChildren[i];
|
||||
mChildren.clear();
|
||||
}
|
||||
|
||||
void Bone::update(const osg::Matrixf* parentMatrixInSkeletonSpace)
|
||||
{
|
||||
if (!mNode)
|
||||
{
|
||||
std::cerr << "Bone without node " << std::endl;
|
||||
}
|
||||
if (parentMatrixInSkeletonSpace)
|
||||
mMatrixInSkeletonSpace = mNode->getMatrix() * (*parentMatrixInSkeletonSpace);
|
||||
else
|
||||
mMatrixInSkeletonSpace = mNode->getMatrix();
|
||||
|
||||
for (unsigned int i=0; i<mChildren.size(); ++i)
|
||||
{
|
||||
mChildren[i]->update(&mMatrixInSkeletonSpace);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue