From Cedric Pinson, updates toosgAnimation.
Merged by Robert Osfield, from OpenSceneGraph-osgWidget-dev.
This commit is contained in:
@@ -78,7 +78,7 @@ namespace osgAnimation
|
||||
{
|
||||
setName(name);
|
||||
_needToRecomputeBindMatrix = false;
|
||||
setUpdateCallback(new UpdateBone);
|
||||
setUpdateCallback(new UpdateBone(name));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,11 +17,6 @@
|
||||
|
||||
namespace osgAnimation {
|
||||
|
||||
struct LinearFunction
|
||||
{
|
||||
inline static void getValueAt(float t, float& result) { result = t;}
|
||||
};
|
||||
|
||||
|
||||
struct OutBounceFunction
|
||||
{
|
||||
@@ -75,7 +70,15 @@ namespace osgAnimation {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Linear function
|
||||
struct LinearFunction
|
||||
{
|
||||
inline static void getValueAt(float t, float& result) { result = t;}
|
||||
};
|
||||
|
||||
|
||||
/// Quad function
|
||||
struct OutQuadFunction
|
||||
{
|
||||
inline static void getValueAt(float t, float& result) { result = - (t * (t -2.0));}
|
||||
@@ -101,6 +104,7 @@ namespace osgAnimation {
|
||||
};
|
||||
|
||||
|
||||
/// Cubic function
|
||||
struct OutCubicFunction
|
||||
{
|
||||
inline static void getValueAt(float t, float& result) { t = t-1.0; result = t*t*t + 1;}
|
||||
@@ -123,6 +127,35 @@ namespace osgAnimation {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Quart function
|
||||
struct InQuartFunction
|
||||
{
|
||||
inline static void getValueAt(float t, float& result) { result = t*t*t*t*t;}
|
||||
};
|
||||
|
||||
struct OutQuartFunction
|
||||
{
|
||||
inline static void getValueAt(float t, float& result) { t = t - 1; result = - (t*t*t*t -1); }
|
||||
};
|
||||
|
||||
struct InOutQuartFunction
|
||||
{
|
||||
inline static void getValueAt(float t, float& result)
|
||||
{
|
||||
t = t * 2.0;
|
||||
if ( t < 1)
|
||||
result = 0.5*t*t*t*t;
|
||||
else
|
||||
{
|
||||
t -= 2.0;
|
||||
result = -0.5 * (t*t*t*t -2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Motion
|
||||
{
|
||||
public:
|
||||
@@ -185,6 +218,7 @@ namespace osgAnimation {
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct MathMotionTemplate : public Motion
|
||||
{
|
||||
@@ -217,15 +251,21 @@ namespace osgAnimation {
|
||||
// linear
|
||||
typedef MathMotionTemplate<LinearFunction > LinearMotion;
|
||||
|
||||
// quad
|
||||
typedef MathMotionTemplate<OutQuadFunction > OutQuadMotion;
|
||||
typedef MathMotionTemplate<InQuadFunction> InQuadMotion;
|
||||
typedef MathMotionTemplate<InOutQuadFunction> InOutQuadMotion;
|
||||
|
||||
// cubic
|
||||
typedef MathMotionTemplate<OutCubicFunction > OutCubicMotion;
|
||||
typedef MathMotionTemplate<InCubicFunction> InCubicMotion;
|
||||
typedef MathMotionTemplate<InOutCubicFunction> InOutCubicMotion;
|
||||
|
||||
// quad
|
||||
typedef MathMotionTemplate<OutQuadFunction > OutQuadMotion;
|
||||
typedef MathMotionTemplate<InQuadFunction> InQuadMotion;
|
||||
typedef MathMotionTemplate<InOutQuadFunction> InOutQuadMotion;
|
||||
// quart
|
||||
typedef MathMotionTemplate<OutQuartFunction > OutQuartMotion;
|
||||
typedef MathMotionTemplate<InQuartFunction> InQuartMotion;
|
||||
typedef MathMotionTemplate<InOutQuartFunction> InOutQuartMotion;
|
||||
|
||||
|
||||
// bounce
|
||||
typedef MathMotionTemplate<OutBounceFunction > OutBounceMotion;
|
||||
|
||||
@@ -30,7 +30,12 @@
|
||||
namespace osgAnimation
|
||||
{
|
||||
|
||||
|
||||
/// This class manage format for software skinning
|
||||
/// it used the technic on this paper http://www.intel.com/cd/ids/developer/asmo-na/eng/172124.htm
|
||||
/// The idea is to prepare the data to do only v' = M x v with M a combined matrix as below
|
||||
/// M = Mbone1 * w1 + Mbone2 * w2 + ...
|
||||
/// a M matrix is uniq for a set of vertex then to fully compute the skinned mesh
|
||||
/// you have to iterate on each UniqBoneSetVertexSet
|
||||
class TransformVertexFunctor
|
||||
{
|
||||
public:
|
||||
@@ -44,6 +49,7 @@ namespace osgAnimation
|
||||
BoneWeight(BoneType* bone, float weight) : _bone(bone), _weight(weight) {}
|
||||
const BoneType* getBone() const { return &(*_bone); }
|
||||
float getWeight() const { return _weight; }
|
||||
void setWeight(float w) { _weight = w; }
|
||||
protected:
|
||||
osg::ref_ptr<BoneType> _bone;
|
||||
float _weight;
|
||||
@@ -57,6 +63,35 @@ namespace osgAnimation
|
||||
public:
|
||||
BoneWeightList& getBones() { return _bones; }
|
||||
VertexList& getVertexes() { return _vertexes; }
|
||||
|
||||
void resetMatrix()
|
||||
{
|
||||
_result.set(0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
void accummulateMatrix(const osg::Matrix& invBindMatrix, const osg::Matrix& matrix, osg::Matrix::value_type weight)
|
||||
{
|
||||
osg::Matrix m = invBindMatrix * matrix;
|
||||
osg::Matrix::value_type* ptr = m.ptr();
|
||||
osg::Matrix::value_type* 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 computeMatrixForVertexSet()
|
||||
{
|
||||
if (_bones.empty())
|
||||
@@ -65,18 +100,16 @@ namespace osgAnimation
|
||||
_result = MatrixType::identity();
|
||||
return;
|
||||
}
|
||||
_result = MatrixType(0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0);
|
||||
resetMatrix();
|
||||
|
||||
int size = _bones.size();
|
||||
for (int i = 0; i < size; i++)
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
const BoneType* bone = _bones[i].getBone();
|
||||
const MatrixType& invBindMatrix = bone->getInvBindMatrixInSkeletonSpace();
|
||||
const MatrixType& matrix = bone->getMatrixInSkeletonSpace();
|
||||
double w = _bones[i].getWeight();
|
||||
_result = _result + ( (invBindMatrix * matrix ) * w);
|
||||
osg::Matrix::value_type w = _bones[i].getWeight();
|
||||
accummulateMatrix(invBindMatrix, matrix, w);
|
||||
}
|
||||
}
|
||||
const MatrixType& getMatrix() const { return _result;}
|
||||
@@ -97,21 +130,31 @@ namespace osgAnimation
|
||||
{
|
||||
const osgAnimation::VertexInfluenceSet::UniqVertexSetToBoneSet& inf = influence[i];
|
||||
int nbBones = inf.getBones().size();
|
||||
BoneWeightList& boneList = _boneSetVertexSet[i].getBones();
|
||||
|
||||
double sumOfWeight = 0;
|
||||
for (int b = 0; b < nbBones; b++)
|
||||
{
|
||||
const std::string& bname = inf.getBones()[b].getBoneName();
|
||||
float weight = inf.getBones()[b].getWeight();
|
||||
if (map.find(bname) == map.end())
|
||||
BoneMap::const_iterator it = map.find(bname);
|
||||
if (it == map.end())
|
||||
{
|
||||
std::cerr << "Warning TransformVertexFunctor Bone " << bname << " not found, skip the influence group " <<bname << std::endl;
|
||||
osg::notify(osg::WARN) << "TransformVertexFunctor Bone " << bname << " not found, skip the influence group " <<bname << std::endl;
|
||||
continue;
|
||||
}
|
||||
BoneMap::const_iterator it = map.find(bname);
|
||||
if (it == map.end())
|
||||
std::cerr << "Warning TransformVertexFunctor does not find bone " << bname << " in the map" << std::endl;
|
||||
BoneType* bone = it->second.get();
|
||||
_boneSetVertexSet[i].getBones().push_back(BoneWeight(bone, weight));
|
||||
boneList.push_back(BoneWeight(bone, weight));
|
||||
sumOfWeight += weight;
|
||||
}
|
||||
// if a bone referenced by a vertexinfluence is missed it can make the sum less than 1.0
|
||||
// so we check it and renormalize the all weight bone
|
||||
const double threshold = 1e-4;
|
||||
if (!_boneSetVertexSet[i].getBones().empty() &&
|
||||
(sumOfWeight < 1.0 - threshold || sumOfWeight > 1.0 + threshold))
|
||||
{
|
||||
for (int b = 0; b < boneList.size(); b++)
|
||||
boneList[b].setWeight(boneList[b].getWeight() / sumOfWeight);
|
||||
}
|
||||
_boneSetVertexSet[i].getVertexes() = inf.getVertexes();
|
||||
}
|
||||
|
||||
@@ -15,14 +15,15 @@
|
||||
#ifndef OSGANIMATION_TIMELINE_H
|
||||
#define OSGANIMATION_TIMELINE_H
|
||||
|
||||
#include <osgAnimation/Export>
|
||||
#include <osg/Object>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <osg/Notify>
|
||||
#include <osg/Group>
|
||||
#include <osgAnimation/Animation>
|
||||
#include <osgAnimation/AnimationManagerBase>
|
||||
#include <osgAnimation/Export>
|
||||
|
||||
namespace osgAnimation
|
||||
{
|
||||
@@ -213,7 +214,7 @@ namespace osgAnimation
|
||||
// process all pending remove action operation
|
||||
while( !_removeActionOperations.empty())
|
||||
{
|
||||
internalRemoveAction(_removeActionOperations.back().second.get());
|
||||
internalRemoveAction(_removeActionOperations.back().second);
|
||||
_removeActionOperations.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,6 @@ namespace osgAnimation
|
||||
void buildUniqVertexSetToBoneSetList();
|
||||
void clear()
|
||||
{
|
||||
_bone2Vertexes.clear();
|
||||
_bone2Vertexes.clear();
|
||||
_uniqVertexSetToBoneSet.clear();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user