|
|
|
@ -8,6 +8,31 @@
|
|
|
|
|
#include "skeleton.hpp"
|
|
|
|
|
#include "util.hpp"
|
|
|
|
|
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
inline void accumulateMatrix(const osg::Matrixf& invBindMatrix, const osg::Matrixf& matrix, const float weight, osg::Matrixf& result)
|
|
|
|
|
{
|
|
|
|
|
osg::Matrixf m = invBindMatrix * matrix;
|
|
|
|
|
float* ptr = m.ptr();
|
|
|
|
|
float* ptrresult = result.ptr();
|
|
|
|
|
ptrresult[0] += ptr[0] * weight;
|
|
|
|
|
ptrresult[1] += ptr[1] * weight;
|
|
|
|
|
ptrresult[2] += ptr[2] * weight;
|
|
|
|
|
|
|
|
|
|
ptrresult[4] += ptr[4] * weight;
|
|
|
|
|
ptrresult[5] += ptr[5] * weight;
|
|
|
|
|
ptrresult[6] += ptr[6] * weight;
|
|
|
|
|
|
|
|
|
|
ptrresult[8] += ptr[8] * weight;
|
|
|
|
|
ptrresult[9] += ptr[9] * weight;
|
|
|
|
|
ptrresult[10] += ptr[10] * weight;
|
|
|
|
|
|
|
|
|
|
ptrresult[12] += ptr[12] * weight;
|
|
|
|
|
ptrresult[13] += ptr[13] * weight;
|
|
|
|
|
ptrresult[14] += ptr[14] * weight;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace SceneUtil
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
@ -141,28 +166,6 @@ bool RigGeometry::initFromParentSkeleton(osg::NodeVisitor* nv)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void accumulateMatrix(const osg::Matrixf& invBindMatrix, const osg::Matrixf& matrix, float weight, osg::Matrixf& result)
|
|
|
|
|
{
|
|
|
|
|
osg::Matrixf m = invBindMatrix * matrix;
|
|
|
|
|
float* ptr = m.ptr();
|
|
|
|
|
float* ptrresult = result.ptr();
|
|
|
|
|
ptrresult[0] += ptr[0] * weight;
|
|
|
|
|
ptrresult[1] += ptr[1] * weight;
|
|
|
|
|
ptrresult[2] += ptr[2] * weight;
|
|
|
|
|
|
|
|
|
|
ptrresult[4] += ptr[4] * weight;
|
|
|
|
|
ptrresult[5] += ptr[5] * weight;
|
|
|
|
|
ptrresult[6] += ptr[6] * weight;
|
|
|
|
|
|
|
|
|
|
ptrresult[8] += ptr[8] * weight;
|
|
|
|
|
ptrresult[9] += ptr[9] * weight;
|
|
|
|
|
ptrresult[10] += ptr[10] * weight;
|
|
|
|
|
|
|
|
|
|
ptrresult[12] += ptr[12] * weight;
|
|
|
|
|
ptrresult[13] += ptr[13] * weight;
|
|
|
|
|
ptrresult[14] += ptr[14] * weight;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RigGeometry::cull(osg::NodeVisitor* nv)
|
|
|
|
|
{
|
|
|
|
|
if (!mSkeleton)
|
|
|
|
@ -173,7 +176,8 @@ void RigGeometry::cull(osg::NodeVisitor* nv)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((!mSkeleton->getActive() && mLastFrameNumber != 0) || mLastFrameNumber == nv->getTraversalNumber())
|
|
|
|
|
unsigned int traversalNumber = nv->getTraversalNumber();
|
|
|
|
|
if (mLastFrameNumber == traversalNumber || (mLastFrameNumber != 0 && !mSkeleton->getActive()))
|
|
|
|
|
{
|
|
|
|
|
osg::Geometry& geom = *getGeometry(mLastFrameNumber);
|
|
|
|
|
nv->pushOntoNodePath(&geom);
|
|
|
|
@ -181,10 +185,10 @@ void RigGeometry::cull(osg::NodeVisitor* nv)
|
|
|
|
|
nv->popFromNodePath();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
mLastFrameNumber = nv->getTraversalNumber();
|
|
|
|
|
mLastFrameNumber = traversalNumber;
|
|
|
|
|
osg::Geometry& geom = *getGeometry(mLastFrameNumber);
|
|
|
|
|
|
|
|
|
|
mSkeleton->updateBoneMatrices(nv->getTraversalNumber());
|
|
|
|
|
mSkeleton->updateBoneMatrices(traversalNumber);
|
|
|
|
|
|
|
|
|
|
// skinning
|
|
|
|
|
const osg::Vec3Array* positionSrc = static_cast<osg::Vec3Array*>(mSourceGeometry->getVertexArray());
|
|
|
|
@ -195,34 +199,31 @@ void RigGeometry::cull(osg::NodeVisitor* nv)
|
|
|
|
|
osg::Vec3Array* normalDst = static_cast<osg::Vec3Array*>(geom.getNormalArray());
|
|
|
|
|
osg::Vec4Array* tangentDst = static_cast<osg::Vec4Array*>(geom.getTexCoordArray(7));
|
|
|
|
|
|
|
|
|
|
for (Bone2VertexMap::const_iterator it = mBone2VertexMap.begin(); it != mBone2VertexMap.end(); ++it)
|
|
|
|
|
for (auto &pair : mBone2VertexMap)
|
|
|
|
|
{
|
|
|
|
|
osg::Matrixf resultMat (0, 0, 0, 0,
|
|
|
|
|
osg::Matrixf resultMat (0, 0, 0, 0,
|
|
|
|
|
0, 0, 0, 0,
|
|
|
|
|
0, 0, 0, 0,
|
|
|
|
|
0, 0, 0, 1);
|
|
|
|
|
|
|
|
|
|
for (std::vector<BoneWeight>::const_iterator weightIt = it->first.begin(); weightIt != it->first.end(); ++weightIt)
|
|
|
|
|
for (auto &weight : pair.first)
|
|
|
|
|
{
|
|
|
|
|
Bone* bone = weightIt->first.first;
|
|
|
|
|
const osg::Matrix& invBindMatrix = weightIt->first.second;
|
|
|
|
|
float weight = weightIt->second;
|
|
|
|
|
const osg::Matrixf& boneMatrix = bone->mMatrixInSkeletonSpace;
|
|
|
|
|
accumulateMatrix(invBindMatrix, boneMatrix, weight, resultMat);
|
|
|
|
|
accumulateMatrix(weight.first.second, weight.first.first->mMatrixInSkeletonSpace, weight.second, resultMat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mGeomToSkelMatrix)
|
|
|
|
|
resultMat *= (*mGeomToSkelMatrix);
|
|
|
|
|
|
|
|
|
|
for (std::vector<unsigned short>::const_iterator vertexIt = it->second.begin(); vertexIt != it->second.end(); ++vertexIt)
|
|
|
|
|
for (auto &vertex : pair.second)
|
|
|
|
|
{
|
|
|
|
|
unsigned short vertex = *vertexIt;
|
|
|
|
|
(*positionDst)[vertex] = resultMat.preMult((*positionSrc)[vertex]);
|
|
|
|
|
if (normalDst)
|
|
|
|
|
(*normalDst)[vertex] = osg::Matrix::transform3x3((*normalSrc)[vertex], resultMat);
|
|
|
|
|
(*normalDst)[vertex] = osg::Matrixf::transform3x3((*normalSrc)[vertex], resultMat);
|
|
|
|
|
|
|
|
|
|
if (tangentDst)
|
|
|
|
|
{
|
|
|
|
|
osg::Vec4f srcTangent = (*tangentSrc)[vertex];
|
|
|
|
|
osg::Vec3f transformedTangent = osg::Matrix::transform3x3(osg::Vec3f(srcTangent.x(), srcTangent.y(), srcTangent.z()), resultMat);
|
|
|
|
|
const osg::Vec4f& srcTangent = (*tangentSrc)[vertex];
|
|
|
|
|
osg::Vec3f transformedTangent = osg::Matrixf::transform3x3(osg::Vec3f(srcTangent.x(), srcTangent.y(), srcTangent.z()), resultMat);
|
|
|
|
|
(*tangentDst)[vertex] = osg::Vec4f(transformedTangent, srcTangent.w());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|