Index: /OpenSceneGraph/trunk/include/osgAnimation/Interpolator
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/Interpolator (revision 10877)
+++ /OpenSceneGraph/trunk/include/osgAnimation/Interpolator (revision 11009)
@@ -206,6 +206,6 @@
 
             TYPE v0 = keyframes[i].getValue().getPosition() * one_minus_t3;
-            TYPE v1 = keyframes[i].getValue().getTangentPoint1() * (3.0 * t * one_minus_t2);
-            TYPE v2 = keyframes[i].getValue().getTangentPoint2() * (3.0 * t2 * one_minus_t);
+            TYPE v1 = keyframes[i].getValue().getControlPointIn() * (3.0 * t * one_minus_t2);
+            TYPE v2 = keyframes[i].getValue().getControlPointOut() * (3.0 * t2 * one_minus_t);
             TYPE v3 = keyframes[i+1].getValue().getPosition() * (t2 * t);
 
@@ -229,4 +229,5 @@
     typedef TemplateLinearInterpolator<osg::Vec4, osg::Vec4> Vec4LinearInterpolator;
     typedef TemplateSphericalLinearInterpolator<osg::Quat, osg::Quat> QuatSphericalLinearInterpolator;
+    typedef TemplateLinearInterpolator<osg::Matrixf, osg::Matrixf> MatrixLinearInterpolator;
 
     typedef TemplateCubicBezierInterpolator<float, FloatCubicBezier > FloatCubicBezierInterpolator;
Index: /OpenSceneGraph/trunk/include/osgAnimation/Bone
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/Bone (revision 10561)
+++ /OpenSceneGraph/trunk/include/osgAnimation/Bone (revision 11009)
@@ -17,25 +17,9 @@
  */
 
-#ifndef OSGANIMATION_BONE_H
-#define OSGANIMATION_BONE_H
+#ifndef OSGANIMATION_BONE
+#define OSGANIMATION_BONE 1
 
-#include <osg/Transform>
-#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 <osg/MatrixTransform>
 #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 
@@ -44,9 +28,7 @@
     // 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.
-    class OSGANIMATION_EXPORT Bone : public osg::Transform
+    class OSGANIMATION_EXPORT Bone : public osg::MatrixTransform
     {
     public:
-        typedef osg::ref_ptr<Bone> PointerType;
-        typedef std::map<std::string, PointerType > BoneMap;
         typedef osg::Matrix MatrixType;
 
@@ -57,127 +39,23 @@
         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();
         const Bone* getBoneParent() const;
 
-        void setTranslation(const osg::Vec3& trans) { _position = trans;}
-        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& getMatrixInBoneSpace() const { return getMatrix();}
         const osg::Matrix& getMatrixInSkeletonSpace() const { return _boneInSkeletonSpace; }
         const osg::Matrix& getInvBindMatrixInSkeletonSpace() const { return _invBindInSkeletonSpace;}
         void setMatrixInSkeletonSpace(const osg::Matrix& matrix) { _boneInSkeletonSpace = matrix; }
-        void setBindMatrixInBoneSpace(const osg::Matrix& 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();
-
+        void setInvBindMatrixInSkeletonSpace(const osg::Matrix& matrix) { _invBindInSkeletonSpace = matrix; }
 
     protected:
 
-        osg::Vec3 _position;
-        osg::Quat _rotation;
-        osg::Vec3 _scale;
-
-
-        // flag to recompute bind pose
-        bool _needToRecomputeBindMatrix;
-
         // bind data
-        osg::Matrix _bindInBoneSpace;
         osg::Matrix _invBindInSkeletonSpace;
 
         // bone updated
         osg::Matrix _boneInSkeletonSpace;
-    
     };
 
-
-    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;
-    }
-
+    typedef std::map<std::string, osg::ref_ptr<Bone> > BoneMap;
 }
 #endif
Index: /OpenSceneGraph/trunk/include/osgAnimation/Skeleton
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/Skeleton (revision 10751)
+++ /OpenSceneGraph/trunk/include/osgAnimation/Skeleton (revision 11009)
@@ -17,10 +17,10 @@
 
 #include <osgAnimation/Export>
-#include <osgAnimation/Bone>
+#include <osg/MatrixTransform>
 
 namespace osgAnimation 
 {
 
-    class OSGANIMATION_EXPORT Skeleton : public Bone
+    class OSGANIMATION_EXPORT Skeleton : public osg::MatrixTransform
     {
     public:
@@ -41,7 +41,6 @@
         Skeleton();
         Skeleton(const Skeleton&, const osg::CopyOp&);
+        void setDefaultUpdateCallback();
 
-        void setDefaultUpdateCallback();
-        void computeBindMatrix();
     };
 
Index: /OpenSceneGraph/trunk/include/osgAnimation/Target
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/Target (revision 10599)
+++ /OpenSceneGraph/trunk/include/osgAnimation/Target (revision 11009)
@@ -122,4 +122,5 @@
     }
 
+    typedef TemplateTarget<osg::Matrixf> MatrixTarget;
     typedef TemplateTarget<osg::Quat> QuatTarget;
     typedef TemplateTarget<osg::Vec3> Vec3Target;
Index: /OpenSceneGraph/trunk/include/osgAnimation/UpdateBone
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/UpdateBone (revision 11009)
+++ /OpenSceneGraph/trunk/include/osgAnimation/UpdateBone (revision 11009)
@@ -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
Index: /OpenSceneGraph/trunk/include/osgAnimation/RigTransformSoftware
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/RigTransformSoftware (revision 10877)
+++ /OpenSceneGraph/trunk/include/osgAnimation/RigTransformSoftware (revision 11009)
@@ -13,10 +13,12 @@
  */
 
-#ifndef OSGANIMATION_RIG_TRANSFORM_SOFTWARE_H
-#define OSGANIMATION_RIG_TRANSFORM_SOFTWARE_H 1
+#ifndef OSGANIMATION_RIGTRANSFORM_SOFTWARE
+#define OSGANIMATION_RIGTRANSFORM_SOFTWARE 1
 
 #include <osgAnimation/Export>
 #include <osgAnimation/RigTransform>
 #include <osgAnimation/Bone>
+#include <osgAnimation/VertexInfluence>
+#include <osg/observer_ptr>
 
 namespace osgAnimation 
@@ -30,6 +32,6 @@
     public:
 
-        virtual bool init(RigGeometry&);
-        virtual void update(RigGeometry&);
+        RigTransformSoftware();
+        virtual void operator()(RigGeometry&);
     
 
@@ -157,14 +159,11 @@
         }
 
-        const std::vector<osg::Vec3>& getPositionSource() const { return _positionSource;}
-        const std::vector<osg::Vec3>& getNormalSource() const { return _normalSource;}
-
     protected:
 
-        void initVertexSetFromBones(const Bone::BoneMap& map, const VertexInfluenceSet::UniqVertexSetToBoneSetList& influence);
+        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;
 
     };
Index: /OpenSceneGraph/trunk/include/osgAnimation/RigTransformHardware
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/RigTransformHardware (revision 10918)
+++ /OpenSceneGraph/trunk/include/osgAnimation/RigTransformHardware (revision 11009)
@@ -13,6 +13,6 @@
  */
 
-#ifndef OSGANIMATION_RIG_TRANSFORM_HARDWARE_H
-#define OSGANIMATION_RIG_TRANSFORM_HARDWARE_H 1
+#ifndef OSGANIMATION_RIG_TRANSFORM_HARDWARE
+#define OSGANIMATION_RIG_TRANSFORM_HARDWARE 1
 
 #include <osgAnimation/Export>
@@ -33,5 +33,4 @@
         typedef osg::Matrix MatrixType;
         typedef osgAnimation::Bone BoneType;
-        typedef Bone::BoneMap BoneMap;
         typedef std::vector<osg::ref_ptr<osg::Vec4Array> > BoneWeightAttribList;
         typedef std::vector<osg::ref_ptr<BoneType> > BonePalette;
@@ -49,4 +48,6 @@
         typedef std::vector<std::vector<IndexWeightEntry> > VertexIndexWeightList;
 
+        RigTransformHardware();
+
         osg::Vec4Array* getVertexAttrib(int index);
         int getNumVertexAttrib();
@@ -60,10 +61,10 @@
         bool createPalette(int nbVertexes, BoneMap boneMap, const VertexInfluenceSet::VertexIndexToBoneWeightMap& vertexIndexToBoneWeightMap);
 
+        virtual void operator()(RigGeometry&);
+        void setShader(osg::Shader*);
 
-        virtual bool init(RigGeometry&);
-        virtual void update(RigGeometry&);
+    protected:
 
-        void setShader(osg::Shader*);
-    protected:
+        bool init(RigGeometry&);
 
         BoneWeightAttribList createVertexAttribList();
@@ -77,4 +78,6 @@
         osg::ref_ptr<osg::Uniform> _uniformMatrixPalette;
         osg::ref_ptr<osg::Shader> _shader;
+
+        bool _needInit;
     };
 }
Index: /OpenSceneGraph/trunk/include/osgAnimation/StackedRotateAxisElement
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/StackedRotateAxisElement (revision 11009)
+++ /OpenSceneGraph/trunk/include/osgAnimation/StackedRotateAxisElement (revision 11009)
@@ -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
+
Index: /OpenSceneGraph/trunk/include/osgAnimation/MorphGeometry
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/MorphGeometry (revision 10518)
+++ /OpenSceneGraph/trunk/include/osgAnimation/MorphGeometry (revision 11009)
@@ -17,6 +17,6 @@
 
 #include <osgAnimation/Export>
+#include <osgAnimation/AnimationUpdateCallback>
 #include <osg/Geometry>
-#include <osgAnimation/UpdateCallback>
 
 namespace osgAnimation 
Index: /OpenSceneGraph/trunk/include/osgAnimation/BoneMapVisitor
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/BoneMapVisitor (revision 10562)
+++ /OpenSceneGraph/trunk/include/osgAnimation/BoneMapVisitor (revision 11009)
@@ -16,6 +16,6 @@
  */
 
-#ifndef OSGANIMATION_BONEMAP_VISITOR_H
-#define OSGANIMATION_BONEMAP_VISITOR_H 1
+#ifndef OSGANIMATION_BONEMAP_VISITOR
+#define OSGANIMATION_BONEMAP_VISITOR 1
 
 #include <osgAnimation/Export>
@@ -33,8 +33,8 @@
         void apply(osg::Node&);
         void apply(osg::Transform& node);
-        const Bone::BoneMap& getBoneMap() const;
+        const BoneMap& getBoneMap() const;
 
     protected:
-        Bone::BoneMap _map;
+        BoneMap _map;
     };
 }
Index: /OpenSceneGraph/trunk/include/osgAnimation/Sampler
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/Sampler (revision 10527)
+++ /OpenSceneGraph/trunk/include/osgAnimation/Sampler (revision 11009)
@@ -126,4 +126,5 @@
     typedef TemplateSampler<Vec4LinearInterpolator> Vec4LinearSampler;
     typedef TemplateSampler<QuatSphericalLinearInterpolator> QuatSphericalLinearSampler;
+    typedef TemplateSampler<MatrixLinearInterpolator> MatrixLinearSampler;
 
     typedef TemplateSampler<FloatCubicBezierInterpolator> FloatCubicBezierSampler;
Index: /OpenSceneGraph/trunk/include/osgAnimation/Keyframe
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/Keyframe (revision 9877)
+++ /OpenSceneGraph/trunk/include/osgAnimation/Keyframe (revision 11009)
@@ -24,4 +24,5 @@
 #include <osg/Vec3>
 #include <osg/Vec2>
+#include <osg/Matrixf>
 
 namespace osgAnimation 
@@ -115,4 +116,7 @@
     typedef TemplateKeyframeContainer<osg::Quat> QuatKeyframeContainer;
 
+    typedef TemplateKeyframe<osg::Matrixf> MatrixKeyframe;
+    typedef TemplateKeyframeContainer<osg::Matrixf> MatrixKeyframeContainer;
+
     typedef TemplateKeyframe<Vec3Packed> Vec3PackedKeyframe;
     typedef TemplateKeyframeContainer<Vec3Packed> Vec3PackedKeyframeContainer;
Index: /OpenSceneGraph/trunk/include/osgAnimation/StackedTranslateElement
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/StackedTranslateElement (revision 11009)
+++ /OpenSceneGraph/trunk/include/osgAnimation/StackedTranslateElement (revision 11009)
@@ -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
Index: /OpenSceneGraph/trunk/include/osgAnimation/Channel
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/Channel (revision 10656)
+++ /OpenSceneGraph/trunk/include/osgAnimation/Channel (revision 11009)
@@ -173,4 +173,5 @@
     typedef TemplateChannel<Vec4LinearSampler> Vec4LinearChannel;
     typedef TemplateChannel<QuatSphericalLinearSampler> QuatSphericalLinearChannel;
+    typedef TemplateChannel<MatrixLinearSampler> MatrixLinearChannel;
 
     typedef TemplateChannel<FloatCubicBezierSampler> FloatCubicBezierChannel;
Index: /OpenSceneGraph/trunk/include/osgAnimation/StackedTransform
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/StackedTransform (revision 11009)
+++ /OpenSceneGraph/trunk/include/osgAnimation/StackedTransform (revision 11009)
@@ -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
Index: /OpenSceneGraph/trunk/include/osgAnimation/StackedMatrixElement
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/StackedMatrixElement (revision 11009)
+++ /OpenSceneGraph/trunk/include/osgAnimation/StackedMatrixElement (revision 11009)
@@ -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
Index: /OpenSceneGraph/trunk/include/osgAnimation/StackedTransformElement
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/StackedTransformElement (revision 11009)
+++ /OpenSceneGraph/trunk/include/osgAnimation/StackedTransformElement (revision 11009)
@@ -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
Index: /OpenSceneGraph/trunk/include/osgAnimation/CubicBezier
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/CubicBezier (revision 10576)
+++ /OpenSceneGraph/trunk/include/osgAnimation/CubicBezier (revision 11009)
@@ -13,11 +13,10 @@
 */
 
-#ifndef OSGANIMATION_CUBIC_BEZIER_H
-#define OSGANIMATION_CUBIC_BEZIER_H
+#ifndef OSGANIMATION_CUBIC_BEZIER
+#define OSGANIMATION_CUBIC_BEZIER 1
 
 #include <osg/Vec2>
 #include <osg/Vec3>
 #include <osg/Vec4>
-#include <osg/Quat>
 
 namespace osgAnimation
@@ -25,46 +24,48 @@
 
     template <class T>
-    struct TemplateCubicBezier
+    class TemplateCubicBezier
     {
-        T mPoint[3];
-        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) 
+    public:
+        TemplateCubicBezier() {}
+
+        TemplateCubicBezier(const T& p, const T& i, const T& o) : _position(p), _controlPointIn(i), _controlPointOut(o)
         {
-            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() {}
+        // Constructor with value only
+        TemplateCubicBezier(const T& p) : _position(p), _controlPointIn(p), _controlPointOut(p)
+        {
+        }
 
-        const T& getPosition() const { return mPoint[0];}
-        const T& getTangentPoint1() const { return mPoint[1];}
-        const T& getTangentPoint2() const { return mPoint[2];}
-        
+        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>& vec)
+        friend std::ostream& operator << (std::ostream& output, const TemplateCubicBezier<T>& tcb)
         {
-            output << vec.mPoint[0] << " "
-                   << vec.mPoint[1] << " "
-                   << vec.mPoint[2];
+            output << tcb._position << " "
+                   << tcb._controlPointIn << " "
+                   << tcb._controlPointOut;
             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;
         }
+
+    protected:
+        T _position, _controlPointIn, _controlPointOut;
     };
-
 
     typedef TemplateCubicBezier<float> FloatCubicBezier;
Index: /OpenSceneGraph/trunk/include/osgAnimation/RigGeometry
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/RigGeometry (revision 10693)
+++ /OpenSceneGraph/trunk/include/osgAnimation/RigGeometry (revision 11009)
@@ -19,4 +19,5 @@
 #include <osgAnimation/Skeleton>
 #include <osgAnimation/RigTransform>
+#include <osgAnimation/VertexInfluence>
 #include <osg/Geometry>
 
@@ -29,5 +30,5 @@
 
         RigGeometry();
-        RigGeometry(const osg::Geometry& b);
+//        RigGeometry(const osg::Geometry& b);
         RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
 
@@ -64,6 +65,13 @@
         const osg::Matrix& getInvMatrixFromSkeletonToGeometry() const;
 
+        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;
 
@@ -105,5 +113,8 @@
 
                     if (!finder._root.valid())
+                    {
+                        osg::notify(osg::WARN) << "A RigGeometry did not find a parent skeleton for RigGeomtry ( " << geom->getName() << " )" << std::endl;
                         return;
+                    }
                     geom->buildVertexInfluenceSet();
                     geom->setSkeleton(finder._root.get());
Index: /OpenSceneGraph/trunk/include/osgAnimation/StackedQuaternionElement
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/StackedQuaternionElement (revision 11009)
+++ /OpenSceneGraph/trunk/include/osgAnimation/StackedQuaternionElement (revision 11009)
@@ -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
Index: /OpenSceneGraph/trunk/include/osgAnimation/AnimationUpdateCallback
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/AnimationUpdateCallback (revision 11009)
+++ /OpenSceneGraph/trunk/include/osgAnimation/AnimationUpdateCallback (revision 11009)
@@ -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
Index: /OpenSceneGraph/trunk/include/osgAnimation/StackedScaleElement
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/StackedScaleElement (revision 11009)
+++ /OpenSceneGraph/trunk/include/osgAnimation/StackedScaleElement (revision 11009)
@@ -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
+
Index: /OpenSceneGraph/trunk/include/osgAnimation/UpdateMaterial
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/UpdateMaterial (revision 11009)
+++ /OpenSceneGraph/trunk/include/osgAnimation/UpdateMaterial (revision 11009)
@@ -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
Index: /OpenSceneGraph/trunk/include/osgAnimation/EaseMotion
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/EaseMotion (revision 9981)
+++ /OpenSceneGraph/trunk/include/osgAnimation/EaseMotion (revision 11009)
@@ -314,5 +314,5 @@
                 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());
Index: /OpenSceneGraph/trunk/include/osgAnimation/UpdateMatrixTransform
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/UpdateMatrixTransform (revision 11009)
+++ /OpenSceneGraph/trunk/include/osgAnimation/UpdateMatrixTransform (revision 11009)
@@ -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
Index: /OpenSceneGraph/trunk/include/osgAnimation/RigTransform
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/RigTransform (revision 10693)
+++ /OpenSceneGraph/trunk/include/osgAnimation/RigTransform (revision 11009)
@@ -13,6 +13,6 @@
 */
 
-#ifndef OSGANIMATION_RIGTRANSFORM_H
-#define OSGANIMATION_RIGTRANSFORM_H
+#ifndef OSGANIMATION_RIGTRANSFORM
+#define OSGANIMATION_RIGTRANSFORM 1
 
 #include <osg/Referenced>
@@ -26,12 +26,8 @@
     {
     public:
-        RigTransform() : _needInit(true) {}
+        RigTransform() {}
         virtual ~RigTransform() {}
-        bool needInit() const { return _needInit; }
-        virtual bool init(RigGeometry&) = 0;
-        virtual void update(RigGeometry&) = 0;
+        virtual void operator()(RigGeometry& geometry) {}
 
-    protected:
-        bool _needInit;
     };
 
Index: /enSceneGraph/trunk/include/osgAnimation/UpdateCallback
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/UpdateCallback (revision 10701)
+++  (revision )
@@ -1,121 +1,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
Index: /enSceneGraph/trunk/include/osgAnimation/ComputeBindMatrixVisitor
===================================================================
--- /OpenSceneGraph/trunk/include/osgAnimation/ComputeBindMatrixVisitor (revision 10562)
+++  (revision )
@@ -1,43 +1,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
Index: /OpenSceneGraph/trunk/src/osgAnimation/MorphGeometry.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/MorphGeometry.cpp (revision 10599)
+++ /OpenSceneGraph/trunk/src/osgAnimation/MorphGeometry.cpp (revision 11009)
@@ -262,16 +262,11 @@
     if (weightIndex >= 0)
     {
-        osgAnimation::FloatLinearChannel* fc = dynamic_cast<osgAnimation::FloatLinearChannel*>(channel);
-        if (fc)
-        {
-            osgAnimation::FloatTarget* ft = _weightTargets[weightIndex].get();
-            if (ft == 0)
-            {
-                ft = new osgAnimation::FloatTarget;
-                _weightTargets[weightIndex] = ft;
-            }
-            fc->setTarget(ft);
-            return true;
-        }
+        osgAnimation::FloatTarget* ft = _weightTargets[weightIndex].get();
+        if (!ft)
+        {
+            ft = new osgAnimation::FloatTarget;
+            _weightTargets[weightIndex] = ft;
+        }
+        return channel->setTarget(ft);
     }
     else
Index: /OpenSceneGraph/trunk/src/osgAnimation/BoneMapVisitor.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/BoneMapVisitor.cpp (revision 10562)
+++ /OpenSceneGraph/trunk/src/osgAnimation/BoneMapVisitor.cpp (revision 11009)
@@ -17,18 +17,25 @@
 
 #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; }
-void osgAnimation::BoneMapVisitor::apply(osg::Transform& node)
+BoneMapVisitor::BoneMapVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
+
+void BoneMapVisitor::apply(osg::Node&) { return; }
+void BoneMapVisitor::apply(osg::Transform& node)
 {
     Bone* bone = dynamic_cast<Bone*>(&node);
-    if (bone) 
+    if (bone)
     {
         _map[bone->getName()] = bone;
         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;
Index: /OpenSceneGraph/trunk/src/osgAnimation/AnimationManagerBase.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/AnimationManagerBase.cpp (revision 10656)
+++ /OpenSceneGraph/trunk/src/osgAnimation/AnimationManagerBase.cpp (revision 11009)
@@ -29,5 +29,5 @@
 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();
 }
@@ -68,5 +68,5 @@
     for (AnimationList::const_iterator it = animationList.begin();
          it != animationList.end();
-         it++)
+         ++it)
     {
         Animation* animation = dynamic_cast<osgAnimation::Animation*>(it->get()->clone(copyop));
@@ -86,5 +86,5 @@
         for (ChannelList::iterator it = anim->getChannels().begin();
              it != anim->getChannels().end();
-             it++)
+             ++it)
             _targets.insert((*it)->getTarget());
     }
Index: /OpenSceneGraph/trunk/src/osgAnimation/Timeline.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/Timeline.cpp (revision 10904)
+++ /OpenSceneGraph/trunk/src/osgAnimation/Timeline.cpp (revision 11009)
@@ -211,5 +211,5 @@
 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;
Index: /OpenSceneGraph/trunk/src/osgAnimation/StackedTranslateElement.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/StackedTranslateElement.cpp (revision 11009)
+++ /OpenSceneGraph/trunk/src/osgAnimation/StackedTranslateElement.cpp (revision 11009)
@@ -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();
+}
Index: /OpenSceneGraph/trunk/src/osgAnimation/StackedTransform.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/StackedTransform.cpp (revision 11009)
+++ /OpenSceneGraph/trunk/src/osgAnimation/StackedTransform.cpp (revision 11009)
@@ -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;
+}
Index: /OpenSceneGraph/trunk/src/osgAnimation/BasicAnimationManager.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/BasicAnimationManager.cpp (revision 10576)
+++ /OpenSceneGraph/trunk/src/osgAnimation/BasicAnimationManager.cpp (revision 11009)
@@ -39,5 +39,5 @@
     {
         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();
     }
@@ -66,5 +66,5 @@
     {
         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 )
             {
@@ -83,5 +83,5 @@
 
     // 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();
 
@@ -133,5 +133,5 @@
     {
         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 )
                 return true;
@@ -146,5 +146,5 @@
     {
         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 )
                 return true;
Index: /OpenSceneGraph/trunk/src/osgAnimation/StackedMatrixElement.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/StackedMatrixElement.cpp (revision 11009)
+++ /OpenSceneGraph/trunk/src/osgAnimation/StackedMatrixElement.cpp (revision 11009)
@@ -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();
+}
Index: /OpenSceneGraph/trunk/src/osgAnimation/Action.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/Action.cpp (revision 10693)
+++ /OpenSceneGraph/trunk/src/osgAnimation/Action.cpp (revision 11009)
@@ -37,5 +37,5 @@
 {
     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())
@@ -53,5 +53,5 @@
         }
     }
-    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);
 }
Index: /OpenSceneGraph/trunk/src/osgAnimation/LinkVisitor.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/LinkVisitor.cpp (revision 10518)
+++ /OpenSceneGraph/trunk/src/osgAnimation/LinkVisitor.cpp (revision 11009)
@@ -14,5 +14,5 @@
 
 #include <osgAnimation/LinkVisitor>
-#include <osgAnimation/UpdateCallback>
+#include <osgAnimation/AnimationUpdateCallback>
 #include <osg/Notify>
 #include <osg/Geode>
@@ -34,5 +34,5 @@
     return _animations;
 }
-void LinkVisitor::link(osgAnimation::AnimationUpdateCallbackBase* cb)
+void LinkVisitor::link(AnimationUpdateCallbackBase* cb)
 {
     int result = 0;
@@ -50,5 +50,5 @@
         return;
     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();
Index: /OpenSceneGraph/trunk/src/osgAnimation/Animation.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/Animation.cpp (revision 10656)
+++ /OpenSceneGraph/trunk/src/osgAnimation/Animation.cpp (revision 11009)
@@ -25,5 +25,5 @@
 {
     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());
Index: /OpenSceneGraph/trunk/src/osgAnimation/CMakeLists.txt
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/CMakeLists.txt (revision 10693)
+++ /OpenSceneGraph/trunk/src/osgAnimation/CMakeLists.txt (revision 11009)
@@ -20,4 +20,5 @@
     ${HEADER_PATH}/Animation
     ${HEADER_PATH}/AnimationManagerBase
+    ${HEADER_PATH}/AnimationUpdateCallback
     ${HEADER_PATH}/Assert
     ${HEADER_PATH}/BasicAnimationManager
@@ -26,5 +27,4 @@
     ${HEADER_PATH}/Channel
     ${HEADER_PATH}/CubicBezier
-    ${HEADER_PATH}/ComputeBindMatrixVisitor
     ${HEADER_PATH}/EaseMotion
     ${HEADER_PATH}/Export
@@ -41,4 +41,11 @@
     ${HEADER_PATH}/Sampler
     ${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}/StatsHandler
@@ -46,5 +53,7 @@
     ${HEADER_PATH}/Timeline
     ${HEADER_PATH}/TimelineAnimationManager
-    ${HEADER_PATH}/UpdateCallback
+    ${HEADER_PATH}/UpdateBone
+    ${HEADER_PATH}/UpdateMaterial
+    ${HEADER_PATH}/UpdateMatrixTransform
     ${HEADER_PATH}/Vec3Packed
     ${HEADER_PATH}/VertexInfluence
@@ -75,4 +84,10 @@
     RigTransformSoftware.cpp
     Skeleton.cpp
+    StackedMatrixElement.cpp
+    StackedQuaternionElement.cpp
+    StackedRotateAxisElement.cpp
+    StackedScaleElement.cpp
+    StackedTransform.cpp
+    StackedTranslateElement.cpp
     StatsVisitor.cpp
     StatsHandler.cpp
@@ -80,5 +95,7 @@
     TimelineAnimationManager.cpp
     Timeline.cpp
-    UpdateCallback.cpp
+    UpdateBone.cpp
+    UpdateMaterial.cpp
+    UpdateMatrixTransform.cpp
     VertexInfluence.cpp
     ${OPENSCENEGRAPH_VERSIONINFO_RC}
Index: /OpenSceneGraph/trunk/src/osgAnimation/StatsHandler.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/StatsHandler.cpp (revision 10764)
+++ /OpenSceneGraph/trunk/src/osgAnimation/StatsHandler.cpp (revision 11009)
@@ -425,5 +425,5 @@
             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));
              }
Index: /OpenSceneGraph/trunk/src/osgAnimation/RigGeometry.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/RigGeometry.cpp (revision 10877)
+++ /OpenSceneGraph/trunk/src/osgAnimation/RigGeometry.cpp (revision 11009)
@@ -13,4 +13,5 @@
  */
 
+#include <osgAnimation/VertexInfluence>
 #include <osgAnimation/RigGeometry>
 #include <osgAnimation/RigTransformSoftware>
@@ -72,19 +73,8 @@
 }
 
-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) :
     osg::Geometry(b,copyop),
+    _geometry(b._geometry),
     _vertexInfluenceSet(b._vertexInfluenceSet),
     _vertexInfluenceMap(b._vertexInfluenceMap),
@@ -115,5 +105,5 @@
     for (osgAnimation::VertexInfluenceMap::iterator it = _vertexInfluenceMap->begin(); 
          it != _vertexInfluenceMap->end(); 
-         it++)
+         ++it)
         _vertexInfluenceSet.addVertexInfluence(it->second);
 
@@ -131,5 +121,6 @@
     }
     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);
     _needToComputeMatrix = false;
@@ -143,8 +134,65 @@
     }
 
-    if (getRigTransformImplementation()->needInit())
-        if (!getRigTransformImplementation()->init(*this))
-            return;
-    getRigTransformImplementation()->update(*this);
+    RigTransform& implementation = *getRigTransformImplementation();
+    (implementation)(*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);
+        }
+    }
 }
 
@@ -156,2 +204,6 @@
 RigTransform* RigGeometry::getRigTransformImplementation() { return _rigTransformImplementation.get(); }
 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; }
Index: /OpenSceneGraph/trunk/src/osgAnimation/StackedQuaternionElement.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/StackedQuaternionElement.cpp (revision 11009)
+++ /OpenSceneGraph/trunk/src/osgAnimation/StackedQuaternionElement.cpp (revision 11009)
@@ -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();}
Index: /OpenSceneGraph/trunk/src/osgAnimation/StackedScaleElement.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/StackedScaleElement.cpp (revision 11009)
+++ /OpenSceneGraph/trunk/src/osgAnimation/StackedScaleElement.cpp (revision 11009)
@@ -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();
+}
Index: /OpenSceneGraph/trunk/src/osgAnimation/UpdateMaterial.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/UpdateMaterial.cpp (revision 11009)
+++ /OpenSceneGraph/trunk/src/osgAnimation/UpdateMaterial.cpp (revision 11009)
@@ -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;
+}
Index: /OpenSceneGraph/trunk/src/osgAnimation/UpdateMatrixTransform.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/UpdateMatrixTransform.cpp (revision 11009)
+++ /OpenSceneGraph/trunk/src/osgAnimation/UpdateMatrixTransform.cpp (revision 11009)
@@ -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;
+}
Index: /OpenSceneGraph/trunk/src/osgAnimation/VertexInfluence.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/VertexInfluence.cpp (revision 10693)
+++ /OpenSceneGraph/trunk/src/osgAnimation/VertexInfluence.cpp (revision 11009)
@@ -27,5 +27,5 @@
 {
     _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);
@@ -43,5 +43,5 @@
 
     // 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;
@@ -117,5 +117,5 @@
     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;
@@ -133,5 +133,5 @@
 
     _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);
Index: /OpenSceneGraph/trunk/src/osgAnimation/Bone.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/Bone.cpp (revision 10693)
+++ /OpenSceneGraph/trunk/src/osgAnimation/Bone.cpp (revision 11009)
@@ -15,92 +15,21 @@
 #include <osgAnimation/Bone>
 #include <osgAnimation/Skeleton>
-#include <osgAnimation/FindParentAnimationManagerVisitor>
+#include <osgAnimation/UpdateBone>
 #include <osgAnimation/BoneMapVisitor>
-#include <osgAnimation/ComputeBindMatrixVisitor>
 
+using namespace osgAnimation;
 
-osgAnimation::Bone::UpdateBone::UpdateBone(const osgAnimation::Bone::UpdateBone& apc,const osg::CopyOp& copyop) :
-    osg::Object(apc, copyop),
-    osgAnimation::AnimationUpdateCallback<osg::NodeCallback>(apc, copyop)
+Bone::Bone(const Bone& b, const osg::CopyOp& copyop) : osg::MatrixTransform(b,copyop), _invBindInSkeletonSpace(b._invBindInSkeletonSpace), _boneInSkeletonSpace(b._boneInSkeletonSpace)
 {
-    _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)
+Bone::Bone(const std::string& name)
 {
-    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;
+    if (!name.empty())
+        setName(name);
 }
 
 
-/** 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)
-{
-    if (!name.empty())
-        setName(name);
-    _needToRecomputeBindMatrix = false;
-}
-
-
-void osgAnimation::Bone::setDefaultUpdateCallback(const std::string& name)
+void Bone::setDefaultUpdateCallback(const std::string& name)
 {
     std::string cbName = name;
@@ -110,23 +39,10 @@
 }
 
-void osgAnimation::Bone::computeBindMatrix()
-{
-    _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()
+Bone* Bone::getBoneParent()
 {
     if (getParents().empty())
         return 0;
     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);
@@ -136,10 +52,10 @@
     return 0;
 }
-const osgAnimation::Bone* osgAnimation::Bone::getBoneParent() const
+const Bone* Bone::getBoneParent() const
 {
     if (getParents().empty())
         return 0;
     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);
@@ -149,24 +65,2 @@
     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();
-}
Index: /OpenSceneGraph/trunk/src/osgAnimation/Skeleton.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/Skeleton.cpp (revision 10751)
+++ /OpenSceneGraph/trunk/src/osgAnimation/Skeleton.cpp (revision 11009)
@@ -15,12 +15,13 @@
 #include <osgAnimation/Skeleton>
 #include <osgAnimation/Bone>
+#include <osg/Notify>
 
 using namespace osgAnimation;
 
 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(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;
@@ -46,5 +47,5 @@
         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)))
@@ -77,9 +78,11 @@
         {
             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;
         }
-        if (skeleton->needToComputeBindMatrix())
-            skeleton->computeBindMatrix();
     }
     traverse(node,nv);
@@ -90,8 +93,2 @@
     setUpdateCallback(new Skeleton::UpdateSkeleton );
 }
-
-void Skeleton::computeBindMatrix() 
-{
-    _invBindInSkeletonSpace = osg::Matrix::inverse(_bindInBoneSpace); 
-    _needToRecomputeBindMatrix = false; 
-}
Index: /OpenSceneGraph/trunk/src/osgAnimation/UpdateBone.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/UpdateBone.cpp (revision 11009)
+++ /OpenSceneGraph/trunk/src/osgAnimation/UpdateBone.cpp (revision 11009)
@@ -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);
+}
Index: /OpenSceneGraph/trunk/src/osgAnimation/RigTransformSoftware.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/RigTransformSoftware.cpp (revision 10693)
+++ /OpenSceneGraph/trunk/src/osgAnimation/RigTransformSoftware.cpp (revision 11009)
@@ -14,8 +14,15 @@
 
 
+#include <osgAnimation/VertexInfluence>
 #include <osgAnimation/RigTransformSoftware>
+#include <osgAnimation/BoneMapVisitor>
 #include <osgAnimation/RigGeometry>
 
 using namespace osgAnimation;
+
+RigTransformSoftware::RigTransformSoftware()
+{
+    _needInit = true;
+}
 
 bool RigTransformSoftware::init(RigGeometry& geom)
@@ -23,38 +30,74 @@
     if (!geom.getSkeleton())
         return false;
-    Bone::BoneMap bm = geom.getSkeleton()->getBoneMap();
+
+    BoneMapVisitor mapVisitor;
+    geom.getSkeleton()->accept(mapVisitor);
+    BoneMap bm = mapVisitor.getBoneMap();
     initVertexSetFromBones(bm, geom.getVertexInfluenceSet().getUniqVertexSetToBoneSetList());
+
+    geom.copyFrom(*geom.getSourceGeometry());
+    geom.setVertexArray(0);
+    geom.setNormalArray(0);
+
     _needInit = false;
     return true;
 }
 
-void RigTransformSoftware::update(RigGeometry& geom)
+void RigTransformSoftware::operator()(RigGeometry& geom)
 {
-    osg::Vec3Array* pos = dynamic_cast<osg::Vec3Array*>(geom.getVertexArray());
-    if (pos && _positionSource.size() != pos->size()) 
+    if (_needInit)
+        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());
-        geom.getVertexArray()->setDataVariance(osg::Object::DYNAMIC);
+        if (!positionDst)
+        {
+            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());
-        geom.getNormalArray()->setDataVariance(osg::Object::DYNAMIC);
+        if (!normalDst)
+        {
+            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());
-        pos->dirty();
+        compute<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(), 
+                           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());
-        normal->dirty();
+        computeNormal<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(), 
+                           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();
@@ -73,5 +116,5 @@
             const std::string& bname = inf.getBones()[b].getBoneName();
             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()) 
             {
Index: /OpenSceneGraph/trunk/src/osgAnimation/RigTransformHardware.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/RigTransformHardware.cpp (revision 10693)
+++ /OpenSceneGraph/trunk/src/osgAnimation/RigTransformHardware.cpp (revision 11009)
@@ -15,7 +15,16 @@
 #include <osgAnimation/RigTransformHardware>
 #include <osgAnimation/RigGeometry>
+#include <osgAnimation/BoneMapVisitor>
 #include <sstream>
 
 using namespace osgAnimation;
+
+
+RigTransformHardware::RigTransformHardware()
+{
+    _needInit = true;
+    _bonesPerVertex = 0;
+    _nbVertexes = 0;
+}
 
 osg::Vec4Array* RigTransformHardware::getVertexAttrib(int index)
@@ -68,10 +77,10 @@
 
     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;
         const VertexInfluenceSet::BoneWeightList& boneWeightList = it->second;
         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;
@@ -86,5 +95,5 @@
                 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;
                 }
@@ -105,5 +114,5 @@
     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;
@@ -187,18 +196,28 @@
 bool RigTransformHardware::init(RigGeometry& geom)
 {
-    osg::Vec3Array* pos = dynamic_cast<osg::Vec3Array*>(geom.getVertexArray());
-    if (!pos) {
+    osg::Geometry& source = *geom.getSourceGeometry();
+    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;
         return false;
     }
 
-    if (!geom.getSkeleton()) {
-        osg::notify(osg::WARN) << "RigTransformHardware no skeleting set in geometry " << geom.getName() << std::endl;
-        return false;
-    }
-
-    Bone::BoneMap bm = geom.getSkeleton()->getBoneMap();
-
-    if (!createPalette(pos->size(),bm, geom.getVertexInfluenceSet().getVertexToBoneList()))
+    if (!geom.getSkeleton()) 
+    {
+        osg::notify(osg::WARN) << "RigTransformHardware no skeleton set in geometry " << geom.getName() << std::endl;
+        return false;
+    }
+
+
+    // 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;
 
@@ -245,6 +264,9 @@
     return true;
 }
-void RigTransformHardware::update(RigGeometry& geom)
-{
+void RigTransformHardware::operator()(RigGeometry& geom)
+{
+    if (_needInit)
+        if (!init(geom))
+            return;
     computeMatrixPaletteUniform(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry());
 }
Index: /OpenSceneGraph/trunk/src/osgAnimation/StackedRotateAxisElement.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/StackedRotateAxisElement.cpp (revision 11009)
+++ /OpenSceneGraph/trunk/src/osgAnimation/StackedRotateAxisElement.cpp (revision 11009)
@@ -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)); }
Index: /enSceneGraph/trunk/src/osgAnimation/UpdateCallback.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgAnimation/UpdateCallback.cpp (revision 10877)
+++  (revision )
@@ -1,162 +1,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;
-}
Index: /OpenSceneGraph/trunk/src/osgPlugins/bvh/ReaderWriterBVH.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/bvh/ReaderWriterBVH.cpp (revision 9371)
+++ /OpenSceneGraph/trunk/src/osgPlugins/bvh/ReaderWriterBVH.cpp (revision 11009)
@@ -9,4 +9,8 @@
 #include <osgAnimation/Bone>
 #include <osgAnimation/Skeleton>
+#include <osgAnimation/UpdateBone>
+#include <osgAnimation/StackedTransform>
+#include <osgAnimation/StackedTranslateElement>
+#include <osgAnimation/StackedQuaternionElement>
 #include <osgAnimation/BasicAnimationManager>
 
@@ -40,5 +44,15 @@
             {
                 // 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 )
                     parent->getParent(0)->addChild( createRefGeometry(offset, 0.5).get() );
@@ -78,7 +92,8 @@
                     // Process End Site section
                     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 );
-                    parent->addChild( bone.get() );
+                    parent->insertChild( 0, bone.get() );
 
                     if ( _drawingFlag )
@@ -95,7 +110,7 @@
             // Process JOINT section
             osg::ref_ptr<osgAnimation::Bone> bone = new osgAnimation::Bone( fr[1].getStr() );
+            bone->setDataVariance( osg::Object::DYNAMIC );
             bone->setDefaultUpdateCallback();
-            bone->setDataVariance( osg::Object::DYNAMIC );
-            parent->addChild( bone.get() );
+            parent->insertChild( 0, bone.get() );
             _joints.push_back( JointNode(bone, 0) );
 
@@ -195,6 +210,11 @@
         fr.attach( &stream );
 
+        osg::ref_ptr<osgAnimation::Bone> boneroot = new osgAnimation::Bone( "Root" );
+        boneroot->setDefaultUpdateCallback();
+
         osg::ref_ptr<osgAnimation::Skeleton> skelroot = new osgAnimation::Skeleton;
         skelroot->setDefaultUpdateCallback();
+        skelroot->insertChild( 0, boneroot.get() );
+
         osg::ref_ptr<osgAnimation::Animation> anim = new osgAnimation::Animation;
 
@@ -204,5 +224,5 @@
             {
                 ++fr;
-                buildHierarchy( fr, 0, skelroot.get() );
+                buildHierarchy( fr, 0, boneroot.get() );
             }
             else if ( fr.matchSequence("MOTION") )
Index: /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp (revision 10556)
+++ /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp (revision 11009)
@@ -11,12 +11,11 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  * OpenSceneGraph Public License for more details.
-*/
-
-
-#include <osgDB/Registry>
+ */
+
+
 #include <osgDB/FileNameUtils>
 #include <osgDB/FileUtils>
 #include <osgDB/ReaderWriter>
-
+#include <osg/io_utils>
 #include <osgAnimation/AnimationManagerBase>
 #include <osgAnimation/BasicAnimationManager>
@@ -25,8 +24,15 @@
 #include <osgAnimation/Animation>
 #include <osgAnimation/Bone>
+#include <osgAnimation/UpdateBone>
+#include <osgAnimation/UpdateMatrixTransform>
 #include <osgAnimation/Skeleton>
 #include <osgAnimation/RigGeometry>
 #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>
@@ -43,5 +49,5 @@
     osg::Quat att;
     bool iteratorAdvanced = false;
-    if (fr.matchSequence("bindQuaternion %f %f %f %f")) 
+    if (fr.matchSequence("bindQuaternion %f %f %f %f"))
     {
         fr[1].getFloat(att[0]);
@@ -52,8 +58,9 @@
         fr += 5;
         iteratorAdvanced = true;
+        osg::notify(osg::WARN) << "Old osgAnimation file format update your data file" << std::endl;
     }
 
     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]);
@@ -63,8 +70,9 @@
         fr += 4;
         iteratorAdvanced = true;
+        osg::notify(osg::WARN) << "Old osgAnimation file format update your data file" << std::endl;
     }
 
     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]);
@@ -74,29 +82,43 @@
         fr += 4;
         iteratorAdvanced = true;
-    }
-
-    bone.setBindMatrixInBoneSpace( osg::Matrix(att) * osg::Matrix::translate(pos));
+        osg::notify(osg::WARN) << "Old osgAnimation file format update your data file" << std::endl;
+    }
+
+    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;
 }
 
-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);
-    osg::Vec3 t;
-    osg::Quat r;
-    osg::Vec3 s;
-    osg::Quat rs;
-    bone.getBindMatrixInBoneSpace().decompose(t,r,s,rs);
-    fw.indent() << "bindQuaternion "  << r << std::endl;
-    fw.indent() << "bindPosition "  << t << std::endl;
-    fw.indent() << "bindScale "  << s << std::endl;
-    return true;
-}
-
-RegisterDotOsgWrapperProxy g_atkBoneProxy
+    bool res1 = writeMatrix(bone.getInvBindMatrixInSkeletonSpace(), fw, "InvBindMatrixInSkeletonSpace");
+    // write this field for debug only
+    // because it's recompute at each update
+    bool res2 = writeMatrix(bone.getMatrixInSkeletonSpace(), fw, "MatrixInSkeletonSpace");
+    return (res1 || res2);
+}
+
+RegisterDotOsgWrapperProxy g_BoneProxy
 (
     new osgAnimation::Bone,
     "osgAnimation::Bone",
-    "Object Node Transform osgAnimation::Bone Group",
+    "Object Node MatrixTransform osgAnimation::Bone Group",
     &Bone_readLocalData,
     &Bone_writeLocalData
@@ -113,9 +135,9 @@
     return true; 
 }
-RegisterDotOsgWrapperProxy g_atkRootSkeletonProxy
+RegisterDotOsgWrapperProxy g_SkeletonProxy
 (
     new osgAnimation::Skeleton,
     "osgAnimation::Skeleton",
-    "Object Node  Transform osgAnimation::Bone osgAnimation::Skeleton Group",
+    "Object Node MatrixTransform osgAnimation::Skeleton Group",
     &Skeleton_readLocalData,
     &Skeleton_writeLocalData,
@@ -724,5 +746,5 @@
 
     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))
@@ -817,4 +839,11 @@
         geom.setInfluenceMap(vmap.get());
 
+    if (fr.matchSequence("Geometry {"))
+    {
+        osg::Geometry* source = dynamic_cast<osg::Geometry*>(fr.readObject());
+        geom.setSourceGeometry(source);
+        iteratorAdvanced = true;
+    }
+
     return iteratorAdvanced;
 }
@@ -828,5 +857,5 @@
     fw.indent() << "num_influences "  << vm->size() << std::endl;
     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;
@@ -844,4 +873,6 @@
     }
     fw.moveOut();
+
+    fw.writeObject(*geom.getSourceGeometry());
     return true;
 }
@@ -851,5 +882,5 @@
     new osgAnimation::RigGeometry,
     "osgAnimation::RigGeometry",
-    "Object Drawable osgAnimation::RigGeometry Geometry",
+    "Object osgAnimation::RigGeometry Drawable Geometry",
     &RigGeometry_readLocalData,
     &RigGeometry_writeLocalData,
@@ -976,5 +1007,8 @@
 
 
-bool UpdateBone_readLocalData(Object& obj, Input& fr) 
+
+
+
+bool UpdateBone_readLocalData(Object& obj, Input& fr)
 {
     bool iteratorAdvanced = false;
@@ -987,9 +1021,9 @@
 }
 
-RegisterDotOsgWrapperProxy g_atkUpdateBoneProxy
+RegisterDotOsgWrapperProxy g_UpdateBoneProxy
 (
-    new osgAnimation::Bone::UpdateBone,
+    new osgAnimation::UpdateBone,
     "osgAnimation::UpdateBone",
-    "Object NodeCallback osgAnimation::UpdateBone",
+    "Object NodeCallback osgAnimation::UpdateMatrixTransform osgAnimation::UpdateBone",
     &UpdateBone_readLocalData,
     &UpdateBone_writeLocalData,
@@ -1010,5 +1044,5 @@
 }
 
-RegisterDotOsgWrapperProxy g_atkUpdateSkeletonProxy
+RegisterDotOsgWrapperProxy g_UpdateSkeletonProxy
 (
     new osgAnimation::Skeleton::UpdateSkeleton,
@@ -1021,6 +1055,5 @@
 
 
-
-bool UpdateTransform_readLocalData(Object& obj, Input& fr) 
+bool UpdateMorph_readLocalData(Object& obj, Input& fr) 
 {
     bool iteratorAdvanced = false;
@@ -1028,54 +1061,10 @@
 }
 
-bool UpdateTransform_writeLocalData(const Object& obj, Output& fw)
+bool UpdateMorph_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 iteratorAdvanced = false;
-    return iteratorAdvanced;
-}
-
-bool UpdateMorph_writeLocalData(const Object& obj, Output& fw)
-{
-    return true;
-}
-
-RegisterDotOsgWrapperProxy g_atkUpdateMorphProxy
+RegisterDotOsgWrapperProxy g_UpdateMorphProxy
 (
  new osgAnimation::UpdateMorph,
Index: /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/UpdateMaterial.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/UpdateMaterial.cpp (revision 11009)
+++ /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/UpdateMaterial.cpp (revision 11009)
@@ -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
+);
Index: /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/UpdateMatrixTransform.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/UpdateMatrixTransform.cpp (revision 11009)
+++ /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/UpdateMatrixTransform.cpp (revision 11009)
@@ -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
+    );
+
Index: /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/Matrix.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/Matrix.cpp (revision 11009)
+++ /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/Matrix.cpp (revision 11009)
@@ -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;
+}
+
Index: /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/Matrix.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/Matrix.h (revision 11009)
+++ /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/Matrix.h (revision 11009)
@@ -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
Index: /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/StackedTransform.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/StackedTransform.cpp (revision 11009)
+++ /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/StackedTransform.cpp (revision 11009)
@@ -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
+    );
Index: /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/CMakeLists.txt
===================================================================
--- /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/CMakeLists.txt (revision 10975)
+++ /OpenSceneGraph/trunk/src/osgWrappers/deprecated-dotosg/osgAnimation/CMakeLists.txt (revision 11009)
@@ -6,4 +6,2 @@
 #### end var setup  ###
 SETUP_PLUGIN(osganimation)
-
-
Index: /OpenSceneGraph/trunk/examples/osganimationsolid/osganimationsolid.cpp
===================================================================
--- /OpenSceneGraph/trunk/examples/osganimationsolid/osganimationsolid.cpp (revision 9459)
+++ /OpenSceneGraph/trunk/examples/osganimationsolid/osganimationsolid.cpp (revision 11009)
@@ -1,4 +1,4 @@
 /*  -*-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  
@@ -23,5 +23,6 @@
 #include <osgAnimation/BasicAnimationManager>
 #include <osgAnimation/Channel>
-#include <osgAnimation/UpdateCallback>
+#include <osgAnimation/UpdateMatrixTransform>
+#include <osgAnimation/StackedTranslateElement>
 
 using namespace osgAnimation;
@@ -75,5 +76,7 @@
     trans->setName("AnimatedNode");
     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->addChild (geode.get());
Index: /OpenSceneGraph/trunk/examples/osganimationskinning/osganimationskinning.cpp
===================================================================
--- /OpenSceneGraph/trunk/examples/osganimationskinning/osganimationskinning.cpp (revision 10697)
+++ /OpenSceneGraph/trunk/examples/osganimationskinning/osganimationskinning.cpp (revision 11009)
@@ -19,4 +19,5 @@
 #include <osgViewer/Viewer>
 #include <osgGA/TrackballManipulator>
+#include <osgDB/WriteFile>
 #include <osgUtil/SmoothingVisitor>
 #include <osg/io_utils>
@@ -26,4 +27,9 @@
 #include <osgAnimation/RigGeometry>
 #include <osgAnimation/BasicAnimationManager>
+#include <osgAnimation/UpdateMatrixTransform>
+#include <osgAnimation/UpdateBone>
+#include <osgAnimation/StackedTransform>
+#include <osgAnimation/StackedTranslateElement>
+#include <osgAnimation/StackedRotateAxisElement>
 
 osg::Geode* createAxis()
@@ -59,6 +65,7 @@
 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> colors (new osg::Vec3Array());
@@ -120,5 +127,6 @@
     geometry->addPrimitiveSet(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, array->size(), &array->front()));
     geometry->setUseDisplayList( false );
-    return geometry;
+    riggeometry->setSourceGeometry(geometry);
+    return riggeometry;
 }
 
@@ -164,20 +172,25 @@
     skelroot->setDefaultUpdateCallback();
     osg::ref_ptr<osgAnimation::Bone> root = new osgAnimation::Bone;
-    {
-        root->setBindMatrixInBoneSpace(osg::Matrix::identity());
-        root->setBindMatrixInBoneSpace(osg::Matrix::translate(-1,0,0));
-        root->setName("root");
-        root->setDefaultUpdateCallback();
-    }
+    root->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(-1,0,0)));
+    root->setName("root");
+    osgAnimation::UpdateBone* pRootUpdate = new osgAnimation::UpdateBone("root");
+    pRootUpdate->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("translate",osg::Vec3(-1,0,0)));
+    root->setUpdateCallback(pRootUpdate);
 
     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->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;
-    right1->setBindMatrixInBoneSpace(osg::Matrix::translate(1,0,0));
+    right1->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(1,0,0)));
     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());
@@ -191,15 +204,12 @@
     osgAnimation::Animation* anim = new osgAnimation::Animation;
     {
-        osgAnimation::QuatKeyframeContainer* keys0 = new osgAnimation::QuatKeyframeContainer;
-        osg::Quat rotate;
-        rotate.makeRotate(osg::PI_2, osg::Vec3(0,0,1));
-        keys0->push_back(osgAnimation::QuatKeyframe(0,osg::Quat(0,0,0,1)));
-        keys0->push_back(osgAnimation::QuatKeyframe(3,rotate));
-        keys0->push_back(osgAnimation::QuatKeyframe(6,rotate));
-        osgAnimation::QuatSphericalLinearSampler* sampler = new osgAnimation::QuatSphericalLinearSampler;
+        osgAnimation::FloatKeyframeContainer* keys0 = new osgAnimation::FloatKeyframeContainer;
+        keys0->push_back(osgAnimation::FloatKeyframe(0,0));
+        keys0->push_back(osgAnimation::FloatKeyframe(3,osg::PI_2));
+        keys0->push_back(osgAnimation::FloatKeyframe(6,osg::PI_2));
+        osgAnimation::FloatLinearSampler* sampler = new osgAnimation::FloatLinearSampler;
         sampler->setKeyframeContainer(keys0);
-        // osgAnimation::AnimationUpdateCallback* cb = dynamic_cast<osgAnimation::AnimationUpdateCallback*>(right0->getUpdateCallback());
-        osgAnimation::QuatSphericalLinearChannel* channel = new osgAnimation::QuatSphericalLinearChannel(sampler);
-        channel->setName("quaternion");
+        osgAnimation::FloatLinearChannel* channel = new osgAnimation::FloatLinearChannel(sampler);
+        channel->setName("rotate");
         channel->setTargetName("right0");
         anim->addChannel(channel);
@@ -207,15 +217,12 @@
 
     {
-        osgAnimation::QuatKeyframeContainer* keys1 = new osgAnimation::QuatKeyframeContainer;
-        osg::Quat rotate;
-        rotate.makeRotate(osg::PI_2, osg::Vec3(0,0,1));
-        keys1->push_back(osgAnimation::QuatKeyframe(0,osg::Quat(0,0,0,1)));
-        keys1->push_back(osgAnimation::QuatKeyframe(3,osg::Quat(0,0,0,1)));
-        keys1->push_back(osgAnimation::QuatKeyframe(6,rotate));
-        osgAnimation::QuatSphericalLinearSampler* sampler = new osgAnimation::QuatSphericalLinearSampler;
+        osgAnimation::FloatKeyframeContainer* keys1 = new osgAnimation::FloatKeyframeContainer;
+        keys1->push_back(osgAnimation::FloatKeyframe(0,0));
+        keys1->push_back(osgAnimation::FloatKeyframe(3,0));
+        keys1->push_back(osgAnimation::FloatKeyframe(6,osg::PI_2));
+        osgAnimation::FloatLinearSampler* sampler = new osgAnimation::FloatLinearSampler;
         sampler->setKeyframeContainer(keys1);
-        osgAnimation::QuatSphericalLinearChannel* channel = new osgAnimation::QuatSphericalLinearChannel(sampler);
-        //osgAnimation::AnimationUpdateCallback* cb = dynamic_cast<osgAnimation::AnimationUpdateCallback*>(right1->getUpdateCallback());
-        channel->setName("quaternion");
+        osgAnimation::FloatLinearChannel* channel = new osgAnimation::FloatLinearChannel(sampler);
+        channel->setName("rotate");
         channel->setTargetName("right1");
         anim->addChannel(channel);
@@ -246,5 +253,5 @@
     geode->addDrawable(geom);
     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->setDataVariance(osg::Object::DYNAMIC);
@@ -261,4 +268,5 @@
     }
 
+    osgDB::writeNodeFile(*scene, "skinning.osg");
     return 0;
 }
Index: /OpenSceneGraph/trunk/examples/osganimationhardware/osganimationhardware.cpp
===================================================================
--- /OpenSceneGraph/trunk/examples/osganimationhardware/osganimationhardware.cpp (revision 10923)
+++ /OpenSceneGraph/trunk/examples/osganimationhardware/osganimationhardware.cpp (revision 11009)
@@ -30,4 +30,5 @@
 #include <osgAnimation/RigTransformHardware>
 #include <osgAnimation/AnimationManagerBase>
+#include <osgAnimation/BoneMapVisitor>
 
 #include <sstream>
@@ -44,4 +45,13 @@
 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)
     {
@@ -57,5 +67,7 @@
         }
 
-        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()))
@@ -137,6 +149,9 @@
         }
 
+#if 0
         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.setInitialBound(new osg::Drawable::ComputeBoundingBoxCallback);
+#endif
     }
 };
