From Cedric Pinson, "Here a list of changes:

Bone now inherit from MatrixTransform. It simplify a lot the update of
Bone matrix. It helps to have the bone system more generic. eg it's now
possible to have animation data with precomputed bind matrix. The other
benefit, is now the collada plugin will be able to use osgAnimation to
display skinned mesh. Michael Plating did a great work to improve this
aspect, he is working on the collada plugin and should be able to submit
a new version soon.
The RigGeometry has been refactored so now it works when you save and
reload RigGeometry because the source is not touched anymore. The
benefit with this update is that it should be now possible to use a
MorphGeometry as source for a RigGeometry.

The bad news is that the format has changed, so i have rebuild osg-data
related to osgAnimation data, updated the blender exporter to export to
the new format.
The fbx plugin could be touched about this commit, i dont compile it so
i can't give more information about it.
The bvh plugin has been updated by Wang rui so this one is fixed with
the new code of osgAnimation.
The examples has been updated to work with the new code too...

The example osg-data/example.osg should be remove, it's an old example
that does not work.

For people using blender the blender exporter up to date is here:
http://hg.plopbyte.net/osgexport2/
it will be merge to http://hg.plopbyte.net/osgexport/ as soon as the
modification will be push in the trunk.
"
This commit is contained in:
Robert Osfield 2010-01-27 12:24:55 +00:00
parent 0abf08b806
commit db4d58b01d
65 changed files with 1967 additions and 862 deletions

View File

@ -29,6 +29,7 @@
#include <osgAnimation/RigGeometry> #include <osgAnimation/RigGeometry>
#include <osgAnimation/RigTransformHardware> #include <osgAnimation/RigTransformHardware>
#include <osgAnimation/AnimationManagerBase> #include <osgAnimation/AnimationManagerBase>
#include <osgAnimation/BoneMapVisitor>
#include <sstream> #include <sstream>
@ -43,6 +44,15 @@ osg::ref_ptr<osg::Program> program;
// show how to override the default RigTransformHardware for customized usage // show how to override the default RigTransformHardware for customized usage
struct MyRigTransformHardware : public osgAnimation::RigTransformHardware struct MyRigTransformHardware : public osgAnimation::RigTransformHardware
{ {
void operator()(osgAnimation::RigGeometry& geom)
{
if (_needInit)
if (!init(geom))
return;
computeMatrixPaletteUniform(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry());
}
bool init(osgAnimation::RigGeometry& geom) bool init(osgAnimation::RigGeometry& geom)
{ {
osg::Vec3Array* pos = dynamic_cast<osg::Vec3Array*>(geom.getVertexArray()); osg::Vec3Array* pos = dynamic_cast<osg::Vec3Array*>(geom.getVertexArray());
@ -56,7 +66,9 @@ struct MyRigTransformHardware : public osgAnimation::RigTransformHardware
return false; return false;
} }
osgAnimation::Bone::BoneMap bm = geom.getSkeleton()->getBoneMap(); osgAnimation::BoneMapVisitor mapVisitor;
geom.getSkeleton()->accept(mapVisitor);
osgAnimation::BoneMap bm = mapVisitor.getBoneMap();
if (!createPalette(pos->size(),bm, geom.getVertexInfluenceSet().getVertexToBoneList())) if (!createPalette(pos->size(),bm, geom.getVertexInfluenceSet().getVertexToBoneList()))
return false; return false;
@ -136,8 +148,11 @@ struct SetupRigGeometry : public osg::NodeVisitor
rig->setRigTransformImplementation(new MyRigTransformHardware); rig->setRigTransformImplementation(new MyRigTransformHardware);
} }
#if 0
if (geom.getName() != std::string("BoundingBox")) // we disable compute of bounding box for all geometry except our bounding box if (geom.getName() != std::string("BoundingBox")) // we disable compute of bounding box for all geometry except our bounding box
geom.setComputeBoundingBoxCallback(new osg::Drawable::ComputeBoundingBoxCallback); geom.setComputeBoundingBoxCallback(new osg::Drawable::ComputeBoundingBoxCallback);
// geom.setInitialBound(new osg::Drawable::ComputeBoundingBoxCallback);
#endif
} }
}; };

View File

@ -18,6 +18,7 @@
#include <osg/Geode> #include <osg/Geode>
#include <osgViewer/Viewer> #include <osgViewer/Viewer>
#include <osgGA/TrackballManipulator> #include <osgGA/TrackballManipulator>
#include <osgDB/WriteFile>
#include <osgUtil/SmoothingVisitor> #include <osgUtil/SmoothingVisitor>
#include <osg/io_utils> #include <osg/io_utils>
@ -25,6 +26,11 @@
#include <osgAnimation/Skeleton> #include <osgAnimation/Skeleton>
#include <osgAnimation/RigGeometry> #include <osgAnimation/RigGeometry>
#include <osgAnimation/BasicAnimationManager> #include <osgAnimation/BasicAnimationManager>
#include <osgAnimation/UpdateMatrixTransform>
#include <osgAnimation/UpdateBone>
#include <osgAnimation/StackedTransform>
#include <osgAnimation/StackedTranslateElement>
#include <osgAnimation/StackedRotateAxisElement>
osg::Geode* createAxis() osg::Geode* createAxis()
{ {
@ -58,8 +64,9 @@ osg::Geode* createAxis()
osgAnimation::RigGeometry* createTesselatedBox(int nsplit, float size) osgAnimation::RigGeometry* createTesselatedBox(int nsplit, float size)
{ {
osgAnimation::RigGeometry* geometry = new osgAnimation::RigGeometry; osgAnimation::RigGeometry* riggeometry = new osgAnimation::RigGeometry;
osg::Geometry* geometry = new osg::Geometry;
osg::ref_ptr<osg::Vec3Array> vertices (new osg::Vec3Array()); osg::ref_ptr<osg::Vec3Array> vertices (new osg::Vec3Array());
osg::ref_ptr<osg::Vec3Array> colors (new osg::Vec3Array()); osg::ref_ptr<osg::Vec3Array> colors (new osg::Vec3Array());
geometry->setVertexArray (vertices.get()); geometry->setVertexArray (vertices.get());
@ -119,7 +126,8 @@ osgAnimation::RigGeometry* createTesselatedBox(int nsplit, float size)
geometry->addPrimitiveSet(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, array->size(), &array->front())); geometry->addPrimitiveSet(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, array->size(), &array->front()));
geometry->setUseDisplayList( false ); geometry->setUseDisplayList( false );
return geometry; riggeometry->setSourceGeometry(geometry);
return riggeometry;
} }
@ -163,22 +171,27 @@ int main (int argc, char* argv[])
osg::ref_ptr<osgAnimation::Skeleton> skelroot = new osgAnimation::Skeleton; osg::ref_ptr<osgAnimation::Skeleton> skelroot = new osgAnimation::Skeleton;
skelroot->setDefaultUpdateCallback(); skelroot->setDefaultUpdateCallback();
osg::ref_ptr<osgAnimation::Bone> root = new osgAnimation::Bone; osg::ref_ptr<osgAnimation::Bone> root = new osgAnimation::Bone;
{ root->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(-1,0,0)));
root->setBindMatrixInBoneSpace(osg::Matrix::identity()); root->setName("root");
root->setBindMatrixInBoneSpace(osg::Matrix::translate(-1,0,0)); osgAnimation::UpdateBone* pRootUpdate = new osgAnimation::UpdateBone("root");
root->setName("root"); pRootUpdate->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("translate",osg::Vec3(-1,0,0)));
root->setDefaultUpdateCallback(); root->setUpdateCallback(pRootUpdate);
}
osg::ref_ptr<osgAnimation::Bone> right0 = new osgAnimation::Bone; osg::ref_ptr<osgAnimation::Bone> right0 = new osgAnimation::Bone;
right0->setBindMatrixInBoneSpace(osg::Matrix::translate(1,0,0)); right0->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(0,0,0)));
right0->setName("right0"); right0->setName("right0");
right0->setDefaultUpdateCallback("right0"); osgAnimation::UpdateBone* pRight0Update = new osgAnimation::UpdateBone("right0");
pRight0Update->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("translate", osg::Vec3(1,0,0)));
pRight0Update->getStackedTransforms().push_back(new osgAnimation::StackedRotateAxisElement("rotate", osg::Vec3(0,0,1), 0));
right0->setUpdateCallback(pRight0Update);
osg::ref_ptr<osgAnimation::Bone> right1 = new osgAnimation::Bone; osg::ref_ptr<osgAnimation::Bone> right1 = new osgAnimation::Bone;
right1->setBindMatrixInBoneSpace(osg::Matrix::translate(1,0,0)); right1->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(1,0,0)));
right1->setName("right1"); right1->setName("right1");
right1->setDefaultUpdateCallback("right1"); osgAnimation::UpdateBone* pRight1Update = new osgAnimation::UpdateBone("right1");
pRight1Update->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("translate", osg::Vec3(1,0,0)));
pRight1Update->getStackedTransforms().push_back(new osgAnimation::StackedRotateAxisElement("rotate", osg::Vec3(0,0,1), 0));
right1->setUpdateCallback(pRight1Update);
root->addChild(right0.get()); root->addChild(right0.get());
right0->addChild(right1.get()); right0->addChild(right1.get());
@ -190,33 +203,27 @@ int main (int argc, char* argv[])
osgAnimation::Animation* anim = new osgAnimation::Animation; osgAnimation::Animation* anim = new osgAnimation::Animation;
{ {
osgAnimation::QuatKeyframeContainer* keys0 = new osgAnimation::QuatKeyframeContainer; osgAnimation::FloatKeyframeContainer* keys0 = new osgAnimation::FloatKeyframeContainer;
osg::Quat rotate; keys0->push_back(osgAnimation::FloatKeyframe(0,0));
rotate.makeRotate(osg::PI_2, osg::Vec3(0,0,1)); keys0->push_back(osgAnimation::FloatKeyframe(3,osg::PI_2));
keys0->push_back(osgAnimation::QuatKeyframe(0,osg::Quat(0,0,0,1))); keys0->push_back(osgAnimation::FloatKeyframe(6,osg::PI_2));
keys0->push_back(osgAnimation::QuatKeyframe(3,rotate)); osgAnimation::FloatLinearSampler* sampler = new osgAnimation::FloatLinearSampler;
keys0->push_back(osgAnimation::QuatKeyframe(6,rotate));
osgAnimation::QuatSphericalLinearSampler* sampler = new osgAnimation::QuatSphericalLinearSampler;
sampler->setKeyframeContainer(keys0); sampler->setKeyframeContainer(keys0);
// osgAnimation::AnimationUpdateCallback* cb = dynamic_cast<osgAnimation::AnimationUpdateCallback*>(right0->getUpdateCallback()); osgAnimation::FloatLinearChannel* channel = new osgAnimation::FloatLinearChannel(sampler);
osgAnimation::QuatSphericalLinearChannel* channel = new osgAnimation::QuatSphericalLinearChannel(sampler); channel->setName("rotate");
channel->setName("quaternion");
channel->setTargetName("right0"); channel->setTargetName("right0");
anim->addChannel(channel); anim->addChannel(channel);
} }
{ {
osgAnimation::QuatKeyframeContainer* keys1 = new osgAnimation::QuatKeyframeContainer; osgAnimation::FloatKeyframeContainer* keys1 = new osgAnimation::FloatKeyframeContainer;
osg::Quat rotate; keys1->push_back(osgAnimation::FloatKeyframe(0,0));
rotate.makeRotate(osg::PI_2, osg::Vec3(0,0,1)); keys1->push_back(osgAnimation::FloatKeyframe(3,0));
keys1->push_back(osgAnimation::QuatKeyframe(0,osg::Quat(0,0,0,1))); keys1->push_back(osgAnimation::FloatKeyframe(6,osg::PI_2));
keys1->push_back(osgAnimation::QuatKeyframe(3,osg::Quat(0,0,0,1))); osgAnimation::FloatLinearSampler* sampler = new osgAnimation::FloatLinearSampler;
keys1->push_back(osgAnimation::QuatKeyframe(6,rotate));
osgAnimation::QuatSphericalLinearSampler* sampler = new osgAnimation::QuatSphericalLinearSampler;
sampler->setKeyframeContainer(keys1); sampler->setKeyframeContainer(keys1);
osgAnimation::QuatSphericalLinearChannel* channel = new osgAnimation::QuatSphericalLinearChannel(sampler); osgAnimation::FloatLinearChannel* channel = new osgAnimation::FloatLinearChannel(sampler);
//osgAnimation::AnimationUpdateCallback* cb = dynamic_cast<osgAnimation::AnimationUpdateCallback*>(right1->getUpdateCallback()); channel->setName("rotate");
channel->setName("quaternion");
channel->setTargetName("right1"); channel->setTargetName("right1");
anim->addChannel(channel); anim->addChannel(channel);
} }
@ -245,7 +252,7 @@ int main (int argc, char* argv[])
osg::Geode* geode = new osg::Geode; osg::Geode* geode = new osg::Geode;
geode->addDrawable(geom); geode->addDrawable(geom);
skelroot->addChild(geode); skelroot->addChild(geode);
osg::ref_ptr<osg::Vec3Array> src = dynamic_cast<osg::Vec3Array*>(geom->getVertexArray()); osg::ref_ptr<osg::Vec3Array> src = dynamic_cast<osg::Vec3Array*>(geom->getSourceGeometry()->getVertexArray());
geom->getOrCreateStateSet()->setMode(GL_LIGHTING, false); geom->getOrCreateStateSet()->setMode(GL_LIGHTING, false);
geom->setDataVariance(osg::Object::DYNAMIC); geom->setDataVariance(osg::Object::DYNAMIC);
@ -260,6 +267,7 @@ int main (int argc, char* argv[])
viewer.frame(); viewer.frame();
} }
osgDB::writeNodeFile(*scene, "skinning.osg");
return 0; return 0;
} }

View File

@ -1,5 +1,5 @@
/* -*-c++-*- /* -*-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 * 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 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@ -22,7 +22,8 @@
#include <osgAnimation/BasicAnimationManager> #include <osgAnimation/BasicAnimationManager>
#include <osgAnimation/Channel> #include <osgAnimation/Channel>
#include <osgAnimation/UpdateCallback> #include <osgAnimation/UpdateMatrixTransform>
#include <osgAnimation/StackedTranslateElement>
using namespace osgAnimation; using namespace osgAnimation;
@ -74,7 +75,9 @@ int main (int argc, char* argv[])
osg::ref_ptr<osg::MatrixTransform> trans = new osg::MatrixTransform(); osg::ref_ptr<osg::MatrixTransform> trans = new osg::MatrixTransform();
trans->setName("AnimatedNode"); trans->setName("AnimatedNode");
trans->setDataVariance(osg::Object::DYNAMIC); trans->setDataVariance(osg::Object::DYNAMIC);
trans->setUpdateCallback(new osgAnimation::UpdateTransform("AnimatedCallback")); osgAnimation::UpdateMatrixTransform* updatecb = new osgAnimation::UpdateMatrixTransform("AnimatedCallback");
updatecb->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("position"));
trans->setUpdateCallback(updatecb);
trans->setMatrix(osg::Matrix::identity()); trans->setMatrix(osg::Matrix::identity());
trans->addChild (geode.get()); trans->addChild (geode.get());

View File

@ -0,0 +1,72 @@
/* -*-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_ANIMATION_UPDATE_CALLBACK
#define OSGANIMATION_ANIMATION_UPDATE_CALLBACK 1
#include <osg/Object>
#include <osgAnimation/Channel>
#include <osgAnimation/Animation>
#include <string>
namespace osgAnimation
{
class AnimationUpdateCallbackBase : public virtual osg::Object
{
public:
virtual bool link(Channel* channel) = 0;
virtual int link(Animation* animation) = 0;
};
template <class T>
class AnimationUpdateCallback : public AnimationUpdateCallbackBase, public T
{
public:
AnimationUpdateCallback() {}
AnimationUpdateCallback(const std::string& name) { T::setName(name);}
AnimationUpdateCallback(const AnimationUpdateCallback& apc,const osg::CopyOp& copyop): T(apc, copyop) {}
META_Object(osgAnimation, AnimationUpdateCallback<T>);
const std::string& getName() const { return T::getName(); }
bool link(Channel* channel) { return 0; }
int link(Animation* animation)
{
if (T::getName().empty())
{
osg::notify(osg::WARN) << "An update callback has no name, it means it could link only with \"\" named Target, often an error, discard" << std::endl;
return 0;
}
int nbLinks = 0;
for (ChannelList::iterator it = animation->getChannels().begin();
it != animation->getChannels().end();
++it)
{
std::string targetName = (*it)->getTargetName();
if (targetName == T::getName())
{
AnimationUpdateCallbackBase* a = this;
a->link((*it).get());
nbLinks++;
}
}
return nbLinks;
}
};
}
#endif

View File

@ -16,38 +16,20 @@
* Michael Platings <mplatings@pixelpower.com> * Michael Platings <mplatings@pixelpower.com>
*/ */
#ifndef OSGANIMATION_BONE_H #ifndef OSGANIMATION_BONE
#define OSGANIMATION_BONE_H #define OSGANIMATION_BONE 1
#include <osg/Transform> #include <osg/MatrixTransform>
#include <osg/Quat>
#include <osg/Vec3>
#include <osg/Node>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Notify>
#include <osg/io_utils>
#include <osg/NodeVisitor>
#include <osgAnimation/Export> #include <osgAnimation/Export>
#include <osgAnimation/Target>
#include <osgAnimation/Sampler>
#include <osgAnimation/Channel>
#include <osgAnimation/Keyframe>
#include <osgAnimation/UpdateCallback>
#include <osgAnimation/Animation>
#include <osgAnimation/AnimationManagerBase>
#include <osgAnimation/VertexInfluence>
namespace osgAnimation namespace osgAnimation
{ {
// A bone can't have more than one parent Bone, so sharing a part of Bone's hierarchy // A bone can't have more than one parent Bone, so sharing a part of Bone's hierarchy
// makes no sense. You can share the entire hierarchy but not only a part of it. // makes no sense. You can share the entire hierarchy but not only a part of it.
class OSGANIMATION_EXPORT Bone : public osg::Transform class OSGANIMATION_EXPORT Bone : public osg::MatrixTransform
{ {
public: public:
typedef osg::ref_ptr<Bone> PointerType;
typedef std::map<std::string, PointerType > BoneMap;
typedef osg::Matrix MatrixType; typedef osg::Matrix MatrixType;
META_Node(osgAnimation, Bone); META_Node(osgAnimation, Bone);
@ -56,128 +38,24 @@ namespace osgAnimation
void setDefaultUpdateCallback(const std::string& name = ""); void setDefaultUpdateCallback(const std::string& name = "");
class OSGANIMATION_EXPORT UpdateBone : public AnimationUpdateCallback <osg::NodeCallback>
{
protected:
osg::ref_ptr<osgAnimation::Vec3Target> _position;
osg::ref_ptr<osgAnimation::QuatTarget> _quaternion;
osg::ref_ptr<osgAnimation::Vec3Target> _scale;
public:
META_Object(osgAnimation, UpdateBone);
UpdateBone(const UpdateBone& apc,const osg::CopyOp& copyop);
UpdateBone(const std::string& name = "") : AnimationUpdateCallback <osg::NodeCallback>(name)
{
setName(name);
_quaternion = new osgAnimation::QuatTarget;
_position = new osgAnimation::Vec3Target;
_scale = new osgAnimation::Vec3Target;
}
void update(osgAnimation::Bone& bone)
{
bone.setTranslation(_position->getValue());
bone.setRotation(_quaternion->getValue());
bone.setScale(_scale->getValue());
bone.dirtyBound();
}
osgAnimation::QuatTarget* getQuaternion() {return _quaternion.get();}
osgAnimation::Vec3Target* getPosition() {return _position.get();}
osgAnimation::Vec3Target* getScale() {return _scale.get();}
bool needLink() const
{
// the idea is to return true if nothing is linked
return !((_position->getCount() + _quaternion->getCount() + _scale->getCount()) > 3);
}
/** Link channel*/
bool link(osgAnimation::Channel* channel);
/** Callback method called by the NodeVisitor when visiting a node.*/
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
};
virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const;
virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const;
Bone* getBoneParent(); Bone* getBoneParent();
const Bone* getBoneParent() const; const Bone* getBoneParent() const;
void setTranslation(const osg::Vec3& trans) { _position = trans;} const osg::Matrix& getMatrixInBoneSpace() const { return getMatrix();}
void setRotation(const osg::Quat& quat) { _rotation = quat;}
void setScale(const osg::Vec3& scale) { _scale = scale;}
const osg::Vec3& getTranslation() const { return _position;}
const osg::Quat& getRotation() const { return _rotation;}
const osg::Vec3& getScale() const { return _scale;}
osg::Matrix getMatrixInBoneSpace() const { return (osg::Matrix(getRotation())) * osg::Matrix::translate(getTranslation()) * _bindInBoneSpace;}
const osg::Matrix& getBindMatrixInBoneSpace() const { return _bindInBoneSpace; }
const osg::Matrix& getMatrixInSkeletonSpace() const { return _boneInSkeletonSpace; } const osg::Matrix& getMatrixInSkeletonSpace() const { return _boneInSkeletonSpace; }
const osg::Matrix& getInvBindMatrixInSkeletonSpace() const { return _invBindInSkeletonSpace;} const osg::Matrix& getInvBindMatrixInSkeletonSpace() const { return _invBindInSkeletonSpace;}
void setMatrixInSkeletonSpace(const osg::Matrix& matrix) { _boneInSkeletonSpace = matrix; } void setMatrixInSkeletonSpace(const osg::Matrix& matrix) { _boneInSkeletonSpace = matrix; }
void setBindMatrixInBoneSpace(const osg::Matrix& matrix) void setInvBindMatrixInSkeletonSpace(const osg::Matrix& matrix) { _invBindInSkeletonSpace = matrix; }
{
_bindInBoneSpace = matrix;
_needToRecomputeBindMatrix = true;
}
inline bool needToComputeBindMatrix() { return _needToRecomputeBindMatrix;}
virtual void computeBindMatrix();
void setNeedToComputeBindMatrix(bool state) { _needToRecomputeBindMatrix = state; }
/** Add Node to Group.
* If node is not NULL and is not contained in Group then increment its
* reference count, add it to the child list and dirty the bounding
* sphere to force it to recompute on next getBound() and return true for success.
* Otherwise return false. Scene nodes can't be added as child nodes.
*/
virtual bool addChild( Node *child );
BoneMap getBoneMap();
protected: protected:
osg::Vec3 _position;
osg::Quat _rotation;
osg::Vec3 _scale;
// flag to recompute bind pose
bool _needToRecomputeBindMatrix;
// bind data // bind data
osg::Matrix _bindInBoneSpace;
osg::Matrix _invBindInSkeletonSpace; osg::Matrix _invBindInSkeletonSpace;
// bone updated // bone updated
osg::Matrix _boneInSkeletonSpace; osg::Matrix _boneInSkeletonSpace;
}; };
typedef std::map<std::string, osg::ref_ptr<Bone> > BoneMap;
inline bool Bone::computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor*) const
{
if (_referenceFrame==RELATIVE_RF)
matrix.preMult(getMatrixInBoneSpace());
else
matrix = getMatrixInBoneSpace();
return true;
}
inline bool Bone::computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor*) const
{
if (_referenceFrame==RELATIVE_RF)
matrix.postMult(osg::Matrix::inverse(getMatrixInBoneSpace()));
else
matrix = osg::Matrix::inverse(getMatrixInBoneSpace());
return true;
}
} }
#endif #endif

View File

@ -15,8 +15,8 @@
* Cedric Pinson <cedric.pinson@plopbyte.net> * Cedric Pinson <cedric.pinson@plopbyte.net>
*/ */
#ifndef OSGANIMATION_BONEMAP_VISITOR_H #ifndef OSGANIMATION_BONEMAP_VISITOR
#define OSGANIMATION_BONEMAP_VISITOR_H 1 #define OSGANIMATION_BONEMAP_VISITOR 1
#include <osgAnimation/Export> #include <osgAnimation/Export>
#include <osgAnimation/Bone> #include <osgAnimation/Bone>
@ -32,10 +32,10 @@ namespace osgAnimation
void apply(osg::Node&); void apply(osg::Node&);
void apply(osg::Transform& node); void apply(osg::Transform& node);
const Bone::BoneMap& getBoneMap() const; const BoneMap& getBoneMap() const;
protected: protected:
Bone::BoneMap _map; BoneMap _map;
}; };
} }

View File

@ -172,6 +172,7 @@ namespace osgAnimation
typedef TemplateChannel<Vec3LinearSampler> Vec3LinearChannel; typedef TemplateChannel<Vec3LinearSampler> Vec3LinearChannel;
typedef TemplateChannel<Vec4LinearSampler> Vec4LinearChannel; typedef TemplateChannel<Vec4LinearSampler> Vec4LinearChannel;
typedef TemplateChannel<QuatSphericalLinearSampler> QuatSphericalLinearChannel; typedef TemplateChannel<QuatSphericalLinearSampler> QuatSphericalLinearChannel;
typedef TemplateChannel<MatrixLinearSampler> MatrixLinearChannel;
typedef TemplateChannel<FloatCubicBezierSampler> FloatCubicBezierChannel; typedef TemplateChannel<FloatCubicBezierSampler> FloatCubicBezierChannel;
typedef TemplateChannel<DoubleCubicBezierSampler> DoubleCubicBezierChannel; typedef TemplateChannel<DoubleCubicBezierSampler> DoubleCubicBezierChannel;

View File

@ -1,43 +0,0 @@
/* -*-c++-*-
* 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
* (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 COMPUTE_BIND_MATRIX_VISITOR_H
#define COMPUTE_BIND_MATRIX_VISITOR_H 1
#include <osg/NodeVisitor>
#include <osgAnimation/Bone>
namespace osgAnimation
{
class ComputeBindMatrixVisitor : public osg::NodeVisitor
{
public:
ComputeBindMatrixVisitor(): osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
void apply(osg::Node& node) { return; }
void apply(osg::Transform& node)
{
osgAnimation::Bone* bone = dynamic_cast<osgAnimation::Bone*>(&node);
if (!bone)
return;
if (bone->needToComputeBindMatrix())
bone->computeBindMatrix();
traverse(node);
}
};
}
#endif

View File

@ -12,60 +12,61 @@
* OpenSceneGraph Public License for more details. * OpenSceneGraph Public License for more details.
*/ */
#ifndef OSGANIMATION_CUBIC_BEZIER_H #ifndef OSGANIMATION_CUBIC_BEZIER
#define OSGANIMATION_CUBIC_BEZIER_H #define OSGANIMATION_CUBIC_BEZIER 1
#include <osg/Vec2> #include <osg/Vec2>
#include <osg/Vec3> #include <osg/Vec3>
#include <osg/Vec4> #include <osg/Vec4>
#include <osg/Quat>
namespace osgAnimation namespace osgAnimation
{ {
template <class T> template <class T>
struct TemplateCubicBezier class TemplateCubicBezier
{ {
T mPoint[3]; public:
const T& getP0() const { return mPoint[0];}
const T& getP1() const { return mPoint[1];}
const T& getP2() const { return mPoint[2];}
TemplateCubicBezier(const T& v0, const T& v1, const T& v2)
{
mPoint[0] = v0;
mPoint[1] = v1;
mPoint[2] = v2;
}
// Constructor with value only
TemplateCubicBezier(const T& v0)
{
mPoint[0] = v0;
mPoint[1] = v0;
mPoint[2] = v0;
}
TemplateCubicBezier() {} TemplateCubicBezier() {}
const T& getPosition() const { return mPoint[0];} TemplateCubicBezier(const T& p, const T& i, const T& o) : _position(p), _controlPointIn(i), _controlPointOut(o)
const T& getTangentPoint1() const { return mPoint[1];}
const T& getTangentPoint2() const { return mPoint[2];}
// steaming operators.
friend std::ostream& operator << (std::ostream& output, const TemplateCubicBezier<T>& vec)
{ {
output << vec.mPoint[0] << " " }
<< vec.mPoint[1] << " "
<< vec.mPoint[2]; // Constructor with value only
TemplateCubicBezier(const T& p) : _position(p), _controlPointIn(p), _controlPointOut(p)
{
}
const T& getPosition() const { return _position;}
const T& getControlPointIn() const { return _controlPointIn;}
const T& getControlPointOut() const { return _controlPointOut;}
T& getPosition() { return _position;}
T& getControlPointIn() { return _controlPointIn;}
T& getControlPointOut() { return _controlPointOut;}
void setPosition(const T& v) {_position = v;}
void setControlPointIn(const T& v) {_controlPointIn = v;}
void setControlPointOut(const T& v) {_controlPointOut = v;}
// steaming operators.
friend std::ostream& operator << (std::ostream& output, const TemplateCubicBezier<T>& tcb)
{
output << tcb._position << " "
<< tcb._controlPointIn << " "
<< tcb._controlPointOut;
return output; // to enable cascading return output; // to enable cascading
} }
friend std::istream& operator >> (std::istream& input, TemplateCubicBezier<T>& vec) friend std::istream& operator >> (std::istream& input, TemplateCubicBezier<T>& tcb)
{ {
input >> vec.mPoint[0] >> vec.mPoint[1] >> vec.mPoint[2]; input >> tcb._position >> tcb._controlPointIn >> tcb._controlPointOut;
return input; return input;
} }
};
protected:
T _position, _controlPointIn, _controlPointOut;
};
typedef TemplateCubicBezier<float> FloatCubicBezier; typedef TemplateCubicBezier<float> FloatCubicBezier;
typedef TemplateCubicBezier<double> DoubleCubicBezier; typedef TemplateCubicBezier<double> DoubleCubicBezier;

View File

@ -313,7 +313,7 @@ namespace osgAnimation {
osg::notify(osg::WARN) << "CompositeMotion::getValueInNormalizedRange no Motion in the CompositeMotion, add motion to have result" << std::endl; osg::notify(osg::WARN) << "CompositeMotion::getValueInNormalizedRange no Motion in the CompositeMotion, add motion to have result" << std::endl;
return; return;
} }
for (MotionList::const_iterator it = _motions.begin(); it != _motions.end(); it++) for (MotionList::const_iterator it = _motions.begin(); it != _motions.end(); ++it)
{ {
const Motion* motion = static_cast<const Motion*>(it->get()); const Motion* motion = static_cast<const Motion*>(it->get());
float durationInRange = motion->getDuration() / getDuration(); float durationInRange = motion->getDuration() / getDuration();

View File

@ -205,8 +205,8 @@ namespace osgAnimation
float t2 = t * t; float t2 = t * t;
TYPE v0 = keyframes[i].getValue().getPosition() * one_minus_t3; TYPE v0 = keyframes[i].getValue().getPosition() * one_minus_t3;
TYPE v1 = keyframes[i].getValue().getTangentPoint1() * (3.0 * t * one_minus_t2); TYPE v1 = keyframes[i].getValue().getControlPointIn() * (3.0 * t * one_minus_t2);
TYPE v2 = keyframes[i].getValue().getTangentPoint2() * (3.0 * t2 * one_minus_t); TYPE v2 = keyframes[i].getValue().getControlPointOut() * (3.0 * t2 * one_minus_t);
TYPE v3 = keyframes[i+1].getValue().getPosition() * (t2 * t); TYPE v3 = keyframes[i+1].getValue().getPosition() * (t2 * t);
result = v0 + v1 + v2 + v3; result = v0 + v1 + v2 + v3;
@ -228,6 +228,7 @@ namespace osgAnimation
typedef TemplateLinearInterpolator<osg::Vec3, Vec3Packed> Vec3PackedLinearInterpolator; typedef TemplateLinearInterpolator<osg::Vec3, Vec3Packed> Vec3PackedLinearInterpolator;
typedef TemplateLinearInterpolator<osg::Vec4, osg::Vec4> Vec4LinearInterpolator; typedef TemplateLinearInterpolator<osg::Vec4, osg::Vec4> Vec4LinearInterpolator;
typedef TemplateSphericalLinearInterpolator<osg::Quat, osg::Quat> QuatSphericalLinearInterpolator; typedef TemplateSphericalLinearInterpolator<osg::Quat, osg::Quat> QuatSphericalLinearInterpolator;
typedef TemplateLinearInterpolator<osg::Matrixf, osg::Matrixf> MatrixLinearInterpolator;
typedef TemplateCubicBezierInterpolator<float, FloatCubicBezier > FloatCubicBezierInterpolator; typedef TemplateCubicBezierInterpolator<float, FloatCubicBezier > FloatCubicBezierInterpolator;
typedef TemplateCubicBezierInterpolator<double, DoubleCubicBezier> DoubleCubicBezierInterpolator; typedef TemplateCubicBezierInterpolator<double, DoubleCubicBezier> DoubleCubicBezierInterpolator;

View File

@ -23,6 +23,7 @@
#include <osg/Vec4> #include <osg/Vec4>
#include <osg/Vec3> #include <osg/Vec3>
#include <osg/Vec2> #include <osg/Vec2>
#include <osg/Matrixf>
namespace osgAnimation namespace osgAnimation
{ {
@ -114,6 +115,9 @@ namespace osgAnimation
typedef TemplateKeyframe<osg::Quat> QuatKeyframe; typedef TemplateKeyframe<osg::Quat> QuatKeyframe;
typedef TemplateKeyframeContainer<osg::Quat> QuatKeyframeContainer; typedef TemplateKeyframeContainer<osg::Quat> QuatKeyframeContainer;
typedef TemplateKeyframe<osg::Matrixf> MatrixKeyframe;
typedef TemplateKeyframeContainer<osg::Matrixf> MatrixKeyframeContainer;
typedef TemplateKeyframe<Vec3Packed> Vec3PackedKeyframe; typedef TemplateKeyframe<Vec3Packed> Vec3PackedKeyframe;
typedef TemplateKeyframeContainer<Vec3Packed> Vec3PackedKeyframeContainer; typedef TemplateKeyframeContainer<Vec3Packed> Vec3PackedKeyframeContainer;

View File

@ -16,8 +16,8 @@
#define OSGANIMATION_MORPHGEOMETRY_H #define OSGANIMATION_MORPHGEOMETRY_H
#include <osgAnimation/Export> #include <osgAnimation/Export>
#include <osgAnimation/AnimationUpdateCallback>
#include <osg/Geometry> #include <osg/Geometry>
#include <osgAnimation/UpdateCallback>
namespace osgAnimation namespace osgAnimation
{ {

View File

@ -18,6 +18,7 @@
#include <osgAnimation/Export> #include <osgAnimation/Export>
#include <osgAnimation/Skeleton> #include <osgAnimation/Skeleton>
#include <osgAnimation/RigTransform> #include <osgAnimation/RigTransform>
#include <osgAnimation/VertexInfluence>
#include <osg/Geometry> #include <osg/Geometry>
namespace osgAnimation namespace osgAnimation
@ -28,7 +29,7 @@ namespace osgAnimation
public: public:
RigGeometry(); RigGeometry();
RigGeometry(const osg::Geometry& b); // RigGeometry(const osg::Geometry& b);
RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
META_Object(osgAnimation, RigGeometry); META_Object(osgAnimation, RigGeometry);
@ -63,8 +64,15 @@ namespace osgAnimation
const osg::Matrix& getMatrixFromSkeletonToGeometry() const; const osg::Matrix& getMatrixFromSkeletonToGeometry() const;
const osg::Matrix& getInvMatrixFromSkeletonToGeometry() const; const osg::Matrix& getInvMatrixFromSkeletonToGeometry() const;
protected: osg::Geometry* getSourceGeometry();
const osg::Geometry* getSourceGeometry() const;
void setSourceGeometry(osg::Geometry* geometry);
void copyFrom(osg::Geometry& from);
protected:
osg::ref_ptr<osg::Geometry> _geometry;
osg::ref_ptr<RigTransform> _rigTransformImplementation; osg::ref_ptr<RigTransform> _rigTransformImplementation;
VertexInfluenceSet _vertexInfluenceSet; VertexInfluenceSet _vertexInfluenceSet;
@ -104,7 +112,10 @@ namespace osgAnimation
geom->getParents()[0]->accept(finder); geom->getParents()[0]->accept(finder);
if (!finder._root.valid()) if (!finder._root.valid())
{
osg::notify(osg::WARN) << "A RigGeometry did not find a parent skeleton for RigGeomtry ( " << geom->getName() << " )" << std::endl;
return; return;
}
geom->buildVertexInfluenceSet(); geom->buildVertexInfluenceSet();
geom->setSkeleton(finder._root.get()); geom->setSkeleton(finder._root.get());
} }

View File

@ -12,8 +12,8 @@
* OpenSceneGraph Public License for more details. * OpenSceneGraph Public License for more details.
*/ */
#ifndef OSGANIMATION_RIGTRANSFORM_H #ifndef OSGANIMATION_RIGTRANSFORM
#define OSGANIMATION_RIGTRANSFORM_H #define OSGANIMATION_RIGTRANSFORM 1
#include <osg/Referenced> #include <osg/Referenced>
@ -25,14 +25,10 @@ namespace osgAnimation
class RigTransform : public osg::Referenced class RigTransform : public osg::Referenced
{ {
public: public:
RigTransform() : _needInit(true) {} RigTransform() {}
virtual ~RigTransform() {} virtual ~RigTransform() {}
bool needInit() const { return _needInit; } virtual void operator()(RigGeometry& geometry) {}
virtual bool init(RigGeometry&) = 0;
virtual void update(RigGeometry&) = 0;
protected:
bool _needInit;
}; };
} }

View File

@ -12,8 +12,8 @@
* OpenSceneGraph Public License for more details. * OpenSceneGraph Public License for more details.
*/ */
#ifndef OSGANIMATION_RIG_TRANSFORM_HARDWARE_H #ifndef OSGANIMATION_RIG_TRANSFORM_HARDWARE
#define OSGANIMATION_RIG_TRANSFORM_HARDWARE_H 1 #define OSGANIMATION_RIG_TRANSFORM_HARDWARE 1
#include <osgAnimation/Export> #include <osgAnimation/Export>
#include <osgAnimation/RigTransform> #include <osgAnimation/RigTransform>
@ -32,7 +32,6 @@ namespace osgAnimation
public: public:
typedef osg::Matrix MatrixType; typedef osg::Matrix MatrixType;
typedef osgAnimation::Bone BoneType; typedef osgAnimation::Bone BoneType;
typedef Bone::BoneMap BoneMap;
typedef std::vector<osg::ref_ptr<osg::Vec4Array> > BoneWeightAttribList; typedef std::vector<osg::ref_ptr<osg::Vec4Array> > BoneWeightAttribList;
typedef std::vector<osg::ref_ptr<BoneType> > BonePalette; typedef std::vector<osg::ref_ptr<BoneType> > BonePalette;
@ -48,6 +47,8 @@ namespace osgAnimation
}; };
typedef std::vector<std::vector<IndexWeightEntry> > VertexIndexWeightList; typedef std::vector<std::vector<IndexWeightEntry> > VertexIndexWeightList;
RigTransformHardware();
osg::Vec4Array* getVertexAttrib(int index); osg::Vec4Array* getVertexAttrib(int index);
int getNumVertexAttrib(); int getNumVertexAttrib();
@ -59,13 +60,13 @@ namespace osgAnimation
bool createPalette(int nbVertexes, BoneMap boneMap, const VertexInfluenceSet::VertexIndexToBoneWeightMap& vertexIndexToBoneWeightMap); bool createPalette(int nbVertexes, BoneMap boneMap, const VertexInfluenceSet::VertexIndexToBoneWeightMap& vertexIndexToBoneWeightMap);
virtual void operator()(RigGeometry&);
virtual bool init(RigGeometry&);
virtual void update(RigGeometry&);
void setShader(osg::Shader*); void setShader(osg::Shader*);
protected: protected:
bool init(RigGeometry&);
BoneWeightAttribList createVertexAttribList(); BoneWeightAttribList createVertexAttribList();
osg::Uniform* createVertexUniform(); osg::Uniform* createVertexUniform();
@ -76,6 +77,8 @@ namespace osgAnimation
BoneWeightAttribList _boneWeightAttribArrays; BoneWeightAttribList _boneWeightAttribArrays;
osg::ref_ptr<osg::Uniform> _uniformMatrixPalette; osg::ref_ptr<osg::Uniform> _uniformMatrixPalette;
osg::ref_ptr<osg::Shader> _shader; osg::ref_ptr<osg::Shader> _shader;
bool _needInit;
}; };
} }

View File

@ -12,12 +12,14 @@
* OpenSceneGraph Public License for more details. * OpenSceneGraph Public License for more details.
*/ */
#ifndef OSGANIMATION_RIG_TRANSFORM_SOFTWARE_H #ifndef OSGANIMATION_RIGTRANSFORM_SOFTWARE
#define OSGANIMATION_RIG_TRANSFORM_SOFTWARE_H 1 #define OSGANIMATION_RIGTRANSFORM_SOFTWARE 1
#include <osgAnimation/Export> #include <osgAnimation/Export>
#include <osgAnimation/RigTransform> #include <osgAnimation/RigTransform>
#include <osgAnimation/Bone> #include <osgAnimation/Bone>
#include <osgAnimation/VertexInfluence>
#include <osg/observer_ptr>
namespace osgAnimation namespace osgAnimation
{ {
@ -29,8 +31,8 @@ namespace osgAnimation
{ {
public: public:
virtual bool init(RigGeometry&); RigTransformSoftware();
virtual void update(RigGeometry&); virtual void operator()(RigGeometry&);
class BoneWeight class BoneWeight
@ -156,16 +158,13 @@ namespace osgAnimation
} }
} }
const std::vector<osg::Vec3>& getPositionSource() const { return _positionSource;}
const std::vector<osg::Vec3>& getNormalSource() const { return _normalSource;}
protected: protected:
void initVertexSetFromBones(const Bone::BoneMap& map, const VertexInfluenceSet::UniqVertexSetToBoneSetList& influence); bool init(RigGeometry&);
void initVertexSetFromBones(const BoneMap& map, const VertexInfluenceSet::UniqVertexSetToBoneSetList& influence);
std::vector<UniqBoneSetVertexSet> _boneSetVertexSet; std::vector<UniqBoneSetVertexSet> _boneSetVertexSet;
std::vector<osg::Vec3> _positionSource;
std::vector<osg::Vec3> _normalSource; bool _needInit;
}; };
} }

View File

@ -125,6 +125,7 @@ namespace osgAnimation
typedef TemplateSampler<Vec3LinearInterpolator> Vec3LinearSampler; typedef TemplateSampler<Vec3LinearInterpolator> Vec3LinearSampler;
typedef TemplateSampler<Vec4LinearInterpolator> Vec4LinearSampler; typedef TemplateSampler<Vec4LinearInterpolator> Vec4LinearSampler;
typedef TemplateSampler<QuatSphericalLinearInterpolator> QuatSphericalLinearSampler; typedef TemplateSampler<QuatSphericalLinearInterpolator> QuatSphericalLinearSampler;
typedef TemplateSampler<MatrixLinearInterpolator> MatrixLinearSampler;
typedef TemplateSampler<FloatCubicBezierInterpolator> FloatCubicBezierSampler; typedef TemplateSampler<FloatCubicBezierInterpolator> FloatCubicBezierSampler;
typedef TemplateSampler<DoubleCubicBezierInterpolator> DoubleCubicBezierSampler; typedef TemplateSampler<DoubleCubicBezierInterpolator> DoubleCubicBezierSampler;

View File

@ -16,12 +16,12 @@
#define OSGANIMATION_SKELETON 1 #define OSGANIMATION_SKELETON 1
#include <osgAnimation/Export> #include <osgAnimation/Export>
#include <osgAnimation/Bone> #include <osg/MatrixTransform>
namespace osgAnimation namespace osgAnimation
{ {
class OSGANIMATION_EXPORT Skeleton : public Bone class OSGANIMATION_EXPORT Skeleton : public osg::MatrixTransform
{ {
public: public:
META_Node(osgAnimation, Skeleton); META_Node(osgAnimation, Skeleton);
@ -40,9 +40,8 @@ namespace osgAnimation
Skeleton(); Skeleton();
Skeleton(const Skeleton&, const osg::CopyOp&); Skeleton(const Skeleton&, const osg::CopyOp&);
void setDefaultUpdateCallback(); void setDefaultUpdateCallback();
void computeBindMatrix();
}; };
} }

View File

@ -0,0 +1,54 @@
/* -*-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_STACKED_MATRIX_ELEMENT
#define OSGANIMATION_STACKED_MATRIX_ELEMENT 1
#include <osg/Object>
#include <osgAnimation/Export>
#include <osgAnimation/StackedTransformElement>
#include <osgAnimation/Target>
namespace osgAnimation
{
class OSGANIMATION_EXPORT StackedMatrixElement : public StackedTransformElement
{
public:
META_Object(osgAnimation, StackedMatrixElement);
StackedMatrixElement();
StackedMatrixElement(const StackedMatrixElement&, const osg::CopyOp&);
StackedMatrixElement(const std::string& name, const osg::Matrix& matrix);
StackedMatrixElement(const osg::Matrix& matrix);
void applyToMatrix(osg::Matrix& matrix) const { matrix = _matrix * matrix; }
osg::Matrix getAsMatrix() const { return _matrix; }
const osg::Matrix& getMatrix() const { return _matrix;}
void setMatrix(const osg::Matrix& matrix) { _matrix = matrix;}
bool isIdentity() const { return _matrix.isIdentity(); }
void update();
virtual Target* getOrCreateTarget();
virtual Target* getTarget() {return _target.get();}
virtual const Target* getTarget() const {return _target.get();}
protected:
osg::Matrix _matrix;
osg::ref_ptr<MatrixTarget> _target;
};
}
#endif

View File

@ -0,0 +1,54 @@
/* -*-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_STACKED_QUATERNION_ELEMENT
#define OSGANIMATION_STACKED_QUATERNION_ELEMENT 1
#include <osgAnimation/Export>
#include <osgAnimation/StackedTransformElement>
#include <osgAnimation/Target>
namespace osgAnimation
{
class OSGANIMATION_EXPORT StackedQuaternionElement : public StackedTransformElement
{
public:
META_Object(osgAnimation, StackedQuaternionElement);
StackedQuaternionElement();
StackedQuaternionElement(const StackedQuaternionElement&, const osg::CopyOp&);
StackedQuaternionElement(const std::string&, const osg::Quat& q = osg::Quat(0,0,0,1));
StackedQuaternionElement(const osg::Quat&);
void applyToMatrix(osg::Matrix& matrix) const;
osg::Matrix getAsMatrix() const;
bool isIdentity() const;
void update();
const osg::Quat& getQuaternion() const;
void setQuaternion(const osg::Quat&);
virtual Target* getOrCreateTarget();
virtual Target* getTarget();
virtual const Target* getTarget() const;
protected:
osg::Quat _quaternion;
osg::ref_ptr<QuatTarget> _target;
};
}
#endif

View File

@ -0,0 +1,59 @@
/* -*-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_STACKED_ROTATE_AXIS_ELEMENT
#define OSGANIMATION_STACKED_ROTATE_AXIS_ELEMENT 1
#include <osgAnimation/Export>
#include <osgAnimation/StackedTransformElement>
#include <osgAnimation/Target>
#include <osg/Vec3>
namespace osgAnimation
{
class OSGANIMATION_EXPORT StackedRotateAxisElement : public StackedTransformElement
{
public:
META_Object(osgAnimation, StackedRotateAxisElement);
StackedRotateAxisElement();
StackedRotateAxisElement(const StackedRotateAxisElement&, const osg::CopyOp&);
StackedRotateAxisElement(const std::string& name, const osg::Vec3& axis, double angle);
StackedRotateAxisElement(const osg::Vec3& axis, double angle);
void applyToMatrix(osg::Matrix& matrix) const;
osg::Matrix getAsMatrix() const;
bool isIdentity() const { return (_angle == 0); }
void update();
const osg::Vec3& getAxis() const;
const double getAngle() const;
void setAxis(const osg::Vec3&);
void setAngle(const double&);
virtual Target* getOrCreateTarget();
virtual Target* getTarget() {return _target.get();}
virtual const Target* getTarget() const {return _target.get();}
protected:
osg::Vec3 _axis;
double _angle;
osg::ref_ptr<FloatTarget> _target;
};
}
#endif

View File

@ -0,0 +1,56 @@
/* -*-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_STACKED_SCALE_ELEMENT
#define OSGANIMATION_STACKED_SCALE_ELEMENT 1
#include <osg/Object>
#include <osgAnimation/Export>
#include <osgAnimation/StackedTransformElement>
#include <osgAnimation/Target>
namespace osgAnimation
{
class OSGANIMATION_EXPORT StackedScaleElement : public StackedTransformElement
{
public:
META_Object(osgAnimation, StackedScaleElement)
StackedScaleElement();
StackedScaleElement(const StackedScaleElement&, const osg::CopyOp&);
StackedScaleElement(const std::string& name, const osg::Vec3& scale = osg::Vec3(1,1,1));
StackedScaleElement(const osg::Vec3& scale);
void applyToMatrix(osg::Matrix& matrix) const;
osg::Matrix getAsMatrix() const;
bool isIdentity() const;
void update();
const osg::Vec3& getScale() const;
void setScale(const osg::Vec3& scale);
virtual Target* getOrCreateTarget();
virtual Target* getTarget();
virtual const Target* getTarget() const;
protected:
osg::Vec3 _scale;
osg::ref_ptr<Vec3Target> _target;
};
}
#endif

View File

@ -0,0 +1,42 @@
/* -*-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_STACKED_TRANSFORM
#define OSGANIMATION_STACKED_TRANSFORM 1
#include <osg/MixinVector>
#include <osgAnimation/Export>
#include <osgAnimation/StackedTransformElement>
namespace osgAnimation
{
class OSGANIMATION_EXPORT StackedTransform : public osg::MixinVector<osg::ref_ptr<StackedTransformElement> >
{
public:
StackedTransform();
StackedTransform(const StackedTransform&, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
void update();
const osg::Matrix& getMatrix() const;
protected:
osg::Matrix _matrix;
};
}
#endif

View File

@ -0,0 +1,42 @@
/* -*-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_STACKED_TRANSFORM_ELEMENT
#define OSGANIMATION_STACKED_TRANSFORM_ELEMENT 1
#include <osgAnimation/Export>
#include <osg/Object>
#include <osg/Matrix>
namespace osgAnimation
{
class Target;
class OSGANIMATION_EXPORT StackedTransformElement : public osg::Object
{
public:
StackedTransformElement() {}
StackedTransformElement(const StackedTransformElement& rhs, const osg::CopyOp& c) : osg::Object(rhs, c) {}
virtual void applyToMatrix(osg::Matrix& matrix) const = 0;
virtual osg::Matrix getAsMatrix() const = 0;
virtual bool isIdentity() const = 0;
virtual void update() = 0;
virtual Target* getOrCreateTarget() {return 0;}
virtual Target* getTarget() {return 0;}
virtual const Target* getTarget() const {return 0;}
};
}
#endif

View File

@ -0,0 +1,54 @@
/* -*-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_STACKED_TRANSLATE_ELEMENT
#define OSGANIMATION_STACKED_TRANSLATE_ELEMENT 1
#include <osgAnimation/Export>
#include <osgAnimation/StackedTransformElement>
#include <osgAnimation/Target>
namespace osgAnimation
{
class OSGANIMATION_EXPORT StackedTranslateElement : public StackedTransformElement
{
public:
META_Object(osgAnimation, StackedTranslateElement);
StackedTranslateElement();
StackedTranslateElement(const StackedTranslateElement&, const osg::CopyOp&);
StackedTranslateElement(const std::string&, const osg::Vec3& translate = osg::Vec3(0,0,0));
StackedTranslateElement(const osg::Vec3& translate);
void applyToMatrix(osg::Matrix& matrix) const;
osg::Matrix getAsMatrix() const;
bool isIdentity() const;
void update();
const osg::Vec3& getTranslate() const;
void setTranslate(const osg::Vec3& );
virtual Target* getOrCreateTarget();
virtual Target* getTarget();
virtual const Target* getTarget() const;
protected:
osg::Vec3 _translate;
osg::ref_ptr<Vec3Target> _target;
};
}
#endif

View File

@ -121,6 +121,7 @@ namespace osgAnimation
_target *= 1.0/sqrt(len2); _target *= 1.0/sqrt(len2);
} }
typedef TemplateTarget<osg::Matrixf> MatrixTarget;
typedef TemplateTarget<osg::Quat> QuatTarget; typedef TemplateTarget<osg::Quat> QuatTarget;
typedef TemplateTarget<osg::Vec3> Vec3Target; typedef TemplateTarget<osg::Vec3> Vec3Target;
typedef TemplateTarget<osg::Vec4> Vec4Target; typedef TemplateTarget<osg::Vec4> Vec4Target;

View File

@ -0,0 +1,36 @@
/* -*-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_UPDATE_BONE
#define OSGANIMATION_UPDATE_BONE 1
#include <osgAnimation/Export>
#include <osgAnimation/UpdateMatrixTransform>
namespace osgAnimation
{
class OSGANIMATION_EXPORT UpdateBone : public UpdateMatrixTransform
{
public:
META_Object(osgAnimation, UpdateBone);
UpdateBone(const std::string& name = "");
UpdateBone(const UpdateBone&,const osg::CopyOp&);
void operator()(osg::Node* node, osg::NodeVisitor* nv);
};
}
#endif

View File

@ -1,121 +0,0 @@
/* -*-c++-*-
* 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
* (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_UPDATE_CALLBACK_H
#define OSGANIMATION_UPDATE_CALLBACK_H
#include <osg/Vec3>
#include <osg/NodeCallback>
#include <osg/StateAttribute>
#include <osg/Material>
#include <osg/observer_ptr>
#include <osgAnimation/AnimationManagerBase>
#include <osgAnimation/Export>
namespace osgAnimation
{
class AnimationUpdateCallbackBase : public virtual osg::Object
{
public:
virtual bool link(osgAnimation::Channel* channel) = 0;
virtual int link(osgAnimation::Animation* animation) = 0;
};
template <class T>
class AnimationUpdateCallback : public AnimationUpdateCallbackBase, public T
{
public:
AnimationUpdateCallback() {}
AnimationUpdateCallback(const std::string& name) { T::setName(name);}
AnimationUpdateCallback(const AnimationUpdateCallback& apc,const osg::CopyOp& copyop):
T(apc, copyop) {}
META_Object(osgAnimation, AnimationUpdateCallback<T>);
const std::string& getName() const { return T::getName(); }
bool link(osgAnimation::Channel* channel) { return 0; }
int link(osgAnimation::Animation* animation)
{
if (T::getName().empty())
osg::notify(osg::WARN) << "An update callback has no name, it means it can link only with \"\" named Target, often an error" << std::endl;
int nbLinks = 0;
for (osgAnimation::ChannelList::iterator it = animation->getChannels().begin();
it != animation->getChannels().end();
it++)
{
std::string targetName = (*it)->getTargetName();
if (targetName == T::getName())
{
AnimationUpdateCallbackBase* a = this;
a->link((*it).get());
nbLinks++;
}
}
return nbLinks;
}
};
class OSGANIMATION_EXPORT UpdateTransform : public AnimationUpdateCallback<osg::NodeCallback>
{
protected:
osg::ref_ptr<osgAnimation::Vec3Target> _euler;
osg::ref_ptr<osgAnimation::Vec3Target> _position;
osg::ref_ptr<osgAnimation::Vec3Target> _scale;
public:
META_Object(osgAnimation, UpdateTransform);
UpdateTransform(const std::string& name = "");
UpdateTransform(const UpdateTransform& apc,const osg::CopyOp& copyop);
/** Callback method called by the NodeVisitor when visiting a node.*/
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
void update(osg::MatrixTransform& mat);
void update(osg::PositionAttitudeTransform& pat);
bool link(osgAnimation::Channel* channel);
osgAnimation::Vec3Target* getEuler() {return _euler.get();}
osgAnimation::Vec3Target* getPosition() {return _position.get();}
osgAnimation::Vec3Target* getScale() {return _scale.get();}
};
class OSGANIMATION_EXPORT UpdateMaterial : public AnimationUpdateCallback<osg::StateAttributeCallback>
{
protected:
osg::ref_ptr<osgAnimation::Vec4Target> _diffuse;
public:
META_Object(osgAnimation, UpdateMaterial);
UpdateMaterial(const std::string& name = "");
UpdateMaterial(const UpdateMaterial& apc,const osg::CopyOp& copyop);
/** Callback method called by the NodeVisitor when visiting a node.*/
virtual void operator () (osg::StateAttribute*, osg::NodeVisitor*);
void update(osg::Material& material);
bool link(osgAnimation::Channel* channel);
osgAnimation::Vec4Target* getDiffuse();
};
}
#endif

View File

@ -0,0 +1,46 @@
/* -*-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_UPDATE_MATERIAL
#define OSGANIMATION_UPDATE_MATERIAL 1
#include <osgAnimation/AnimationUpdateCallback>
#include <osgAnimation/Export>
#include <osg/StateAttribute>
#include <osg/Material>
namespace osgAnimation
{
class OSGANIMATION_EXPORT UpdateMaterial : public AnimationUpdateCallback<osg::StateAttributeCallback>
{
protected:
osg::ref_ptr<Vec4Target> _diffuse;
public:
META_Object(osgAnimation, UpdateMaterial);
UpdateMaterial(const std::string& name = "");
UpdateMaterial(const UpdateMaterial& apc,const osg::CopyOp& copyop);
/** Callback method called by the NodeVisitor when visiting a node.*/
virtual void operator () (osg::StateAttribute*, osg::NodeVisitor*);
void update(osg::Material& material);
bool link(Channel* channel);
Vec4Target* getDiffuse();
};
}
#endif

View File

@ -0,0 +1,48 @@
/* -*-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_UPDATE_MATRIX_TRANSFORM
#define OSGANIMATION_UPDATE_MATRIX_TRANSFORM 1
#include <osgAnimation/Export>
#include <osgAnimation/AnimationUpdateCallback>
#include <osgAnimation/StackedTransform>
#include <osg/NodeCallback>
namespace osgAnimation
{
class OSGANIMATION_EXPORT UpdateMatrixTransform : public AnimationUpdateCallback<osg::NodeCallback>
{
public:
META_Object(osgAnimation, UpdateMatrixTransform);
UpdateMatrixTransform(const std::string& name = "");
UpdateMatrixTransform(const UpdateMatrixTransform& apc,const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
// Callback method called by the NodeVisitor when visiting a node.
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
virtual bool link(osgAnimation::Channel* channel);
StackedTransform& getStackedTransforms() { return _transforms;}
const StackedTransform& getStackedTransforms() const { return _transforms;}
protected:
StackedTransform _transforms;
};
}
#endif

View File

@ -36,7 +36,7 @@ Action::Callback* Action::getFrameCallback(unsigned int frame)
void Action::removeCallback(Callback* cb) void Action::removeCallback(Callback* cb)
{ {
std::vector<unsigned int> keyToRemove; std::vector<unsigned int> keyToRemove;
for (FrameCallback::iterator it = _framesCallback.begin(); it != _framesCallback.end(); it++) for (FrameCallback::iterator it = _framesCallback.begin(); it != _framesCallback.end(); ++it)
{ {
if (it->second.get()) if (it->second.get())
{ {
@ -52,7 +52,7 @@ void Action::removeCallback(Callback* cb)
} }
} }
} }
for (std::vector<unsigned int>::iterator it = keyToRemove.begin(); it != keyToRemove.end(); it++) for (std::vector<unsigned int>::iterator it = keyToRemove.begin(); it != keyToRemove.end(); ++it)
_framesCallback.erase(*it); _framesCallback.erase(*it);
} }

View File

@ -24,7 +24,7 @@ Animation::Animation(const osgAnimation::Animation& anim, const osg::CopyOp& cop
_playmode(anim._playmode) _playmode(anim._playmode)
{ {
const ChannelList& cl = anim.getChannels(); const ChannelList& cl = anim.getChannels();
for (ChannelList::const_iterator it = cl.begin(); it != cl.end(); it++) for (ChannelList::const_iterator it = cl.begin(); it != cl.end(); ++it)
{ {
addChannel(it->get()->clone()); addChannel(it->get()->clone());
} }

View File

@ -28,7 +28,7 @@ AnimationManagerBase::AnimationManagerBase()
void AnimationManagerBase::clearTargets() void AnimationManagerBase::clearTargets()
{ {
for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); it++) for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); ++it)
(*it).get()->reset(); (*it).get()->reset();
} }
@ -67,7 +67,7 @@ AnimationManagerBase::AnimationManagerBase(const AnimationManagerBase& b, const
const AnimationList& animationList = b.getAnimationList(); const AnimationList& animationList = b.getAnimationList();
for (AnimationList::const_iterator it = animationList.begin(); for (AnimationList::const_iterator it = animationList.begin();
it != animationList.end(); it != animationList.end();
it++) ++it)
{ {
Animation* animation = dynamic_cast<osgAnimation::Animation*>(it->get()->clone(copyop)); Animation* animation = dynamic_cast<osgAnimation::Animation*>(it->get()->clone(copyop));
_animations.push_back(animation); _animations.push_back(animation);
@ -85,7 +85,7 @@ void AnimationManagerBase::buildTargetReference()
Animation* anim = (*iterAnim).get(); Animation* anim = (*iterAnim).get();
for (ChannelList::iterator it = anim->getChannels().begin(); for (ChannelList::iterator it = anim->getChannels().begin();
it != anim->getChannels().end(); it != anim->getChannels().end();
it++) ++it)
_targets.insert((*it)->getTarget()); _targets.insert((*it)->getTarget());
} }
} }

View File

@ -38,7 +38,7 @@ void BasicAnimationManager::stopAll()
for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim ) for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim )
{ {
AnimationList& list = iterAnim->second; AnimationList& list = iterAnim->second;
for (AnimationList::iterator it = list.begin(); it != list.end(); it++) for (AnimationList::iterator it = list.begin(); it != list.end(); ++it)
(*it)->resetTargets(); (*it)->resetTargets();
} }
_animationsPlaying.clear(); _animationsPlaying.clear();
@ -65,7 +65,7 @@ bool BasicAnimationManager::stopAnimation(Animation* pAnimation)
for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim ) for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim )
{ {
AnimationList& list = iterAnim->second; AnimationList& list = iterAnim->second;
for (AnimationList::iterator it = list.begin(); it != list.end(); it++) for (AnimationList::iterator it = list.begin(); it != list.end(); ++it)
if( (*it) == pAnimation ) if( (*it) == pAnimation )
{ {
(*it)->resetTargets(); (*it)->resetTargets();
@ -82,7 +82,7 @@ void BasicAnimationManager::update (double time)
_lastUpdate = time; // keep time of last update _lastUpdate = time; // keep time of last update
// could filtered with an active flag // could filtered with an active flag
for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); it++) for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); ++it)
(*it).get()->reset(); (*it).get()->reset();
// update from high priority to low priority // update from high priority to low priority
@ -132,7 +132,7 @@ bool BasicAnimationManager::isPlaying(Animation* pAnimation)
for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim ) for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim )
{ {
AnimationList& list = iterAnim->second; AnimationList& list = iterAnim->second;
for (AnimationList::iterator it = list.begin(); it != list.end(); it++) for (AnimationList::iterator it = list.begin(); it != list.end(); ++it)
if ( (*it) == pAnimation ) if ( (*it) == pAnimation )
return true; return true;
} }
@ -145,7 +145,7 @@ bool BasicAnimationManager::isPlaying(const std::string& name)
for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim ) for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim )
{ {
AnimationList& list = iterAnim->second; AnimationList& list = iterAnim->second;
for (AnimationList::iterator it = list.begin(); it != list.end(); it++) for (AnimationList::iterator it = list.begin(); it != list.end(); ++it)
if ( (*it)->getName() == name ) if ( (*it)->getName() == name )
return true; return true;
} }

View File

@ -14,94 +14,23 @@
#include <osgAnimation/Bone> #include <osgAnimation/Bone>
#include <osgAnimation/Skeleton> #include <osgAnimation/Skeleton>
#include <osgAnimation/FindParentAnimationManagerVisitor> #include <osgAnimation/UpdateBone>
#include <osgAnimation/BoneMapVisitor> #include <osgAnimation/BoneMapVisitor>
#include <osgAnimation/ComputeBindMatrixVisitor>
using namespace osgAnimation;
osgAnimation::Bone::UpdateBone::UpdateBone(const osgAnimation::Bone::UpdateBone& apc,const osg::CopyOp& copyop) : Bone::Bone(const Bone& b, const osg::CopyOp& copyop) : osg::MatrixTransform(b,copyop), _invBindInSkeletonSpace(b._invBindInSkeletonSpace), _boneInSkeletonSpace(b._boneInSkeletonSpace)
osg::Object(apc, copyop),
osgAnimation::AnimationUpdateCallback<osg::NodeCallback>(apc, copyop)
{
_quaternion = new osgAnimation::QuatTarget(apc._quaternion->getValue());
_position = new osgAnimation::Vec3Target(apc._position->getValue());
_scale = new osgAnimation::Vec3Target(apc._scale->getValue());
}
bool osgAnimation::Bone::UpdateBone::link(osgAnimation::Channel* channel)
{
if (channel->getName().find("quaternion") != std::string::npos)
{
return channel->setTarget(_quaternion.get());
}
else if (channel->getName().find("position") != std::string::npos)
{
return channel->setTarget(_position.get());
}
else if (channel->getName().find("scale") != std::string::npos)
{
return channel->setTarget(_scale.get());
}
else
{
osg::notify(osg::WARN) << "Channel " << channel->getName() << " does not contain a valid symbolic name for this class" << className() << std::endl;
}
return false;
}
/** Callback method called by the NodeVisitor when visiting a node.*/
void osgAnimation::Bone::UpdateBone::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
Bone* b = dynamic_cast<Bone*>(node);
if (!b)
{
osg::notify(osg::WARN) << "Warning: UpdateBone set on non-Bone object." << std::endl;
return;
}
if (b->needToComputeBindMatrix())
{
ComputeBindMatrixVisitor visitor;
b->accept(visitor);
}
update(*b);
Bone* parent = b->getBoneParent();
if (parent)
b->setMatrixInSkeletonSpace(b->getMatrixInBoneSpace() * parent->getMatrixInSkeletonSpace());
else
b->setMatrixInSkeletonSpace(b->getMatrixInBoneSpace());
}
traverse(node,nv);
}
osgAnimation::Bone::Bone(const Bone& b, const osg::CopyOp& copyop) :
osg::Transform(b,copyop),
_position(b._position),
_rotation(b._rotation),
_scale(b._scale),
_needToRecomputeBindMatrix(true),
_bindInBoneSpace(b._bindInBoneSpace),
_invBindInSkeletonSpace(b._invBindInSkeletonSpace),
_boneInSkeletonSpace(b._boneInSkeletonSpace)
{ {
} }
osgAnimation::Bone::Bone(const std::string& name) Bone::Bone(const std::string& name)
{ {
if (!name.empty()) if (!name.empty())
setName(name); setName(name);
_needToRecomputeBindMatrix = false;
} }
void osgAnimation::Bone::setDefaultUpdateCallback(const std::string& name) void Bone::setDefaultUpdateCallback(const std::string& name)
{ {
std::string cbName = name; std::string cbName = name;
if (cbName.empty()) if (cbName.empty())
@ -109,25 +38,12 @@ void osgAnimation::Bone::setDefaultUpdateCallback(const std::string& name)
setUpdateCallback(new UpdateBone(cbName)); setUpdateCallback(new UpdateBone(cbName));
} }
void osgAnimation::Bone::computeBindMatrix() Bone* Bone::getBoneParent()
{
_invBindInSkeletonSpace = osg::Matrix::inverse(_bindInBoneSpace);
const Bone* parent = getBoneParent();
_needToRecomputeBindMatrix = false;
if (!parent)
{
osg::notify(osg::WARN) << "Warning " << className() <<"::computeBindMatrix you should not have this message, it means you miss to attach this bone(" << getName() <<") to a Skeleton node" << std::endl;
return;
}
_invBindInSkeletonSpace = parent->getInvBindMatrixInSkeletonSpace() * _invBindInSkeletonSpace;
}
osgAnimation::Bone* osgAnimation::Bone::getBoneParent()
{ {
if (getParents().empty()) if (getParents().empty())
return 0; return 0;
osg::Node::ParentList parents = getParents(); osg::Node::ParentList parents = getParents();
for (osg::Node::ParentList::iterator it = parents.begin(); it != parents.end(); it++) for (osg::Node::ParentList::iterator it = parents.begin(); it != parents.end(); ++it)
{ {
Bone* pb = dynamic_cast<Bone*>(*it); Bone* pb = dynamic_cast<Bone*>(*it);
if (pb) if (pb)
@ -135,12 +51,12 @@ osgAnimation::Bone* osgAnimation::Bone::getBoneParent()
} }
return 0; return 0;
} }
const osgAnimation::Bone* osgAnimation::Bone::getBoneParent() const const Bone* Bone::getBoneParent() const
{ {
if (getParents().empty()) if (getParents().empty())
return 0; return 0;
const osg::Node::ParentList& parents = getParents(); const osg::Node::ParentList& parents = getParents();
for (osg::Node::ParentList::const_iterator it = parents.begin(); it != parents.end(); it++) for (osg::Node::ParentList::const_iterator it = parents.begin(); it != parents.end(); ++it)
{ {
const Bone* pb = dynamic_cast<const Bone*>(*it); const Bone* pb = dynamic_cast<const Bone*>(*it);
if (pb) if (pb)
@ -148,25 +64,3 @@ const osgAnimation::Bone* osgAnimation::Bone::getBoneParent() const
} }
return 0; return 0;
} }
/** Add Node to Group.
* If node is not NULL and is not contained in Group then increment its
* reference count, add it to the child list and dirty the bounding
* sphere to force it to recompute on next getBound() and return true for success.
* Otherwise return false. Scene nodes can't be added as child nodes.
*/
bool osgAnimation::Bone::addChild( Node *child )
{
Bone* bone = dynamic_cast<Bone*>(child);
if (bone)
bone->setNeedToComputeBindMatrix(true);
return osg::Group::addChild(child);
}
osgAnimation::Bone::BoneMap osgAnimation::Bone::getBoneMap()
{
BoneMapVisitor mapVisitor;
this->accept(mapVisitor);
return mapVisitor.getBoneMap();
}

View File

@ -16,20 +16,27 @@
*/ */
#include <osgAnimation/BoneMapVisitor> #include <osgAnimation/BoneMapVisitor>
#include <osgAnimation/Skeleton>
osgAnimation::BoneMapVisitor::BoneMapVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} using namespace osgAnimation;
void osgAnimation::BoneMapVisitor::apply(osg::Node&) { return; } BoneMapVisitor::BoneMapVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
void osgAnimation::BoneMapVisitor::apply(osg::Transform& node)
void BoneMapVisitor::apply(osg::Node&) { return; }
void BoneMapVisitor::apply(osg::Transform& node)
{ {
Bone* bone = dynamic_cast<Bone*>(&node); Bone* bone = dynamic_cast<Bone*>(&node);
if (bone) if (bone)
{ {
_map[bone->getName()] = bone; _map[bone->getName()] = bone;
traverse(node); traverse(node);
} }
Skeleton* skeleton = dynamic_cast<Skeleton*>(&node);
if (skeleton)
traverse(node);
} }
const osgAnimation::Bone::BoneMap& osgAnimation::BoneMapVisitor::getBoneMap() const
const BoneMap& BoneMapVisitor::getBoneMap() const
{ {
return _map; return _map;
} }

View File

@ -19,13 +19,13 @@ SET(LIB_PUBLIC_HEADERS
${HEADER_PATH}/ActionVisitor ${HEADER_PATH}/ActionVisitor
${HEADER_PATH}/Animation ${HEADER_PATH}/Animation
${HEADER_PATH}/AnimationManagerBase ${HEADER_PATH}/AnimationManagerBase
${HEADER_PATH}/AnimationUpdateCallback
${HEADER_PATH}/Assert ${HEADER_PATH}/Assert
${HEADER_PATH}/BasicAnimationManager ${HEADER_PATH}/BasicAnimationManager
${HEADER_PATH}/Bone ${HEADER_PATH}/Bone
${HEADER_PATH}/BoneMapVisitor ${HEADER_PATH}/BoneMapVisitor
${HEADER_PATH}/Channel ${HEADER_PATH}/Channel
${HEADER_PATH}/CubicBezier ${HEADER_PATH}/CubicBezier
${HEADER_PATH}/ComputeBindMatrixVisitor
${HEADER_PATH}/EaseMotion ${HEADER_PATH}/EaseMotion
${HEADER_PATH}/Export ${HEADER_PATH}/Export
${HEADER_PATH}/FindParentAnimationManagerVisitor ${HEADER_PATH}/FindParentAnimationManagerVisitor
@ -40,12 +40,21 @@ SET(LIB_PUBLIC_HEADERS
${HEADER_PATH}/RigTransformSoftware ${HEADER_PATH}/RigTransformSoftware
${HEADER_PATH}/Sampler ${HEADER_PATH}/Sampler
${HEADER_PATH}/Skeleton ${HEADER_PATH}/Skeleton
${HEADER_PATH}/StackedMatrixElement
${HEADER_PATH}/StackedQuaternionElement
${HEADER_PATH}/StackedRotateAxisElement
${HEADER_PATH}/StackedScaleElement
${HEADER_PATH}/StackedTransformElement
${HEADER_PATH}/StackedTranslateElement
${HEADER_PATH}/StackedTransform
${HEADER_PATH}/StatsVisitor ${HEADER_PATH}/StatsVisitor
${HEADER_PATH}/StatsHandler ${HEADER_PATH}/StatsHandler
${HEADER_PATH}/Target ${HEADER_PATH}/Target
${HEADER_PATH}/Timeline ${HEADER_PATH}/Timeline
${HEADER_PATH}/TimelineAnimationManager ${HEADER_PATH}/TimelineAnimationManager
${HEADER_PATH}/UpdateCallback ${HEADER_PATH}/UpdateBone
${HEADER_PATH}/UpdateMaterial
${HEADER_PATH}/UpdateMatrixTransform
${HEADER_PATH}/Vec3Packed ${HEADER_PATH}/Vec3Packed
${HEADER_PATH}/VertexInfluence ${HEADER_PATH}/VertexInfluence
) )
@ -74,12 +83,20 @@ ADD_LIBRARY(${LIB_NAME}
RigTransformHardware.cpp RigTransformHardware.cpp
RigTransformSoftware.cpp RigTransformSoftware.cpp
Skeleton.cpp Skeleton.cpp
StackedMatrixElement.cpp
StackedQuaternionElement.cpp
StackedRotateAxisElement.cpp
StackedScaleElement.cpp
StackedTransform.cpp
StackedTranslateElement.cpp
StatsVisitor.cpp StatsVisitor.cpp
StatsHandler.cpp StatsHandler.cpp
Target.cpp Target.cpp
TimelineAnimationManager.cpp TimelineAnimationManager.cpp
Timeline.cpp Timeline.cpp
UpdateCallback.cpp UpdateBone.cpp
UpdateMaterial.cpp
UpdateMatrixTransform.cpp
VertexInfluence.cpp VertexInfluence.cpp
${OPENSCENEGRAPH_VERSIONINFO_RC} ${OPENSCENEGRAPH_VERSIONINFO_RC}
) )

View File

@ -13,7 +13,7 @@
*/ */
#include <osgAnimation/LinkVisitor> #include <osgAnimation/LinkVisitor>
#include <osgAnimation/UpdateCallback> #include <osgAnimation/AnimationUpdateCallback>
#include <osg/Notify> #include <osg/Notify>
#include <osg/Geode> #include <osg/Geode>
@ -33,7 +33,7 @@ AnimationList& LinkVisitor::getAnimationList()
{ {
return _animations; return _animations;
} }
void LinkVisitor::link(osgAnimation::AnimationUpdateCallbackBase* cb) void LinkVisitor::link(AnimationUpdateCallbackBase* cb)
{ {
int result = 0; int result = 0;
for (int i = 0; i < (int)_animations.size(); i++) for (int i = 0; i < (int)_animations.size(); i++)
@ -49,7 +49,7 @@ void LinkVisitor::handle_stateset(osg::StateSet* stateset)
if (!stateset) if (!stateset)
return; return;
osg::StateSet::AttributeList& attr = stateset->getAttributeList(); osg::StateSet::AttributeList& attr = stateset->getAttributeList();
for (osg::StateSet::AttributeList::iterator it = attr.begin(); it != attr.end(); it++) for (osg::StateSet::AttributeList::iterator it = attr.begin(); it != attr.end(); ++it)
{ {
osg::StateAttribute* sattr = it->second.first.get(); osg::StateAttribute* sattr = it->second.first.get();
osgAnimation::AnimationUpdateCallbackBase* cb = dynamic_cast<osgAnimation::AnimationUpdateCallbackBase*>(sattr->getUpdateCallback()); osgAnimation::AnimationUpdateCallbackBase* cb = dynamic_cast<osgAnimation::AnimationUpdateCallbackBase*>(sattr->getUpdateCallback());

View File

@ -261,18 +261,13 @@ bool UpdateMorph::link(osgAnimation::Channel* channel)
if (weightIndex >= 0) if (weightIndex >= 0)
{ {
osgAnimation::FloatLinearChannel* fc = dynamic_cast<osgAnimation::FloatLinearChannel*>(channel); osgAnimation::FloatTarget* ft = _weightTargets[weightIndex].get();
if (fc) if (!ft)
{ {
osgAnimation::FloatTarget* ft = _weightTargets[weightIndex].get(); ft = new osgAnimation::FloatTarget;
if (ft == 0) _weightTargets[weightIndex] = ft;
{
ft = new osgAnimation::FloatTarget;
_weightTargets[weightIndex] = ft;
}
fc->setTarget(ft);
return true;
} }
return channel->setTarget(ft);
} }
else else
{ {

View File

@ -12,6 +12,7 @@
* OpenSceneGraph Public License for more details. * OpenSceneGraph Public License for more details.
*/ */
#include <osgAnimation/VertexInfluence>
#include <osgAnimation/RigGeometry> #include <osgAnimation/RigGeometry>
#include <osgAnimation/RigTransformSoftware> #include <osgAnimation/RigTransformSoftware>
#include <sstream> #include <sstream>
@ -71,21 +72,10 @@ RigGeometry::RigGeometry()
setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback); setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback);
} }
RigGeometry::RigGeometry(const osg::Geometry& b) : osg::Geometry(b, osg::CopyOp::SHALLOW_COPY)
{
_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 RigComputeBoundingBoxCallback);
}
RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) : RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) :
osg::Geometry(b,copyop), osg::Geometry(b,copyop),
_geometry(b._geometry),
_vertexInfluenceSet(b._vertexInfluenceSet), _vertexInfluenceSet(b._vertexInfluenceSet),
_vertexInfluenceMap(b._vertexInfluenceMap), _vertexInfluenceMap(b._vertexInfluenceMap),
_needToComputeMatrix(b._needToComputeMatrix) _needToComputeMatrix(b._needToComputeMatrix)
@ -114,7 +104,7 @@ void RigGeometry::buildVertexInfluenceSet()
_vertexInfluenceSet.clear(); _vertexInfluenceSet.clear();
for (osgAnimation::VertexInfluenceMap::iterator it = _vertexInfluenceMap->begin(); for (osgAnimation::VertexInfluenceMap::iterator it = _vertexInfluenceMap->begin();
it != _vertexInfluenceMap->end(); it != _vertexInfluenceMap->end();
it++) ++it)
_vertexInfluenceSet.addVertexInfluence(it->second); _vertexInfluenceSet.addVertexInfluence(it->second);
_vertexInfluenceSet.buildVertex2BoneList(); _vertexInfluenceSet.buildVertex2BoneList();
@ -130,7 +120,8 @@ void RigGeometry::computeMatrixFromRootSkeleton()
return; return;
} }
osg::MatrixList mtxList = getParent(0)->getWorldMatrices(_root.get()); osg::MatrixList mtxList = getParent(0)->getWorldMatrices(_root.get());
_matrixFromSkeletonToGeometry = mtxList[0]; osg::Matrix notRoot = _root->getMatrix();
_matrixFromSkeletonToGeometry = mtxList[0] * osg::Matrix::inverse(notRoot);
_invMatrixFromSkeletonToGeometry = osg::Matrix::inverse(_matrixFromSkeletonToGeometry); _invMatrixFromSkeletonToGeometry = osg::Matrix::inverse(_matrixFromSkeletonToGeometry);
_needToComputeMatrix = false; _needToComputeMatrix = false;
} }
@ -142,10 +133,67 @@ void RigGeometry::update()
_rigTransformImplementation = new RigTransformSoftware; _rigTransformImplementation = new RigTransformSoftware;
} }
if (getRigTransformImplementation()->needInit()) RigTransform& implementation = *getRigTransformImplementation();
if (!getRigTransformImplementation()->init(*this)) (implementation)(*this);
return; }
getRigTransformImplementation()->update(*this);
void RigGeometry::copyFrom(osg::Geometry& from)
{
bool copyToSelf = (this==&from);
osg::Geometry& target = *this;
if (!copyToSelf) target.setStateSet(from.getStateSet());
// copy over primitive sets.
if (!copyToSelf) target.getPrimitiveSetList() = from.getPrimitiveSetList();
if (from.getVertexArray())
{
if (!copyToSelf) target.setVertexArray(from.getVertexArray());
}
target.setNormalBinding(from.getNormalBinding());
if (from.getNormalArray())
{
if (!copyToSelf) target.setNormalArray(from.getNormalArray());
}
target.setColorBinding(from.getColorBinding());
if (from.getColorArray())
{
if (!copyToSelf) target.setColorArray(from.getColorArray());
}
target.setSecondaryColorBinding(from.getSecondaryColorBinding());
if (from.getSecondaryColorArray())
{
if (!copyToSelf) target.setSecondaryColorArray(from.getSecondaryColorArray());
}
target.setFogCoordBinding(from.getFogCoordBinding());
if (from.getFogCoordArray())
{
if (!copyToSelf) target.setFogCoordArray(from.getFogCoordArray());
}
for(unsigned int ti=0;ti<from.getNumTexCoordArrays();++ti)
{
if (from.getTexCoordArray(ti))
{
if (!copyToSelf) target.setTexCoordArray(ti,from.getTexCoordArray(ti));
}
}
ArrayDataList& arrayList = from.getVertexAttribArrayList();
for(unsigned int vi=0;vi< arrayList.size();++vi)
{
ArrayData& arrayData = arrayList[vi];
if (arrayData.array.valid())
{
if (!copyToSelf) target.setVertexAttribData(vi,arrayData);
}
}
} }
const VertexInfluenceSet& RigGeometry::getVertexInfluenceSet() const { return _vertexInfluenceSet;} const VertexInfluenceSet& RigGeometry::getVertexInfluenceSet() const { return _vertexInfluenceSet;}
@ -155,3 +203,7 @@ Skeleton* RigGeometry::getSkeleton() { return _root.get(); }
void RigGeometry::setSkeleton(Skeleton* root) { _root = root;} void RigGeometry::setSkeleton(Skeleton* root) { _root = root;}
RigTransform* RigGeometry::getRigTransformImplementation() { return _rigTransformImplementation.get(); } RigTransform* RigGeometry::getRigTransformImplementation() { return _rigTransformImplementation.get(); }
void RigGeometry::setRigTransformImplementation(RigTransform* rig) { _rigTransformImplementation = rig; } void RigGeometry::setRigTransformImplementation(RigTransform* rig) { _rigTransformImplementation = rig; }
osg::Geometry* RigGeometry::getSourceGeometry() { return _geometry.get(); }
const osg::Geometry* RigGeometry::getSourceGeometry() const { return _geometry.get(); }
void RigGeometry::setSourceGeometry(osg::Geometry* geometry) { _geometry = geometry; }

View File

@ -14,10 +14,19 @@
#include <osgAnimation/RigTransformHardware> #include <osgAnimation/RigTransformHardware>
#include <osgAnimation/RigGeometry> #include <osgAnimation/RigGeometry>
#include <osgAnimation/BoneMapVisitor>
#include <sstream> #include <sstream>
using namespace osgAnimation; using namespace osgAnimation;
RigTransformHardware::RigTransformHardware()
{
_needInit = true;
_bonesPerVertex = 0;
_nbVertexes = 0;
}
osg::Vec4Array* RigTransformHardware::getVertexAttrib(int index) osg::Vec4Array* RigTransformHardware::getVertexAttrib(int index)
{ {
if (index >= (int)_boneWeightAttribArrays.size()) if (index >= (int)_boneWeightAttribArrays.size())
@ -67,12 +76,12 @@ bool RigTransformHardware::createPalette(int nbVertexes, BoneMap boneMap, const
vertexIndexWeight.resize(nbVertexes); vertexIndexWeight.resize(nbVertexes);
int maxBonePerVertex = 0; int maxBonePerVertex = 0;
for (VertexInfluenceSet::VertexIndexToBoneWeightMap::const_iterator it = vertexIndexToBoneWeightMap.begin(); it != vertexIndexToBoneWeightMap.end(); it++) for (VertexInfluenceSet::VertexIndexToBoneWeightMap::const_iterator it = vertexIndexToBoneWeightMap.begin(); it != vertexIndexToBoneWeightMap.end(); ++it)
{ {
int vertexIndex = it->first; int vertexIndex = it->first;
const VertexInfluenceSet::BoneWeightList& boneWeightList = it->second; const VertexInfluenceSet::BoneWeightList& boneWeightList = it->second;
int bonesForThisVertex = 0; int bonesForThisVertex = 0;
for (VertexInfluenceSet::BoneWeightList::const_iterator it = boneWeightList.begin(); it != boneWeightList.end(); it++) for (VertexInfluenceSet::BoneWeightList::const_iterator it = boneWeightList.begin(); it != boneWeightList.end(); ++it)
{ {
const VertexInfluenceSet::BoneWeight& bw = *it; const VertexInfluenceSet::BoneWeight& bw = *it;
if (boneNameCountMap.find(bw.getBoneName()) != boneNameCountMap.end()) if (boneNameCountMap.find(bw.getBoneName()) != boneNameCountMap.end())
@ -85,7 +94,7 @@ bool RigTransformHardware::createPalette(int nbVertexes, BoneMap boneMap, const
{ {
if (boneMap.find(bw.getBoneName()) == boneMap.end()) if (boneMap.find(bw.getBoneName()) == boneMap.end())
{ {
osg::notify(osg::WARN) << "RigTransformHardware::createPalette can't find bone " << bw.getBoneName() << " skip this influence" << std::endl; osg::notify(osg::INFO) << "RigTransformHardware::createPalette can't find bone " << bw.getBoneName() << " skip this influence" << std::endl;
continue; continue;
} }
boneNameCountMap[bw.getBoneName()] = 1; // for stats boneNameCountMap[bw.getBoneName()] = 1; // for stats
@ -104,7 +113,7 @@ bool RigTransformHardware::createPalette(int nbVertexes, BoneMap boneMap, const
osg::notify(osg::INFO) << "RigTransformHardware::createPalette maximum number of bone per vertex is " << maxBonePerVertex << std::endl; 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; osg::notify(osg::INFO) << "RigTransformHardware::createPalette matrix palette has " << boneNameCountMap.size() << " entries" << std::endl;
for (BoneNameCountMap::iterator it = boneNameCountMap.begin(); it != boneNameCountMap.end(); it++) 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 Bone " << it->first << " is used " << it->second << " times" << std::endl;
} }
@ -186,20 +195,30 @@ void RigTransformHardware::setShader(osg::Shader* shader)
bool RigTransformHardware::init(RigGeometry& geom) bool RigTransformHardware::init(RigGeometry& geom)
{ {
osg::Vec3Array* pos = dynamic_cast<osg::Vec3Array*>(geom.getVertexArray()); osg::Geometry& source = *geom.getSourceGeometry();
if (!pos) { osg::Vec3Array* positionSrc = dynamic_cast<osg::Vec3Array*>(source.getVertexArray());
if (!positionSrc)
{
osg::notify(osg::WARN) << "RigTransformHardware no vertex array in the geometry " << geom.getName() << std::endl; osg::notify(osg::WARN) << "RigTransformHardware no vertex array in the geometry " << geom.getName() << std::endl;
return false; return false;
} }
if (!geom.getSkeleton()) { if (!geom.getSkeleton())
osg::notify(osg::WARN) << "RigTransformHardware no skeleting set in geometry " << geom.getName() << std::endl; {
osg::notify(osg::WARN) << "RigTransformHardware no skeleton set in geometry " << geom.getName() << std::endl;
return false; return false;
} }
Bone::BoneMap bm = geom.getSkeleton()->getBoneMap();
if (!createPalette(pos->size(),bm, geom.getVertexInfluenceSet().getVertexToBoneList())) // copy shallow from source geometry to rig
geom.copyFrom(source);
BoneMapVisitor mapVisitor;
geom.getSkeleton()->accept(mapVisitor);
BoneMap bm = mapVisitor.getBoneMap();
if (!createPalette(positionSrc->size(),bm, geom.getVertexInfluenceSet().getVertexToBoneList()))
return false; return false;
osg::ref_ptr<osg::Program> program = new osg::Program; osg::ref_ptr<osg::Program> program = new osg::Program;
@ -244,7 +263,10 @@ bool RigTransformHardware::init(RigGeometry& geom)
_needInit = false; _needInit = false;
return true; return true;
} }
void RigTransformHardware::update(RigGeometry& geom) void RigTransformHardware::operator()(RigGeometry& geom)
{ {
if (_needInit)
if (!init(geom))
return;
computeMatrixPaletteUniform(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry()); computeMatrixPaletteUniform(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry());
} }

View File

@ -13,49 +13,92 @@
*/ */
#include <osgAnimation/VertexInfluence>
#include <osgAnimation/RigTransformSoftware> #include <osgAnimation/RigTransformSoftware>
#include <osgAnimation/BoneMapVisitor>
#include <osgAnimation/RigGeometry> #include <osgAnimation/RigGeometry>
using namespace osgAnimation; using namespace osgAnimation;
RigTransformSoftware::RigTransformSoftware()
{
_needInit = true;
}
bool RigTransformSoftware::init(RigGeometry& geom) bool RigTransformSoftware::init(RigGeometry& geom)
{ {
if (!geom.getSkeleton()) if (!geom.getSkeleton())
return false; return false;
Bone::BoneMap bm = geom.getSkeleton()->getBoneMap();
BoneMapVisitor mapVisitor;
geom.getSkeleton()->accept(mapVisitor);
BoneMap bm = mapVisitor.getBoneMap();
initVertexSetFromBones(bm, geom.getVertexInfluenceSet().getUniqVertexSetToBoneSetList()); initVertexSetFromBones(bm, geom.getVertexInfluenceSet().getUniqVertexSetToBoneSetList());
geom.copyFrom(*geom.getSourceGeometry());
geom.setVertexArray(0);
geom.setNormalArray(0);
_needInit = false; _needInit = false;
return true; return true;
} }
void RigTransformSoftware::update(RigGeometry& geom) void RigTransformSoftware::operator()(RigGeometry& geom)
{ {
osg::Vec3Array* pos = dynamic_cast<osg::Vec3Array*>(geom.getVertexArray()); if (_needInit)
if (pos && _positionSource.size() != pos->size()) if (!init(geom))
return;
osg::Geometry& source = *geom.getSourceGeometry();
osg::Geometry& destination = geom;
osg::Vec3Array* positionSrc = dynamic_cast<osg::Vec3Array*>(source.getVertexArray());
osg::Vec3Array* positionDst = dynamic_cast<osg::Vec3Array*>(destination.getVertexArray());
if (positionSrc && (!positionDst || (positionDst->size() != positionSrc->size()) ) )
{ {
_positionSource = std::vector<osg::Vec3>(pos->begin(),pos->end()); if (!positionDst)
geom.getVertexArray()->setDataVariance(osg::Object::DYNAMIC); {
positionDst = new osg::Vec3Array;
positionDst->setDataVariance(osg::Object::DYNAMIC);
destination.setVertexArray(positionDst);
}
*positionDst = *positionSrc;
} }
osg::Vec3Array* normal = dynamic_cast<osg::Vec3Array*>(geom.getNormalArray());
if (normal && _normalSource.size() != normal->size()) osg::Vec3Array* normalSrc = dynamic_cast<osg::Vec3Array*>(source.getNormalArray());
osg::Vec3Array* normalDst = dynamic_cast<osg::Vec3Array*>(destination.getNormalArray());
if (normalSrc && (!normalDst || (normalDst->size() != normalSrc->size()) ) )
{ {
_normalSource = std::vector<osg::Vec3>(normal->begin(),normal->end()); if (!normalDst)
geom.getNormalArray()->setDataVariance(osg::Object::DYNAMIC); {
normalDst = new osg::Vec3Array;
normalDst->setDataVariance(osg::Object::DYNAMIC);
destination.setNormalArray(normalDst);
destination.setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
}
*normalDst = *normalSrc;
} }
if (!_positionSource.empty()) if (positionDst && !positionDst->empty())
{ {
compute<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry(), &_positionSource.front(), &pos->front()); compute<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(),
pos->dirty(); geom.getInvMatrixFromSkeletonToGeometry(),
&positionSrc->front(),
&positionDst->front());
positionDst->dirty();
} }
if (!_normalSource.empty())
if (normalDst && !normalDst->empty())
{ {
computeNormal<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry(), &_normalSource.front(), &normal->front()); computeNormal<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(),
normal->dirty(); geom.getInvMatrixFromSkeletonToGeometry(),
&normalSrc->front(),
&normalDst->front());
normalDst->dirty();
} }
} }
void RigTransformSoftware::initVertexSetFromBones(const Bone::BoneMap& map, const VertexInfluenceSet::UniqVertexSetToBoneSetList& influence) void RigTransformSoftware::initVertexSetFromBones(const BoneMap& map, const VertexInfluenceSet::UniqVertexSetToBoneSetList& influence)
{ {
_boneSetVertexSet.clear(); _boneSetVertexSet.clear();
@ -72,7 +115,7 @@ void RigTransformSoftware::initVertexSetFromBones(const Bone::BoneMap& map, cons
{ {
const std::string& bname = inf.getBones()[b].getBoneName(); const std::string& bname = inf.getBones()[b].getBoneName();
float weight = inf.getBones()[b].getWeight(); float weight = inf.getBones()[b].getWeight();
Bone::BoneMap::const_iterator it = map.find(bname); BoneMap::const_iterator it = map.find(bname);
if (it == map.end()) if (it == map.end())
{ {
osg::notify(osg::WARN) << "RigTransformSoftware Bone " << bname << " not found, skip the influence group " <<bname << std::endl; osg::notify(osg::WARN) << "RigTransformSoftware Bone " << bname << " not found, skip the influence group " <<bname << std::endl;

View File

@ -14,14 +14,15 @@
#include <osgAnimation/Skeleton> #include <osgAnimation/Skeleton>
#include <osgAnimation/Bone> #include <osgAnimation/Bone>
#include <osg/Notify>
using namespace osgAnimation; using namespace osgAnimation;
Skeleton::Skeleton() {} Skeleton::Skeleton() {}
Skeleton::Skeleton(const Skeleton& b, const osg::CopyOp& copyop) : Bone(b,copyop) {} Skeleton::Skeleton(const Skeleton& b, const osg::CopyOp& copyop) : osg::MatrixTransform(b,copyop) {}
Skeleton::UpdateSkeleton::UpdateSkeleton() : _needValidate(true) {} Skeleton::UpdateSkeleton::UpdateSkeleton() : _needValidate(true) {}
Skeleton::UpdateSkeleton::UpdateSkeleton(const UpdateSkeleton& us, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) : osg::Object(us, copyop), osg::NodeCallback(us, copyop) Skeleton::UpdateSkeleton::UpdateSkeleton(const UpdateSkeleton& us, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) : osg::Object(us, copyop), osg::NodeCallback(us, copyop)
{ {
_needValidate = true; _needValidate = true;
} }
@ -45,7 +46,7 @@ public:
bool foundNonBone = false; bool foundNonBone = false;
for (unsigned i = 0; i < bone->getNumChildren(); ++i) for (unsigned int i = 0; i < bone->getNumChildren(); ++i)
{ {
if (dynamic_cast<Bone*>(bone->getChild(i))) if (dynamic_cast<Bone*>(bone->getChild(i)))
{ {
@ -76,11 +77,13 @@ void Skeleton::UpdateSkeleton::operator()(osg::Node* node, osg::NodeVisitor* nv)
if (_needValidate && skeleton) if (_needValidate && skeleton)
{ {
ValidateSkeletonVisitor visitor; ValidateSkeletonVisitor visitor;
node->accept(visitor); for (unsigned int i = 0; i < skeleton->getNumChildren(); ++i)
{
osg::Node* child = skeleton->getChild(i);
child->accept(visitor);
}
_needValidate = false; _needValidate = false;
} }
if (skeleton->needToComputeBindMatrix())
skeleton->computeBindMatrix();
} }
traverse(node,nv); traverse(node,nv);
} }
@ -89,9 +92,3 @@ void Skeleton::setDefaultUpdateCallback()
{ {
setUpdateCallback(new Skeleton::UpdateSkeleton ); setUpdateCallback(new Skeleton::UpdateSkeleton );
} }
void Skeleton::computeBindMatrix()
{
_invBindInSkeletonSpace = osg::Matrix::inverse(_bindInBoneSpace);
_needToRecomputeBindMatrix = false;
}

View 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.
*/
#include <osgAnimation/StackedMatrixElement>
using namespace osgAnimation;
StackedMatrixElement::StackedMatrixElement() {}
StackedMatrixElement::StackedMatrixElement(const std::string& name, const osg::Matrix& matrix) : StackedTransformElement(), _matrix(matrix) { setName(name); }
StackedMatrixElement::StackedMatrixElement(const osg::Matrix& matrix) : _matrix(matrix) { setName("matrix"); }
StackedMatrixElement::StackedMatrixElement(const StackedMatrixElement& rhs, const osg::CopyOp& c) : StackedTransformElement(rhs, c), _matrix(rhs._matrix)
{
if (rhs._target.valid())
_target = new MatrixTarget(*rhs._target);
}
Target* StackedMatrixElement::getOrCreateTarget()
{
if (!_target.valid())
_target = new MatrixTarget(_matrix);
return _target.get();
}
void StackedMatrixElement::update()
{
if (_target.valid())
_matrix = _target->getValue();
}

View File

@ -0,0 +1,53 @@
/* -*-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/StackedQuaternionElement>
using namespace osgAnimation;
StackedQuaternionElement::StackedQuaternionElement(const std::string& name, const osg::Quat& quaternion) : _quaternion(quaternion) { setName(name); }
StackedQuaternionElement::StackedQuaternionElement(const StackedQuaternionElement& rhs, const osg::CopyOp&) : StackedTransformElement(rhs), _quaternion(rhs._quaternion)
{
if (rhs._target.valid())
_target = new QuatTarget(*rhs._target);
}
StackedQuaternionElement::StackedQuaternionElement(const osg::Quat& quat) : _quaternion(quat) { setName("quaternion"); }
StackedQuaternionElement::StackedQuaternionElement()
{
}
const osg::Quat& StackedQuaternionElement::getQuaternion() const { return _quaternion; }
void StackedQuaternionElement::setQuaternion(const osg::Quat& q) { _quaternion = q; }
void StackedQuaternionElement::applyToMatrix(osg::Matrix& matrix) const {matrix.preMultRotate(_quaternion);}
osg::Matrix StackedQuaternionElement::getAsMatrix() const { return osg::Matrix(_quaternion); }
bool StackedQuaternionElement::isIdentity() const { return (_quaternion[0] == 0 && _quaternion[1] == 0 && _quaternion[2] == 0 && _quaternion[3] == 1.0); }
void StackedQuaternionElement::update()
{
if (_target.valid())
_quaternion = _target->getValue();
}
Target* StackedQuaternionElement::getOrCreateTarget()
{
if (!_target.valid())
_target = new QuatTarget(_quaternion);
return _target.get();
}
Target* StackedQuaternionElement::getTarget() {return _target.get();}
const Target* StackedQuaternionElement::getTarget() const {return _target.get();}

View File

@ -0,0 +1,55 @@
/* -*-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/StackedRotateAxisElement>
using namespace osgAnimation;
StackedRotateAxisElement::StackedRotateAxisElement(const std::string& name, const osg::Vec3& axis, double angle) : StackedTransformElement(), _axis(axis), _angle(angle) { setName(name); }
StackedRotateAxisElement::StackedRotateAxisElement(const osg::Vec3& axis, double angle) : _axis(axis), _angle(angle) { setName("rotateaxis"); }
StackedRotateAxisElement::StackedRotateAxisElement() {}
StackedRotateAxisElement::StackedRotateAxisElement(const StackedRotateAxisElement& rhs, const osg::CopyOp&) : StackedTransformElement(rhs), _axis(rhs._axis), _angle(rhs._angle)
{
if (rhs._target.valid())
_target = new FloatTarget(*rhs._target);
}
osg::Matrix StackedRotateAxisElement::getAsMatrix() const { return osg::Matrix::rotate(osg::Quat(_angle, _axis)); }
void StackedRotateAxisElement::update()
{
if (_target.valid())
_angle = _target->getValue();
}
const osg::Vec3& StackedRotateAxisElement::getAxis() const { return _axis; }
const double StackedRotateAxisElement::getAngle() const { return _angle; }
void StackedRotateAxisElement::setAxis(const osg::Vec3& axis)
{
_axis = axis;
}
void StackedRotateAxisElement::setAngle(const double& angle)
{
_angle = angle;
}
Target* StackedRotateAxisElement::getOrCreateTarget()
{
if (!_target.valid())
_target = new FloatTarget(_angle);
return _target.get();
}
void StackedRotateAxisElement::applyToMatrix(osg::Matrix& matrix) const { matrix.preMultRotate(osg::Quat(_angle, _axis)); }

View File

@ -0,0 +1,56 @@
/* -*-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/StackedScaleElement>
using namespace osgAnimation;
StackedScaleElement::StackedScaleElement(const std::string& name, const osg::Vec3& scale) : _scale(scale) { setName(name); }
StackedScaleElement::StackedScaleElement(const osg::Vec3& scale) : _scale(scale) { setName("scale"); }
StackedScaleElement::StackedScaleElement(const StackedScaleElement& rhs, const osg::CopyOp&) : StackedTransformElement(rhs), _scale(rhs._scale)
{
if (rhs._target.valid())
_target = new Vec3Target(*rhs._target);
}
const osg::Vec3& StackedScaleElement::getScale() const { return _scale; }
void StackedScaleElement::setScale(const osg::Vec3& scale) { _scale = scale; }
Target* StackedScaleElement::getTarget() {return _target.get();}
const Target* StackedScaleElement::getTarget() const {return _target.get();}
bool StackedScaleElement::isIdentity() const { return (_scale.x() == 1 && _scale.y() == 1 && _scale.z() == 1); }
osg::Matrix StackedScaleElement::getAsMatrix() const { return osg::Matrix::scale(_scale); }
void StackedScaleElement::applyToMatrix(osg::Matrix& matrix) const { matrix.preMultScale(_scale); }
StackedScaleElement::StackedScaleElement()
{
_scale = osg::Vec3(1,1,1);
}
void StackedScaleElement::update()
{
if (_target.valid())
_scale = _target->getValue();
}
Target* StackedScaleElement::getOrCreateTarget()
{
if (!_target.valid())
_target = new Vec3Target(_scale);
return _target.get();
}

View File

@ -0,0 +1,66 @@
/* -*-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/StackedTransform>
using namespace osgAnimation;
StackedTransform::StackedTransform() {}
StackedTransform::StackedTransform(const StackedTransform& rhs, const osg::CopyOp& co)
{
reserve(rhs.size());
for (StackedTransform::const_iterator it = rhs.begin(); it != rhs.end(); ++it)
{
const StackedTransformElement* element = *it;
if (element)
push_back(osg::clone(element,co));
}
}
void StackedTransform::update()
{
int dirty = 0;
for (StackedTransform::iterator it = begin(); it != end(); ++it)
{
StackedTransformElement* element = *it;
if (!element)
continue;
// update and check if there are changes
element->update();
if (element->isIdentity())
continue;
dirty++;
}
if (!dirty)
return;
// dirty update matrix
_matrix.makeIdentity();
for (StackedTransform::iterator it = begin(); it != end(); ++it)
{
StackedTransformElement* element = *it;
if (!element || element->isIdentity())
continue;
element->applyToMatrix(_matrix);
}
}
const osg::Matrix& StackedTransform::getMatrix() const
{
return _matrix;
}

View File

@ -0,0 +1,50 @@
/* -*-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/StackedTranslateElement>
using namespace osgAnimation;
StackedTranslateElement::StackedTranslateElement(const std::string& name, const osg::Vec3& translate) : _translate(translate) { setName(name); }
StackedTranslateElement::StackedTranslateElement(const osg::Vec3& translate) : _translate(translate) { setName("translate"); }
StackedTranslateElement::StackedTranslateElement() {}
StackedTranslateElement::StackedTranslateElement(const StackedTranslateElement& rhs, const osg::CopyOp&) : StackedTransformElement(rhs), _translate(rhs._translate)
{
if (rhs._target.valid())
_target = new Vec3Target(*rhs._target);
}
void StackedTranslateElement::applyToMatrix(osg::Matrix& matrix) const {matrix.preMultTranslate(_translate);}
osg::Matrix StackedTranslateElement::getAsMatrix() const { return osg::Matrix::translate(_translate); }
bool StackedTranslateElement::isIdentity() const { return (_translate[0] == 0 && _translate[1] == 0 && _translate[2] == 0); }
const osg::Vec3& StackedTranslateElement::getTranslate() const { return _translate; }
void StackedTranslateElement::setTranslate(const osg::Vec3& value) { _translate = value; }
Target* StackedTranslateElement::getOrCreateTarget()
{
if (!_target.valid())
_target = new Vec3Target(_translate);
return _target.get();
}
Target* StackedTranslateElement::getTarget() {return _target.get();}
const Target* StackedTranslateElement::getTarget() const {return _target.get();}
void StackedTranslateElement::update()
{
if (_target.valid())
_translate = _target->getValue();
}

View File

@ -424,7 +424,7 @@ struct ValueTextDrawCallback : public virtual osg::Drawable::DrawCallback
osg::Vec3 pos(leftPos, _statsHeight-24.0f,0.0f); osg::Vec3 pos(leftPos, _statsHeight-24.0f,0.0f);
pos.y() -= characterSize *2 + backgroundMargin; pos.y() -= characterSize *2 + backgroundMargin;
for (std::map<std::string, StatAction >::iterator it = _actions.begin(); it != _actions.end(); it++) { for (std::map<std::string, StatAction >::iterator it = _actions.begin(); it != _actions.end(); ++it) {
(*it).second._group->setNodeMask(~osg::Node::NodeMask(1)); (*it).second._group->setNodeMask(~osg::Node::NodeMask(1));
} }

View File

@ -210,7 +210,7 @@ void Timeline::processPendingOperation()
void Timeline::internalRemoveAction(Action* action) void Timeline::internalRemoveAction(Action* action)
{ {
for (ActionLayers::iterator it = _actions.begin(); it != _actions.end(); it++) for (ActionLayers::iterator it = _actions.begin(); it != _actions.end(); ++it)
{ {
ActionList& fa = it->second; ActionList& fa = it->second;
for (unsigned int i = 0; i < fa.size(); i++) for (unsigned int i = 0; i < fa.size(); i++)

View File

@ -0,0 +1,54 @@
/* -*-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 <osg/NodeVisitor>
#include <osgAnimation/Bone>
#include <osgAnimation/UpdateBone>
using namespace osgAnimation;
UpdateBone::UpdateBone(const std::string& name) : UpdateMatrixTransform(name)
{
}
UpdateBone::UpdateBone(const UpdateBone& apc,const osg::CopyOp& copyop) : osg::Object(apc,copyop), UpdateMatrixTransform(apc, copyop)
{
}
/** Callback method called by the NodeVisitor when visiting a node.*/
void UpdateBone::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
Bone* b = dynamic_cast<Bone*>(node);
if (!b)
{
osg::notify(osg::WARN) << "Warning: UpdateBone set on non-Bone object." << std::endl;
return;
}
// here we would prefer to have a flag inside transform stack in order to avoid update and a dirty state in matrixTransform if it's not require.
_transforms.update();
const osg::Matrix& matrix = _transforms.getMatrix();
b->setMatrix(matrix);
Bone* parent = b->getBoneParent();
if (parent)
b->setMatrixInSkeletonSpace(b->getMatrixInBoneSpace() * parent->getMatrixInSkeletonSpace());
else
b->setMatrixInSkeletonSpace(b->getMatrixInBoneSpace());
}
traverse(node,nv);
}

View File

@ -1,162 +0,0 @@
/* -*-c++-*-
* 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
* (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.
*
* Authors:
* Cedric Pinson <cedric.pinson@plopbyte.net>
* Michael Platings <mplatings@pixelpower.com>
*/
#include <osgAnimation/UpdateCallback>
#include <osg/MatrixTransform>
#include <osg/PositionAttitudeTransform>
#include <osg/Math>
using namespace osgAnimation;
UpdateTransform::UpdateTransform(const UpdateTransform& apc,const osg::CopyOp& copyop)
: osg::Object(apc, copyop),
AnimationUpdateCallback<osg::NodeCallback>(apc, copyop)
{
_euler = new osgAnimation::Vec3Target(apc._euler->getValue());
_position = new osgAnimation::Vec3Target(apc._position->getValue());
_scale = new osgAnimation::Vec3Target(apc._scale->getValue());
}
UpdateTransform::UpdateTransform(const std::string& name):
AnimationUpdateCallback<osg::NodeCallback>(name)
{
_euler = new osgAnimation::Vec3Target;
_position = new osgAnimation::Vec3Target;
_scale = new osgAnimation::Vec3Target(osg::Vec3(1,1,1));
}
/** Callback method called by the NodeVisitor when visiting a node.*/
void UpdateTransform::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
osg::MatrixTransform* matrix = dynamic_cast<osg::MatrixTransform*>(node);
if (matrix)
{
update(*matrix);
}
else
{
osg::PositionAttitudeTransform* pat = dynamic_cast<osg::PositionAttitudeTransform*>(node);
if (pat)
update(*pat);
}
}
traverse(node,nv);
}
void UpdateTransform::update(osg::MatrixTransform& mat)
{
float z = _euler->getValue()[2];
float x = _euler->getValue()[0];
float y = _euler->getValue()[1];
osg::Matrix m =
osg::Matrix::rotate(x,1.0,0.0,0.0) *
osg::Matrix::rotate(y,0.0,1.0,0.0) *
osg::Matrix::rotate(z,0.0,0.0,1.0);
m = osg::Matrix::scale(_scale->getValue()) * m * osg::Matrix::translate(_position->getValue());
mat.setMatrix(m);
if (!m.valid())
osg::notify(osg::WARN) << this << " UpdateTransform::update detected NaN" << std::endl;
}
void UpdateTransform::update(osg::PositionAttitudeTransform& pat)
{
float heading = _euler->getValue()[0];
float pitch = _euler->getValue()[1];
float roll = _euler->getValue()[2];
osg::Matrix m = osg::Matrix::rotate(roll,0.0,1.0,0.0) * osg::Matrix::rotate(pitch,1.0,0.0,0.0) * osg::Matrix::rotate(-heading,0.0,0.0,1.0);
osg::Quat q = m.getRotate();
pat.setPosition(_position->getValue());
pat.setScale(_scale->getValue());
pat.setAttitude(q);
pat.dirtyBound();
}
bool UpdateTransform::link(osgAnimation::Channel* channel)
{
if (channel->getName().find("euler") != std::string::npos)
{
return channel->setTarget(_euler.get());
}
else if (channel->getName().find("position") != std::string::npos)
{
return channel->setTarget(_position.get());
}
else if (channel->getName().find("scale") != std::string::npos)
{
return channel->setTarget(_scale.get());
}
else
{
osg::notify(osg::WARN) << "Channel " << channel->getName() << " does not contain a valid symbolic name for this class" << className() << std::endl;
}
return false;
}
UpdateMaterial::UpdateMaterial(const UpdateMaterial& apc,const osg::CopyOp& copyop)
: osg::Object(apc, copyop),
AnimationUpdateCallback<osg::StateAttributeCallback>(apc, copyop)
{
_diffuse = new osgAnimation::Vec4Target(apc._diffuse->getValue());
}
UpdateMaterial::UpdateMaterial(const std::string& name):
AnimationUpdateCallback<osg::StateAttributeCallback>(name)
{
_diffuse = new osgAnimation::Vec4Target(osg::Vec4(1,0,1,1));
}
/** Callback method called by the NodeVisitor when visiting a node.*/
void UpdateMaterial::operator()(osg::StateAttribute* sa, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
osg::Material* material = dynamic_cast<osg::Material*>(sa);
if (material)
update(*material);
}
}
osgAnimation::Vec4Target* UpdateMaterial::getDiffuse() { return _diffuse.get(); }
void UpdateMaterial::update(osg::Material& material)
{
osg::Vec4 diffuse = _diffuse->getValue();
material.setDiffuse(osg::Material::FRONT_AND_BACK, diffuse);
}
bool UpdateMaterial::link(osgAnimation::Channel* channel)
{
if (channel->getName().find("diffuse") != std::string::npos)
{
return channel->setTarget(_diffuse.get());
}
else
{
osg::notify(osg::WARN) << "Channel " << channel->getName() << " does not contain a valid symbolic name for this class " << className() << std::endl;
}
return false;
}

View File

@ -0,0 +1,63 @@
/* -*-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/UpdateMaterial>
#include <osg/NodeVisitor>
using namespace osgAnimation;
UpdateMaterial::UpdateMaterial(const UpdateMaterial& apc,const osg::CopyOp& copyop)
: osg::Object(apc, copyop),
AnimationUpdateCallback<osg::StateAttributeCallback>(apc, copyop)
{
_diffuse = new osgAnimation::Vec4Target(apc._diffuse->getValue());
}
UpdateMaterial::UpdateMaterial(const std::string& name):
AnimationUpdateCallback<osg::StateAttributeCallback>(name)
{
_diffuse = new osgAnimation::Vec4Target(osg::Vec4(1,0,1,1));
}
/** Callback method called by the NodeVisitor when visiting a node.*/
void UpdateMaterial::operator()(osg::StateAttribute* sa, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
osg::Material* material = dynamic_cast<osg::Material*>(sa);
if (material)
update(*material);
}
}
osgAnimation::Vec4Target* UpdateMaterial::getDiffuse() { return _diffuse.get(); }
void UpdateMaterial::update(osg::Material& material)
{
osg::Vec4 diffuse = _diffuse->getValue();
material.setDiffuse(osg::Material::FRONT_AND_BACK, diffuse);
}
bool UpdateMaterial::link(osgAnimation::Channel* channel)
{
if (channel->getName().find("diffuse") != std::string::npos)
{
return channel->setTarget(_diffuse.get());
}
else
{
osg::notify(osg::WARN) << "Channel " << channel->getName() << " does not contain a valid symbolic name for this class " << className() << std::endl;
}
return false;
}

View File

@ -0,0 +1,67 @@
/* -*-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/UpdateMatrixTransform>
#include <osg/NodeVisitor>
#include <osg/MatrixTransform>
using namespace osgAnimation;
UpdateMatrixTransform::UpdateMatrixTransform( const UpdateMatrixTransform& apc,const osg::CopyOp& copyop) : osg::Object(apc,copyop), AnimationUpdateCallback<osg::NodeCallback>(apc, copyop)
{
_transforms = StackedTransform(apc.getStackedTransforms(), copyop);
}
UpdateMatrixTransform::UpdateMatrixTransform(const std::string& name) : AnimationUpdateCallback<osg::NodeCallback>(name)
{
}
/** Callback method called by the NodeVisitor when visiting a node.*/
void UpdateMatrixTransform::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
osg::MatrixTransform* matrixTransform = dynamic_cast<osg::MatrixTransform*>(node);
if (matrixTransform)
{
// here we would prefer to have a flag inside transform stack in order to avoid update and a dirty state in matrixTransform if it's not require.
_transforms.update();
const osg::Matrix& matrix = _transforms.getMatrix();
matrixTransform->setMatrix(matrix);
}
}
traverse(node,nv);
}
bool UpdateMatrixTransform::link(osgAnimation::Channel* channel)
{
const std::string& channelName = channel->getName();
// check if we can link a StackedTransformElement to the current Channel
for (StackedTransform::iterator it = _transforms.begin(); it != _transforms.end(); ++it)
{
StackedTransformElement* element = *it;
if (element && !element->getName().empty() && channelName == element->getName())
{
Target* target = element->getOrCreateTarget();
if (target && channel->setTarget(target))
return true;
}
}
osg::notify(osg::INFO) << "UpdateMatrixTransform::link Channel " << channel->getName() << " does not contain a symbolic name that can be linked to a StackedTransformElement." << std::endl;
return false;
}

View File

@ -26,7 +26,7 @@ const VertexInfluenceSet::VertexIndexToBoneWeightMap& VertexInfluenceSet::getVer
void VertexInfluenceSet::buildVertex2BoneList() void VertexInfluenceSet::buildVertex2BoneList()
{ {
_vertex2Bones.clear(); _vertex2Bones.clear();
for (BoneToVertexList::const_iterator it = _bone2Vertexes.begin(); it != _bone2Vertexes.end(); it++) for (BoneToVertexList::const_iterator it = _bone2Vertexes.begin(); it != _bone2Vertexes.end(); ++it)
{ {
const VertexInfluence& vi = (*it); const VertexInfluence& vi = (*it);
int size = vi.size(); int size = vi.size();
@ -42,7 +42,7 @@ void VertexInfluenceSet::buildVertex2BoneList()
} }
// normalize weight per vertex // normalize weight per vertex
for (VertexIndexToBoneWeightMap::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); it++) for (VertexIndexToBoneWeightMap::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it)
{ {
BoneWeightList& bones = it->second; BoneWeightList& bones = it->second;
int size = bones.size(); int size = bones.size();
@ -116,7 +116,7 @@ void VertexInfluenceSet::buildUniqVertexSetToBoneSetList()
typedef std::map<BoneWeightList,UniqVertexSetToBoneSet, SortByBoneWeightList> UnifyBoneGroup; typedef std::map<BoneWeightList,UniqVertexSetToBoneSet, SortByBoneWeightList> UnifyBoneGroup;
UnifyBoneGroup unifyBuffer; UnifyBoneGroup unifyBuffer;
for (VertexIndexToBoneWeightMap::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); it++) for (VertexIndexToBoneWeightMap::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it)
{ {
BoneWeightList bones = it->second; BoneWeightList bones = it->second;
int vertexIndex = it->first; int vertexIndex = it->first;
@ -132,7 +132,7 @@ void VertexInfluenceSet::buildUniqVertexSetToBoneSetList()
} }
_uniqVertexSetToBoneSet.reserve(unifyBuffer.size()); _uniqVertexSetToBoneSet.reserve(unifyBuffer.size());
for (UnifyBoneGroup::iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); it++) for (UnifyBoneGroup::iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); ++it)
{ {
_uniqVertexSetToBoneSet.push_back(it->second); _uniqVertexSetToBoneSet.push_back(it->second);
} }

View File

@ -8,6 +8,10 @@
#include <osgAnimation/Bone> #include <osgAnimation/Bone>
#include <osgAnimation/Skeleton> #include <osgAnimation/Skeleton>
#include <osgAnimation/UpdateBone>
#include <osgAnimation/StackedTransform>
#include <osgAnimation/StackedTranslateElement>
#include <osgAnimation/StackedQuaternionElement>
#include <osgAnimation/BasicAnimationManager> #include <osgAnimation/BasicAnimationManager>
class BvhMotionBuilder : public osg::Referenced class BvhMotionBuilder : public osg::Referenced
@ -39,7 +43,17 @@ public:
if ( fr.readSequence(offset) ) if ( fr.readSequence(offset) )
{ {
// Process OFFSET section // Process OFFSET section
parent->setBindMatrixInBoneSpace( osg::Matrix::translate(offset) ); parent->setMatrixInSkeletonSpace( osg::Matrix::translate(offset) *
parent->getMatrixInSkeletonSpace() );
osgAnimation::UpdateBone* updateBone =
static_cast<osgAnimation::UpdateBone*>( parent->getUpdateCallback() );
if ( updateBone )
{
osgAnimation::StackedTransform& stack = updateBone->getStackedTransforms();
stack.push_back( new osgAnimation::StackedTranslateElement("position", offset) );
stack.push_back( new osgAnimation::StackedQuaternionElement("quaternion", osg::Quat()) );
}
if ( _drawingFlag && parent->getNumParents() && level>0 ) if ( _drawingFlag && parent->getNumParents() && level>0 )
parent->getParent(0)->addChild( createRefGeometry(offset, 0.5).get() ); parent->getParent(0)->addChild( createRefGeometry(offset, 0.5).get() );
} }
@ -77,9 +91,10 @@ public:
{ {
// Process End Site section // Process End Site section
osg::ref_ptr<osgAnimation::Bone> bone = new osgAnimation::Bone( parent->getName()+"End" ); osg::ref_ptr<osgAnimation::Bone> bone = new osgAnimation::Bone( parent->getName()+"End" );
bone->setBindMatrixInBoneSpace( osg::Matrix::translate(offsetEndSite) ); bone->setMatrixInSkeletonSpace( osg::Matrix::translate(offsetEndSite) *
bone->getMatrixInSkeletonSpace() );
bone->setDataVariance( osg::Object::DYNAMIC ); bone->setDataVariance( osg::Object::DYNAMIC );
parent->addChild( bone.get() ); parent->insertChild( 0, bone.get() );
if ( _drawingFlag ) if ( _drawingFlag )
parent->addChild( createRefGeometry(offsetEndSite, 0.5).get() ); parent->addChild( createRefGeometry(offsetEndSite, 0.5).get() );
@ -94,9 +109,9 @@ public:
// Process JOINT section // Process JOINT section
osg::ref_ptr<osgAnimation::Bone> bone = new osgAnimation::Bone( fr[1].getStr() ); osg::ref_ptr<osgAnimation::Bone> bone = new osgAnimation::Bone( fr[1].getStr() );
bone->setDefaultUpdateCallback();
bone->setDataVariance( osg::Object::DYNAMIC ); bone->setDataVariance( osg::Object::DYNAMIC );
parent->addChild( bone.get() ); bone->setDefaultUpdateCallback();
parent->insertChild( 0, bone.get() );
_joints.push_back( JointNode(bone, 0) ); _joints.push_back( JointNode(bone, 0) );
int entry = fr[1].getNoNestedBrackets(); int entry = fr[1].getNoNestedBrackets();
@ -194,8 +209,13 @@ public:
osgDB::Input fr; osgDB::Input fr;
fr.attach( &stream ); fr.attach( &stream );
osg::ref_ptr<osgAnimation::Bone> boneroot = new osgAnimation::Bone( "Root" );
boneroot->setDefaultUpdateCallback();
osg::ref_ptr<osgAnimation::Skeleton> skelroot = new osgAnimation::Skeleton; osg::ref_ptr<osgAnimation::Skeleton> skelroot = new osgAnimation::Skeleton;
skelroot->setDefaultUpdateCallback(); skelroot->setDefaultUpdateCallback();
skelroot->insertChild( 0, boneroot.get() );
osg::ref_ptr<osgAnimation::Animation> anim = new osgAnimation::Animation; osg::ref_ptr<osgAnimation::Animation> anim = new osgAnimation::Animation;
while( !fr.eof() ) while( !fr.eof() )
@ -203,7 +223,7 @@ public:
if ( fr.matchSequence("HIERARCHY") ) if ( fr.matchSequence("HIERARCHY") )
{ {
++fr; ++fr;
buildHierarchy( fr, 0, skelroot.get() ); buildHierarchy( fr, 0, boneroot.get() );
} }
else if ( fr.matchSequence("MOTION") ) else if ( fr.matchSequence("MOTION") )
{ {

View File

@ -5,5 +5,3 @@ FILE(GLOB TARGET_H *.h)
SET(TARGET_ADDED_LIBRARIES osgAnimation ) SET(TARGET_ADDED_LIBRARIES osgAnimation )
#### end var setup ### #### end var setup ###
SETUP_PLUGIN(osganimation) SETUP_PLUGIN(osganimation)

View File

@ -0,0 +1,51 @@
#include "Matrix.h"
bool readMatrix(osg::Matrix& matrix, osgDB::Input& fr, const char* keyword)
{
bool iteratorAdvanced = false;
if (fr[0].matchWord(keyword) && fr[1].isOpenBracket())
{
int entry = fr[0].getNoNestedBrackets();
fr += 2;
int row=0;
int col=0;
double v;
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
{
if (fr[0].getFloat(v))
{
matrix(row,col)=v;
++col;
if (col>=4)
{
col = 0;
++row;
}
++fr;
}
else fr.advanceOverCurrentFieldOrBlock();
}
iteratorAdvanced = true;
}
return iteratorAdvanced;
}
bool writeMatrix(const osg::Matrix& matrix, osgDB::Output& fw, const char* keyword)
{
fw.indent() << keyword <<" {" << std::endl;
fw.moveIn();
fw.indent() << matrix(0,0) << " " << matrix(0,1) << " " << matrix(0,2) << " " << matrix(0,3) << std::endl;
fw.indent() << matrix(1,0) << " " << matrix(1,1) << " " << matrix(1,2) << " " << matrix(1,3) << std::endl;
fw.indent() << matrix(2,0) << " " << matrix(2,1) << " " << matrix(2,2) << " " << matrix(2,3) << std::endl;
fw.indent() << matrix(3,0) << " " << matrix(3,1) << " " << matrix(3,2) << " " << matrix(3,3) << std::endl;
fw.moveOut();
fw.indent() << "}"<< std::endl;
return true;
}

View File

@ -0,0 +1,13 @@
#ifndef DOTOSG_MATRIX
#define DOTOSG_MATRIX
#include <osg/Matrix>
#include <osgDB/Input>
#include <osgDB/Output>
extern bool readMatrix(osg::Matrix& matrix, osgDB::Input& fr, const char* keyword="Matrix");
extern bool writeMatrix(const osg::Matrix& matrix, osgDB::Output& fw, const char* keyword="Matrix");
#endif

View File

@ -10,24 +10,30 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details. * OpenSceneGraph Public License for more details.
*/ */
#include <osgDB/Registry>
#include <osgDB/FileNameUtils> #include <osgDB/FileNameUtils>
#include <osgDB/FileUtils> #include <osgDB/FileUtils>
#include <osgDB/ReaderWriter> #include <osgDB/ReaderWriter>
#include <osg/io_utils>
#include <osgAnimation/AnimationManagerBase> #include <osgAnimation/AnimationManagerBase>
#include <osgAnimation/BasicAnimationManager> #include <osgAnimation/BasicAnimationManager>
#include <osgAnimation/TimelineAnimationManager> #include <osgAnimation/TimelineAnimationManager>
#include <osgAnimation/VertexInfluence> #include <osgAnimation/VertexInfluence>
#include <osgAnimation/Animation> #include <osgAnimation/Animation>
#include <osgAnimation/Bone> #include <osgAnimation/Bone>
#include <osgAnimation/UpdateBone>
#include <osgAnimation/UpdateMatrixTransform>
#include <osgAnimation/Skeleton> #include <osgAnimation/Skeleton>
#include <osgAnimation/RigGeometry> #include <osgAnimation/RigGeometry>
#include <osgAnimation/MorphGeometry> #include <osgAnimation/MorphGeometry>
#include <osgAnimation/UpdateCallback> #include <osgAnimation/StackedTransform>
#include <osgAnimation/StackedTranslateElement>
#include <osgAnimation/StackedRotateAxisElement>
#include <osgAnimation/StackedMatrixElement>
#include <osgAnimation/StackedScaleElement>
#include "Matrix.h"
#include <osgDB/Registry> #include <osgDB/Registry>
#include <osgDB/Input> #include <osgDB/Input>
@ -42,7 +48,7 @@ bool Bone_readLocalData(Object& obj, Input& fr)
osg::Quat att; osg::Quat att;
bool iteratorAdvanced = false; bool iteratorAdvanced = false;
if (fr.matchSequence("bindQuaternion %f %f %f %f")) if (fr.matchSequence("bindQuaternion %f %f %f %f"))
{ {
fr[1].getFloat(att[0]); fr[1].getFloat(att[0]);
fr[2].getFloat(att[1]); fr[2].getFloat(att[1]);
@ -51,10 +57,11 @@ bool Bone_readLocalData(Object& obj, Input& fr)
fr += 5; fr += 5;
iteratorAdvanced = true; iteratorAdvanced = true;
osg::notify(osg::WARN) << "Old osgAnimation file format update your data file" << std::endl;
} }
osg::Vec3d pos(0,0,0); osg::Vec3d pos(0,0,0);
if (fr.matchSequence("bindPosition %f %f %f")) if (fr.matchSequence("bindPosition %f %f %f"))
{ {
fr[1].getFloat(pos[0]); fr[1].getFloat(pos[0]);
fr[2].getFloat(pos[1]); fr[2].getFloat(pos[1]);
@ -62,10 +69,11 @@ bool Bone_readLocalData(Object& obj, Input& fr)
fr += 4; fr += 4;
iteratorAdvanced = true; iteratorAdvanced = true;
osg::notify(osg::WARN) << "Old osgAnimation file format update your data file" << std::endl;
} }
osg::Vec3d scale(1,1,1); osg::Vec3d scale(1,1,1);
if (fr.matchSequence("bindScale %f %f %f")) if (fr.matchSequence("bindScale %f %f %f"))
{ {
fr[1].getFloat(scale[0]); fr[1].getFloat(scale[0]);
fr[2].getFloat(scale[1]); fr[2].getFloat(scale[1]);
@ -73,31 +81,45 @@ bool Bone_readLocalData(Object& obj, Input& fr)
fr += 4; fr += 4;
iteratorAdvanced = true; iteratorAdvanced = true;
osg::notify(osg::WARN) << "Old osgAnimation file format update your data file" << std::endl;
} }
bone.setBindMatrixInBoneSpace( osg::Matrix(att) * osg::Matrix::translate(pos)); if (fr.matchSequence("InvBindMatrixInSkeletonSpace {"))
{
Matrix matrix;
if (readMatrix(matrix,fr, "InvBindMatrixInSkeletonSpace"))
{
bone.setInvBindMatrixInSkeletonSpace(matrix);
iteratorAdvanced = true;
}
}
if (fr.matchSequence("MatrixInSkeletonSpace {"))
{
Matrix matrix;
if (readMatrix(matrix,fr, "MatrixInSkeletonSpace"))
{
bone.setMatrixInSkeletonSpace(matrix);
iteratorAdvanced = true;
}
}
return iteratorAdvanced; return iteratorAdvanced;
} }
bool Bone_writeLocalData(const Object& obj, Output& fw) bool Bone_writeLocalData(const Object& obj, Output& fw)
{ {
const osgAnimation::Bone& bone = dynamic_cast<const osgAnimation::Bone&>(obj); const osgAnimation::Bone& bone = dynamic_cast<const osgAnimation::Bone&>(obj);
osg::Vec3 t; bool res1 = writeMatrix(bone.getInvBindMatrixInSkeletonSpace(), fw, "InvBindMatrixInSkeletonSpace");
osg::Quat r; // write this field for debug only
osg::Vec3 s; // because it's recompute at each update
osg::Quat rs; bool res2 = writeMatrix(bone.getMatrixInSkeletonSpace(), fw, "MatrixInSkeletonSpace");
bone.getBindMatrixInBoneSpace().decompose(t,r,s,rs); return (res1 || res2);
fw.indent() << "bindQuaternion " << r << std::endl;
fw.indent() << "bindPosition " << t << std::endl;
fw.indent() << "bindScale " << s << std::endl;
return true;
} }
RegisterDotOsgWrapperProxy g_atkBoneProxy RegisterDotOsgWrapperProxy g_BoneProxy
( (
new osgAnimation::Bone, new osgAnimation::Bone,
"osgAnimation::Bone", "osgAnimation::Bone",
"Object Node Transform osgAnimation::Bone Group", "Object Node MatrixTransform osgAnimation::Bone Group",
&Bone_readLocalData, &Bone_readLocalData,
&Bone_writeLocalData &Bone_writeLocalData
); );
@ -112,11 +134,11 @@ bool Skeleton_writeLocalData(const Object& obj, Output& fr)
{ {
return true; return true;
} }
RegisterDotOsgWrapperProxy g_atkRootSkeletonProxy RegisterDotOsgWrapperProxy g_SkeletonProxy
( (
new osgAnimation::Skeleton, new osgAnimation::Skeleton,
"osgAnimation::Skeleton", "osgAnimation::Skeleton",
"Object Node Transform osgAnimation::Bone osgAnimation::Skeleton Group", "Object Node MatrixTransform osgAnimation::Skeleton Group",
&Skeleton_readLocalData, &Skeleton_readLocalData,
&Skeleton_writeLocalData, &Skeleton_writeLocalData,
DotOsgWrapper::READ_AND_WRITE DotOsgWrapper::READ_AND_WRITE
@ -723,7 +745,7 @@ bool AnimationManagerBase_writeLocalData(const osgAnimation::AnimationManagerBas
const osgAnimation::AnimationList& animList = manager.getAnimationList(); const osgAnimation::AnimationList& animList = manager.getAnimationList();
fw.indent() << "num_animations " << animList.size() << std::endl; fw.indent() << "num_animations " << animList.size() << std::endl;
for (osgAnimation::AnimationList::const_iterator it = animList.begin(); it != animList.end(); it++) for (osgAnimation::AnimationList::const_iterator it = animList.begin(); it != animList.end(); ++it)
{ {
if (!fw.writeObject(**it)) if (!fw.writeObject(**it))
osg::notify(osg::WARN)<<"Warning: can't write an animation object"<< std::endl; osg::notify(osg::WARN)<<"Warning: can't write an animation object"<< std::endl;
@ -816,6 +838,13 @@ bool RigGeometry_readLocalData(Object& obj, Input& fr)
if (!vmap->empty()) if (!vmap->empty())
geom.setInfluenceMap(vmap.get()); geom.setInfluenceMap(vmap.get());
if (fr.matchSequence("Geometry {"))
{
osg::Geometry* source = dynamic_cast<osg::Geometry*>(fr.readObject());
geom.setSourceGeometry(source);
iteratorAdvanced = true;
}
return iteratorAdvanced; return iteratorAdvanced;
} }
@ -827,7 +856,7 @@ bool RigGeometry_writeLocalData(const Object& obj, Output& fw)
return true; return true;
fw.indent() << "num_influences " << vm->size() << std::endl; fw.indent() << "num_influences " << vm->size() << std::endl;
fw.moveIn(); fw.moveIn();
for (osgAnimation::VertexInfluenceMap::const_iterator it = vm->begin(); it != vm->end(); it++) for (osgAnimation::VertexInfluenceMap::const_iterator it = vm->begin(); it != vm->end(); ++it)
{ {
std::string name = it->first; std::string name = it->first;
if (name.empty()) if (name.empty())
@ -843,6 +872,8 @@ bool RigGeometry_writeLocalData(const Object& obj, Output& fw)
fw.indent() << "}" << std::endl; fw.indent() << "}" << std::endl;
} }
fw.moveOut(); fw.moveOut();
fw.writeObject(*geom.getSourceGeometry());
return true; return true;
} }
@ -850,7 +881,7 @@ RegisterDotOsgWrapperProxy g_atkRigGeometryProxy
( (
new osgAnimation::RigGeometry, new osgAnimation::RigGeometry,
"osgAnimation::RigGeometry", "osgAnimation::RigGeometry",
"Object Drawable osgAnimation::RigGeometry Geometry", "Object osgAnimation::RigGeometry Drawable Geometry",
&RigGeometry_readLocalData, &RigGeometry_readLocalData,
&RigGeometry_writeLocalData, &RigGeometry_writeLocalData,
DotOsgWrapper::READ_AND_WRITE DotOsgWrapper::READ_AND_WRITE
@ -975,7 +1006,10 @@ RegisterDotOsgWrapperProxy g_osgAnimationMorphGeometryProxy
); );
bool UpdateBone_readLocalData(Object& obj, Input& fr)
bool UpdateBone_readLocalData(Object& obj, Input& fr)
{ {
bool iteratorAdvanced = false; bool iteratorAdvanced = false;
return iteratorAdvanced; return iteratorAdvanced;
@ -986,11 +1020,11 @@ bool UpdateBone_writeLocalData(const Object& obj, Output& fw)
return true; return true;
} }
RegisterDotOsgWrapperProxy g_atkUpdateBoneProxy RegisterDotOsgWrapperProxy g_UpdateBoneProxy
( (
new osgAnimation::Bone::UpdateBone, new osgAnimation::UpdateBone,
"osgAnimation::UpdateBone", "osgAnimation::UpdateBone",
"Object NodeCallback osgAnimation::UpdateBone", "Object NodeCallback osgAnimation::UpdateMatrixTransform osgAnimation::UpdateBone",
&UpdateBone_readLocalData, &UpdateBone_readLocalData,
&UpdateBone_writeLocalData, &UpdateBone_writeLocalData,
DotOsgWrapper::READ_AND_WRITE DotOsgWrapper::READ_AND_WRITE
@ -1009,7 +1043,7 @@ bool UpdateSkeleton_writeLocalData(const Object& obj, Output& fw)
return true; return true;
} }
RegisterDotOsgWrapperProxy g_atkUpdateSkeletonProxy RegisterDotOsgWrapperProxy g_UpdateSkeletonProxy
( (
new osgAnimation::Skeleton::UpdateSkeleton, new osgAnimation::Skeleton::UpdateSkeleton,
"osgAnimation::UpdateSkeleton", "osgAnimation::UpdateSkeleton",
@ -1020,51 +1054,6 @@ RegisterDotOsgWrapperProxy g_atkUpdateSkeletonProxy
); );
bool UpdateTransform_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
return iteratorAdvanced;
}
bool UpdateTransform_writeLocalData(const Object& obj, Output& fw)
{
return true;
}
RegisterDotOsgWrapperProxy g_atkUpdateTransformProxy
(
new osgAnimation::UpdateTransform,
"osgAnimation::UpdateTransform",
"Object NodeCallback osgAnimation::UpdateTransform",
&UpdateTransform_readLocalData,
&UpdateTransform_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
bool UpdateMaterial_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
return iteratorAdvanced;
}
bool UpdateMaterial_writeLocalData(const Object& obj, Output& fw)
{
return true;
}
RegisterDotOsgWrapperProxy g_UpdateMaterialProxy
(
new osgAnimation::UpdateMaterial,
"osgAnimation::UpdateMaterial",
"Object StateAttribute::Callback osgAnimation::UpdateMaterial",
&UpdateMaterial_readLocalData,
&UpdateMaterial_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
bool UpdateMorph_readLocalData(Object& obj, Input& fr) bool UpdateMorph_readLocalData(Object& obj, Input& fr)
{ {
bool iteratorAdvanced = false; bool iteratorAdvanced = false;
@ -1076,7 +1065,7 @@ bool UpdateMorph_writeLocalData(const Object& obj, Output& fw)
return true; return true;
} }
RegisterDotOsgWrapperProxy g_atkUpdateMorphProxy RegisterDotOsgWrapperProxy g_UpdateMorphProxy
( (
new osgAnimation::UpdateMorph, new osgAnimation::UpdateMorph,
"osgAnimation::UpdateMorph", "osgAnimation::UpdateMorph",

View File

@ -0,0 +1,228 @@
/* -*-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/StackedTranslateElement>
#include <osgAnimation/StackedMatrixElement>
#include <osgAnimation/StackedScaleElement>
#include <osgAnimation/StackedRotateAxisElement>
#include <osgAnimation/StackedQuaternionElement>
#include <osgDB/Input>
#include <osgDB/Output>
#include <osgDB/Registry>
#include <osgDB/ReaderWriter>
#include <osg/io_utils>
#include "Matrix.h"
using namespace osgDB;
using namespace osg;
bool readStackedTranslateElement(Object& obj, Input& fr)
{
osgAnimation::StackedTranslateElement& element = dynamic_cast<osgAnimation::StackedTranslateElement&>(obj);
bool iteratorAdvanced = false;
if (fr.matchSequence("translate %f %f %f"))
{
++fr;
osg::Vec3 translate;
fr[0].getFloat(translate.x());
fr[1].getFloat(translate.y());
fr[2].getFloat(translate.z());
element.setTranslate(translate);
fr += 3;
iteratorAdvanced = true;
}
return iteratorAdvanced;
}
bool writeStackedTranslateElement(const Object& obj, Output& fw)
{
const osgAnimation::StackedTranslateElement& element = dynamic_cast<const osgAnimation::StackedTranslateElement&>(obj);
fw.indent() << "translate " << element.getTranslate() << std::endl;
return true;
}
RegisterDotOsgWrapperProxy g_StackedTranslateElementProxy
(
new osgAnimation::StackedTranslateElement,
"osgAnimation::StackedTranslateElement",
"Object osgAnimation::StackedTranslateElement",
&readStackedTranslateElement,
&writeStackedTranslateElement,
DotOsgWrapper::READ_AND_WRITE
);
bool readStackedScaleElement(Object& obj, Input& fr)
{
osgAnimation::StackedScaleElement& element = dynamic_cast<osgAnimation::StackedScaleElement&>(obj);
bool iteratorAdvanced = false;
if (fr.matchSequence("scale %f %f %f"))
{
++fr;
osg::Vec3 scale;
fr[0].getFloat(scale.x());
fr[1].getFloat(scale.y());
fr[2].getFloat(scale.z());
element.setScale(scale);
fr += 3;
iteratorAdvanced = true;
}
return iteratorAdvanced;
}
bool writeStackedScaleElement(const Object& obj, Output& fw)
{
const osgAnimation::StackedScaleElement& element = dynamic_cast<const osgAnimation::StackedScaleElement&>(obj);
fw.indent() << "scale " << element.getScale() << std::endl;
return true;
}
RegisterDotOsgWrapperProxy g_StackedScaleElementProxy
(
new osgAnimation::StackedScaleElement,
"osgAnimation::StackedScaleElement",
"Object osgAnimation::StackedScaleElement",
&readStackedScaleElement,
&writeStackedScaleElement,
DotOsgWrapper::READ_AND_WRITE
);
bool readStackedMatrixElement(Object& obj, Input& fr)
{
osgAnimation::StackedMatrixElement& element = dynamic_cast<osgAnimation::StackedMatrixElement&>(obj);
bool iteratorAdvanced = false;
if (fr[0].matchWord("Matrix"))
{
osg::Matrix matrix;
matrix.makeIdentity();
iteratorAdvanced = readMatrix(matrix, fr);
element.setMatrix(matrix);
}
return iteratorAdvanced;
}
bool writeStackedMatrixElement(const Object& obj, Output& fw)
{
const osgAnimation::StackedMatrixElement& element = dynamic_cast<const osgAnimation::StackedMatrixElement&>(obj);
writeMatrix(element.getMatrix(), fw);
return true;
}
RegisterDotOsgWrapperProxy g_StackedMatrixElementProxy
(
new osgAnimation::StackedMatrixElement,
"osgAnimation::StackedMatrixElement",
"Object osgAnimation::StackedMatrixElement",
&readStackedMatrixElement,
&writeStackedMatrixElement,
DotOsgWrapper::READ_AND_WRITE
);
bool writeStackedRotateAxisElement(const Object& obj, Output& fw)
{
const osgAnimation::StackedRotateAxisElement& element = dynamic_cast<const osgAnimation::StackedRotateAxisElement&>(obj);
fw.indent() << "axis " << element.getAxis() << std::endl;
fw.indent() << "angle " << element.getAngle() << std::endl;
return true;
}
bool readStackedRotateAxisElement(Object& obj, Input& fr)
{
osgAnimation::StackedRotateAxisElement& element = dynamic_cast<osgAnimation::StackedRotateAxisElement&>(obj);
bool iteratorAdvanced = false;
if (fr.matchSequence("axis %f %f %f"))
{
++fr;
osg::Vec3 axis;
fr[0].getFloat(axis.x());
fr[1].getFloat(axis.y());
fr[2].getFloat(axis.z());
element.setAxis(axis);
fr += 3;
iteratorAdvanced = true;
}
if (fr.matchSequence("angle %f"))
{
++fr;
double angle = 0;
fr[0].getFloat(angle);
++fr;
element.setAngle(angle);
iteratorAdvanced = true;
}
return iteratorAdvanced;
}
RegisterDotOsgWrapperProxy g_StackedRotateAxisElementProxy
(
new osgAnimation::StackedRotateAxisElement,
"osgAnimation::StackedRotateAxisElement",
"Object osgAnimation::StackedRotateAxisElement",
&readStackedRotateAxisElement,
&writeStackedRotateAxisElement,
DotOsgWrapper::READ_AND_WRITE
);
bool readStackedQuaternionElement(Object& obj, Input& fr)
{
osgAnimation::StackedQuaternionElement& element = dynamic_cast<osgAnimation::StackedQuaternionElement&>(obj);
bool iteratorAdvanced = false;
if (fr.matchSequence("quaternion %f %f %f %f"))
{
++fr;
osg::Quat quaternion;
fr[0].getFloat(quaternion[0]);
fr[1].getFloat(quaternion[1]);
fr[2].getFloat(quaternion[2]);
fr[3].getFloat(quaternion[3]);
element.setQuaternion(quaternion);
fr += 4;
iteratorAdvanced = true;
}
return iteratorAdvanced;
}
bool writeStackedQuaternionElement(const Object& obj, Output& fw)
{
const osgAnimation::StackedQuaternionElement& element = dynamic_cast<const osgAnimation::StackedQuaternionElement&>(obj);
fw.indent() << "quaternion " << element.getQuaternion() << std::endl;
return true;
}
RegisterDotOsgWrapperProxy g_StackedQuaternionElementProxy
(
new osgAnimation::StackedQuaternionElement,
"osgAnimation::StackedQuaternionElement",
"Object osgAnimation::StackedQuaternionElement",
&readStackedQuaternionElement,
&writeStackedQuaternionElement,
DotOsgWrapper::READ_AND_WRITE
);

View File

@ -0,0 +1,47 @@
/* -*-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 <osgDB/Input>
#include <osgDB/Output>
#include <osgDB/Registry>
#include <osgDB/ReaderWriter>
#include <osg/io_utils>
#include <osgAnimation/UpdateMaterial>
using namespace osg;
using namespace osgDB;
bool UpdateMaterial_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
return iteratorAdvanced;
}
bool UpdateMaterial_writeLocalData(const Object& obj, Output& fw)
{
return true;
}
RegisterDotOsgWrapperProxy g_UpdateMaterialProxy
(
new osgAnimation::UpdateMaterial,
"osgAnimation::UpdateMaterial",
"Object StateAttribute::Callback osgAnimation::UpdateMaterial",
&UpdateMaterial_readLocalData,
&UpdateMaterial_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);

View File

@ -0,0 +1,70 @@
/* -*-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 <osgDB/Input>
#include <osgDB/Output>
#include <osgDB/Registry>
#include <osgDB/ReaderWriter>
#include <osg/io_utils>
#include <osgAnimation/StackedTransformElement>
#include <osgAnimation/UpdateMatrixTransform>
using namespace osg;
using namespace osgDB;
bool UpdateMatrixTransform_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
osgAnimation::UpdateMatrixTransform& updateCallback = dynamic_cast<osgAnimation::UpdateMatrixTransform&>(obj);
osgAnimation::StackedTransform& stackedTransform = updateCallback.getStackedTransforms();
int entry = fr[0].getNoNestedBrackets();
while (!fr.eof() && fr[0].getNoNestedBrackets() == entry && fr.matchSequence("%w {"))
{
osgAnimation::StackedTransformElement* element = dynamic_cast<osgAnimation::StackedTransformElement*>(fr.readObject());
if (element)
stackedTransform.push_back(element);
}
return iteratorAdvanced;
}
bool UpdateMatrixTransform_writeLocalData(const Object& obj, Output& fw)
{
const osgAnimation::UpdateMatrixTransform* uc = dynamic_cast<const osgAnimation::UpdateMatrixTransform*>(&obj);
const osgAnimation::StackedTransform& transforms = uc->getStackedTransforms();
for (osgAnimation::StackedTransform::const_iterator it = transforms.begin(); it != transforms.end(); ++it)
{
osgAnimation::StackedTransformElement* element = *it;
if (element)
fw.writeObject(*element);
}
return true;
}
RegisterDotOsgWrapperProxy g_UpdateMatrixTransformProxy
(
new osgAnimation::UpdateMatrixTransform,
"osgAnimation::UpdateMatrixTransform",
"Object NodeCallback osgAnimation::UpdateMatrixTransform",
&UpdateMatrixTransform_readLocalData,
&UpdateMatrixTransform_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);