mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-22 06:39:48 +00:00
Merged pull request #1882
This commit is contained in:
commit
fe38b806e7
2 changed files with 40 additions and 38 deletions
|
@ -129,6 +129,7 @@
|
||||||
Feature #4581: Use proper logging system
|
Feature #4581: Use proper logging system
|
||||||
Task #2490: Don't open command prompt window on Release-mode builds automatically
|
Task #2490: Don't open command prompt window on Release-mode builds automatically
|
||||||
Task #4545: Enable is_pod string test
|
Task #4545: Enable is_pod string test
|
||||||
|
Task #4605: Optimize skinning
|
||||||
Task #4606: Support Rapture3D's OpenAL driver
|
Task #4606: Support Rapture3D's OpenAL driver
|
||||||
|
|
||||||
0.44.0
|
0.44.0
|
||||||
|
|
|
@ -8,6 +8,31 @@
|
||||||
#include "skeleton.hpp"
|
#include "skeleton.hpp"
|
||||||
#include "util.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
|
namespace SceneUtil
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -141,28 +166,6 @@ bool RigGeometry::initFromParentSkeleton(osg::NodeVisitor* nv)
|
||||||
return true;
|
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)
|
void RigGeometry::cull(osg::NodeVisitor* nv)
|
||||||
{
|
{
|
||||||
if (!mSkeleton)
|
if (!mSkeleton)
|
||||||
|
@ -173,7 +176,8 @@ void RigGeometry::cull(osg::NodeVisitor* nv)
|
||||||
return;
|
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);
|
osg::Geometry& geom = *getGeometry(mLastFrameNumber);
|
||||||
nv->pushOntoNodePath(&geom);
|
nv->pushOntoNodePath(&geom);
|
||||||
|
@ -181,10 +185,10 @@ void RigGeometry::cull(osg::NodeVisitor* nv)
|
||||||
nv->popFromNodePath();
|
nv->popFromNodePath();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mLastFrameNumber = nv->getTraversalNumber();
|
mLastFrameNumber = traversalNumber;
|
||||||
osg::Geometry& geom = *getGeometry(mLastFrameNumber);
|
osg::Geometry& geom = *getGeometry(mLastFrameNumber);
|
||||||
|
|
||||||
mSkeleton->updateBoneMatrices(nv->getTraversalNumber());
|
mSkeleton->updateBoneMatrices(traversalNumber);
|
||||||
|
|
||||||
// skinning
|
// skinning
|
||||||
const osg::Vec3Array* positionSrc = static_cast<osg::Vec3Array*>(mSourceGeometry->getVertexArray());
|
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::Vec3Array* normalDst = static_cast<osg::Vec3Array*>(geom.getNormalArray());
|
||||||
osg::Vec4Array* tangentDst = static_cast<osg::Vec4Array*>(geom.getTexCoordArray(7));
|
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, 0,
|
0, 0, 0, 0,
|
||||||
0, 0, 0, 1);
|
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;
|
accumulateMatrix(weight.first.second, weight.first.first->mMatrixInSkeletonSpace, weight.second, resultMat);
|
||||||
const osg::Matrix& invBindMatrix = weightIt->first.second;
|
|
||||||
float weight = weightIt->second;
|
|
||||||
const osg::Matrixf& boneMatrix = bone->mMatrixInSkeletonSpace;
|
|
||||||
accumulateMatrix(invBindMatrix, boneMatrix, weight, resultMat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mGeomToSkelMatrix)
|
if (mGeomToSkelMatrix)
|
||||||
resultMat *= (*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]);
|
(*positionDst)[vertex] = resultMat.preMult((*positionSrc)[vertex]);
|
||||||
if (normalDst)
|
if (normalDst)
|
||||||
(*normalDst)[vertex] = osg::Matrix::transform3x3((*normalSrc)[vertex], resultMat);
|
(*normalDst)[vertex] = osg::Matrixf::transform3x3((*normalSrc)[vertex], resultMat);
|
||||||
|
|
||||||
if (tangentDst)
|
if (tangentDst)
|
||||||
{
|
{
|
||||||
osg::Vec4f srcTangent = (*tangentSrc)[vertex];
|
const osg::Vec4f& srcTangent = (*tangentSrc)[vertex];
|
||||||
osg::Vec3f transformedTangent = osg::Matrix::transform3x3(osg::Vec3f(srcTangent.x(), srcTangent.y(), srcTangent.z()), resultMat);
|
osg::Vec3f transformedTangent = osg::Matrixf::transform3x3(osg::Vec3f(srcTangent.x(), srcTangent.y(), srcTangent.z()), resultMat);
|
||||||
(*tangentDst)[vertex] = osg::Vec4f(transformedTangent, srcTangent.w());
|
(*tangentDst)[vertex] = osg::Vec4f(transformedTangent, srcTangent.w());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue