From Cedric Pinson and Jeremey Moles, Changes to OpenSceneGraph-osgWidget-dev branch.

Notes from Robert Osfield, Merged changes to OpenSceneGraph-osgWidget-dev r9367 (prior to my botched attempt at merged svn/trunk into the branch).
This commit is contained in:
Robert Osfield
2008-12-16 20:29:00 +00:00
parent 3313327ab4
commit 60fc821764
36 changed files with 1218 additions and 836 deletions

View File

@@ -12,78 +12,39 @@
* OpenSceneGraph Public License for more details.
*/
#ifndef OSGANIMATION_ANIMATIONMANAGERBASE_H
#define OSGANIMATION_ANIMATIONMANAGERBASE_H
#ifndef OSGANIMATION_ANIMATION_MANAGER_BASE_H
#define OSGANIMATION_ANIMATION_MANAGER_BASE_H
#include <osgAnimation/Animation>
#include <osgAnimation/Export>
#include <osg/FrameStamp>
#include <osg/Group>
namespace osgAnimation
{
class OSGANIMATION_EXPORT AnimationManagerBase : public osg::Group
class OSGANIMATION_EXPORT AnimationManagerBase : public osg::NodeCallback
{
public:
typedef std::set<osg::ref_ptr<Target> > TargetSet;
struct UpdateCallback : public osg::NodeCallback
{
/** Callback method called by the NodeVisitor when visiting a node.*/
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
AnimationManagerBase* b = dynamic_cast<AnimationManagerBase*>(node);
if (b)
{
if (b->needToLink())
{
/** manager need to link, it means that an animation has been added
so we need to relink all item animated with all animations.
We apply the linker visitor on the manager node to affect
all its children.
But it should not be done here, it should be done in the
update of AnimationManager
*/
b->link();
}
const osg::FrameStamp* fs = nv->getFrameStamp();
b->update(fs->getSimulationTime());
}
}
traverse(node,nv);
}
};
AnimationManagerBase();
AnimationManagerBase(const AnimationManagerBase& b, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) :
osg::Group(b,copyop)
{
_animations = b._animations;
_targets = b._targets;
_needToLink = b._needToLink;
}
AnimationManagerBase(const AnimationManagerBase& b, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY);
virtual ~AnimationManagerBase();
virtual void update (double time) = 0;
virtual void buildTargetReference();
virtual void registerAnimation (Animation* animation);
virtual void link();
virtual void link(osg::Node* subgraph);
virtual void update(double t) = 0;
virtual bool needToLink() const;
const AnimationList& getAnimationList() const { return _animations;}
AnimationMap getAnimationMap() const;
void clearTargets()
{
for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); it++)
(*it).get()->reset();
}
void normalizeTargets()
{
for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); it++)
(*it).get()->normalize();
}
/** Callback method called by the NodeVisitor when visiting a node.*/
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
/// Operation that must be done each frame
void clearTargets();
void normalizeTargets();
protected:
@@ -91,8 +52,6 @@ namespace osgAnimation
AnimationList _animations;
TargetSet _targets;
bool _needToLink;
};
}
#endif

View File

@@ -0,0 +1,53 @@
/* -*-c++-*-
* Copyright (C) 2008 Cedric Pinson <mornifle@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_BASIC_ANIMATION_MANAGER_H
#define OSGANIMATION_BASIC_ANIMATION_MANAGER_H
#include <osg/Group>
#include <osgAnimation/AnimationManagerBase>
#include <osgAnimation/Export>
#include <osg/FrameStamp>
namespace osgAnimation
{
class OSGANIMATION_EXPORT BasicAnimationManager : public AnimationManagerBase
{
public:
META_Object(osgAnimation, BasicAnimationManager);
BasicAnimationManager();
BasicAnimationManager(const AnimationManagerBase& b, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY) : AnimationManagerBase(b,copyop) {}
virtual ~BasicAnimationManager();
void update (double time);
void playAnimation (Animation* pAnimation, int priority = 0, float weight = 1.0);
bool stopAnimation (Animation* pAnimation);
bool findAnimation (Animation* pAnimation);
bool isPlaying (Animation* pAnimation);
bool isPlaying (const std::string& animationName);
void stopAll();
protected:
typedef std::map<int, AnimationList > AnimationLayers;
AnimationLayers _animationsPlaying;
double _lastUpdate;
};
}
#endif

View File

@@ -30,31 +30,9 @@
#include <osgAnimation/Keyframe>
#include <osgAnimation/UpdateCallback>
#include <osgAnimation/Animation>
#include <osgAnimation/AnimationManager>
#include <osgAnimation/AnimationManagerBase>
#include <osgAnimation/VertexInfluence>
namespace osgAnimation
{
inline osg::Matrix operator* (const osg::Matrix matrix, double v)
{
osg::Matrix result;
for (int i = 0; i < 16; i++)
result.ptr()[i] = matrix.ptr()[i] * v;
return result;
}
inline osg::Matrix operator+ (const osg::Matrix a, const osg::Matrix b)
{
osg::Matrix result;
for (int i = 0; i < 16; i++)
result.ptr()[i] = a.ptr()[i] + b.ptr()[i];
return result;
}
}
namespace osgAnimation
{
@@ -68,19 +46,10 @@ namespace osgAnimation
typedef osg::Matrix MatrixType;
META_Node(osgAnimation, Bone);
Bone(const Bone& b, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) :
osg::Transform(b,copyop),
_position(b._position),
_rotation(b._rotation),
_scale(b._scale) {}
Bone(const std::string& name = "")
{
setName(name);
_needToRecomputeBindMatrix = false;
setUpdateCallback(new UpdateBone(name));
}
Bone(const Bone& b, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY);
Bone(const std::string& name = "");
void setDefaultUpdateCallback(const std::string& name = "");
struct BoneMapVisitor : public osg::NodeVisitor
{
@@ -103,11 +72,18 @@ namespace osgAnimation
{
osg::ref_ptr<osgAnimation::AnimationManagerBase> _manager;
FindNearestParentAnimationManager() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_PARENTS) {}
void apply(osg::Group& node)
void apply(osg::Node& node)
{
if (_manager.valid())
return;
_manager = dynamic_cast<osgAnimation::AnimationManagerBase*>(&node);
osg::NodeCallback* callback = node.getUpdateCallback();
while (callback)
{
_manager = dynamic_cast<osgAnimation::AnimationManagerBase*>(callback);
if (_manager.valid())
return;
callback = callback->getNestedCallback();
}
traverse(node);
}
};
@@ -219,25 +195,9 @@ namespace osgAnimation
}
};
osg::Vec3 _position;
osg::Quat _rotation;
osg::Vec3 _scale;
virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const;
virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const;
// flag to recompute bind pose
bool _needToRecomputeBindMatrix;
// bind data
osg::Matrix _bindInBoneSpace;
osg::Matrix _invBindInSkeletonSpace;
// bone updated
osg::Matrix _boneInSkeletonSpace;
Bone* getBoneParent();
const Bone* getBoneParent() const;
@@ -251,7 +211,7 @@ namespace osgAnimation
const osg::Matrix& getBindMatrixInBoneSpace() const { return _bindInBoneSpace; }
const osg::Matrix& getMatrixInSkeletonSpace() const { return _boneInSkeletonSpace; }
const osg::Matrix& getInvBindMatrixInSkeletonSpace() const { return _invBindInSkeletonSpace;}
void setBoneInSkeletonSpace(const osg::Matrix& matrix) { _boneInSkeletonSpace = matrix; }
void setBindMatrixInBoneSpace(const osg::Matrix& matrix)
{
_bindInBoneSpace = matrix;
@@ -262,7 +222,7 @@ namespace osgAnimation
virtual void computeBindMatrix();
bool needLink() const;
void setNeedToComputeBindMatrix(bool state) { _needToRecomputeBindMatrix = state; }
/** Add Node to Group.
@@ -274,6 +234,24 @@ namespace osgAnimation
virtual bool addChild( Node *child );
BoneMap getBoneMap();
protected:
osg::Vec3 _position;
osg::Quat _rotation;
osg::Vec3 _scale;
// flag to recompute bind pose
bool _needToRecomputeBindMatrix;
// bind data
osg::Matrix _bindInBoneSpace;
osg::Matrix _invBindInSkeletonSpace;
// bone updated
osg::Matrix _boneInSkeletonSpace;
};

View File

@@ -15,6 +15,12 @@
#ifndef OSGANIMATION_EASE_MOTION_H
#define OSGANIMATION_EASE_MOTION_H
#include <osg/Referenced>
#include <osg/ref_ptr>
#include <osg/Notify>
#include <osg/Math>
#include <vector>
namespace osgAnimation {
@@ -156,7 +162,7 @@ namespace osgAnimation {
class Motion
class Motion : public osg::Referenced
{
public:
typedef float value_type;
@@ -165,28 +171,36 @@ namespace osgAnimation {
CLAMP,
LOOP,
};
Motion(float startValue = 0, float duration = 1, float changeValue = 1, TimeBehaviour tb = CLAMP) : _time(0), _b(startValue), _c(changeValue), _d(duration), _behaviour(tb) {}
Motion(float startValue = 0, float duration = 1, float changeValue = 1, TimeBehaviour tb = CLAMP) : _time(0), _startValue(startValue), _changeValue(changeValue), _duration(duration), _behaviour(tb) {}
virtual ~Motion() {}
void reset() { setTime(0);}
float getTime() const { return _time; }
void update(float dt)
float evaluateTime(float time) const
{
_time += dt;
switch (_behaviour)
{
case CLAMP:
if (_time > _d)
_time = _d;
else if (_time < 0.0)
_time = 0.0;
if (time > _duration)
time = _duration;
else if (time < 0.0)
time = 0.0;
break;
case LOOP:
_time = fmodf(_time, _d);
if (time <= 0)
time = 0;
else
time = fmodf(time, _duration);
break;
}
return time;
}
void update(float dt)
{
_time = evaluateTime(_time + dt);
}
void setTime(float time) { _time = time; update(0);}
void setTime(float time) { _time = evaluateTime(time);}
void getValue(value_type& result) const { getValueAt(_time, result); }
value_type getValue() const
{
@@ -197,23 +211,24 @@ namespace osgAnimation {
void getValueAt(float time, value_type& result) const
{
getValueInNormalizedRange(time/_d, result);
result = result * _c + _b;
getValueInNormalizedRange(evaluateTime(time)/_duration, result);
result = result * _changeValue + _startValue;
}
value_type getValueAt(float time) const
{
value_type result;
getValueAt(time, result);
getValueAt(evaluateTime(time), result);
return result;
}
virtual void getValueInNormalizedRange(float t, value_type& result) const = 0;
float getDuration() const { return _duration;}
protected:
float _time;
float _b;
float _c;
float _d;
float _startValue;
float _changeValue;
float _duration;
TimeBehaviour _behaviour;
};
@@ -246,6 +261,39 @@ namespace osgAnimation {
}
};
struct CompositeMotion : public Motion
{
typedef std::vector<osg::ref_ptr<Motion> > MotionList;
MotionList _motions;
MotionList& getMotionList() { return _motions; }
const MotionList& getMotionList() const { return _motions; }
CompositeMotion(float startValue = 0, float duration = 1, float changeValue = 1, TimeBehaviour tb = CLAMP) : Motion(startValue, duration, changeValue, tb) {}
virtual void getValueInNormalizedRange(float t, value_type& result) const
{
if (_motions.empty())
{
result = 0;
osg::notify(osg::WARN) << "CompositeMotion::getValueInNormalizedRange no Motion in the CompositeMotion, add motion to have result" << std::endl;
return;
}
for (MotionList::const_iterator it = _motions.begin(); it != _motions.end(); it++)
{
const Motion* motion = static_cast<const Motion*>(it->get());
float durationInRange = motion->getDuration() / getDuration();
if (t < durationInRange)
{
float tInRange = t/durationInRange * motion->getDuration();
motion->getValueAt( tInRange, result);
return;
} else
t = t - durationInRange;
}
osg::notify(osg::WARN) << "CompositeMotion::getValueInNormalizedRange did find the value in range, something wrong" << std::endl;
result = 0;
}
};
// linear

View File

@@ -41,9 +41,9 @@ namespace osgAnimation
};
struct UpdateVertex : public osg::Drawable::UpdateCallback
struct UpdateVertex : public osg::Drawable::UpdateCallback
{
virtual void update(osg::NodeVisitor*, osg::Drawable* drw)
virtual void update(osg::NodeVisitor*, osg::Drawable* drw)
{
RigGeometry* geom = dynamic_cast<RigGeometry*>(drw);
if (!geom)
@@ -92,31 +92,9 @@ namespace osgAnimation
};
RigGeometry()
{
setUseDisplayList(false);
setUpdateCallback(new UpdateVertex);
setDataVariance(osg::Object::DYNAMIC);
_needToComputeMatrix = true;
_matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
}
RigGeometry(const osg::Geometry& b) : osg::Geometry(b, osg::CopyOp::SHALLOW_COPY)
{
setUseDisplayList(false);
setUpdateCallback(new UpdateVertex);
setDataVariance(osg::Object::DYNAMIC);
_needToComputeMatrix = true;
_matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
}
RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) :
osg::Geometry(b,copyop),
_positionSource(b._positionSource),
_normalSource(b._normalSource),
_vertexInfluenceSet(b._vertexInfluenceSet),
_vertexInfluenceMap(b._vertexInfluenceMap),
_transformVertexes(b._transformVertexes),
_needToComputeMatrix(b._needToComputeMatrix) {}
RigGeometry();
RigGeometry(const osg::Geometry& b);
RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
virtual osg::Object* cloneType() const { return new RigGeometry(); }
virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new RigGeometry(*this,copyop); }

View File

@@ -27,16 +27,18 @@ namespace osgAnimation
public:
META_Node(osgAnimation, Skeleton);
struct UpdateCallback : public osg::NodeCallback
struct UpdateSkeleton : public osg::NodeCallback
{
META_Object(osgAnimation, UpdateSkeleton);
UpdateSkeleton() {}
UpdateSkeleton(const UpdateSkeleton& us, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) : osg::NodeCallback(us, copyop) {}
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
};
Skeleton(const Skeleton& b, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) : Bone(b,copyop) {}
Skeleton();
void setDefaultUpdateCallback(void);
void computeBindMatrix() { _invBindInSkeletonSpace = osg::Matrix::inverse(_bindInBoneSpace); }
};
}

View File

@@ -153,7 +153,7 @@ namespace osgAnimation
if (!_boneSetVertexSet[i].getBones().empty() &&
(sumOfWeight < 1.0 - threshold || sumOfWeight > 1.0 + threshold))
{
for (int b = 0; b < boneList.size(); b++)
for (int b = 0; b < (int)boneList.size(); b++)
boneList[b].setWeight(boneList[b].getWeight() / sumOfWeight);
}
_boneSetVertexSet[i].getVertexes() = inf.getVertexes();

View File

@@ -165,9 +165,14 @@ namespace osgAnimation
typedef std::pair<unsigned int, osg::ref_ptr<Action> > FrameAction;
typedef std::vector<FrameAction> ActionList;
typedef std::map<int, ActionList> ActionLayers;
enum State
{
Play,
Stop,
};
ActionLayers _actions;
double _lastUpdate;
double _speed;
unsigned int _currentFrame;
@@ -177,12 +182,6 @@ namespace osgAnimation
bool _loop;
bool _initFirstFrame;
enum State
{
Play,
Stop,
};
State _state;
// to manage pending operation
@@ -240,20 +239,8 @@ namespace osgAnimation
META_Object(osgAnimation, Timeline);
Timeline()
{
_lastUpdate = 0;
_currentFrame = 0;
_fps = 25;
_speed = 1.0;
_state = Stop;
_initFirstFrame = false;
_previousFrameEvaluated = 0;
_evaluating = 0;
_numberFrame = -1; // something like infinity
setName("Timeline");
}
Timeline(const Timeline& nc,const osg::CopyOp&) {}
Timeline();
Timeline(const Timeline& nc,const osg::CopyOp& op = osg::CopyOp::SHALLOW_COPY);
State getStatus() const { return _state; }
const ActionList& getActionLayer(int i)
{
@@ -541,23 +528,6 @@ namespace osgAnimation
class OSGANIMATION_EXPORT AnimationManagerTimeline : public AnimationManagerBase
{
protected:
osg::ref_ptr<Timeline> _timeline;
public:
META_Node(osgAnimation, AnimationManagerTimeline);
AnimationManagerTimeline();
AnimationManagerTimeline(const AnimationManagerBase& manager);
AnimationManagerTimeline(const AnimationManagerTimeline& nc,const osg::CopyOp&) {}
Timeline* getTimeline() { return _timeline.get(); }
void update(double time);
};
}
#endif

View File

@@ -0,0 +1,44 @@
/* -*-c++-*-
* Copyright (C) 2008 Cedric Pinson <mornifle@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_TIMELINE_ANIMATION_MANAGER_H
#define OSGANIMATION_TIMELINE_ANIMATION_MANAGER_H
#include <osgAnimation/Export>
#include <osgAnimation/AnimationManagerBase>
#include <osgAnimation/Timeline>
namespace osgAnimation
{
class OSGANIMATION_EXPORT TimelineAnimationManager : public AnimationManagerBase
{
protected:
osg::ref_ptr<Timeline> _timeline;
public:
META_Object(osgAnimation, TimelineAnimationManager);
TimelineAnimationManager();
TimelineAnimationManager(const AnimationManagerBase& manager);
TimelineAnimationManager(const TimelineAnimationManager& nc,const osg::CopyOp&);
Timeline* getTimeline() { return _timeline.get(); }
const Timeline* getTimeline() const { return _timeline.get(); }
void update(double time);
};
}
#endif

View File

@@ -397,7 +397,7 @@ class OSGWIDGET_EXPORT EventInterface
bool canKeyUp () const { return (_eventMask & EVENT_KEY_UP) != 0; }
private:
typedef std::list<osg::ref_ptr<Callback> > CallbackList;
typedef std::list<osg::observer_ptr<Callback> > CallbackList;
unsigned int _eventMask;
CallbackList _callbacks;