diff --git a/examples/osganimationhardware/osganimationhardware.cpp b/examples/osganimationhardware/osganimationhardware.cpp index 420387f64..ed3d9163e 100644 --- a/examples/osganimationhardware/osganimationhardware.cpp +++ b/examples/osganimationhardware/osganimationhardware.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -43,6 +44,15 @@ osg::ref_ptr program; // show how to override the default RigTransformHardware for customized usage 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) { osg::Vec3Array* pos = dynamic_cast(geom.getVertexArray()); @@ -56,7 +66,9 @@ struct MyRigTransformHardware : public osgAnimation::RigTransformHardware return false; } - osgAnimation::Bone::BoneMap bm = geom.getSkeleton()->getBoneMap(); + osgAnimation::BoneMapVisitor mapVisitor; + geom.getSkeleton()->accept(mapVisitor); + osgAnimation::BoneMap bm = mapVisitor.getBoneMap(); if (!createPalette(pos->size(),bm, geom.getVertexInfluenceSet().getVertexToBoneList())) return false; @@ -136,8 +148,11 @@ struct SetupRigGeometry : public osg::NodeVisitor rig->setRigTransformImplementation(new MyRigTransformHardware); } +#if 0 if (geom.getName() != std::string("BoundingBox")) // we disable compute of bounding box for all geometry except our bounding box geom.setComputeBoundingBoxCallback(new osg::Drawable::ComputeBoundingBoxCallback); +// geom.setInitialBound(new osg::Drawable::ComputeBoundingBoxCallback); +#endif } }; diff --git a/examples/osganimationskinning/osganimationskinning.cpp b/examples/osganimationskinning/osganimationskinning.cpp index 66e81a3fd..2cfba6cbc 100644 --- a/examples/osganimationskinning/osganimationskinning.cpp +++ b/examples/osganimationskinning/osganimationskinning.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -25,6 +26,11 @@ #include #include #include +#include +#include +#include +#include +#include osg::Geode* createAxis() { @@ -58,8 +64,9 @@ osg::Geode* createAxis() 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 vertices (new osg::Vec3Array()); osg::ref_ptr colors (new osg::Vec3Array()); geometry->setVertexArray (vertices.get()); @@ -119,7 +126,8 @@ osgAnimation::RigGeometry* createTesselatedBox(int nsplit, float size) geometry->addPrimitiveSet(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, array->size(), &array->front())); geometry->setUseDisplayList( false ); - return geometry; + riggeometry->setSourceGeometry(geometry); + return riggeometry; } @@ -163,22 +171,27 @@ int main (int argc, char* argv[]) osg::ref_ptr skelroot = new osgAnimation::Skeleton; skelroot->setDefaultUpdateCallback(); osg::ref_ptr 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 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 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()); right0->addChild(right1.get()); @@ -190,33 +203,27 @@ int main (int argc, char* argv[]) 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(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); } { - 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(right1->getUpdateCallback()); - channel->setName("quaternion"); + osgAnimation::FloatLinearChannel* channel = new osgAnimation::FloatLinearChannel(sampler); + channel->setName("rotate"); channel->setTargetName("right1"); anim->addChannel(channel); } @@ -245,7 +252,7 @@ int main (int argc, char* argv[]) osg::Geode* geode = new osg::Geode; geode->addDrawable(geom); skelroot->addChild(geode); - osg::ref_ptr src = dynamic_cast(geom->getVertexArray()); + osg::ref_ptr src = dynamic_cast(geom->getSourceGeometry()->getVertexArray()); geom->getOrCreateStateSet()->setMode(GL_LIGHTING, false); geom->setDataVariance(osg::Object::DYNAMIC); @@ -260,6 +267,7 @@ int main (int argc, char* argv[]) viewer.frame(); } + osgDB::writeNodeFile(*scene, "skinning.osg"); return 0; } diff --git a/examples/osganimationsolid/osganimationsolid.cpp b/examples/osganimationsolid/osganimationsolid.cpp index 6fd67c7a2..6ce649b78 100644 --- a/examples/osganimationsolid/osganimationsolid.cpp +++ b/examples/osganimationsolid/osganimationsolid.cpp @@ -1,5 +1,5 @@ /* -*-c++-*- - * Copyright (C) 2008 Cedric Pinson + * Copyright (C) 2008 Cedric Pinson * * 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 @@ -22,7 +22,8 @@ #include #include -#include +#include +#include using namespace osgAnimation; @@ -74,7 +75,9 @@ int main (int argc, char* argv[]) osg::ref_ptr trans = new osg::MatrixTransform(); 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()); diff --git a/include/osgAnimation/AnimationUpdateCallback b/include/osgAnimation/AnimationUpdateCallback new file mode 100644 index 000000000..9cb526773 --- /dev/null +++ b/include/osgAnimation/AnimationUpdateCallback @@ -0,0 +1,72 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include +#include +#include + +namespace osgAnimation +{ + + class AnimationUpdateCallbackBase : public virtual osg::Object + { + public: + virtual bool link(Channel* channel) = 0; + virtual int link(Animation* animation) = 0; + }; + + + template + 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); + + 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 diff --git a/include/osgAnimation/Bone b/include/osgAnimation/Bone index ae98d2385..43e01d78c 100644 --- a/include/osgAnimation/Bone +++ b/include/osgAnimation/Bone @@ -16,38 +16,20 @@ * Michael Platings */ -#ifndef OSGANIMATION_BONE_H -#define OSGANIMATION_BONE_H +#ifndef OSGANIMATION_BONE +#define OSGANIMATION_BONE 1 -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include namespace osgAnimation { // 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 PointerType; - typedef std::map BoneMap; typedef osg::Matrix MatrixType; META_Node(osgAnimation, Bone); @@ -56,128 +38,24 @@ namespace osgAnimation void setDefaultUpdateCallback(const std::string& name = ""); - class OSGANIMATION_EXPORT UpdateBone : public AnimationUpdateCallback - { - protected: - osg::ref_ptr _position; - osg::ref_ptr _quaternion; - osg::ref_ptr _scale; - - public: - META_Object(osgAnimation, UpdateBone); - UpdateBone(const UpdateBone& apc,const osg::CopyOp& copyop); - - UpdateBone(const std::string& name = "") : AnimationUpdateCallback (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 > BoneMap; } #endif diff --git a/include/osgAnimation/BoneMapVisitor b/include/osgAnimation/BoneMapVisitor index 97cfa143f..d41538493 100644 --- a/include/osgAnimation/BoneMapVisitor +++ b/include/osgAnimation/BoneMapVisitor @@ -15,8 +15,8 @@ * Cedric Pinson */ -#ifndef OSGANIMATION_BONEMAP_VISITOR_H -#define OSGANIMATION_BONEMAP_VISITOR_H 1 +#ifndef OSGANIMATION_BONEMAP_VISITOR +#define OSGANIMATION_BONEMAP_VISITOR 1 #include #include @@ -32,10 +32,10 @@ namespace osgAnimation void apply(osg::Node&); void apply(osg::Transform& node); - const Bone::BoneMap& getBoneMap() const; + const BoneMap& getBoneMap() const; protected: - Bone::BoneMap _map; + BoneMap _map; }; } diff --git a/include/osgAnimation/Channel b/include/osgAnimation/Channel index 0c98267b7..a91316406 100644 --- a/include/osgAnimation/Channel +++ b/include/osgAnimation/Channel @@ -172,6 +172,7 @@ namespace osgAnimation typedef TemplateChannel Vec3LinearChannel; typedef TemplateChannel Vec4LinearChannel; typedef TemplateChannel QuatSphericalLinearChannel; + typedef TemplateChannel MatrixLinearChannel; typedef TemplateChannel FloatCubicBezierChannel; typedef TemplateChannel DoubleCubicBezierChannel; diff --git a/include/osgAnimation/ComputeBindMatrixVisitor b/include/osgAnimation/ComputeBindMatrixVisitor deleted file mode 100644 index a99ce15bc..000000000 --- a/include/osgAnimation/ComputeBindMatrixVisitor +++ /dev/null @@ -1,43 +0,0 @@ -/* -*-c++-*- - * Copyright (C) 2008 Cedric Pinson - * - * 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 -#include - -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(&node); - if (!bone) - return; - if (bone->needToComputeBindMatrix()) - bone->computeBindMatrix(); - - traverse(node); - } - }; - -} - -#endif diff --git a/include/osgAnimation/CubicBezier b/include/osgAnimation/CubicBezier index 70f270dbd..2bb514d7f 100644 --- a/include/osgAnimation/CubicBezier +++ b/include/osgAnimation/CubicBezier @@ -12,60 +12,61 @@ * OpenSceneGraph Public License for more details. */ -#ifndef OSGANIMATION_CUBIC_BEZIER_H -#define OSGANIMATION_CUBIC_BEZIER_H +#ifndef OSGANIMATION_CUBIC_BEZIER +#define OSGANIMATION_CUBIC_BEZIER 1 #include #include #include -#include namespace osgAnimation { template - 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) - { - 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; - } - + public: TemplateCubicBezier() {} - const T& getPosition() const { return mPoint[0];} - const T& getTangentPoint1() const { return mPoint[1];} - const T& getTangentPoint2() const { return mPoint[2];} - - // steaming operators. - friend std::ostream& operator << (std::ostream& output, const TemplateCubicBezier& vec) + TemplateCubicBezier(const T& p, const T& i, const T& o) : _position(p), _controlPointIn(i), _controlPointOut(o) { - output << vec.mPoint[0] << " " - << vec.mPoint[1] << " " - << vec.mPoint[2]; + } + + // Constructor with value only + TemplateCubicBezier(const T& p) : _position(p), _controlPointIn(p), _controlPointOut(p) + { + } + + const T& getPosition() const { return _position;} + const T& getControlPointIn() const { return _controlPointIn;} + const T& getControlPointOut() const { return _controlPointOut;} + + T& getPosition() { return _position;} + T& getControlPointIn() { return _controlPointIn;} + T& getControlPointOut() { return _controlPointOut;} + + void setPosition(const T& v) {_position = v;} + void setControlPointIn(const T& v) {_controlPointIn = v;} + void setControlPointOut(const T& v) {_controlPointOut = v;} + + // steaming operators. + friend std::ostream& operator << (std::ostream& output, const TemplateCubicBezier& tcb) + { + output << tcb._position << " " + << tcb._controlPointIn << " " + << tcb._controlPointOut; return output; // to enable cascading } - friend std::istream& operator >> (std::istream& input, TemplateCubicBezier& vec) + friend std::istream& operator >> (std::istream& input, TemplateCubicBezier& 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 FloatCubicBezier; typedef TemplateCubicBezier DoubleCubicBezier; diff --git a/include/osgAnimation/EaseMotion b/include/osgAnimation/EaseMotion index 3eb6d9478..7a41e3a50 100644 --- a/include/osgAnimation/EaseMotion +++ b/include/osgAnimation/EaseMotion @@ -313,7 +313,7 @@ namespace osgAnimation { osg::notify(osg::WARN) << "CompositeMotion::getValueInNormalizedRange no Motion in the CompositeMotion, add motion to have result" << std::endl; return; } - for (MotionList::const_iterator it = _motions.begin(); it != _motions.end(); it++) + for (MotionList::const_iterator it = _motions.begin(); it != _motions.end(); ++it) { const Motion* motion = static_cast(it->get()); float durationInRange = motion->getDuration() / getDuration(); diff --git a/include/osgAnimation/Interpolator b/include/osgAnimation/Interpolator index f1c7eddac..a5bda3b0e 100644 --- a/include/osgAnimation/Interpolator +++ b/include/osgAnimation/Interpolator @@ -205,8 +205,8 @@ namespace osgAnimation float t2 = t * t; 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); result = v0 + v1 + v2 + v3; @@ -228,6 +228,7 @@ namespace osgAnimation typedef TemplateLinearInterpolator Vec3PackedLinearInterpolator; typedef TemplateLinearInterpolator Vec4LinearInterpolator; typedef TemplateSphericalLinearInterpolator QuatSphericalLinearInterpolator; + typedef TemplateLinearInterpolator MatrixLinearInterpolator; typedef TemplateCubicBezierInterpolator FloatCubicBezierInterpolator; typedef TemplateCubicBezierInterpolator DoubleCubicBezierInterpolator; diff --git a/include/osgAnimation/Keyframe b/include/osgAnimation/Keyframe index e194cc5ca..c83c31746 100644 --- a/include/osgAnimation/Keyframe +++ b/include/osgAnimation/Keyframe @@ -23,6 +23,7 @@ #include #include #include +#include namespace osgAnimation { @@ -114,6 +115,9 @@ namespace osgAnimation typedef TemplateKeyframe QuatKeyframe; typedef TemplateKeyframeContainer QuatKeyframeContainer; + typedef TemplateKeyframe MatrixKeyframe; + typedef TemplateKeyframeContainer MatrixKeyframeContainer; + typedef TemplateKeyframe Vec3PackedKeyframe; typedef TemplateKeyframeContainer Vec3PackedKeyframeContainer; diff --git a/include/osgAnimation/MorphGeometry b/include/osgAnimation/MorphGeometry index d03d2a7f2..2e350abca 100644 --- a/include/osgAnimation/MorphGeometry +++ b/include/osgAnimation/MorphGeometry @@ -16,8 +16,8 @@ #define OSGANIMATION_MORPHGEOMETRY_H #include +#include #include -#include namespace osgAnimation { diff --git a/include/osgAnimation/RigGeometry b/include/osgAnimation/RigGeometry index 6469d5fc7..ac0deea8a 100644 --- a/include/osgAnimation/RigGeometry +++ b/include/osgAnimation/RigGeometry @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace osgAnimation @@ -28,7 +29,7 @@ namespace osgAnimation public: RigGeometry(); - RigGeometry(const osg::Geometry& b); +// RigGeometry(const osg::Geometry& b); RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); META_Object(osgAnimation, RigGeometry); @@ -63,8 +64,15 @@ namespace osgAnimation const osg::Matrix& getMatrixFromSkeletonToGeometry() const; const osg::Matrix& getInvMatrixFromSkeletonToGeometry() const; - protected: + osg::Geometry* getSourceGeometry(); + const osg::Geometry* getSourceGeometry() const; + void setSourceGeometry(osg::Geometry* geometry); + void copyFrom(osg::Geometry& from); + + protected: + + osg::ref_ptr _geometry; osg::ref_ptr _rigTransformImplementation; VertexInfluenceSet _vertexInfluenceSet; @@ -104,7 +112,10 @@ namespace osgAnimation geom->getParents()[0]->accept(finder); 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()); } diff --git a/include/osgAnimation/RigTransform b/include/osgAnimation/RigTransform index 94c0aeba2..3c97f7e8c 100644 --- a/include/osgAnimation/RigTransform +++ b/include/osgAnimation/RigTransform @@ -12,8 +12,8 @@ * OpenSceneGraph Public License for more details. */ -#ifndef OSGANIMATION_RIGTRANSFORM_H -#define OSGANIMATION_RIGTRANSFORM_H +#ifndef OSGANIMATION_RIGTRANSFORM +#define OSGANIMATION_RIGTRANSFORM 1 #include @@ -25,14 +25,10 @@ namespace osgAnimation class RigTransform : public osg::Referenced { 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; }; } diff --git a/include/osgAnimation/RigTransformHardware b/include/osgAnimation/RigTransformHardware index 5ff192252..53a0c8c92 100644 --- a/include/osgAnimation/RigTransformHardware +++ b/include/osgAnimation/RigTransformHardware @@ -12,8 +12,8 @@ * OpenSceneGraph Public License for more details. */ -#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 #include @@ -32,7 +32,6 @@ namespace osgAnimation public: typedef osg::Matrix MatrixType; typedef osgAnimation::Bone BoneType; - typedef Bone::BoneMap BoneMap; typedef std::vector > BoneWeightAttribList; typedef std::vector > BonePalette; @@ -48,6 +47,8 @@ namespace osgAnimation }; typedef std::vector > VertexIndexWeightList; + RigTransformHardware(); + osg::Vec4Array* getVertexAttrib(int index); int getNumVertexAttrib(); @@ -59,13 +60,13 @@ namespace osgAnimation bool createPalette(int nbVertexes, BoneMap boneMap, const VertexInfluenceSet::VertexIndexToBoneWeightMap& vertexIndexToBoneWeightMap); - - virtual bool init(RigGeometry&); - virtual void update(RigGeometry&); - + virtual void operator()(RigGeometry&); void setShader(osg::Shader*); + protected: + bool init(RigGeometry&); + BoneWeightAttribList createVertexAttribList(); osg::Uniform* createVertexUniform(); @@ -76,6 +77,8 @@ namespace osgAnimation BoneWeightAttribList _boneWeightAttribArrays; osg::ref_ptr _uniformMatrixPalette; osg::ref_ptr _shader; + + bool _needInit; }; } diff --git a/include/osgAnimation/RigTransformSoftware b/include/osgAnimation/RigTransformSoftware index 15cacd60a..16c06c619 100644 --- a/include/osgAnimation/RigTransformSoftware +++ b/include/osgAnimation/RigTransformSoftware @@ -12,12 +12,14 @@ * OpenSceneGraph Public License for more details. */ -#ifndef OSGANIMATION_RIG_TRANSFORM_SOFTWARE_H -#define OSGANIMATION_RIG_TRANSFORM_SOFTWARE_H 1 +#ifndef OSGANIMATION_RIGTRANSFORM_SOFTWARE +#define OSGANIMATION_RIGTRANSFORM_SOFTWARE 1 #include #include #include +#include +#include namespace osgAnimation { @@ -29,8 +31,8 @@ namespace osgAnimation { public: - virtual bool init(RigGeometry&); - virtual void update(RigGeometry&); + RigTransformSoftware(); + virtual void operator()(RigGeometry&); class BoneWeight @@ -156,16 +158,13 @@ namespace osgAnimation } } - const std::vector& getPositionSource() const { return _positionSource;} - const std::vector& 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 _boneSetVertexSet; - std::vector _positionSource; - std::vector _normalSource; + + bool _needInit; }; } diff --git a/include/osgAnimation/Sampler b/include/osgAnimation/Sampler index 55a1b9cc9..cda31b982 100644 --- a/include/osgAnimation/Sampler +++ b/include/osgAnimation/Sampler @@ -125,6 +125,7 @@ namespace osgAnimation typedef TemplateSampler Vec3LinearSampler; typedef TemplateSampler Vec4LinearSampler; typedef TemplateSampler QuatSphericalLinearSampler; + typedef TemplateSampler MatrixLinearSampler; typedef TemplateSampler FloatCubicBezierSampler; typedef TemplateSampler DoubleCubicBezierSampler; diff --git a/include/osgAnimation/Skeleton b/include/osgAnimation/Skeleton index 1c75d0c1b..c476e6e2c 100644 --- a/include/osgAnimation/Skeleton +++ b/include/osgAnimation/Skeleton @@ -16,12 +16,12 @@ #define OSGANIMATION_SKELETON 1 #include -#include +#include namespace osgAnimation { - class OSGANIMATION_EXPORT Skeleton : public Bone + class OSGANIMATION_EXPORT Skeleton : public osg::MatrixTransform { public: META_Node(osgAnimation, Skeleton); @@ -40,9 +40,8 @@ namespace osgAnimation Skeleton(); Skeleton(const Skeleton&, const osg::CopyOp&); - void setDefaultUpdateCallback(); - void computeBindMatrix(); + }; } diff --git a/include/osgAnimation/StackedMatrixElement b/include/osgAnimation/StackedMatrixElement new file mode 100644 index 000000000..1a33c7ccb --- /dev/null +++ b/include/osgAnimation/StackedMatrixElement @@ -0,0 +1,54 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include +#include +#include + +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 _target; + }; + +} + +#endif diff --git a/include/osgAnimation/StackedQuaternionElement b/include/osgAnimation/StackedQuaternionElement new file mode 100644 index 000000000..1384950c1 --- /dev/null +++ b/include/osgAnimation/StackedQuaternionElement @@ -0,0 +1,54 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include +#include + +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 _target; + }; + +} + +#endif diff --git a/include/osgAnimation/StackedRotateAxisElement b/include/osgAnimation/StackedRotateAxisElement new file mode 100644 index 000000000..d5a160869 --- /dev/null +++ b/include/osgAnimation/StackedRotateAxisElement @@ -0,0 +1,59 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include +#include +#include + +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 _target; + }; + +} + +#endif + diff --git a/include/osgAnimation/StackedScaleElement b/include/osgAnimation/StackedScaleElement new file mode 100644 index 000000000..a36cc5be3 --- /dev/null +++ b/include/osgAnimation/StackedScaleElement @@ -0,0 +1,56 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include +#include +#include + +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 _target; + }; + + +} + +#endif + diff --git a/include/osgAnimation/StackedTransform b/include/osgAnimation/StackedTransform new file mode 100644 index 000000000..59c1eed4f --- /dev/null +++ b/include/osgAnimation/StackedTransform @@ -0,0 +1,42 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include +#include + +namespace osgAnimation +{ + + class OSGANIMATION_EXPORT StackedTransform : public osg::MixinVector > + { + 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 diff --git a/include/osgAnimation/StackedTransformElement b/include/osgAnimation/StackedTransformElement new file mode 100644 index 000000000..3a6628ff1 --- /dev/null +++ b/include/osgAnimation/StackedTransformElement @@ -0,0 +1,42 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include +#include + +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 diff --git a/include/osgAnimation/StackedTranslateElement b/include/osgAnimation/StackedTranslateElement new file mode 100644 index 000000000..9728d0bee --- /dev/null +++ b/include/osgAnimation/StackedTranslateElement @@ -0,0 +1,54 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include +#include + +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 _target; + }; + +} + +#endif diff --git a/include/osgAnimation/Target b/include/osgAnimation/Target index c7c43362b..4e519c01e 100644 --- a/include/osgAnimation/Target +++ b/include/osgAnimation/Target @@ -121,6 +121,7 @@ namespace osgAnimation _target *= 1.0/sqrt(len2); } + typedef TemplateTarget MatrixTarget; typedef TemplateTarget QuatTarget; typedef TemplateTarget Vec3Target; typedef TemplateTarget Vec4Target; diff --git a/include/osgAnimation/UpdateBone b/include/osgAnimation/UpdateBone new file mode 100644 index 000000000..916b2b912 --- /dev/null +++ b/include/osgAnimation/UpdateBone @@ -0,0 +1,36 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include + +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 diff --git a/include/osgAnimation/UpdateCallback b/include/osgAnimation/UpdateCallback deleted file mode 100644 index a2cb32a4e..000000000 --- a/include/osgAnimation/UpdateCallback +++ /dev/null @@ -1,121 +0,0 @@ -/* -*-c++-*- - * Copyright (C) 2008 Cedric Pinson - * - * 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 -#include -#include -#include -#include -#include -#include - -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 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); - - 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 - { - protected: - osg::ref_ptr _euler; - osg::ref_ptr _position; - osg::ref_ptr _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 - { - protected: - osg::ref_ptr _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 diff --git a/include/osgAnimation/UpdateMaterial b/include/osgAnimation/UpdateMaterial new file mode 100644 index 000000000..8d9fe6a53 --- /dev/null +++ b/include/osgAnimation/UpdateMaterial @@ -0,0 +1,46 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include +#include +#include + +namespace osgAnimation +{ + + class OSGANIMATION_EXPORT UpdateMaterial : public AnimationUpdateCallback + { + protected: + osg::ref_ptr _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 diff --git a/include/osgAnimation/UpdateMatrixTransform b/include/osgAnimation/UpdateMatrixTransform new file mode 100644 index 000000000..94be6b689 --- /dev/null +++ b/include/osgAnimation/UpdateMatrixTransform @@ -0,0 +1,48 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include +#include +#include + +namespace osgAnimation +{ + + class OSGANIMATION_EXPORT UpdateMatrixTransform : public AnimationUpdateCallback + { + 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 diff --git a/src/osgAnimation/Action.cpp b/src/osgAnimation/Action.cpp index fa28f7de8..0c4648d8a 100644 --- a/src/osgAnimation/Action.cpp +++ b/src/osgAnimation/Action.cpp @@ -36,7 +36,7 @@ Action::Callback* Action::getFrameCallback(unsigned int frame) void Action::removeCallback(Callback* cb) { std::vector 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()) { @@ -52,7 +52,7 @@ void Action::removeCallback(Callback* cb) } } } - for (std::vector::iterator it = keyToRemove.begin(); it != keyToRemove.end(); it++) + for (std::vector::iterator it = keyToRemove.begin(); it != keyToRemove.end(); ++it) _framesCallback.erase(*it); } diff --git a/src/osgAnimation/Animation.cpp b/src/osgAnimation/Animation.cpp index e8232ddb0..948d94c36 100644 --- a/src/osgAnimation/Animation.cpp +++ b/src/osgAnimation/Animation.cpp @@ -24,7 +24,7 @@ Animation::Animation(const osgAnimation::Animation& anim, const osg::CopyOp& cop _playmode(anim._playmode) { 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()); } diff --git a/src/osgAnimation/AnimationManagerBase.cpp b/src/osgAnimation/AnimationManagerBase.cpp index 83ca83e14..166165380 100644 --- a/src/osgAnimation/AnimationManagerBase.cpp +++ b/src/osgAnimation/AnimationManagerBase.cpp @@ -28,7 +28,7 @@ AnimationManagerBase::AnimationManagerBase() 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(); } @@ -67,7 +67,7 @@ AnimationManagerBase::AnimationManagerBase(const AnimationManagerBase& b, const const AnimationList& animationList = b.getAnimationList(); for (AnimationList::const_iterator it = animationList.begin(); it != animationList.end(); - it++) + ++it) { Animation* animation = dynamic_cast(it->get()->clone(copyop)); _animations.push_back(animation); @@ -85,7 +85,7 @@ void AnimationManagerBase::buildTargetReference() Animation* anim = (*iterAnim).get(); for (ChannelList::iterator it = anim->getChannels().begin(); it != anim->getChannels().end(); - it++) + ++it) _targets.insert((*it)->getTarget()); } } diff --git a/src/osgAnimation/BasicAnimationManager.cpp b/src/osgAnimation/BasicAnimationManager.cpp index 93c718978..53788ab2c 100644 --- a/src/osgAnimation/BasicAnimationManager.cpp +++ b/src/osgAnimation/BasicAnimationManager.cpp @@ -38,7 +38,7 @@ void BasicAnimationManager::stopAll() for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim ) { 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(); } _animationsPlaying.clear(); @@ -65,7 +65,7 @@ bool BasicAnimationManager::stopAnimation(Animation* pAnimation) for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim ) { 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 ) { (*it)->resetTargets(); @@ -82,7 +82,7 @@ void BasicAnimationManager::update (double time) _lastUpdate = time; // keep time of last update // 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(); // update from high priority to low priority @@ -132,7 +132,7 @@ bool BasicAnimationManager::isPlaying(Animation* pAnimation) for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim ) { 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; } @@ -145,7 +145,7 @@ bool BasicAnimationManager::isPlaying(const std::string& name) for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim ) { 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; } diff --git a/src/osgAnimation/Bone.cpp b/src/osgAnimation/Bone.cpp index 1617d4c9c..ec50b2fa7 100644 --- a/src/osgAnimation/Bone.cpp +++ b/src/osgAnimation/Bone.cpp @@ -14,94 +14,23 @@ #include #include -#include +#include #include -#include +using namespace osgAnimation; -osgAnimation::Bone::UpdateBone::UpdateBone(const osgAnimation::Bone::UpdateBone& apc,const osg::CopyOp& copyop) : - osg::Object(apc, copyop), - osgAnimation::AnimationUpdateCallback(apc, copyop) -{ - _quaternion = new osgAnimation::QuatTarget(apc._quaternion->getValue()); - _position = new osgAnimation::Vec3Target(apc._position->getValue()); - _scale = new osgAnimation::Vec3Target(apc._scale->getValue()); -} - -bool osgAnimation::Bone::UpdateBone::link(osgAnimation::Channel* channel) -{ - if (channel->getName().find("quaternion") != std::string::npos) - { - return channel->setTarget(_quaternion.get()); - } - else if (channel->getName().find("position") != std::string::npos) - { - return channel->setTarget(_position.get()); - } - else if (channel->getName().find("scale") != std::string::npos) - { - return channel->setTarget(_scale.get()); - } - else - { - osg::notify(osg::WARN) << "Channel " << channel->getName() << " does not contain a valid symbolic name for this class" << className() << std::endl; - } - return false; -} - - -/** Callback method called by the NodeVisitor when visiting a node.*/ -void osgAnimation::Bone::UpdateBone::operator()(osg::Node* node, osg::NodeVisitor* nv) -{ - if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR) - { - Bone* b = dynamic_cast(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) +Bone::Bone(const Bone& b, const osg::CopyOp& copyop) : osg::MatrixTransform(b,copyop), _invBindInSkeletonSpace(b._invBindInSkeletonSpace), _boneInSkeletonSpace(b._boneInSkeletonSpace) { } -osgAnimation::Bone::Bone(const std::string& name) +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; if (cbName.empty()) @@ -109,25 +38,12 @@ void osgAnimation::Bone::setDefaultUpdateCallback(const std::string& name) setUpdateCallback(new UpdateBone(cbName)); } -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(*it); if (pb) @@ -135,12 +51,12 @@ osgAnimation::Bone* osgAnimation::Bone::getBoneParent() } 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(*it); if (pb) @@ -148,25 +64,3 @@ const osgAnimation::Bone* osgAnimation::Bone::getBoneParent() const } 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(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(); -} diff --git a/src/osgAnimation/BoneMapVisitor.cpp b/src/osgAnimation/BoneMapVisitor.cpp index d5e1f20fb..befa9297f 100644 --- a/src/osgAnimation/BoneMapVisitor.cpp +++ b/src/osgAnimation/BoneMapVisitor.cpp @@ -16,20 +16,27 @@ */ #include +#include -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(&node); - if (bone) + if (bone) { _map[bone->getName()] = bone; traverse(node); } + Skeleton* skeleton = dynamic_cast(&node); + if (skeleton) + traverse(node); } -const osgAnimation::Bone::BoneMap& osgAnimation::BoneMapVisitor::getBoneMap() const + +const BoneMap& BoneMapVisitor::getBoneMap() const { return _map; } diff --git a/src/osgAnimation/CMakeLists.txt b/src/osgAnimation/CMakeLists.txt index 7fe99dcfc..d8849c062 100644 --- a/src/osgAnimation/CMakeLists.txt +++ b/src/osgAnimation/CMakeLists.txt @@ -19,13 +19,13 @@ SET(LIB_PUBLIC_HEADERS ${HEADER_PATH}/ActionVisitor ${HEADER_PATH}/Animation ${HEADER_PATH}/AnimationManagerBase + ${HEADER_PATH}/AnimationUpdateCallback ${HEADER_PATH}/Assert ${HEADER_PATH}/BasicAnimationManager ${HEADER_PATH}/Bone ${HEADER_PATH}/BoneMapVisitor ${HEADER_PATH}/Channel ${HEADER_PATH}/CubicBezier - ${HEADER_PATH}/ComputeBindMatrixVisitor ${HEADER_PATH}/EaseMotion ${HEADER_PATH}/Export ${HEADER_PATH}/FindParentAnimationManagerVisitor @@ -40,12 +40,21 @@ SET(LIB_PUBLIC_HEADERS ${HEADER_PATH}/RigTransformSoftware ${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 ${HEADER_PATH}/Target ${HEADER_PATH}/Timeline ${HEADER_PATH}/TimelineAnimationManager - ${HEADER_PATH}/UpdateCallback + ${HEADER_PATH}/UpdateBone + ${HEADER_PATH}/UpdateMaterial + ${HEADER_PATH}/UpdateMatrixTransform ${HEADER_PATH}/Vec3Packed ${HEADER_PATH}/VertexInfluence ) @@ -74,12 +83,20 @@ ADD_LIBRARY(${LIB_NAME} RigTransformHardware.cpp RigTransformSoftware.cpp Skeleton.cpp + StackedMatrixElement.cpp + StackedQuaternionElement.cpp + StackedRotateAxisElement.cpp + StackedScaleElement.cpp + StackedTransform.cpp + StackedTranslateElement.cpp StatsVisitor.cpp StatsHandler.cpp Target.cpp TimelineAnimationManager.cpp Timeline.cpp - UpdateCallback.cpp + UpdateBone.cpp + UpdateMaterial.cpp + UpdateMatrixTransform.cpp VertexInfluence.cpp ${OPENSCENEGRAPH_VERSIONINFO_RC} ) diff --git a/src/osgAnimation/LinkVisitor.cpp b/src/osgAnimation/LinkVisitor.cpp index 6037f8f5f..1a3065dbe 100644 --- a/src/osgAnimation/LinkVisitor.cpp +++ b/src/osgAnimation/LinkVisitor.cpp @@ -13,7 +13,7 @@ */ #include -#include +#include #include #include @@ -33,7 +33,7 @@ AnimationList& LinkVisitor::getAnimationList() { return _animations; } -void LinkVisitor::link(osgAnimation::AnimationUpdateCallbackBase* cb) +void LinkVisitor::link(AnimationUpdateCallbackBase* cb) { int result = 0; for (int i = 0; i < (int)_animations.size(); i++) @@ -49,7 +49,7 @@ void LinkVisitor::handle_stateset(osg::StateSet* stateset) if (!stateset) 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(); osgAnimation::AnimationUpdateCallbackBase* cb = dynamic_cast(sattr->getUpdateCallback()); diff --git a/src/osgAnimation/MorphGeometry.cpp b/src/osgAnimation/MorphGeometry.cpp index d2d36c7e0..0961520b1 100644 --- a/src/osgAnimation/MorphGeometry.cpp +++ b/src/osgAnimation/MorphGeometry.cpp @@ -261,18 +261,13 @@ bool UpdateMorph::link(osgAnimation::Channel* channel) if (weightIndex >= 0) { - osgAnimation::FloatLinearChannel* fc = dynamic_cast(channel); - if (fc) + osgAnimation::FloatTarget* ft = _weightTargets[weightIndex].get(); + if (!ft) { - osgAnimation::FloatTarget* ft = _weightTargets[weightIndex].get(); - if (ft == 0) - { - ft = new osgAnimation::FloatTarget; - _weightTargets[weightIndex] = ft; - } - fc->setTarget(ft); - return true; + ft = new osgAnimation::FloatTarget; + _weightTargets[weightIndex] = ft; } + return channel->setTarget(ft); } else { diff --git a/src/osgAnimation/RigGeometry.cpp b/src/osgAnimation/RigGeometry.cpp index 71e4c6f92..39b4cc879 100644 --- a/src/osgAnimation/RigGeometry.cpp +++ b/src/osgAnimation/RigGeometry.cpp @@ -12,6 +12,7 @@ * OpenSceneGraph Public License for more details. */ +#include #include #include #include @@ -71,21 +72,10 @@ RigGeometry::RigGeometry() setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback); } -RigGeometry::RigGeometry(const osg::Geometry& b) : osg::Geometry(b, osg::CopyOp::SHALLOW_COPY) -{ - _supportsDisplayList = false; - setUseVertexBufferObjects(true); - setUpdateCallback(new UpdateVertex); - setDataVariance(osg::Object::DYNAMIC); - _needToComputeMatrix = true; - _matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity(); - - // disable the computation of boundingbox for the rig mesh - setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback); -} RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) : osg::Geometry(b,copyop), + _geometry(b._geometry), _vertexInfluenceSet(b._vertexInfluenceSet), _vertexInfluenceMap(b._vertexInfluenceMap), _needToComputeMatrix(b._needToComputeMatrix) @@ -114,7 +104,7 @@ void RigGeometry::buildVertexInfluenceSet() _vertexInfluenceSet.clear(); for (osgAnimation::VertexInfluenceMap::iterator it = _vertexInfluenceMap->begin(); it != _vertexInfluenceMap->end(); - it++) + ++it) _vertexInfluenceSet.addVertexInfluence(it->second); _vertexInfluenceSet.buildVertex2BoneList(); @@ -130,7 +120,8 @@ void RigGeometry::computeMatrixFromRootSkeleton() return; } 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; } @@ -142,10 +133,67 @@ void RigGeometry::update() _rigTransformImplementation = new RigTransformSoftware; } - 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 #include +#include #include using namespace osgAnimation; + +RigTransformHardware::RigTransformHardware() +{ + _needInit = true; + _bonesPerVertex = 0; + _nbVertexes = 0; +} + osg::Vec4Array* RigTransformHardware::getVertexAttrib(int index) { if (index >= (int)_boneWeightAttribArrays.size()) @@ -67,12 +76,12 @@ bool RigTransformHardware::createPalette(int nbVertexes, BoneMap boneMap, const vertexIndexWeight.resize(nbVertexes); 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; if (boneNameCountMap.find(bw.getBoneName()) != boneNameCountMap.end()) @@ -85,7 +94,7 @@ bool RigTransformHardware::createPalette(int nbVertexes, BoneMap boneMap, const { if (boneMap.find(bw.getBoneName()) == boneMap.end()) { - 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; } boneNameCountMap[bw.getBoneName()] = 1; // for stats @@ -104,7 +113,7 @@ bool RigTransformHardware::createPalette(int nbVertexes, BoneMap boneMap, const osg::notify(osg::INFO) << "RigTransformHardware::createPalette maximum number of bone per vertex is " << maxBonePerVertex << std::endl; osg::notify(osg::INFO) << "RigTransformHardware::createPalette 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; } @@ -186,20 +195,30 @@ void RigTransformHardware::setShader(osg::Shader* shader) bool RigTransformHardware::init(RigGeometry& geom) { - osg::Vec3Array* pos = dynamic_cast(geom.getVertexArray()); - if (!pos) { + osg::Geometry& source = *geom.getSourceGeometry(); + osg::Vec3Array* positionSrc = dynamic_cast(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; + if (!geom.getSkeleton()) + { + osg::notify(osg::WARN) << "RigTransformHardware no skeleton set in geometry " << geom.getName() << std::endl; return false; } - Bone::BoneMap bm = geom.getSkeleton()->getBoneMap(); - if (!createPalette(pos->size(),bm, geom.getVertexInfluenceSet().getVertexToBoneList())) + // copy shallow from source geometry to rig + geom.copyFrom(source); + + + BoneMapVisitor mapVisitor; + geom.getSkeleton()->accept(mapVisitor); + BoneMap bm = mapVisitor.getBoneMap(); + + if (!createPalette(positionSrc->size(),bm, geom.getVertexInfluenceSet().getVertexToBoneList())) return false; osg::ref_ptr program = new osg::Program; @@ -244,7 +263,10 @@ bool RigTransformHardware::init(RigGeometry& geom) _needInit = false; return true; } -void RigTransformHardware::update(RigGeometry& geom) +void RigTransformHardware::operator()(RigGeometry& geom) { + if (_needInit) + if (!init(geom)) + return; computeMatrixPaletteUniform(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry()); } diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 853457679..78af3d396 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -13,49 +13,92 @@ */ +#include #include +#include #include using namespace osgAnimation; +RigTransformSoftware::RigTransformSoftware() +{ + _needInit = true; +} + bool RigTransformSoftware::init(RigGeometry& geom) { 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(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(source.getVertexArray()); + osg::Vec3Array* positionDst = dynamic_cast(destination.getVertexArray()); + if (positionSrc && (!positionDst || (positionDst->size() != positionSrc->size()) ) ) { - _positionSource = std::vector(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(geom.getNormalArray()); - if (normal && _normalSource.size() != normal->size()) + + osg::Vec3Array* normalSrc = dynamic_cast(source.getNormalArray()); + osg::Vec3Array* normalDst = dynamic_cast(destination.getNormalArray()); + if (normalSrc && (!normalDst || (normalDst->size() != normalSrc->size()) ) ) { - _normalSource = std::vector(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(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry(), &_positionSource.front(), &pos->front()); - pos->dirty(); + compute(geom.getMatrixFromSkeletonToGeometry(), + geom.getInvMatrixFromSkeletonToGeometry(), + &positionSrc->front(), + &positionDst->front()); + positionDst->dirty(); } - if (!_normalSource.empty()) + + if (normalDst && !normalDst->empty()) { - computeNormal(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry(), &_normalSource.front(), &normal->front()); - normal->dirty(); + computeNormal(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(); @@ -72,7 +115,7 @@ void RigTransformSoftware::initVertexSetFromBones(const Bone::BoneMap& map, cons { 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()) { osg::notify(osg::WARN) << "RigTransformSoftware Bone " << bname << " not found, skip the influence group " < #include +#include 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; } @@ -45,7 +46,7 @@ public: bool foundNonBone = false; - for (unsigned i = 0; i < bone->getNumChildren(); ++i) + for (unsigned int i = 0; i < bone->getNumChildren(); ++i) { if (dynamic_cast(bone->getChild(i))) { @@ -76,11 +77,13 @@ void Skeleton::UpdateSkeleton::operator()(osg::Node* node, osg::NodeVisitor* nv) if (_needValidate && skeleton) { 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); } @@ -89,9 +92,3 @@ void Skeleton::setDefaultUpdateCallback() { setUpdateCallback(new Skeleton::UpdateSkeleton ); } - -void Skeleton::computeBindMatrix() -{ - _invBindInSkeletonSpace = osg::Matrix::inverse(_bindInBoneSpace); - _needToRecomputeBindMatrix = false; -} diff --git a/src/osgAnimation/StackedMatrixElement.cpp b/src/osgAnimation/StackedMatrixElement.cpp new file mode 100644 index 000000000..909ac26aa --- /dev/null +++ b/src/osgAnimation/StackedMatrixElement.cpp @@ -0,0 +1,40 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 + +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(); +} diff --git a/src/osgAnimation/StackedQuaternionElement.cpp b/src/osgAnimation/StackedQuaternionElement.cpp new file mode 100644 index 000000000..c0fb89e24 --- /dev/null +++ b/src/osgAnimation/StackedQuaternionElement.cpp @@ -0,0 +1,53 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 + +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();} diff --git a/src/osgAnimation/StackedRotateAxisElement.cpp b/src/osgAnimation/StackedRotateAxisElement.cpp new file mode 100644 index 000000000..a6188601a --- /dev/null +++ b/src/osgAnimation/StackedRotateAxisElement.cpp @@ -0,0 +1,55 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 + +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)); } diff --git a/src/osgAnimation/StackedScaleElement.cpp b/src/osgAnimation/StackedScaleElement.cpp new file mode 100644 index 000000000..41b4dd837 --- /dev/null +++ b/src/osgAnimation/StackedScaleElement.cpp @@ -0,0 +1,56 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 + +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(); +} diff --git a/src/osgAnimation/StackedTransform.cpp b/src/osgAnimation/StackedTransform.cpp new file mode 100644 index 000000000..e8e36bf0b --- /dev/null +++ b/src/osgAnimation/StackedTransform.cpp @@ -0,0 +1,66 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 + +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; +} diff --git a/src/osgAnimation/StackedTranslateElement.cpp b/src/osgAnimation/StackedTranslateElement.cpp new file mode 100644 index 000000000..f88710e11 --- /dev/null +++ b/src/osgAnimation/StackedTranslateElement.cpp @@ -0,0 +1,50 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 + +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(); +} diff --git a/src/osgAnimation/StatsHandler.cpp b/src/osgAnimation/StatsHandler.cpp index fd1c0c624..60093b12c 100644 --- a/src/osgAnimation/StatsHandler.cpp +++ b/src/osgAnimation/StatsHandler.cpp @@ -424,7 +424,7 @@ struct ValueTextDrawCallback : public virtual osg::Drawable::DrawCallback osg::Vec3 pos(leftPos, _statsHeight-24.0f,0.0f); pos.y() -= characterSize *2 + backgroundMargin; - for (std::map::iterator it = _actions.begin(); it != _actions.end(); it++) { + for (std::map::iterator it = _actions.begin(); it != _actions.end(); ++it) { (*it).second._group->setNodeMask(~osg::Node::NodeMask(1)); } diff --git a/src/osgAnimation/Timeline.cpp b/src/osgAnimation/Timeline.cpp index eaf41007e..1bb137e52 100644 --- a/src/osgAnimation/Timeline.cpp +++ b/src/osgAnimation/Timeline.cpp @@ -210,7 +210,7 @@ void Timeline::processPendingOperation() 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; for (unsigned int i = 0; i < fa.size(); i++) diff --git a/src/osgAnimation/UpdateBone.cpp b/src/osgAnimation/UpdateBone.cpp new file mode 100644 index 000000000..c3e7d67ce --- /dev/null +++ b/src/osgAnimation/UpdateBone.cpp @@ -0,0 +1,54 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include +#include + +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(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); +} diff --git a/src/osgAnimation/UpdateCallback.cpp b/src/osgAnimation/UpdateCallback.cpp deleted file mode 100644 index be36ea470..000000000 --- a/src/osgAnimation/UpdateCallback.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* -*-c++-*- - * Copyright (C) 2008 Cedric Pinson - * - * 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 - * Michael Platings - */ - -#include -#include -#include -#include - -using namespace osgAnimation; - - -UpdateTransform::UpdateTransform(const UpdateTransform& apc,const osg::CopyOp& copyop) - : osg::Object(apc, copyop), - AnimationUpdateCallback(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(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(node); - if (matrix) - { - update(*matrix); - } - else - { - osg::PositionAttitudeTransform* pat = dynamic_cast(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(apc, copyop) -{ - _diffuse = new osgAnimation::Vec4Target(apc._diffuse->getValue()); -} - -UpdateMaterial::UpdateMaterial(const std::string& name): - AnimationUpdateCallback(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(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; -} diff --git a/src/osgAnimation/UpdateMaterial.cpp b/src/osgAnimation/UpdateMaterial.cpp new file mode 100644 index 000000000..4f2a8dd51 --- /dev/null +++ b/src/osgAnimation/UpdateMaterial.cpp @@ -0,0 +1,63 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include + +using namespace osgAnimation; + +UpdateMaterial::UpdateMaterial(const UpdateMaterial& apc,const osg::CopyOp& copyop) + : osg::Object(apc, copyop), + AnimationUpdateCallback(apc, copyop) +{ + _diffuse = new osgAnimation::Vec4Target(apc._diffuse->getValue()); +} + +UpdateMaterial::UpdateMaterial(const std::string& name): + AnimationUpdateCallback(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(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; +} diff --git a/src/osgAnimation/UpdateMatrixTransform.cpp b/src/osgAnimation/UpdateMatrixTransform.cpp new file mode 100644 index 000000000..d770da830 --- /dev/null +++ b/src/osgAnimation/UpdateMatrixTransform.cpp @@ -0,0 +1,67 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include +#include + +using namespace osgAnimation; + +UpdateMatrixTransform::UpdateMatrixTransform( const UpdateMatrixTransform& apc,const osg::CopyOp& copyop) : osg::Object(apc,copyop), AnimationUpdateCallback(apc, copyop) +{ + _transforms = StackedTransform(apc.getStackedTransforms(), copyop); +} + +UpdateMatrixTransform::UpdateMatrixTransform(const std::string& name) : AnimationUpdateCallback(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(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; +} diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index d523a9623..e605d4574 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -26,7 +26,7 @@ const VertexInfluenceSet::VertexIndexToBoneWeightMap& VertexInfluenceSet::getVer void VertexInfluenceSet::buildVertex2BoneList() { _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); int size = vi.size(); @@ -42,7 +42,7 @@ void VertexInfluenceSet::buildVertex2BoneList() } // 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; int size = bones.size(); @@ -116,7 +116,7 @@ void VertexInfluenceSet::buildUniqVertexSetToBoneSetList() typedef std::map UnifyBoneGroup; 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; int vertexIndex = it->first; @@ -132,7 +132,7 @@ void VertexInfluenceSet::buildUniqVertexSetToBoneSetList() } _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); } diff --git a/src/osgPlugins/bvh/ReaderWriterBVH.cpp b/src/osgPlugins/bvh/ReaderWriterBVH.cpp index 439f316fc..2a1242714 100644 --- a/src/osgPlugins/bvh/ReaderWriterBVH.cpp +++ b/src/osgPlugins/bvh/ReaderWriterBVH.cpp @@ -8,6 +8,10 @@ #include #include +#include +#include +#include +#include #include class BvhMotionBuilder : public osg::Referenced @@ -39,7 +43,17 @@ public: if ( fr.readSequence(offset) ) { // Process OFFSET section - parent->setBindMatrixInBoneSpace( osg::Matrix::translate(offset) ); + parent->setMatrixInSkeletonSpace( osg::Matrix::translate(offset) * + parent->getMatrixInSkeletonSpace() ); + osgAnimation::UpdateBone* updateBone = + static_cast( 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() ); } @@ -77,9 +91,10 @@ public: { // Process End Site section osg::ref_ptr 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 ) parent->addChild( createRefGeometry(offsetEndSite, 0.5).get() ); @@ -94,9 +109,9 @@ public: // Process JOINT section osg::ref_ptr bone = new osgAnimation::Bone( fr[1].getStr() ); - bone->setDefaultUpdateCallback(); bone->setDataVariance( osg::Object::DYNAMIC ); - parent->addChild( bone.get() ); + bone->setDefaultUpdateCallback(); + parent->insertChild( 0, bone.get() ); _joints.push_back( JointNode(bone, 0) ); int entry = fr[1].getNoNestedBrackets(); @@ -194,8 +209,13 @@ public: osgDB::Input fr; fr.attach( &stream ); + osg::ref_ptr boneroot = new osgAnimation::Bone( "Root" ); + boneroot->setDefaultUpdateCallback(); + osg::ref_ptr skelroot = new osgAnimation::Skeleton; skelroot->setDefaultUpdateCallback(); + skelroot->insertChild( 0, boneroot.get() ); + osg::ref_ptr anim = new osgAnimation::Animation; while( !fr.eof() ) @@ -203,7 +223,7 @@ public: if ( fr.matchSequence("HIERARCHY") ) { ++fr; - buildHierarchy( fr, 0, skelroot.get() ); + buildHierarchy( fr, 0, boneroot.get() ); } else if ( fr.matchSequence("MOTION") ) { diff --git a/src/osgWrappers/deprecated-dotosg/osgAnimation/CMakeLists.txt b/src/osgWrappers/deprecated-dotosg/osgAnimation/CMakeLists.txt index 43c9fe4da..a4f50231d 100644 --- a/src/osgWrappers/deprecated-dotosg/osgAnimation/CMakeLists.txt +++ b/src/osgWrappers/deprecated-dotosg/osgAnimation/CMakeLists.txt @@ -5,5 +5,3 @@ FILE(GLOB TARGET_H *.h) SET(TARGET_ADDED_LIBRARIES osgAnimation ) #### end var setup ### SETUP_PLUGIN(osganimation) - - diff --git a/src/osgWrappers/deprecated-dotosg/osgAnimation/Matrix.cpp b/src/osgWrappers/deprecated-dotosg/osgAnimation/Matrix.cpp new file mode 100644 index 000000000..bb36713a9 --- /dev/null +++ b/src/osgWrappers/deprecated-dotosg/osgAnimation/Matrix.cpp @@ -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; +} + diff --git a/src/osgWrappers/deprecated-dotosg/osgAnimation/Matrix.h b/src/osgWrappers/deprecated-dotosg/osgAnimation/Matrix.h new file mode 100644 index 000000000..e5fa46724 --- /dev/null +++ b/src/osgWrappers/deprecated-dotosg/osgAnimation/Matrix.h @@ -0,0 +1,13 @@ +#ifndef DOTOSG_MATRIX +#define DOTOSG_MATRIX + +#include + +#include +#include + +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 diff --git a/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp b/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp index 2dffc5522..5a91eb2f6 100644 --- a/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp +++ b/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp @@ -10,24 +10,30 @@ * 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 #include #include #include - +#include #include #include #include #include #include #include +#include +#include #include #include #include -#include +#include +#include +#include +#include +#include +#include "Matrix.h" #include #include @@ -42,7 +48,7 @@ bool Bone_readLocalData(Object& obj, Input& fr) 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]); fr[2].getFloat(att[1]); @@ -51,10 +57,11 @@ bool Bone_readLocalData(Object& obj, Input& fr) 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]); fr[2].getFloat(pos[1]); @@ -62,10 +69,11 @@ bool Bone_readLocalData(Object& obj, Input& fr) 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]); fr[2].getFloat(scale[1]); @@ -73,31 +81,45 @@ bool Bone_readLocalData(Object& obj, Input& fr) fr += 4; iteratorAdvanced = true; + osg::notify(osg::WARN) << "Old osgAnimation file format update your data file" << std::endl; } - bone.setBindMatrixInBoneSpace( osg::Matrix(att) * osg::Matrix::translate(pos)); + if (fr.matchSequence("InvBindMatrixInSkeletonSpace {")) + { + Matrix matrix; + if (readMatrix(matrix,fr, "InvBindMatrixInSkeletonSpace")) + { + bone.setInvBindMatrixInSkeletonSpace(matrix); + iteratorAdvanced = true; + } + } + if (fr.matchSequence("MatrixInSkeletonSpace {")) + { + Matrix matrix; + if (readMatrix(matrix,fr, "MatrixInSkeletonSpace")) + { + bone.setMatrixInSkeletonSpace(matrix); + iteratorAdvanced = true; + } + } return iteratorAdvanced; } -bool Bone_writeLocalData(const Object& obj, Output& fw) +bool Bone_writeLocalData(const Object& obj, Output& fw) { const osgAnimation::Bone& bone = dynamic_cast(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; + 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_atkBoneProxy +RegisterDotOsgWrapperProxy g_BoneProxy ( new osgAnimation::Bone, "osgAnimation::Bone", - "Object Node Transform osgAnimation::Bone Group", + "Object Node MatrixTransform osgAnimation::Bone Group", &Bone_readLocalData, &Bone_writeLocalData ); @@ -112,11 +134,11 @@ bool Skeleton_writeLocalData(const Object& obj, Output& fr) { 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, DotOsgWrapper::READ_AND_WRITE @@ -723,7 +745,7 @@ bool AnimationManagerBase_writeLocalData(const osgAnimation::AnimationManagerBas const osgAnimation::AnimationList& animList = manager.getAnimationList(); 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)) osg::notify(osg::WARN)<<"Warning: can't write an animation object"<< std::endl; @@ -816,6 +838,13 @@ bool RigGeometry_readLocalData(Object& obj, Input& fr) if (!vmap->empty()) geom.setInfluenceMap(vmap.get()); + if (fr.matchSequence("Geometry {")) + { + osg::Geometry* source = dynamic_cast(fr.readObject()); + geom.setSourceGeometry(source); + iteratorAdvanced = true; + } + return iteratorAdvanced; } @@ -827,7 +856,7 @@ bool RigGeometry_writeLocalData(const Object& obj, Output& fw) return true; 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; if (name.empty()) @@ -843,6 +872,8 @@ bool RigGeometry_writeLocalData(const Object& obj, Output& fw) fw.indent() << "}" << std::endl; } fw.moveOut(); + + fw.writeObject(*geom.getSourceGeometry()); return true; } @@ -850,7 +881,7 @@ RegisterDotOsgWrapperProxy g_atkRigGeometryProxy ( new osgAnimation::RigGeometry, "osgAnimation::RigGeometry", - "Object Drawable osgAnimation::RigGeometry Geometry", + "Object osgAnimation::RigGeometry Drawable Geometry", &RigGeometry_readLocalData, &RigGeometry_writeLocalData, DotOsgWrapper::READ_AND_WRITE @@ -975,7 +1006,10 @@ RegisterDotOsgWrapperProxy g_osgAnimationMorphGeometryProxy ); -bool UpdateBone_readLocalData(Object& obj, Input& fr) + + + +bool UpdateBone_readLocalData(Object& obj, Input& fr) { bool iteratorAdvanced = false; return iteratorAdvanced; @@ -986,11 +1020,11 @@ bool UpdateBone_writeLocalData(const Object& obj, Output& fw) return true; } -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, DotOsgWrapper::READ_AND_WRITE @@ -1009,7 +1043,7 @@ bool UpdateSkeleton_writeLocalData(const Object& obj, Output& fw) return true; } -RegisterDotOsgWrapperProxy g_atkUpdateSkeletonProxy +RegisterDotOsgWrapperProxy g_UpdateSkeletonProxy ( new osgAnimation::Skeleton::UpdateSkeleton, "osgAnimation::UpdateSkeleton", @@ -1020,51 +1054,6 @@ RegisterDotOsgWrapperProxy g_atkUpdateSkeletonProxy ); - -bool UpdateTransform_readLocalData(Object& obj, Input& fr) -{ - bool iteratorAdvanced = false; - return iteratorAdvanced; -} - -bool UpdateTransform_writeLocalData(const Object& obj, Output& fw) -{ - return true; -} - -RegisterDotOsgWrapperProxy g_atkUpdateTransformProxy -( - new osgAnimation::UpdateTransform, - "osgAnimation::UpdateTransform", - "Object NodeCallback osgAnimation::UpdateTransform", - &UpdateTransform_readLocalData, - &UpdateTransform_writeLocalData, - DotOsgWrapper::READ_AND_WRITE -); - - - -bool UpdateMaterial_readLocalData(Object& obj, Input& fr) -{ - bool iteratorAdvanced = false; - return iteratorAdvanced; -} - -bool UpdateMaterial_writeLocalData(const Object& obj, Output& fw) -{ - return true; -} - -RegisterDotOsgWrapperProxy g_UpdateMaterialProxy -( - new osgAnimation::UpdateMaterial, - "osgAnimation::UpdateMaterial", - "Object StateAttribute::Callback osgAnimation::UpdateMaterial", - &UpdateMaterial_readLocalData, - &UpdateMaterial_writeLocalData, - DotOsgWrapper::READ_AND_WRITE -); - bool UpdateMorph_readLocalData(Object& obj, Input& fr) { bool iteratorAdvanced = false; @@ -1076,7 +1065,7 @@ bool UpdateMorph_writeLocalData(const Object& obj, Output& fw) return true; } -RegisterDotOsgWrapperProxy g_atkUpdateMorphProxy +RegisterDotOsgWrapperProxy g_UpdateMorphProxy ( new osgAnimation::UpdateMorph, "osgAnimation::UpdateMorph", diff --git a/src/osgWrappers/deprecated-dotosg/osgAnimation/StackedTransform.cpp b/src/osgWrappers/deprecated-dotosg/osgAnimation/StackedTransform.cpp new file mode 100644 index 000000000..d67295e13 --- /dev/null +++ b/src/osgWrappers/deprecated-dotosg/osgAnimation/StackedTransform.cpp @@ -0,0 +1,228 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Matrix.h" + +using namespace osgDB; +using namespace osg; + +bool readStackedTranslateElement(Object& obj, Input& fr) +{ + osgAnimation::StackedTranslateElement& element = dynamic_cast(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(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(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(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(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(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(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(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(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(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 + ); diff --git a/src/osgWrappers/deprecated-dotosg/osgAnimation/UpdateMaterial.cpp b/src/osgWrappers/deprecated-dotosg/osgAnimation/UpdateMaterial.cpp new file mode 100644 index 000000000..f7acb1250 --- /dev/null +++ b/src/osgWrappers/deprecated-dotosg/osgAnimation/UpdateMaterial.cpp @@ -0,0 +1,47 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include +#include +#include +#include +#include + + +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 +); diff --git a/src/osgWrappers/deprecated-dotosg/osgAnimation/UpdateMatrixTransform.cpp b/src/osgWrappers/deprecated-dotosg/osgAnimation/UpdateMatrixTransform.cpp new file mode 100644 index 000000000..e538c0010 --- /dev/null +++ b/src/osgWrappers/deprecated-dotosg/osgAnimation/UpdateMatrixTransform.cpp @@ -0,0 +1,70 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * 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 +#include +#include +#include +#include +#include +#include + + +using namespace osg; +using namespace osgDB; + +bool UpdateMatrixTransform_readLocalData(Object& obj, Input& fr) +{ + bool iteratorAdvanced = false; + + osgAnimation::UpdateMatrixTransform& updateCallback = dynamic_cast(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(fr.readObject()); + if (element) + stackedTransform.push_back(element); + } + return iteratorAdvanced; +} + + + +bool UpdateMatrixTransform_writeLocalData(const Object& obj, Output& fw) +{ + const osgAnimation::UpdateMatrixTransform* uc = dynamic_cast(&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 + ); +