From Cedric Pinson, The following commit include:
* Refactore of RigGeometry to support hardware skinning * Refactore of Timeline to split Action in differents files * Add example how to use hardware skinning
This commit is contained in:
@@ -57,6 +57,17 @@ namespace osgAnimation
|
||||
_nestedCallback = callback;
|
||||
}
|
||||
|
||||
void removeCallback(Callback* cb)
|
||||
{
|
||||
if (!cb)
|
||||
return;
|
||||
|
||||
if (_nestedCallback.get() == cb)
|
||||
_nestedCallback = _nestedCallback->getNestedCallback();
|
||||
else
|
||||
_nestedCallback->removeCallback(cb);
|
||||
}
|
||||
|
||||
protected:
|
||||
osg::ref_ptr<Callback> _nestedCallback;
|
||||
};
|
||||
@@ -87,7 +98,9 @@ namespace osgAnimation
|
||||
return 0;
|
||||
return _framesCallback[frame].get();
|
||||
}
|
||||
|
||||
|
||||
void removeCallback(Callback*);
|
||||
|
||||
Callback* getFrameCallback(unsigned int frame);
|
||||
Callback* getFrameCallback(double time);
|
||||
unsigned int getFramesPerSecond() const { return _fps; }
|
||||
@@ -127,82 +140,6 @@ namespace osgAnimation
|
||||
|
||||
|
||||
|
||||
// blend in from 0 to weight in duration
|
||||
class OSGANIMATION_EXPORT BlendIn : public Action
|
||||
{
|
||||
double _weight;
|
||||
osg::ref_ptr<Animation> _animation;
|
||||
|
||||
public:
|
||||
META_Action(osgAnimation, BlendIn);
|
||||
BlendIn() : _weight(0) {}
|
||||
BlendIn(const BlendIn& a, const osg::CopyOp& c) : Action(a,c) { _weight = a._weight; _animation = a._animation;}
|
||||
BlendIn(Animation* animation, double duration, double weight);
|
||||
double getWeight() const { return _weight;}
|
||||
Animation* getAnimation() { return _animation.get(); }
|
||||
void computeWeight(unsigned int frame);
|
||||
};
|
||||
|
||||
// blend in from 0 to weight in duration
|
||||
class OSGANIMATION_EXPORT BlendOut : public Action
|
||||
{
|
||||
double _weight;
|
||||
osg::ref_ptr<Animation> _animation;
|
||||
public:
|
||||
META_Action(osgAnimation, BlendOut);
|
||||
BlendOut() : _weight(0) {}
|
||||
BlendOut(const BlendOut& a, const osg::CopyOp& c) : Action(a,c) { _weight = a._weight; _animation = a._animation;}
|
||||
BlendOut(Animation* animation, double duration);
|
||||
Animation* getAnimation() { return _animation.get(); }
|
||||
double getWeight() const { return _weight;}
|
||||
void computeWeight(unsigned int frame);
|
||||
};
|
||||
|
||||
|
||||
class OSGANIMATION_EXPORT ActionAnimation : public Action
|
||||
{
|
||||
public:
|
||||
META_Action(osgAnimation, ActionAnimation);
|
||||
ActionAnimation() {}
|
||||
ActionAnimation(const ActionAnimation& a, const osg::CopyOp& c) : Action(a,c) { _animation = a._animation;}
|
||||
ActionAnimation(Animation* animation);
|
||||
void updateAnimation(unsigned int frame, int priority);
|
||||
Animation* getAnimation() { return _animation.get(); }
|
||||
|
||||
protected:
|
||||
osg::ref_ptr<Animation> _animation;
|
||||
};
|
||||
|
||||
|
||||
// encapsulate animation with blend in blend out for classic usage
|
||||
class OSGANIMATION_EXPORT StripAnimation : public Action
|
||||
{
|
||||
public:
|
||||
META_Action(osgAnimation, StripAnimation);
|
||||
StripAnimation() {}
|
||||
StripAnimation(const StripAnimation& a, const osg::CopyOp& c);
|
||||
StripAnimation(Animation* animation, double blendInDuration = 0.0, double blendOutDuration = 0.0, double blendInWeightTarget = 1.0 );
|
||||
ActionAnimation* getActionAnimation() { return _animation.get(); }
|
||||
BlendIn* getBlendIn() { return _blendIn.get(); }
|
||||
BlendOut* getBlendOut() { return _blendOut.second.get(); }
|
||||
const ActionAnimation* getActionAnimation() const { return _animation.get(); }
|
||||
const BlendIn* getBlendIn() const { return _blendIn.get(); }
|
||||
const BlendOut* getBlendOut() const { return _blendOut.second.get(); }
|
||||
unsigned int getBlendOutStartFrame() const { return _blendOut.first; }
|
||||
|
||||
unsigned int getLoop() const { return _animation->getLoop(); }
|
||||
void setLoop(unsigned int loop);
|
||||
void traverse(ActionVisitor& visitor);
|
||||
|
||||
protected:
|
||||
typedef std::pair<unsigned int, osg::ref_ptr<BlendOut> > FrameBlendOut;
|
||||
osg::ref_ptr<BlendIn> _blendIn;
|
||||
FrameBlendOut _blendOut;
|
||||
osg::ref_ptr<ActionAnimation> _animation;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
41
include/osgAnimation/ActionAnimation
Normal file
41
include/osgAnimation/ActionAnimation
Normal file
@@ -0,0 +1,41 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2009 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSGANIMATION_ACTION_ANIMATION_H
|
||||
#define OSGANIMATION_ACTION_ANIMATION_H
|
||||
|
||||
#include <osgAnimation/Action>
|
||||
#include <osgAnimation/Export>
|
||||
|
||||
|
||||
namespace osgAnimation {
|
||||
|
||||
|
||||
class OSGANIMATION_EXPORT ActionAnimation : public Action
|
||||
{
|
||||
public:
|
||||
META_Action(osgAnimation, ActionAnimation);
|
||||
ActionAnimation();
|
||||
ActionAnimation(const ActionAnimation& a, const osg::CopyOp& c);
|
||||
ActionAnimation(Animation* animation);
|
||||
void updateAnimation(unsigned int frame, int priority);
|
||||
Animation* getAnimation() { return _animation.get(); }
|
||||
|
||||
protected:
|
||||
osg::ref_ptr<Animation> _animation;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
44
include/osgAnimation/ActionBlendIn
Normal file
44
include/osgAnimation/ActionBlendIn
Normal file
@@ -0,0 +1,44 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2009 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSGANIMATION_ACTION_BLENDIN_H
|
||||
#define OSGANIMATION_ACTION_BLENDIN_H
|
||||
|
||||
#include <osgAnimation/Action>
|
||||
#include <osgAnimation/Export>
|
||||
|
||||
|
||||
namespace osgAnimation {
|
||||
|
||||
|
||||
/// blend in from 0 to weight in duration
|
||||
class OSGANIMATION_EXPORT ActionBlendIn : public Action
|
||||
{
|
||||
public:
|
||||
META_Action(osgAnimation, ActionBlendIn);
|
||||
ActionBlendIn();
|
||||
ActionBlendIn(const ActionBlendIn& a, const osg::CopyOp& c);
|
||||
ActionBlendIn(Animation* animation, double duration, double weight);
|
||||
double getWeight() const { return _weight;}
|
||||
Animation* getAnimation() { return _animation.get(); }
|
||||
void computeWeight(unsigned int frame);
|
||||
|
||||
protected:
|
||||
double _weight;
|
||||
osg::ref_ptr<Animation> _animation;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
45
include/osgAnimation/ActionBlendOut
Normal file
45
include/osgAnimation/ActionBlendOut
Normal file
@@ -0,0 +1,45 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2009 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSGANIMATION_ACTION_BLENDOUT_H
|
||||
#define OSGANIMATION_ACTION_BLENDOUT_H
|
||||
|
||||
#include <osgAnimation/Action>
|
||||
#include <osgAnimation/Export>
|
||||
|
||||
|
||||
namespace osgAnimation {
|
||||
|
||||
|
||||
/// blend out from weight to 0 in duration
|
||||
class OSGANIMATION_EXPORT ActionBlendOut : public Action
|
||||
{
|
||||
public:
|
||||
META_Action(osgAnimation, ActionBlendOut);
|
||||
ActionBlendOut();
|
||||
ActionBlendOut(const ActionBlendOut& a, const osg::CopyOp& c);
|
||||
ActionBlendOut(Animation* animation, double duration);
|
||||
Animation* getAnimation() { return _animation.get(); }
|
||||
double getWeight() const { return _weight;}
|
||||
void computeWeight(unsigned int frame);
|
||||
|
||||
protected:
|
||||
double _weight;
|
||||
osg::ref_ptr<Animation> _animation;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
57
include/osgAnimation/ActionStripAnimation
Normal file
57
include/osgAnimation/ActionStripAnimation
Normal file
@@ -0,0 +1,57 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2009 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSGANIMATION_ACTION_STRIPANIMATION_H
|
||||
#define OSGANIMATION_ACTION_STRIPANIMATION_H
|
||||
|
||||
#include <osgAnimation/Action>
|
||||
#include <osgAnimation/Export>
|
||||
#include <osgAnimation/FrameAction>
|
||||
#include <osgAnimation/ActionBlendIn>
|
||||
#include <osgAnimation/ActionBlendOut>
|
||||
#include <osgAnimation/ActionAnimation>
|
||||
|
||||
namespace osgAnimation
|
||||
{
|
||||
|
||||
// encapsulate animation with blend in blend out for classic usage
|
||||
class OSGANIMATION_EXPORT ActionStripAnimation : public Action
|
||||
{
|
||||
public:
|
||||
META_Action(osgAnimation, ActionStripAnimation);
|
||||
ActionStripAnimation() {}
|
||||
ActionStripAnimation(const ActionStripAnimation& a, const osg::CopyOp& c);
|
||||
ActionStripAnimation(Animation* animation, double blendInDuration = 0.0, double blendOutDuration = 0.0, double blendInWeightTarget = 1.0 );
|
||||
ActionAnimation* getAnimation();
|
||||
ActionBlendIn* getBlendIn();
|
||||
ActionBlendOut* getBlendOut();
|
||||
const ActionAnimation* getAnimation() const;
|
||||
const ActionBlendIn* getBlendIn() const;
|
||||
const ActionBlendOut* getBlendOut() const;
|
||||
unsigned int getBlendOutStartFrame() const;
|
||||
|
||||
unsigned int getLoop() const;
|
||||
void setLoop(unsigned int loop);
|
||||
void traverse(ActionVisitor& visitor);
|
||||
|
||||
protected:
|
||||
typedef std::pair<unsigned int, osg::ref_ptr<ActionBlendOut> > FrameBlendOut;
|
||||
osg::ref_ptr<ActionBlendIn> _blendIn;
|
||||
FrameBlendOut _blendOut;
|
||||
osg::ref_ptr<ActionAnimation> _animation;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -25,10 +25,10 @@ namespace osgAnimation
|
||||
|
||||
class Timeline;
|
||||
class Action;
|
||||
class BlendIn;
|
||||
class BlendOut;
|
||||
class ActionBlendIn;
|
||||
class ActionBlendOut;
|
||||
class ActionAnimation;
|
||||
class StripAnimation;
|
||||
class ActionStripAnimation;
|
||||
|
||||
#define META_ActionVisitor(library,name) \
|
||||
virtual const char* libraryName() const { return #library; }\
|
||||
@@ -56,10 +56,10 @@ namespace osgAnimation
|
||||
|
||||
virtual void apply(Action& action);
|
||||
virtual void apply(Timeline& tm);
|
||||
virtual void apply(BlendIn& action);
|
||||
virtual void apply(BlendOut& action);
|
||||
virtual void apply(ActionBlendIn& action);
|
||||
virtual void apply(ActionBlendOut& action);
|
||||
virtual void apply(ActionAnimation& action);
|
||||
virtual void apply(StripAnimation& action);
|
||||
virtual void apply(ActionStripAnimation& action);
|
||||
|
||||
protected:
|
||||
std::vector<FrameAction> _stackFrameAction;
|
||||
@@ -72,7 +72,7 @@ namespace osgAnimation
|
||||
{
|
||||
protected:
|
||||
unsigned int _frame;
|
||||
|
||||
unsigned int _currentAnimationPriority;
|
||||
public:
|
||||
META_ActionVisitor(osgAnimation, UpdateActionVisitor);
|
||||
UpdateActionVisitor();
|
||||
@@ -83,10 +83,10 @@ namespace osgAnimation
|
||||
|
||||
void apply(Timeline& action);
|
||||
void apply(Action& action);
|
||||
void apply(BlendIn& action);
|
||||
void apply(BlendOut& action);
|
||||
void apply(ActionBlendIn& action);
|
||||
void apply(ActionBlendOut& action);
|
||||
void apply(ActionAnimation& action);
|
||||
void apply(StripAnimation& action);
|
||||
void apply(ActionStripAnimation& action);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
|
||||
* Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
@@ -16,8 +16,8 @@
|
||||
#define OSGANIMATION_RIGGEOMETRY_H
|
||||
|
||||
#include <osgAnimation/Export>
|
||||
#include <osgAnimation/Skinning>
|
||||
#include <osgAnimation/Skeleton>
|
||||
#include <osgAnimation/RigTransform>
|
||||
#include <osg/Geometry>
|
||||
|
||||
namespace osgAnimation
|
||||
@@ -33,44 +33,51 @@ namespace osgAnimation
|
||||
|
||||
META_Object(osgAnimation, RigGeometry);
|
||||
|
||||
void setInfluenceMap(osgAnimation::VertexInfluenceMap* vertexInfluenceMap) { _vertexInfluenceMap = vertexInfluenceMap; }
|
||||
const osgAnimation::VertexInfluenceMap* getInfluenceMap() const { return _vertexInfluenceMap.get();}
|
||||
osgAnimation::VertexInfluenceMap* getInfluenceMap() { return _vertexInfluenceMap.get();}
|
||||
void setInfluenceMap(VertexInfluenceMap* vertexInfluenceMap) { _vertexInfluenceMap = vertexInfluenceMap; }
|
||||
const VertexInfluenceMap* getInfluenceMap() const { return _vertexInfluenceMap.get();}
|
||||
VertexInfluenceMap* getInfluenceMap() { return _vertexInfluenceMap.get();}
|
||||
|
||||
const Skeleton* getSkeleton() const;
|
||||
Skeleton* getSkeleton();
|
||||
// will be used by the update callback to init correctly the rig mesh
|
||||
void setSkeleton(Skeleton*);
|
||||
|
||||
void setNeedToComputeMatrix(bool state) { _needToComputeMatrix = state;}
|
||||
bool getNeedToComputeMatrix() const { return _needToComputeMatrix;}
|
||||
|
||||
void buildVertexSet();
|
||||
void buildTransformer(Skeleton* root);
|
||||
|
||||
// this build the internal database about vertex influence and bones
|
||||
void buildVertexInfluenceSet();
|
||||
const VertexInfluenceSet& getVertexInfluenceSet() const;
|
||||
|
||||
void computeMatrixFromRootSkeleton();
|
||||
|
||||
virtual void transformSoftwareMethod();
|
||||
const osgAnimation::VertexInfluenceSet& getVertexInfluenceSet() const { return _vertexInfluenceSet;}
|
||||
|
||||
const std::vector<osg::Vec3>& getPositionSource() const { return _positionSource;}
|
||||
const std::vector<osg::Vec3>& getNormalSource() const { return _normalSource;}
|
||||
// set implementation of rig method
|
||||
void setRigTransformImplementation(RigTransform*);
|
||||
RigTransform* getRigTransformImplementation();
|
||||
|
||||
virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
|
||||
void update();
|
||||
|
||||
const osg::Matrix& getMatrixFromSkeletonToGeometry() const;
|
||||
const osg::Matrix& getInvMatrixFromSkeletonToGeometry() const;
|
||||
|
||||
protected:
|
||||
|
||||
std::vector<osg::Vec3> _positionSource;
|
||||
std::vector<osg::Vec3> _normalSource;
|
||||
osg::ref_ptr<RigTransform> _rigTransformImplementation;
|
||||
|
||||
osgAnimation::VertexInfluenceSet _vertexInfluenceSet;
|
||||
osg::ref_ptr<osgAnimation::VertexInfluenceMap> _vertexInfluenceMap;
|
||||
osgAnimation::TransformVertexFunctor _transformVertexes;
|
||||
VertexInfluenceSet _vertexInfluenceSet;
|
||||
osg::ref_ptr<VertexInfluenceMap> _vertexInfluenceMap;
|
||||
|
||||
osg::Matrix _matrixFromSkeletonToGeometry;
|
||||
osg::Matrix _invMatrixFromSkeletonToGeometry;
|
||||
osg::observer_ptr<Skeleton> _root;
|
||||
bool _needToComputeMatrix;
|
||||
|
||||
|
||||
struct FindNearestParentSkeleton : public osg::NodeVisitor
|
||||
{
|
||||
osg::ref_ptr<osgAnimation::Skeleton> _root;
|
||||
osg::ref_ptr<Skeleton> _root;
|
||||
FindNearestParentSkeleton() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_PARENTS) {}
|
||||
void apply(osg::Transform& node)
|
||||
{
|
||||
@@ -98,8 +105,8 @@ namespace osgAnimation
|
||||
|
||||
if (!finder._root.valid())
|
||||
return;
|
||||
geom->buildVertexSet();
|
||||
geom->buildTransformer(finder._root.get());
|
||||
geom->buildVertexInfluenceSet();
|
||||
geom->setSkeleton(finder._root.get());
|
||||
}
|
||||
|
||||
if (!geom->getSkeleton())
|
||||
@@ -107,34 +114,10 @@ namespace osgAnimation
|
||||
|
||||
if (geom->getNeedToComputeMatrix())
|
||||
geom->computeMatrixFromRootSkeleton();
|
||||
geom->transformSoftwareMethod();
|
||||
|
||||
geom->update();
|
||||
}
|
||||
};
|
||||
|
||||
/** BuildVertexTransformerVisitor is used to setup RigGeometry drawable
|
||||
* throw a subgraph.
|
||||
*/
|
||||
struct BuildVertexTransformerVisitor : public osg::NodeVisitor
|
||||
{
|
||||
osg::ref_ptr<Skeleton> _root;
|
||||
BuildVertexTransformerVisitor(Skeleton* root): osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) { _root = root;}
|
||||
|
||||
META_NodeVisitor("osgAnimation","BuildVertexTransformerVisitor")
|
||||
|
||||
void apply(osg::Geode& node)
|
||||
{
|
||||
int num = node.getNumDrawables();
|
||||
for (int i = 0; i < num; i++) {
|
||||
RigGeometry* geom = dynamic_cast<RigGeometry*>(node.getDrawable(i));
|
||||
if (geom)
|
||||
{
|
||||
geom->buildVertexSet();
|
||||
geom->buildTransformer(_root.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
40
include/osgAnimation/RigTransform
Normal file
40
include/osgAnimation/RigTransform
Normal file
@@ -0,0 +1,40 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2009 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSGANIMATION_RIGTRANSFORM_H
|
||||
#define OSGANIMATION_RIGTRANSFORM_H
|
||||
|
||||
#include <osg/Referenced>
|
||||
|
||||
namespace osgAnimation
|
||||
{
|
||||
|
||||
class RigGeometry;
|
||||
|
||||
class RigTransform : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
RigTransform() : _needInit(true) {}
|
||||
virtual ~RigTransform() {}
|
||||
bool needInit() const { return _needInit; }
|
||||
virtual bool init(RigGeometry&) = 0;
|
||||
virtual void update(RigGeometry&) = 0;
|
||||
|
||||
protected:
|
||||
bool _needInit;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
82
include/osgAnimation/RigTransformHardware
Normal file
82
include/osgAnimation/RigTransformHardware
Normal file
@@ -0,0 +1,82 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2009 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSGANIMATION_RIG_TRANSFORM_HARDWARE_H
|
||||
#define OSGANIMATION_RIG_TRANSFORM_HARDWARE_H 1
|
||||
|
||||
#include <osgAnimation/Export>
|
||||
#include <osgAnimation/RigTransform>
|
||||
#include <osgAnimation/VertexInfluence>
|
||||
#include <osgAnimation/Bone>
|
||||
#include <osg/Matrix>
|
||||
#include <osg/Array>
|
||||
|
||||
namespace osgAnimation
|
||||
{
|
||||
class RigGeometry;
|
||||
|
||||
/// This class manage format for hardware skinning
|
||||
class OSGANIMATION_EXPORT RigTransformHardware : public RigTransform
|
||||
{
|
||||
public:
|
||||
typedef osg::Matrix MatrixType;
|
||||
typedef osgAnimation::Bone BoneType;
|
||||
typedef Bone::BoneMap BoneMap;
|
||||
typedef std::vector<osg::ref_ptr<osg::Vec4Array> > BoneWeightAttribList;
|
||||
typedef std::vector<osg::ref_ptr<BoneType> > BonePalette;
|
||||
|
||||
typedef std::vector<osg::Matrix> MatrixPalette;
|
||||
struct IndexWeightEntry
|
||||
{
|
||||
int _boneIndex;
|
||||
float _boneWeight;
|
||||
IndexWeightEntry() { _boneIndex = 0; _boneWeight = 0;}
|
||||
IndexWeightEntry(float index, float weight) { _boneIndex = index; _boneWeight = weight;}
|
||||
int getIndex() const { return _boneIndex; }
|
||||
float getWeight() const { return _boneWeight; }
|
||||
};
|
||||
typedef std::vector<std::vector<IndexWeightEntry> > VertexIndexWeightList;
|
||||
|
||||
osg::Vec4Array* getVertexAttrib(int index);
|
||||
int getNumVertexAttrib();
|
||||
|
||||
osg::Uniform* getMatrixPaletteUniform();
|
||||
void computeMatrixPaletteUniform(const osg::Matrix& transformFromSkeletonToGeometry, const osg::Matrix& invTransformFromSkeletonToGeometry);
|
||||
|
||||
int getNumBonesPerVertex() const;
|
||||
int getNumVertexes() const;
|
||||
|
||||
bool createPalette(int nbVertexes, BoneMap boneMap, const VertexInfluenceSet::VertexIndexToBoneWeightMap& vertexIndexToBoneWeightMap);
|
||||
|
||||
|
||||
virtual bool init(RigGeometry&);
|
||||
virtual void update(RigGeometry&);
|
||||
|
||||
void setShader(osg::Shader*);
|
||||
protected:
|
||||
|
||||
BoneWeightAttribList createVertexAttribList();
|
||||
osg::Uniform* createVertexUniform();
|
||||
|
||||
int _bonesPerVertex;
|
||||
int _nbVertexes;
|
||||
VertexIndexWeightList _vertexIndexMatrixWeightList;
|
||||
BonePalette _bonePalette;
|
||||
BoneWeightAttribList _boneWeightAttribArrays;
|
||||
osg::ref_ptr<osg::Uniform> _uniformMatrixPalette;
|
||||
osg::ref_ptr<osg::Shader> _shader;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
168
include/osgAnimation/RigTransformSoftware
Normal file
168
include/osgAnimation/RigTransformSoftware
Normal file
@@ -0,0 +1,168 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2009 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSGANIMATION_RIG_TRANSFORM_SOFTWARE_H
|
||||
#define OSGANIMATION_RIG_TRANSFORM_SOFTWARE_H 1
|
||||
|
||||
#include <osgAnimation/Export>
|
||||
#include <osgAnimation/RigTransform>
|
||||
#include <osgAnimation/Bone>
|
||||
|
||||
namespace osgAnimation
|
||||
{
|
||||
|
||||
class RigGeometry;
|
||||
|
||||
/// This class manage format for hardware skinning
|
||||
class OSGANIMATION_EXPORT RigTransformSoftware : public RigTransform
|
||||
{
|
||||
public:
|
||||
|
||||
virtual bool init(RigGeometry&);
|
||||
virtual void update(RigGeometry&);
|
||||
|
||||
|
||||
class BoneWeight
|
||||
{
|
||||
public:
|
||||
BoneWeight(Bone* bone, float weight) : _bone(bone), _weight(weight) {}
|
||||
const Bone* getBone() const { return _bone.get(); }
|
||||
float getWeight() const { return _weight; }
|
||||
void setWeight(float w) { _weight = w; }
|
||||
protected:
|
||||
osg::observer_ptr<Bone> _bone;
|
||||
float _weight;
|
||||
};
|
||||
|
||||
typedef std::vector<BoneWeight> BoneWeightList;
|
||||
typedef std::vector<int> VertexList;
|
||||
|
||||
class UniqBoneSetVertexSet
|
||||
{
|
||||
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())
|
||||
{
|
||||
osg::notify(osg::WARN) << "RigTransformSoftware::UniqBoneSetVertexSet no bones found" << std::endl;
|
||||
_result = osg::Matrix::identity();
|
||||
return;
|
||||
}
|
||||
resetMatrix();
|
||||
|
||||
int size = _bones.size();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
const Bone* bone = _bones[i].getBone();
|
||||
const osg::Matrix& invBindMatrix = bone->getInvBindMatrixInSkeletonSpace();
|
||||
const osg::Matrix& matrix = bone->getMatrixInSkeletonSpace();
|
||||
osg::Matrix::value_type w = _bones[i].getWeight();
|
||||
accummulateMatrix(invBindMatrix, matrix, w);
|
||||
}
|
||||
}
|
||||
const osg::Matrix& getMatrix() const { return _result;}
|
||||
protected:
|
||||
BoneWeightList _bones;
|
||||
VertexList _vertexes;
|
||||
osg::Matrix _result;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <class V> void compute(const osg::Matrix& transform, const osg::Matrix& invTransform, const V* src, V* dst)
|
||||
{
|
||||
// the result of matrix mult should be cached to be used for vertexes transform and normal transform and maybe other computation
|
||||
int size = _boneSetVertexSet.size();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
UniqBoneSetVertexSet& uniq = _boneSetVertexSet[i];
|
||||
uniq.computeMatrixForVertexSet();
|
||||
osg::Matrix matrix = transform * uniq.getMatrix() * invTransform;
|
||||
|
||||
const VertexList& vertexes = uniq.getVertexes();
|
||||
int vertexSize = vertexes.size();
|
||||
for (int j = 0; j < vertexSize; j++)
|
||||
{
|
||||
int idx = vertexes[j];
|
||||
dst[idx] = src[idx] * matrix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class V> void computeNormal(const osg::Matrix& transform, const osg::Matrix& invTransform, const V* src, V* dst)
|
||||
{
|
||||
int size = _boneSetVertexSet.size();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
UniqBoneSetVertexSet& uniq = _boneSetVertexSet[i];
|
||||
uniq.computeMatrixForVertexSet();
|
||||
osg::Matrix matrix = transform * uniq.getMatrix() * invTransform;
|
||||
|
||||
const VertexList& vertexes = uniq.getVertexes();
|
||||
int vertexSize = vertexes.size();
|
||||
for (int j = 0; j < vertexSize; j++)
|
||||
{
|
||||
int idx = vertexes[j];
|
||||
dst[idx] = osg::Matrix::transform3x3(src[idx],matrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<osg::Vec3>& getPositionSource() const { return _positionSource;}
|
||||
const std::vector<osg::Vec3>& getNormalSource() const { return _normalSource;}
|
||||
|
||||
protected:
|
||||
|
||||
void initVertexSetFromBones(const Bone::BoneMap& map, const VertexInfluenceSet::UniqVertexSetToBoneSetList& influence);
|
||||
|
||||
std::vector<UniqBoneSetVertexSet> _boneSetVertexSet;
|
||||
std::vector<osg::Vec3> _positionSource;
|
||||
std::vector<osg::Vec3> _normalSource;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -41,10 +41,10 @@ namespace osgAnimation
|
||||
void setFrame(unsigned int frame) { _frame = frame; }
|
||||
void apply(Timeline& action);
|
||||
void apply(Action& action);
|
||||
void apply(BlendIn& action);
|
||||
void apply(BlendOut& action);
|
||||
void apply(ActionBlendIn& action);
|
||||
void apply(ActionBlendOut& action);
|
||||
void apply(ActionAnimation& action);
|
||||
void apply(StripAnimation& action);
|
||||
void apply(ActionStripAnimation& action);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace osgAnimation
|
||||
virtual void addActionAt(unsigned int frame, Action* action, int priority = 0);
|
||||
virtual void addActionAt(double t, Action* action, int priority = 0);
|
||||
void addActionNow(Action* action, int priority = 0);
|
||||
|
||||
|
||||
void clearActions();
|
||||
|
||||
virtual void update(double simulationTime);
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSGANIMATION_VERTEX_INFLUENCES_H
|
||||
#define OSGANIMATION_VERTEX_INFLUENCES_H
|
||||
#ifndef OSGANIMATION_VERTEX_INFLUENCE_H
|
||||
#define OSGANIMATION_VERTEX_INFLUENCE_H 1
|
||||
|
||||
#include <osg/Object>
|
||||
#include <osgAnimation/Export>
|
||||
@@ -38,8 +38,6 @@ namespace osgAnimation
|
||||
std::string _name;
|
||||
};
|
||||
|
||||
// typedef std::map<std::string, VertexInfluence> VertexInfluenceMap;
|
||||
|
||||
class VertexInfluenceMap : public std::map<std::string, VertexInfluence> , public osg::Object
|
||||
{
|
||||
public:
|
||||
@@ -73,7 +71,7 @@ namespace osgAnimation
|
||||
typedef std::vector<BoneWeight> BoneWeightList;
|
||||
typedef std::map<int,BoneWeightList> VertexIndexToBoneWeightMap;
|
||||
|
||||
class UniqVertexSetToBoneSet
|
||||
class UniqVertexSetToBoneSet
|
||||
{
|
||||
public:
|
||||
void setBones(BoneWeightList& bones) { _bones = bones;}
|
||||
@@ -88,14 +86,10 @@ namespace osgAnimation
|
||||
typedef std::vector<UniqVertexSetToBoneSet> UniqVertexSetToBoneSetList;
|
||||
|
||||
const UniqVertexSetToBoneSetList& getUniqVertexSetToBoneSetList() const { return _uniqVertexSetToBoneSet;}
|
||||
void addVertexInfluence(const VertexInfluence& v) { _bone2Vertexes.push_back(v); }
|
||||
void addVertexInfluence(const VertexInfluence& v);
|
||||
void buildVertex2BoneList();
|
||||
void buildUniqVertexSetToBoneSetList();
|
||||
void clear()
|
||||
{
|
||||
_bone2Vertexes.clear();
|
||||
_uniqVertexSetToBoneSet.clear();
|
||||
}
|
||||
void clear();
|
||||
|
||||
const VertexIndexToBoneWeightMap& getVertexToBoneList() const;
|
||||
protected:
|
||||
|
||||
@@ -14,15 +14,17 @@
|
||||
|
||||
#include <osgAnimation/Action>
|
||||
|
||||
osgAnimation::Action::Action()
|
||||
using namespace osgAnimation;
|
||||
|
||||
Action::Action()
|
||||
{
|
||||
_numberFrame = 25;
|
||||
_fps = 25;
|
||||
_speed = 1.0;
|
||||
_loop = 1;
|
||||
}
|
||||
osgAnimation::Action::Action(const Action&,const osg::CopyOp&) {}
|
||||
osgAnimation::Action::Callback* osgAnimation::Action::getFrameCallback(unsigned int frame)
|
||||
Action::Action(const Action&,const osg::CopyOp&) {}
|
||||
Action::Callback* Action::getFrameCallback(unsigned int frame)
|
||||
{
|
||||
if (_framesCallback.find(frame) != _framesCallback.end())
|
||||
{
|
||||
@@ -31,7 +33,30 @@ osgAnimation::Action::Callback* osgAnimation::Action::getFrameCallback(unsigned
|
||||
return 0;
|
||||
}
|
||||
|
||||
osgAnimation::Action::Callback* osgAnimation::Action::getFrameCallback(double time)
|
||||
void Action::removeCallback(Callback* cb)
|
||||
{
|
||||
std::vector<unsigned int> keyToRemove;
|
||||
for (FrameCallback::iterator it = _framesCallback.begin(); it != _framesCallback.end(); it++)
|
||||
{
|
||||
if (it->second.get())
|
||||
{
|
||||
if (it->second.get() == cb)
|
||||
{
|
||||
it->second = it->second->getNestedCallback();
|
||||
if (!it->second.valid())
|
||||
keyToRemove.push_back(it->first);
|
||||
}
|
||||
else
|
||||
{
|
||||
it->second->removeCallback(cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (std::vector<unsigned int>::iterator it = keyToRemove.begin(); it != keyToRemove.end(); it++)
|
||||
_framesCallback.erase(*it);
|
||||
}
|
||||
|
||||
Action::Callback* Action::getFrameCallback(double time)
|
||||
{
|
||||
unsigned int frame = static_cast<unsigned int>(floor(time * _fps));
|
||||
return getFrameCallback(frame);
|
||||
@@ -56,117 +81,3 @@ bool osgAnimation::Action::evaluateFrame(unsigned int frame, unsigned int& resul
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
osgAnimation::BlendIn::BlendIn(Animation* animation, double duration, double weight)
|
||||
{
|
||||
_animation = animation;
|
||||
_weight = weight;
|
||||
float d = duration * _fps;
|
||||
setNumFrames(static_cast<unsigned int>(floor(d)) + 1);
|
||||
setName("BlendIn");
|
||||
}
|
||||
|
||||
void osgAnimation::BlendIn::computeWeight(unsigned int frame)
|
||||
{
|
||||
|
||||
// frame + 1 because the start is 0 and we want to start the blend in at the first
|
||||
// frame.
|
||||
double ratio = ( (frame+1) * 1.0 / (getNumFrames()) );
|
||||
double w = _weight * ratio;
|
||||
|
||||
osg::notify(osg::DEBUG_INFO) << getName() << " BlendIn frame " << frame << " weight " << w << std::endl;
|
||||
_animation->setWeight(w);
|
||||
}
|
||||
|
||||
|
||||
osgAnimation::BlendOut::BlendOut(Animation* animation, double duration)
|
||||
{
|
||||
_animation = animation;
|
||||
float d = duration * _fps;
|
||||
setNumFrames(static_cast<unsigned int>(floor(d) + 1));
|
||||
_weight = 1.0;
|
||||
setName("BlendOut");
|
||||
}
|
||||
|
||||
void osgAnimation::BlendOut::computeWeight(unsigned int frame)
|
||||
{
|
||||
double ratio = ( (frame+1) * 1.0 / (getNumFrames()) );
|
||||
double w = _weight * (1.0-ratio);
|
||||
osg::notify(osg::DEBUG_INFO) << getName() << " BlendOut frame " << frame << " weight " << w << std::endl;
|
||||
_animation->setWeight(w);
|
||||
}
|
||||
|
||||
|
||||
osgAnimation::ActionAnimation::ActionAnimation(Animation* animation) : _animation(animation)
|
||||
{
|
||||
Action::setDuration(animation->getDuration());
|
||||
setName(animation->getName());
|
||||
}
|
||||
void osgAnimation::ActionAnimation::updateAnimation(unsigned int frame, int priority)
|
||||
{
|
||||
_animation->update(frame * 1.0/_fps, priority);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
osgAnimation::StripAnimation::StripAnimation(const StripAnimation& a, const osg::CopyOp& c) : Action(a,c)
|
||||
{
|
||||
_animation = a._animation;
|
||||
_blendIn = a._blendIn;
|
||||
_blendOut = a._blendOut;
|
||||
}
|
||||
|
||||
osgAnimation::StripAnimation::StripAnimation(Animation* animation, double blendInDuration, double blendOutDuration, double blendInWeightTarget)
|
||||
{
|
||||
_blendIn = new BlendIn(animation, blendInDuration, blendInWeightTarget);
|
||||
_animation = new ActionAnimation(animation);
|
||||
unsigned int start = static_cast<unsigned int>(floor((_animation->getDuration() - blendOutDuration) * _fps));
|
||||
_blendOut = FrameBlendOut(start, new BlendOut(animation, blendOutDuration));
|
||||
setName(animation->getName() + "_Strip");
|
||||
_blendIn->setName(_animation->getName() + "_" + _blendIn->getName());
|
||||
_blendOut.second->setName(_animation->getName() + "_" + _blendOut.second->getName());
|
||||
setDuration(animation->getDuration());
|
||||
}
|
||||
|
||||
|
||||
void osgAnimation::StripAnimation::setLoop(unsigned int loop)
|
||||
{
|
||||
_animation->setLoop(loop);
|
||||
if (!loop)
|
||||
setDuration(-1);
|
||||
else
|
||||
setDuration(loop * _animation->getDuration());
|
||||
|
||||
// duration changed re evaluate the blendout duration
|
||||
unsigned int start = static_cast<unsigned int>(floor((getDuration() - _blendOut.second->getDuration()) * _fps));
|
||||
_blendOut = FrameBlendOut(start, _blendOut.second);
|
||||
}
|
||||
|
||||
void osgAnimation::StripAnimation::traverse(ActionVisitor& visitor)
|
||||
{
|
||||
if (_blendIn.valid())
|
||||
{
|
||||
unsigned int f = visitor.getStackedFrameAction().back().first;
|
||||
visitor.pushFrameActionOnStack(FrameAction(f,_blendIn.get()));
|
||||
_blendIn->accept(visitor);
|
||||
visitor.popFrameAction();
|
||||
}
|
||||
if (_blendOut.second.valid())
|
||||
{
|
||||
unsigned int f = visitor.getStackedFrameAction().back().first;
|
||||
visitor.pushFrameActionOnStack(FrameAction(f + _blendOut.first,_blendOut.second.get()));
|
||||
_blendOut.second.get()->accept(visitor);
|
||||
visitor.popFrameAction();
|
||||
}
|
||||
|
||||
if (_animation.valid())
|
||||
{
|
||||
unsigned int f = visitor.getStackedFrameAction().back().first;
|
||||
visitor.pushFrameActionOnStack(FrameAction(f,_animation.get()));
|
||||
_animation->accept(visitor);
|
||||
visitor.popFrameAction();
|
||||
}
|
||||
}
|
||||
|
||||
32
src/osgAnimation/ActionAnimation.cpp
Normal file
32
src/osgAnimation/ActionAnimation.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2009 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include <osgAnimation/ActionAnimation>
|
||||
|
||||
using namespace osgAnimation;
|
||||
|
||||
ActionAnimation::ActionAnimation() {}
|
||||
|
||||
ActionAnimation::ActionAnimation(const ActionAnimation& a, const osg::CopyOp& c) : Action(a,c) { _animation = a._animation;}
|
||||
|
||||
ActionAnimation::ActionAnimation(Animation* animation) : _animation(animation)
|
||||
{
|
||||
Action::setDuration(animation->getDuration());
|
||||
setName(animation->getName());
|
||||
}
|
||||
|
||||
void ActionAnimation::updateAnimation(unsigned int frame, int priority)
|
||||
{
|
||||
_animation->update(frame * 1.0/_fps, priority);
|
||||
}
|
||||
45
src/osgAnimation/ActionBlendIn.cpp
Normal file
45
src/osgAnimation/ActionBlendIn.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2009 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include <osgAnimation/ActionBlendIn>
|
||||
|
||||
using namespace osgAnimation;
|
||||
|
||||
ActionBlendIn::ActionBlendIn() : _weight(0) {}
|
||||
ActionBlendIn::ActionBlendIn(const ActionBlendIn& a, const osg::CopyOp& c) : Action(a,c)
|
||||
{
|
||||
_weight = a._weight;
|
||||
_animation = a._animation;
|
||||
}
|
||||
|
||||
ActionBlendIn::ActionBlendIn(Animation* animation, double duration, double weight)
|
||||
{
|
||||
_animation = animation;
|
||||
_weight = weight;
|
||||
float d = duration * _fps;
|
||||
setNumFrames(static_cast<unsigned int>(floor(d)) + 1);
|
||||
setName("BlendIn");
|
||||
}
|
||||
|
||||
void ActionBlendIn::computeWeight(unsigned int frame)
|
||||
{
|
||||
|
||||
// frame + 1 because the start is 0 and we want to start the blend in at the first
|
||||
// frame.
|
||||
double ratio = ( (frame+1) * 1.0 / (getNumFrames()) );
|
||||
double w = _weight * ratio;
|
||||
|
||||
osg::notify(osg::DEBUG_INFO) << getName() << " BlendIn frame " << frame << " weight " << w << std::endl;
|
||||
_animation->setWeight(w);
|
||||
}
|
||||
41
src/osgAnimation/ActionBlendOut.cpp
Normal file
41
src/osgAnimation/ActionBlendOut.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2009 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include <osgAnimation/ActionBlendOut>
|
||||
|
||||
using namespace osgAnimation;
|
||||
|
||||
ActionBlendOut::ActionBlendOut() : _weight(0) {}
|
||||
ActionBlendOut::ActionBlendOut(const ActionBlendOut& a, const osg::CopyOp& c) : Action(a,c)
|
||||
{
|
||||
_weight = a._weight;
|
||||
_animation = a._animation;
|
||||
}
|
||||
|
||||
ActionBlendOut::ActionBlendOut(Animation* animation, double duration)
|
||||
{
|
||||
_animation = animation;
|
||||
float d = duration * _fps;
|
||||
setNumFrames(static_cast<unsigned int>(floor(d) + 1));
|
||||
_weight = 1.0;
|
||||
setName("BlendOut");
|
||||
}
|
||||
|
||||
void ActionBlendOut::computeWeight(unsigned int frame)
|
||||
{
|
||||
double ratio = ( (frame+1) * 1.0 / (getNumFrames()) );
|
||||
double w = _weight * (1.0-ratio);
|
||||
osg::notify(osg::DEBUG_INFO) << getName() << " BlendOut frame " << frame << " weight " << w << std::endl;
|
||||
_animation->setWeight(w);
|
||||
}
|
||||
88
src/osgAnimation/ActionStripAnimation.cpp
Normal file
88
src/osgAnimation/ActionStripAnimation.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2009 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include <osgAnimation/ActionStripAnimation>
|
||||
|
||||
using namespace osgAnimation;
|
||||
|
||||
ActionAnimation* ActionStripAnimation::getAnimation() { return _animation.get(); }
|
||||
ActionBlendIn* ActionStripAnimation::getBlendIn() { return _blendIn.get(); }
|
||||
ActionBlendOut* ActionStripAnimation::getBlendOut() { return _blendOut.second.get(); }
|
||||
const ActionAnimation* ActionStripAnimation::getAnimation() const { return _animation.get(); }
|
||||
const ActionBlendIn* ActionStripAnimation::getBlendIn() const { return _blendIn.get(); }
|
||||
const ActionBlendOut* ActionStripAnimation::getBlendOut() const { return _blendOut.second.get(); }
|
||||
unsigned int ActionStripAnimation::getBlendOutStartFrame() const { return _blendOut.first; }
|
||||
|
||||
unsigned int ActionStripAnimation::getLoop() const { return _animation->getLoop(); }
|
||||
|
||||
|
||||
ActionStripAnimation::ActionStripAnimation(const ActionStripAnimation& a, const osg::CopyOp& c) : Action(a,c)
|
||||
{
|
||||
_animation = a._animation;
|
||||
_blendIn = a._blendIn;
|
||||
_blendOut = a._blendOut;
|
||||
}
|
||||
|
||||
ActionStripAnimation::ActionStripAnimation(Animation* animation, double blendInDuration, double blendOutDuration, double blendInWeightTarget)
|
||||
{
|
||||
_blendIn = new ActionBlendIn(animation, blendInDuration, blendInWeightTarget);
|
||||
_animation = new ActionAnimation(animation);
|
||||
unsigned int start = static_cast<unsigned int>(floor((_animation->getDuration() - blendOutDuration) * _fps));
|
||||
_blendOut = FrameBlendOut(start, new ActionBlendOut(animation, blendOutDuration));
|
||||
setName(animation->getName() + "_Strip");
|
||||
_blendIn->setName(_animation->getName() + "_" + _blendIn->getName());
|
||||
_blendOut.second->setName(_animation->getName() + "_" + _blendOut.second->getName());
|
||||
setDuration(animation->getDuration());
|
||||
}
|
||||
|
||||
|
||||
void ActionStripAnimation::setLoop(unsigned int loop)
|
||||
{
|
||||
_animation->setLoop(loop);
|
||||
if (!loop)
|
||||
setDuration(-1);
|
||||
else
|
||||
setDuration(loop * _animation->getDuration());
|
||||
|
||||
// duration changed re evaluate the blendout duration
|
||||
unsigned int start = static_cast<unsigned int>(floor((getDuration() - _blendOut.second->getDuration()) * _fps));
|
||||
_blendOut = FrameBlendOut(start, _blendOut.second);
|
||||
}
|
||||
|
||||
void ActionStripAnimation::traverse(ActionVisitor& visitor)
|
||||
{
|
||||
if (_blendIn.valid())
|
||||
{
|
||||
unsigned int f = visitor.getStackedFrameAction().back().first;
|
||||
visitor.pushFrameActionOnStack(FrameAction(f,_blendIn.get()));
|
||||
_blendIn->accept(visitor);
|
||||
visitor.popFrameAction();
|
||||
}
|
||||
if (_blendOut.second.valid())
|
||||
{
|
||||
unsigned int f = visitor.getStackedFrameAction().back().first;
|
||||
visitor.pushFrameActionOnStack(FrameAction(f + _blendOut.first,_blendOut.second.get()));
|
||||
_blendOut.second.get()->accept(visitor);
|
||||
visitor.popFrameAction();
|
||||
}
|
||||
|
||||
if (_animation.valid())
|
||||
{
|
||||
unsigned int f = visitor.getStackedFrameAction().back().first;
|
||||
visitor.pushFrameActionOnStack(FrameAction(f,_animation.get()));
|
||||
_animation->accept(visitor);
|
||||
visitor.popFrameAction();
|
||||
}
|
||||
}
|
||||
@@ -13,40 +13,52 @@
|
||||
*/
|
||||
|
||||
#include <osgAnimation/Action>
|
||||
#include <osgAnimation/ActionBlendIn>
|
||||
#include <osgAnimation/ActionBlendOut>
|
||||
#include <osgAnimation/ActionStripAnimation>
|
||||
#include <osgAnimation/ActionAnimation>
|
||||
#include <osgAnimation/ActionVisitor>
|
||||
#include <osgAnimation/Timeline>
|
||||
|
||||
osgAnimation::ActionVisitor::ActionVisitor()
|
||||
using namespace osgAnimation;
|
||||
|
||||
ActionVisitor::ActionVisitor()
|
||||
{
|
||||
_currentLayer = 0;
|
||||
}
|
||||
void osgAnimation::ActionVisitor::pushFrameActionOnStack(const FrameAction& fa) { _stackFrameAction.push_back(fa); }
|
||||
void osgAnimation::ActionVisitor::popFrameAction() { _stackFrameAction.pop_back(); }
|
||||
void osgAnimation::ActionVisitor::pushTimelineOnStack(Timeline* tm) { _stackTimeline.push_back(tm); }
|
||||
void osgAnimation::ActionVisitor::popTimeline() { _stackTimeline.pop_back(); }
|
||||
void osgAnimation::ActionVisitor::apply(Action& action) { traverse(action); }
|
||||
void osgAnimation::ActionVisitor::apply(Timeline& tm) { tm.traverse(*this); }
|
||||
void osgAnimation::ActionVisitor::apply(BlendIn& action) { apply(static_cast<Action&>(action));}
|
||||
void osgAnimation::ActionVisitor::apply(BlendOut& action) { apply(static_cast<Action&>(action)); }
|
||||
void osgAnimation::ActionVisitor::apply(ActionAnimation& action) { apply(static_cast<Action&>(action)); }
|
||||
void osgAnimation::ActionVisitor::apply(StripAnimation& action) { apply(static_cast<Action&>(action)); }
|
||||
void osgAnimation::ActionVisitor::traverse(Action& action)
|
||||
void ActionVisitor::pushFrameActionOnStack(const FrameAction& fa) { _stackFrameAction.push_back(fa); }
|
||||
void ActionVisitor::popFrameAction() { _stackFrameAction.pop_back(); }
|
||||
void ActionVisitor::pushTimelineOnStack(Timeline* tm) { _stackTimeline.push_back(tm); }
|
||||
void ActionVisitor::popTimeline() { _stackTimeline.pop_back(); }
|
||||
void ActionVisitor::apply(Action& action) { traverse(action); }
|
||||
void ActionVisitor::apply(Timeline& tm) { tm.traverse(*this); }
|
||||
void ActionVisitor::apply(ActionBlendIn& action) { apply(static_cast<Action&>(action));}
|
||||
void ActionVisitor::apply(ActionBlendOut& action) { apply(static_cast<Action&>(action)); }
|
||||
void ActionVisitor::apply(ActionAnimation& action) { apply(static_cast<Action&>(action)); }
|
||||
void ActionVisitor::apply(ActionStripAnimation& action) { apply(static_cast<Action&>(action)); }
|
||||
void ActionVisitor::traverse(Action& action)
|
||||
{
|
||||
action.traverse(*this);
|
||||
}
|
||||
|
||||
osgAnimation::Timeline* osgAnimation::ActionVisitor::getCurrentTimeline()
|
||||
Timeline* ActionVisitor::getCurrentTimeline()
|
||||
{
|
||||
if (_stackTimeline.empty())
|
||||
return 0;
|
||||
return _stackTimeline.back();
|
||||
}
|
||||
|
||||
osgAnimation::UpdateActionVisitor::UpdateActionVisitor() { _frame = 0; }
|
||||
|
||||
|
||||
void osgAnimation::UpdateActionVisitor::apply(Timeline& tm)
|
||||
UpdateActionVisitor::UpdateActionVisitor()
|
||||
{
|
||||
_frame = 0;
|
||||
_currentAnimationPriority = 0;
|
||||
}
|
||||
|
||||
|
||||
void UpdateActionVisitor::apply(Timeline& tm)
|
||||
{
|
||||
_currentAnimationPriority = 0;
|
||||
|
||||
tm.setEvaluating(true);
|
||||
|
||||
tm.traverse(*this);
|
||||
@@ -56,7 +68,7 @@ void osgAnimation::UpdateActionVisitor::apply(Timeline& tm)
|
||||
tm.setLastFrameEvaluated(_frame);
|
||||
}
|
||||
|
||||
bool osgAnimation::UpdateActionVisitor::isActive(Action& action) const
|
||||
bool UpdateActionVisitor::isActive(Action& action) const
|
||||
{
|
||||
FrameAction fa = _stackFrameAction.back();
|
||||
if (_frame < fa.first)
|
||||
@@ -70,12 +82,12 @@ bool osgAnimation::UpdateActionVisitor::isActive(Action& action) const
|
||||
return action.evaluateFrame(f, frameInAction, loopDone);
|
||||
}
|
||||
|
||||
unsigned int osgAnimation::UpdateActionVisitor::getLocalFrame() const
|
||||
unsigned int UpdateActionVisitor::getLocalFrame() const
|
||||
{
|
||||
return _frame - _stackFrameAction.back().first;
|
||||
}
|
||||
|
||||
void osgAnimation::UpdateActionVisitor::apply(Action& action)
|
||||
void UpdateActionVisitor::apply(Action& action)
|
||||
{
|
||||
if (isActive(action))
|
||||
{
|
||||
@@ -102,7 +114,7 @@ void osgAnimation::UpdateActionVisitor::apply(Action& action)
|
||||
}
|
||||
}
|
||||
|
||||
void osgAnimation::UpdateActionVisitor::apply(BlendIn& action)
|
||||
void UpdateActionVisitor::apply(ActionBlendIn& action)
|
||||
{
|
||||
if (isActive(action))
|
||||
{
|
||||
@@ -112,7 +124,7 @@ void osgAnimation::UpdateActionVisitor::apply(BlendIn& action)
|
||||
}
|
||||
}
|
||||
|
||||
void osgAnimation::UpdateActionVisitor::apply(BlendOut& action)
|
||||
void UpdateActionVisitor::apply(ActionBlendOut& action)
|
||||
{
|
||||
if (isActive(action))
|
||||
{
|
||||
@@ -122,17 +134,18 @@ void osgAnimation::UpdateActionVisitor::apply(BlendOut& action)
|
||||
}
|
||||
}
|
||||
|
||||
void osgAnimation::UpdateActionVisitor::apply(ActionAnimation& action)
|
||||
void UpdateActionVisitor::apply(ActionAnimation& action)
|
||||
{
|
||||
if (isActive(action))
|
||||
if (isActive(action))
|
||||
{
|
||||
unsigned int frame = getLocalFrame();
|
||||
apply(static_cast<Action&>(action));
|
||||
action.updateAnimation(frame, getCurrentLayer());
|
||||
// action.updateAnimation(frame, getCurrentLayer());
|
||||
action.updateAnimation(frame, -_currentAnimationPriority++);
|
||||
}
|
||||
}
|
||||
|
||||
void osgAnimation::UpdateActionVisitor::apply(StripAnimation& action)
|
||||
void UpdateActionVisitor::apply(ActionStripAnimation& action)
|
||||
{
|
||||
if (isActive(action))
|
||||
{
|
||||
@@ -143,18 +156,18 @@ void osgAnimation::UpdateActionVisitor::apply(StripAnimation& action)
|
||||
|
||||
|
||||
|
||||
osgAnimation::ClearActionVisitor::ClearActionVisitor(ClearType type) : _clearType(type)
|
||||
ClearActionVisitor::ClearActionVisitor(ClearType type) : _clearType(type)
|
||||
{
|
||||
}
|
||||
|
||||
void osgAnimation::ClearActionVisitor::apply(Timeline& tm)
|
||||
void ClearActionVisitor::apply(Timeline& tm)
|
||||
{
|
||||
_remove.clear();
|
||||
tm.traverse(*this);
|
||||
for (int i = 0; i < (int)_remove.size(); i++)
|
||||
tm.removeAction(_remove[i].get());
|
||||
}
|
||||
void osgAnimation::ClearActionVisitor::apply(Action& action)
|
||||
void ClearActionVisitor::apply(Action& action)
|
||||
{
|
||||
FrameAction fa = _stackFrameAction.back();
|
||||
switch( _clearType) {
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include <osgAnimation/Skinning>
|
||||
#include <osgAnimation/Bone>
|
||||
#include <osgAnimation/Skeleton>
|
||||
#include <osgAnimation/FindParentAnimationManagerVisitor>
|
||||
|
||||
@@ -11,7 +11,11 @@ SET(LIB_NAME osgAnimation)
|
||||
SET(HEADER_PATH ${OpenSceneGraph_SOURCE_DIR}/include/${LIB_NAME})
|
||||
SET(LIB_PUBLIC_HEADERS
|
||||
${HEADER_PATH}/Action
|
||||
${HEADER_PATH}/ActionAnimation
|
||||
${HEADER_PATH}/ActionBlendIn
|
||||
${HEADER_PATH}/ActionBlendOut
|
||||
${HEADER_PATH}/ActionCallback
|
||||
${HEADER_PATH}/ActionStripAnimation
|
||||
${HEADER_PATH}/ActionVisitor
|
||||
${HEADER_PATH}/Animation
|
||||
${HEADER_PATH}/AnimationManagerBase
|
||||
@@ -31,9 +35,11 @@ SET(LIB_PUBLIC_HEADERS
|
||||
${HEADER_PATH}/LinkVisitor
|
||||
${HEADER_PATH}/MorphGeometry
|
||||
${HEADER_PATH}/RigGeometry
|
||||
${HEADER_PATH}/RigTransform
|
||||
${HEADER_PATH}/RigTransformHardware
|
||||
${HEADER_PATH}/RigTransformSoftware
|
||||
${HEADER_PATH}/Sampler
|
||||
${HEADER_PATH}/Skeleton
|
||||
${HEADER_PATH}/Skinning
|
||||
${HEADER_PATH}/StatsVisitor
|
||||
${HEADER_PATH}/StatsHandler
|
||||
${HEADER_PATH}/Target
|
||||
@@ -49,7 +55,11 @@ ADD_LIBRARY(${LIB_NAME}
|
||||
${OPENSCENEGRAPH_USER_DEFINED_DYNAMIC_OR_STATIC}
|
||||
${LIB_PUBLIC_HEADERS}
|
||||
Action.cpp
|
||||
ActionAnimation.cpp
|
||||
ActionBlendIn.cpp
|
||||
ActionBlendOut.cpp
|
||||
ActionCallback.cpp
|
||||
ActionStripAnimation.cpp
|
||||
ActionVisitor.cpp
|
||||
Animation.cpp
|
||||
AnimationManagerBase.cpp
|
||||
@@ -61,6 +71,8 @@ ADD_LIBRARY(${LIB_NAME}
|
||||
LinkVisitor.cpp
|
||||
MorphGeometry.cpp
|
||||
RigGeometry.cpp
|
||||
RigTransformHardware.cpp
|
||||
RigTransformSoftware.cpp
|
||||
Skeleton.cpp
|
||||
StatsVisitor.cpp
|
||||
StatsHandler.cpp
|
||||
|
||||
@@ -1,70 +1,75 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
|
||||
* Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* Cedric Pinson <mornifle@plopbyte.net>
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include <osgAnimation/RigGeometry>
|
||||
#include <osgAnimation/RigTransformSoftware>
|
||||
#include <sstream>
|
||||
#include <osg/GL2Extensions>
|
||||
|
||||
using namespace osgAnimation;
|
||||
|
||||
RigGeometry::RigGeometry()
|
||||
{
|
||||
setUseDisplayList(false);
|
||||
_supportsDisplayList = false;
|
||||
setUseVertexBufferObjects(true);
|
||||
setUpdateCallback(new UpdateVertex);
|
||||
setDataVariance(osg::Object::DYNAMIC);
|
||||
_needToComputeMatrix = true;
|
||||
_matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
|
||||
|
||||
// disable the computation of boundingbox for the rig mesh
|
||||
setComputeBoundingBoxCallback(new ComputeBoundingBoxCallback);
|
||||
}
|
||||
|
||||
RigGeometry::RigGeometry(const osg::Geometry& b) : osg::Geometry(b, osg::CopyOp::SHALLOW_COPY)
|
||||
{
|
||||
setUseDisplayList(false);
|
||||
_supportsDisplayList = false;
|
||||
setUseVertexBufferObjects(true);
|
||||
setUpdateCallback(new UpdateVertex);
|
||||
setDataVariance(osg::Object::DYNAMIC);
|
||||
_needToComputeMatrix = true;
|
||||
_matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
|
||||
|
||||
// disable the computation of boundingbox for the rig mesh
|
||||
setComputeBoundingBoxCallback(new ComputeBoundingBoxCallback);
|
||||
}
|
||||
|
||||
RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) :
|
||||
RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) :
|
||||
osg::Geometry(b,copyop),
|
||||
_positionSource(b._positionSource),
|
||||
_normalSource(b._normalSource),
|
||||
_vertexInfluenceSet(b._vertexInfluenceSet),
|
||||
_vertexInfluenceMap(b._vertexInfluenceMap),
|
||||
_transformVertexes(b._transformVertexes),
|
||||
_needToComputeMatrix(b._needToComputeMatrix)
|
||||
_needToComputeMatrix(b._needToComputeMatrix)
|
||||
{
|
||||
// we dont copy the RigImplementation yet. because the RigImplementation need to be initialized in a valid graph, with a skeleton ...
|
||||
// dont know yet what to do with a clone of a RigGeometry
|
||||
}
|
||||
|
||||
void RigGeometry::buildTransformer(Skeleton* root)
|
||||
|
||||
const osg::Matrix& RigGeometry::getMatrixFromSkeletonToGeometry() const { return _matrixFromSkeletonToGeometry; }
|
||||
const osg::Matrix& RigGeometry::getInvMatrixFromSkeletonToGeometry() const { return _invMatrixFromSkeletonToGeometry;}
|
||||
|
||||
|
||||
void RigGeometry::drawImplementation(osg::RenderInfo& renderInfo) const
|
||||
{
|
||||
Bone::BoneMap bm = root->getBoneMap();
|
||||
_transformVertexes.init(bm, _vertexInfluenceSet.getUniqVertexSetToBoneSetList());
|
||||
_root = root;
|
||||
osg::Geometry::drawImplementation(renderInfo);
|
||||
}
|
||||
|
||||
void RigGeometry::buildVertexSet()
|
||||
void RigGeometry::buildVertexInfluenceSet()
|
||||
{
|
||||
if (!_vertexInfluenceMap.valid())
|
||||
if (!_vertexInfluenceMap.valid())
|
||||
{
|
||||
osg::notify(osg::WARN) << "buildVertexSet can't be called without VertexInfluence already set to the RigGeometry ( " << getName() << " ) " << std::endl;
|
||||
osg::notify(osg::WARN) << "buildVertexInfluenceSet can't be called without VertexInfluence already set to the RigGeometry ( " << getName() << " ) " << std::endl;
|
||||
return;
|
||||
}
|
||||
_vertexInfluenceSet.clear();
|
||||
@@ -75,12 +80,12 @@ void RigGeometry::buildVertexSet()
|
||||
|
||||
_vertexInfluenceSet.buildVertex2BoneList();
|
||||
_vertexInfluenceSet.buildUniqVertexSetToBoneSetList();
|
||||
std::cout << "uniq groups " << _vertexInfluenceSet.getUniqVertexSetToBoneSetList().size() << " for " << getName() << std::endl;
|
||||
osg::notify(osg::NOTICE) << "uniq groups " << _vertexInfluenceSet.getUniqVertexSetToBoneSetList().size() << " for " << getName() << std::endl;
|
||||
}
|
||||
|
||||
void RigGeometry::computeMatrixFromRootSkeleton()
|
||||
void RigGeometry::computeMatrixFromRootSkeleton()
|
||||
{
|
||||
if (!_root.valid())
|
||||
if (!_root.valid())
|
||||
{
|
||||
osg::notify(osg::WARN) << "Warning " << className() <<"::computeMatrixFromRootSkeleton if you have this message it means you miss to call buildTransformer(Skeleton* root), or your RigGeometry (" << getName() <<") is not attached to a Skeleton subgraph" << std::endl;
|
||||
return;
|
||||
@@ -91,39 +96,23 @@ void RigGeometry::computeMatrixFromRootSkeleton()
|
||||
_needToComputeMatrix = false;
|
||||
}
|
||||
|
||||
void RigGeometry::transformSoftwareMethod()
|
||||
void RigGeometry::update()
|
||||
{
|
||||
setUseDisplayList(false);
|
||||
setUseVertexBufferObjects(true);
|
||||
|
||||
// std::cout << getName() << " _matrixFromSkeletonToGeometry" << _matrixFromSkeletonToGeometry << std::endl;
|
||||
osg::Vec3Array* pos = dynamic_cast<osg::Vec3Array*>(getVertexArray());
|
||||
if (pos && _positionSource.size() != pos->size())
|
||||
if (!getRigTransformImplementation())
|
||||
{
|
||||
_positionSource = std::vector<osg::Vec3>(pos->begin(),pos->end());
|
||||
getVertexArray()->setDataVariance(osg::Object::DYNAMIC);
|
||||
}
|
||||
osg::Vec3Array* normal = dynamic_cast<osg::Vec3Array*>(getNormalArray());
|
||||
if (normal && _normalSource.size() != normal->size())
|
||||
{
|
||||
_normalSource = std::vector<osg::Vec3>(normal->begin(),normal->end());
|
||||
getNormalArray()->setDataVariance(osg::Object::DYNAMIC);
|
||||
_rigTransformImplementation = new RigTransformSoftware;
|
||||
}
|
||||
|
||||
if (!_positionSource.empty())
|
||||
{
|
||||
_transformVertexes.compute<osg::Vec3>(_matrixFromSkeletonToGeometry, _invMatrixFromSkeletonToGeometry, &_positionSource.front(), &pos->front());
|
||||
pos->dirty();
|
||||
}
|
||||
if (!_normalSource.empty())
|
||||
{
|
||||
_transformVertexes.computeNormal<osg::Vec3>(_matrixFromSkeletonToGeometry, _invMatrixFromSkeletonToGeometry, &_normalSource.front(), &normal->front());
|
||||
normal->dirty();
|
||||
}
|
||||
if (getUseDisplayList())
|
||||
dirtyDisplayList();
|
||||
dirtyBound();
|
||||
if (getRigTransformImplementation()->needInit())
|
||||
if (!getRigTransformImplementation()->init(*this))
|
||||
return;
|
||||
getRigTransformImplementation()->update(*this);
|
||||
}
|
||||
|
||||
const osgAnimation::Skeleton* RigGeometry::getSkeleton() const { return _root.get(); }
|
||||
osgAnimation::Skeleton* RigGeometry::getSkeleton() { return _root.get(); }
|
||||
const VertexInfluenceSet& RigGeometry::getVertexInfluenceSet() const { return _vertexInfluenceSet;}
|
||||
|
||||
const Skeleton* RigGeometry::getSkeleton() const { return _root.get(); }
|
||||
Skeleton* RigGeometry::getSkeleton() { return _root.get(); }
|
||||
void RigGeometry::setSkeleton(Skeleton* root) { _root = root;}
|
||||
RigTransform* RigGeometry::getRigTransformImplementation() { return _rigTransformImplementation.get(); }
|
||||
void RigGeometry::setRigTransformImplementation(RigTransform* rig) { _rigTransformImplementation = rig; }
|
||||
|
||||
250
src/osgAnimation/RigTransformHardware.cpp
Normal file
250
src/osgAnimation/RigTransformHardware.cpp
Normal file
@@ -0,0 +1,250 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2009 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include <osgAnimation/RigTransformHardware>
|
||||
#include <osgAnimation/RigGeometry>
|
||||
#include <sstream>
|
||||
|
||||
using namespace osgAnimation;
|
||||
|
||||
osg::Vec4Array* RigTransformHardware::getVertexAttrib(int index)
|
||||
{
|
||||
if (index >= (int)_boneWeightAttribArrays.size())
|
||||
return 0;
|
||||
return _boneWeightAttribArrays[index].get();
|
||||
}
|
||||
|
||||
int RigTransformHardware::getNumVertexAttrib()
|
||||
{
|
||||
return _boneWeightAttribArrays.size();
|
||||
}
|
||||
|
||||
osg::Uniform* RigTransformHardware::getMatrixPaletteUniform()
|
||||
{
|
||||
return _uniformMatrixPalette.get();
|
||||
}
|
||||
|
||||
|
||||
void RigTransformHardware::computeMatrixPaletteUniform(const osg::Matrix& transformFromSkeletonToGeometry, const osg::Matrix& invTransformFromSkeletonToGeometry)
|
||||
{
|
||||
for (int i = 0; i < (int)_bonePalette.size(); i++)
|
||||
{
|
||||
osg::ref_ptr<Bone> bone = _bonePalette[i].get();
|
||||
const osg::Matrix& invBindMatrix = bone->getInvBindMatrixInSkeletonSpace();
|
||||
const osg::Matrix& boneMatrix = bone->getMatrixInSkeletonSpace();
|
||||
osg::Matrix resultBoneMatrix = invBindMatrix * boneMatrix;
|
||||
osg::Matrix result = transformFromSkeletonToGeometry * resultBoneMatrix * invTransformFromSkeletonToGeometry;
|
||||
if (!_uniformMatrixPalette->setElement(i, result))
|
||||
osg::notify(osg::WARN) << "RigTransformHardware::computeUniformMatrixPalette can't set uniform at " << i << " elements" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int RigTransformHardware::getNumBonesPerVertex() const { return _bonesPerVertex;}
|
||||
int RigTransformHardware::getNumVertexes() const { return _nbVertexes;}
|
||||
|
||||
bool RigTransformHardware::createPalette(int nbVertexes, BoneMap boneMap, const VertexInfluenceSet::VertexIndexToBoneWeightMap& vertexIndexToBoneWeightMap)
|
||||
{
|
||||
typedef std::map<std::string, int> BoneNameCountMap;
|
||||
typedef std::map<std::string, int> BoneNamePaletteIndex;
|
||||
BoneNamePaletteIndex bname2palette;
|
||||
BonePalette palette;
|
||||
BoneNameCountMap boneNameCountMap;
|
||||
|
||||
// init vertex attribute data
|
||||
VertexIndexWeightList vertexIndexWeight;
|
||||
vertexIndexWeight.resize(nbVertexes);
|
||||
|
||||
int maxBonePerVertex = 0;
|
||||
for (VertexInfluenceSet::VertexIndexToBoneWeightMap::const_iterator it = vertexIndexToBoneWeightMap.begin(); it != vertexIndexToBoneWeightMap.end(); it++)
|
||||
{
|
||||
int vertexIndex = it->first;
|
||||
const VertexInfluenceSet::BoneWeightList& boneWeightList = it->second;
|
||||
int bonesForThisVertex = 0;
|
||||
for (VertexInfluenceSet::BoneWeightList::const_iterator it = boneWeightList.begin(); it != boneWeightList.end(); it++)
|
||||
{
|
||||
const VertexInfluenceSet::BoneWeight& bw = *it;
|
||||
if (boneNameCountMap.find(bw.getBoneName()) != boneNameCountMap.end())
|
||||
{
|
||||
boneNameCountMap[bw.getBoneName()]++;
|
||||
bonesForThisVertex++; // count max number of bones per vertexes
|
||||
vertexIndexWeight[vertexIndex].push_back(IndexWeightEntry(bname2palette[bw.getBoneName()],bw.getWeight()));
|
||||
}
|
||||
else if (fabs(bw.getWeight()) > 1e-2) // dont use bone with weight too small
|
||||
{
|
||||
if (boneMap.find(bw.getBoneName()) == boneMap.end())
|
||||
{
|
||||
osg::notify(osg::WARN) << "RigTransformHardware::createPalette can't find bone " << bw.getBoneName() << " skip this influence" << std::endl;
|
||||
continue;
|
||||
}
|
||||
boneNameCountMap[bw.getBoneName()] = 1; // for stats
|
||||
bonesForThisVertex++;
|
||||
palette.push_back(boneMap[bw.getBoneName()]);
|
||||
bname2palette[bw.getBoneName()] = palette.size()-1;
|
||||
vertexIndexWeight[vertexIndex].push_back(IndexWeightEntry(bname2palette[bw.getBoneName()],bw.getWeight()));
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::WARN) << "RigTransformHardware::createPalette Bone " << bw.getBoneName() << " has a weight " << bw.getWeight() << " for vertex " << vertexIndex << " this bone will not be in the palette" << std::endl;
|
||||
}
|
||||
}
|
||||
maxBonePerVertex = osg::maximum(maxBonePerVertex, bonesForThisVertex);
|
||||
}
|
||||
osg::notify(osg::INFO) << "RigTransformHardware::createPalette maximum number of bone per vertex is " << maxBonePerVertex << std::endl;
|
||||
osg::notify(osg::INFO) << "RigTransformHardware::createPalette matrix palette has " << boneNameCountMap.size() << " entries" << std::endl;
|
||||
|
||||
for (BoneNameCountMap::iterator it = boneNameCountMap.begin(); it != boneNameCountMap.end(); it++)
|
||||
{
|
||||
osg::notify(osg::INFO) << "RigTransformHardware::createPalette Bone " << it->first << " is used " << it->second << " times" << std::endl;
|
||||
}
|
||||
|
||||
osg::notify(osg::INFO) << "RigTransformHardware::createPalette will use " << boneNameCountMap.size() * 4 << " uniforms" << std::endl;
|
||||
|
||||
|
||||
for (int i = 0 ; i < (int)vertexIndexWeight.size(); i++)
|
||||
vertexIndexWeight[i].resize(maxBonePerVertex);
|
||||
|
||||
_nbVertexes = nbVertexes;
|
||||
_bonesPerVertex = maxBonePerVertex;
|
||||
_bonePalette = palette;
|
||||
_vertexIndexMatrixWeightList = vertexIndexWeight;
|
||||
_uniformMatrixPalette = createVertexUniform();
|
||||
_boneWeightAttribArrays = createVertexAttribList();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// create vertex attribute by 2 bones
|
||||
// vec4(boneIndex0, weight0, boneIndex1, weight1)
|
||||
// if more bones are needed then other attributes are created
|
||||
// vec4(boneIndex2, weight2, boneIndex3, weight3)
|
||||
// the idea is to use this format to have a granularity smaller
|
||||
// than the 4 bones using two vertex attributes
|
||||
//
|
||||
RigTransformHardware::BoneWeightAttribList RigTransformHardware::createVertexAttribList()
|
||||
{
|
||||
BoneWeightAttribList arrayList;
|
||||
int nbArray = static_cast<int>(ceilf(getNumBonesPerVertex() * 0.5));
|
||||
if (!nbArray)
|
||||
return arrayList;
|
||||
|
||||
arrayList.resize(nbArray);
|
||||
for (int i = 0; i < nbArray; i++)
|
||||
{
|
||||
osg::ref_ptr<osg::Vec4Array> array = new osg::Vec4Array;
|
||||
arrayList[i] = array;
|
||||
int nbVertexes = getNumVertexes();
|
||||
array->resize(nbVertexes);
|
||||
for (int j = 0; j < nbVertexes; j++)
|
||||
{
|
||||
for (int b = 0; b < 2; b++)
|
||||
{
|
||||
// the granularity is 2 so if we have only one bone
|
||||
// it's convenient to init the second with a weight 0
|
||||
int boneIndexInList = i*2 + b;
|
||||
int boneIndexInVec4 = b*2;
|
||||
(*array)[j][0 + boneIndexInVec4] = 0;
|
||||
(*array)[j][1 + boneIndexInVec4] = 0;
|
||||
if (boneIndexInList < getNumBonesPerVertex())
|
||||
{
|
||||
float boneIndex = static_cast<float>(_vertexIndexMatrixWeightList[j][boneIndexInList].getIndex());
|
||||
float boneWeight = _vertexIndexMatrixWeightList[j][boneIndexInList].getWeight();
|
||||
// fill the vec4
|
||||
(*array)[j][0 + boneIndexInVec4] = boneIndex;
|
||||
(*array)[j][1 + boneIndexInVec4] = boneWeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
|
||||
osg::Uniform* RigTransformHardware::createVertexUniform()
|
||||
{
|
||||
osg::Uniform* uniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "matrixPalette", _bonePalette.size());
|
||||
return uniform;
|
||||
}
|
||||
|
||||
|
||||
void RigTransformHardware::setShader(osg::Shader* shader)
|
||||
{
|
||||
_shader = shader;
|
||||
}
|
||||
|
||||
bool RigTransformHardware::init(RigGeometry& geom)
|
||||
{
|
||||
osg::Vec3Array* pos = dynamic_cast<osg::Vec3Array*>(geom.getVertexArray());
|
||||
if (!pos) {
|
||||
osg::notify(osg::WARN) << "RigTransformHardware no vertex array in the geometry " << geom.getName() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!geom.getSkeleton()) {
|
||||
osg::notify(osg::WARN) << "RigTransformHardware no skeleting set in geometry " << geom.getName() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
Bone::BoneMap bm = geom.getSkeleton()->getBoneMap();
|
||||
|
||||
if (!createPalette(pos->size(),bm, geom.getVertexInfluenceSet().getVertexToBoneList()))
|
||||
return false;
|
||||
|
||||
osg::ref_ptr<osg::Program> program = new osg::Program;
|
||||
program->setName("HardwareSkinning");
|
||||
if (!_shader.valid())
|
||||
_shader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"skinning.vert");
|
||||
|
||||
if (!_shader.valid()) {
|
||||
osg::notify(osg::WARN) << "RigTransformHardware can't load VertexShader" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// replace max matrix by the value from uniform
|
||||
{
|
||||
std::string str = _shader->getShaderSource();
|
||||
std::string toreplace = std::string("MAX_MATRIX");
|
||||
std::size_t start = str.find(toreplace);
|
||||
std::stringstream ss;
|
||||
ss << getMatrixPaletteUniform()->getNumElements();
|
||||
str.replace(start, toreplace.size(), ss.str());
|
||||
_shader->setShaderSource(str);
|
||||
osg::notify(osg::INFO) << "Shader " << str << std::endl;
|
||||
}
|
||||
|
||||
int attribIndex = 11;
|
||||
int nbAttribs = getNumVertexAttrib();
|
||||
for (int i = 0; i < nbAttribs; i++)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "boneWeight" << i;
|
||||
program->addBindAttribLocation(ss.str(), attribIndex + i);
|
||||
geom.setVertexAttribData(attribIndex + i, osg::Geometry::ArrayData(getVertexAttrib(i),osg::Geometry::BIND_PER_VERTEX));
|
||||
osg::notify(osg::INFO) << "set vertex attrib " << ss.str() << std::endl;
|
||||
}
|
||||
program->addShader(_shader.get());
|
||||
|
||||
osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
|
||||
ss->addUniform(getMatrixPaletteUniform());
|
||||
ss->addUniform(new osg::Uniform("nbBonesPerVertex", getNumBonesPerVertex()));
|
||||
ss->setAttributeAndModes(program.get());
|
||||
geom.setStateSet(ss.get());
|
||||
_needInit = false;
|
||||
return true;
|
||||
}
|
||||
void RigTransformHardware::update(RigGeometry& geom)
|
||||
{
|
||||
computeMatrixPaletteUniform(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry());
|
||||
}
|
||||
96
src/osgAnimation/RigTransformSoftware.cpp
Normal file
96
src/osgAnimation/RigTransformSoftware.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2009 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include <osgAnimation/RigTransformSoftware>
|
||||
#include <osgAnimation/RigGeometry>
|
||||
|
||||
using namespace osgAnimation;
|
||||
|
||||
bool RigTransformSoftware::init(RigGeometry& geom)
|
||||
{
|
||||
if (!geom.getSkeleton())
|
||||
return false;
|
||||
Bone::BoneMap bm = geom.getSkeleton()->getBoneMap();
|
||||
initVertexSetFromBones(bm, geom.getVertexInfluenceSet().getUniqVertexSetToBoneSetList());
|
||||
_needInit = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RigTransformSoftware::update(RigGeometry& geom)
|
||||
{
|
||||
osg::Vec3Array* pos = dynamic_cast<osg::Vec3Array*>(geom.getVertexArray());
|
||||
if (pos && _positionSource.size() != pos->size())
|
||||
{
|
||||
_positionSource = std::vector<osg::Vec3>(pos->begin(),pos->end());
|
||||
geom.getVertexArray()->setDataVariance(osg::Object::DYNAMIC);
|
||||
}
|
||||
osg::Vec3Array* normal = dynamic_cast<osg::Vec3Array*>(geom.getNormalArray());
|
||||
if (normal && _normalSource.size() != normal->size())
|
||||
{
|
||||
_normalSource = std::vector<osg::Vec3>(normal->begin(),normal->end());
|
||||
geom.getNormalArray()->setDataVariance(osg::Object::DYNAMIC);
|
||||
}
|
||||
|
||||
if (!_positionSource.empty())
|
||||
{
|
||||
compute<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry(), &_positionSource.front(), &pos->front());
|
||||
pos->dirty();
|
||||
}
|
||||
if (!_normalSource.empty())
|
||||
{
|
||||
computeNormal<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry(), &_normalSource.front(), &normal->front());
|
||||
normal->dirty();
|
||||
}
|
||||
}
|
||||
|
||||
void RigTransformSoftware::initVertexSetFromBones(const Bone::BoneMap& map, const VertexInfluenceSet::UniqVertexSetToBoneSetList& influence)
|
||||
{
|
||||
_boneSetVertexSet.clear();
|
||||
|
||||
int size = influence.size();
|
||||
_boneSetVertexSet.resize(size);
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
const 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();
|
||||
Bone::BoneMap::const_iterator it = map.find(bname);
|
||||
if (it == map.end())
|
||||
{
|
||||
osg::notify(osg::WARN) << "RigTransformSoftware Bone " << bname << " not found, skip the influence group " <<bname << std::endl;
|
||||
continue;
|
||||
}
|
||||
Bone* bone = it->second.get();
|
||||
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 < (int)boneList.size(); b++)
|
||||
boneList[b].setWeight(boneList[b].getWeight() / sumOfWeight);
|
||||
}
|
||||
_boneSetVertexSet[i].getVertexes() = inf.getVertexes();
|
||||
}
|
||||
}
|
||||
@@ -14,23 +14,29 @@
|
||||
|
||||
#include <osgAnimation/StatsVisitor>
|
||||
#include <osgAnimation/Timeline>
|
||||
#include <osgAnimation/ActionBlendIn>
|
||||
#include <osgAnimation/ActionBlendOut>
|
||||
#include <osgAnimation/ActionStripAnimation>
|
||||
#include <osgAnimation/ActionAnimation>
|
||||
|
||||
osgAnimation::StatsActionVisitor::StatsActionVisitor() {}
|
||||
void osgAnimation::StatsActionVisitor::reset() { _channels.clear(); }
|
||||
using namespace osgAnimation;
|
||||
|
||||
osgAnimation::StatsActionVisitor::StatsActionVisitor(osg::Stats* stats,unsigned int frame)
|
||||
StatsActionVisitor::StatsActionVisitor() {}
|
||||
void StatsActionVisitor::reset() { _channels.clear(); }
|
||||
|
||||
StatsActionVisitor::StatsActionVisitor(osg::Stats* stats,unsigned int frame)
|
||||
{
|
||||
_frame = frame;
|
||||
_stats = stats;
|
||||
}
|
||||
|
||||
void osgAnimation::StatsActionVisitor::apply(Timeline& tm)
|
||||
void StatsActionVisitor::apply(Timeline& tm)
|
||||
{
|
||||
_stats->setAttribute(_frame,"Timeline", tm.getCurrentTime());
|
||||
tm.traverse(*this);
|
||||
}
|
||||
|
||||
void osgAnimation::StatsActionVisitor::apply(Action& action)
|
||||
void StatsActionVisitor::apply(Action& action)
|
||||
{
|
||||
if (isActive(action))
|
||||
{
|
||||
@@ -39,7 +45,7 @@ void osgAnimation::StatsActionVisitor::apply(Action& action)
|
||||
}
|
||||
}
|
||||
|
||||
void osgAnimation::StatsActionVisitor::apply(BlendIn& action)
|
||||
void StatsActionVisitor::apply(ActionBlendIn& action)
|
||||
{
|
||||
if (isActive(action))
|
||||
{
|
||||
@@ -48,7 +54,7 @@ void osgAnimation::StatsActionVisitor::apply(BlendIn& action)
|
||||
}
|
||||
}
|
||||
|
||||
void osgAnimation::StatsActionVisitor::apply(BlendOut& action)
|
||||
void StatsActionVisitor::apply(ActionBlendOut& action)
|
||||
{
|
||||
if (isActive(action))
|
||||
{
|
||||
@@ -57,7 +63,7 @@ void osgAnimation::StatsActionVisitor::apply(BlendOut& action)
|
||||
}
|
||||
}
|
||||
|
||||
void osgAnimation::StatsActionVisitor::apply(ActionAnimation& action)
|
||||
void StatsActionVisitor::apply(ActionAnimation& action)
|
||||
{
|
||||
if (isActive(action))
|
||||
{
|
||||
@@ -66,11 +72,11 @@ void osgAnimation::StatsActionVisitor::apply(ActionAnimation& action)
|
||||
}
|
||||
}
|
||||
|
||||
void osgAnimation::StatsActionVisitor::apply(StripAnimation& action)
|
||||
void StatsActionVisitor::apply(ActionStripAnimation& action)
|
||||
{
|
||||
if (isActive(action))
|
||||
{
|
||||
_channels.push_back(action.getName());
|
||||
_stats->setAttribute(_frame,action.getName(), action.getActionAnimation()->getAnimation()->getWeight());
|
||||
_stats->setAttribute(_frame,action.getName(), action.getAnimation()->getAnimation()->getWeight());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
|
||||
* Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
@@ -10,7 +10,7 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
*/
|
||||
|
||||
#include <osgAnimation/VertexInfluence>
|
||||
#include <osg/Notify>
|
||||
@@ -19,10 +19,11 @@
|
||||
|
||||
using namespace osgAnimation;
|
||||
|
||||
const osgAnimation::VertexInfluenceSet::VertexIndexToBoneWeightMap& osgAnimation::VertexInfluenceSet::getVertexToBoneList() const { return _vertex2Bones;}
|
||||
void VertexInfluenceSet::addVertexInfluence(const VertexInfluence& v) { _bone2Vertexes.push_back(v); }
|
||||
const VertexInfluenceSet::VertexIndexToBoneWeightMap& VertexInfluenceSet::getVertexToBoneList() const { return _vertex2Bones;}
|
||||
// this class manage VertexInfluence database by mesh
|
||||
// reference bones per vertex ...
|
||||
void osgAnimation::VertexInfluenceSet::buildVertex2BoneList()
|
||||
void VertexInfluenceSet::buildVertex2BoneList()
|
||||
{
|
||||
_vertex2Bones.clear();
|
||||
for (BoneToVertexList::const_iterator it = _bone2Vertexes.begin(); it != _bone2Vertexes.end(); it++)
|
||||
@@ -35,7 +36,7 @@ void osgAnimation::VertexInfluenceSet::buildVertex2BoneList()
|
||||
int index = viw.first;
|
||||
float weight = viw.second;
|
||||
if (vi.getName().empty())
|
||||
osg::notify(osg::WARN) << "osgAnimation::VertexInfluenceSet::buildVertex2BoneList warning vertex " << index << " is not assigned to a bone" << std::endl;
|
||||
osg::notify(osg::WARN) << "VertexInfluenceSet::buildVertex2BoneList warning vertex " << index << " is not assigned to a bone" << std::endl;
|
||||
_vertex2Bones[index].push_back(BoneWeight(vi.getName(), weight));
|
||||
}
|
||||
}
|
||||
@@ -64,10 +65,10 @@ void osgAnimation::VertexInfluenceSet::buildVertex2BoneList()
|
||||
|
||||
|
||||
// sort by name and weight
|
||||
struct SortByNameAndWeight : public std::less<osgAnimation::VertexInfluenceSet::BoneWeight>
|
||||
struct SortByNameAndWeight : public std::less<VertexInfluenceSet::BoneWeight>
|
||||
{
|
||||
bool operator()(const osgAnimation::VertexInfluenceSet::BoneWeight& b0,
|
||||
const osgAnimation::VertexInfluenceSet::BoneWeight& b1) const
|
||||
bool operator()(const VertexInfluenceSet::BoneWeight& b0,
|
||||
const VertexInfluenceSet::BoneWeight& b1) const
|
||||
{
|
||||
if (b0.getBoneName() < b1.getBoneName())
|
||||
return true;
|
||||
@@ -79,10 +80,10 @@ struct SortByNameAndWeight : public std::less<osgAnimation::VertexInfluenceSet::
|
||||
}
|
||||
};
|
||||
|
||||
struct SortByBoneWeightList : public std::less<osgAnimation::VertexInfluenceSet::BoneWeightList>
|
||||
struct SortByBoneWeightList : public std::less<VertexInfluenceSet::BoneWeightList>
|
||||
{
|
||||
bool operator()(const osgAnimation::VertexInfluenceSet::BoneWeightList& b0,
|
||||
const osgAnimation::VertexInfluenceSet::BoneWeightList& b1) const
|
||||
bool operator()(const VertexInfluenceSet::BoneWeightList& b0,
|
||||
const VertexInfluenceSet::BoneWeightList& b1) const
|
||||
{
|
||||
if (b0.size() < b1.size())
|
||||
return true;
|
||||
@@ -102,7 +103,13 @@ struct SortByBoneWeightList : public std::less<osgAnimation::VertexInfluenceSet:
|
||||
}
|
||||
};
|
||||
|
||||
void osgAnimation::VertexInfluenceSet::buildUniqVertexSetToBoneSetList()
|
||||
void VertexInfluenceSet::clear()
|
||||
{
|
||||
_bone2Vertexes.clear();
|
||||
_uniqVertexSetToBoneSet.clear();
|
||||
}
|
||||
|
||||
void VertexInfluenceSet::buildUniqVertexSetToBoneSetList()
|
||||
{
|
||||
_uniqVertexSetToBoneSet.clear();
|
||||
|
||||
@@ -130,3 +137,4 @@ void osgAnimation::VertexInfluenceSet::buildUniqVertexSetToBoneSetList()
|
||||
_uniqVertexSetToBoneSet.push_back(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user