+
// animation.hxx - classes to manage model animation.
// Written by David Megginson, started 2002.
//
# error This library requires C++
#endif
-#include <vector>
-
-SG_USING_STD(vector);
-
-#include <plib/sg.h>
-#include <plib/ssg.h>
+#include <osg/ref_ptr>
+#include <osg/Group>
+#include <osg/Node>
+#include <osg/NodeVisitor>
+#include <osg/Texture2D>
+#include <osgDB/ReaderWriter>
-#include <simgear/math/point3d.hxx>
+#include <simgear/scene/util/SGNodeMasks.hxx>
#include <simgear/props/props.hxx>
-
-
-// Don't pull in the headers, since we don't need them here.
-class SGInterpTable;
-class SGCondition;
-
+#include <simgear/props/condition.hxx>
+#include <simgear/structure/SGExpression.hxx>
// Has anyone done anything *really* stupid, like making min and max macros?
#ifdef min
#undef max
#endif
+SGExpressiond*
+read_value(const SGPropertyNode* configNode, SGPropertyNode* modelRoot,
+ const char* unit, double defMin, double defMax);
+\f
+//////////////////////////////////////////////////////////////////////
+// Base class for animation installers
+//////////////////////////////////////////////////////////////////////
+
+class SGAnimation : protected osg::NodeVisitor {
+public:
+ SGAnimation(const SGPropertyNode* configNode, SGPropertyNode* modelRoot);
+ virtual ~SGAnimation();
+
+ static bool animate(osg::Node* node, const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot,
+ const osgDB::ReaderWriter::Options* options);
+
+protected:
+ void apply(osg::Node* node);
+
+ virtual void install(osg::Node& node);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
+
+ virtual void apply(osg::Group& group);
+
+ void removeMode(osg::Node& node, osg::StateAttribute::GLMode mode);
+ void removeAttribute(osg::Node& node, osg::StateAttribute::Type type);
+ void removeTextureMode(osg::Node& node, unsigned unit,
+ osg::StateAttribute::GLMode mode);
+ void removeTextureAttribute(osg::Node& node, unsigned unit,
+ osg::StateAttribute::Type type);
+ void setRenderBinToInherit(osg::Node& node);
+ void cloneDrawables(osg::Node& node);
+
+ std::string getType() const
+ { return std::string(_configNode->getStringValue("type", "")); }
+
+ const SGPropertyNode* getConfig() const
+ { return _configNode; }
+ SGPropertyNode* getModelRoot() const
+ { return _modelRoot; }
+
+ const SGCondition* getCondition() const;
+
+private:
+ void installInGroup(const std::string& name, osg::Group& group,
+ osg::ref_ptr<osg::Group>& animationGroup);
+
+ class RemoveModeVisitor;
+ class RemoveAttributeVisitor;
+ class RemoveTextureModeVisitor;
+ class RemoveTextureAttributeVisitor;
+ class BinToInheritVisitor;
+ class DrawableCloneVisitor;
+
+ bool _found;
+ std::string _name;
+ SGSharedPtr<SGPropertyNode const> _configNode;
+ SGPropertyNode* _modelRoot;
+ std::list<std::string> _objectNames;
+ std::list<osg::ref_ptr<osg::Node> > _installedAnimations;
+ bool _enableHOT;
+ bool _disableShadow;
+};
\f
//////////////////////////////////////////////////////////////////////
-// Animation classes
+// Null animation installer
//////////////////////////////////////////////////////////////////////
-/**
- * Abstract base class for all animations.
- */
-class SGAnimation : public ssgBase
-{
+class SGGroupAnimation : public SGAnimation {
public:
+ SGGroupAnimation(const SGPropertyNode*, SGPropertyNode*);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
+};
- SGAnimation (SGPropertyNode_ptr props, ssgBranch * branch);
+\f
+//////////////////////////////////////////////////////////////////////
+// Translate animation installer
+//////////////////////////////////////////////////////////////////////
+
+class SGTranslateAnimation : public SGAnimation {
+public:
+ SGTranslateAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
+private:
+ class UpdateCallback;
+ SGSharedPtr<const SGCondition> _condition;
+ SGSharedPtr<const SGExpressiond> _animationValue;
+ SGVec3d _axis;
+ double _initialValue;
+};
- virtual ~SGAnimation ();
+\f
+//////////////////////////////////////////////////////////////////////
+// Rotate/Spin animation installer
+//////////////////////////////////////////////////////////////////////
- /**
- * Get the SSG branch holding the animation.
- */
- virtual ssgBranch * getBranch () { return _branch; }
+class SGRotateAnimation : public SGAnimation {
+public:
+ SGRotateAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
+private:
+ class UpdateCallback;
+ class SpinUpdateCallback;
+ SGSharedPtr<const SGCondition> _condition;
+ SGSharedPtr<const SGExpressiond> _animationValue;
+ SGVec3d _axis;
+ SGVec3d _center;
+ double _initialValue;
+ bool _isSpin;
+};
- /**
- * Initialize the animation, after children have been added.
- */
- virtual void init ();
+\f
+//////////////////////////////////////////////////////////////////////
+// Scale animation installer
+//////////////////////////////////////////////////////////////////////
- /**
- * Update the animation.
- */
- virtual void update();
+class SGScaleAnimation : public SGAnimation {
+public:
+ SGScaleAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
+private:
+ class UpdateCallback;
+ SGSharedPtr<const SGCondition> _condition;
+ SGSharedPtr<const SGExpressiond> _animationValue[3];
+ SGVec3d _initialValue;
+ SGVec3d _center;
+};
- /**
- * Set the value of sim_time_sec. This needs to be called every
- * frame in order for the time based animations to work correctly.
- */
- static void set_sim_time_sec( double val ) { sim_time_sec = val; }
+\f
+//////////////////////////////////////////////////////////////////////
+// dist scale animation installer
+//////////////////////////////////////////////////////////////////////
-protected:
+class SGDistScaleAnimation : public SGAnimation {
+public:
+ SGDistScaleAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
+ class Transform;
+};
+
+\f
+//////////////////////////////////////////////////////////////////////
+// dist scale animation installer
+//////////////////////////////////////////////////////////////////////
- static double sim_time_sec;
+class SGFlashAnimation : public SGAnimation {
+public:
+ SGFlashAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
+public:
+ class Transform;
+};
- ssgBranch * _branch;
+\f
+//////////////////////////////////////////////////////////////////////
+// dist scale animation installer
+//////////////////////////////////////////////////////////////////////
+class SGBillboardAnimation : public SGAnimation {
+public:
+ SGBillboardAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
+ class Transform;
};
+\f
+//////////////////////////////////////////////////////////////////////
+// Range animation installer
+//////////////////////////////////////////////////////////////////////
-/**
- * A no-op animation.
- */
-class SGNullAnimation : public SGAnimation
-{
+class SGRangeAnimation : public SGAnimation {
public:
- SGNullAnimation (SGPropertyNode_ptr props);
- virtual ~SGNullAnimation ();
+ SGRangeAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
+private:
+ class UpdateCallback;
+ SGSharedPtr<const SGCondition> _condition;
+ SGSharedPtr<const SGExpressiond> _minAnimationValue;
+ SGSharedPtr<const SGExpressiond> _maxAnimationValue;
+ SGVec2d _initialValue;
};
+\f
+//////////////////////////////////////////////////////////////////////
+// Select animation installer
+//////////////////////////////////////////////////////////////////////
-/**
- * A range, or level-of-detail (LOD) animation.
- */
-class SGRangeAnimation : public SGAnimation
-{
+class SGSelectAnimation : public SGAnimation {
public:
- SGRangeAnimation (SGPropertyNode_ptr props);
- virtual ~SGRangeAnimation ();
+ SGSelectAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
};
+\f
+//////////////////////////////////////////////////////////////////////
+// Alpha test animation installer
+//////////////////////////////////////////////////////////////////////
-/**
- * Animation to turn and face the screen.
- */
-class SGBillboardAnimation : public SGAnimation
-{
+class SGAlphaTestAnimation : public SGAnimation {
public:
- SGBillboardAnimation (SGPropertyNode_ptr props);
- virtual ~SGBillboardAnimation ();
+ SGAlphaTestAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot);
+ virtual void install(osg::Node& node);
};
+\f
+//////////////////////////////////////////////////////////////////////
+// Blend animation installer
+//////////////////////////////////////////////////////////////////////
-/**
- * Animation to select alternative versions of the same object.
- */
-class SGSelectAnimation : public SGAnimation
-{
+class SGBlendAnimation : public SGAnimation {
public:
- SGSelectAnimation( SGPropertyNode *prop_root,
- SGPropertyNode_ptr props );
- virtual ~SGSelectAnimation ();
- virtual void update();
+ SGBlendAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
+ virtual void install(osg::Node& node);
private:
- SGCondition * _condition;
+ class BlendVisitor;
+ class UpdateCallback;
+ SGSharedPtr<SGExpressiond> _animationValue;
};
+\f
+//////////////////////////////////////////////////////////////////////
+// Timed animation installer
+//////////////////////////////////////////////////////////////////////
-/**
- * Animation to spin an object around a center point.
- *
- * This animation rotates at a specific velocity.
- */
-class SGSpinAnimation : public SGAnimation
-{
+class SGTimedAnimation : public SGAnimation {
public:
- SGSpinAnimation( SGPropertyNode *prop_root,
- SGPropertyNode_ptr props,
- double sim_time_sec );
- virtual ~SGSpinAnimation ();
- virtual void update();
+ SGTimedAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
private:
- SGPropertyNode_ptr _prop;
- double _factor;
- double _position_deg;
- double _last_time_sec;
- sgMat4 _matrix;
- sgVec3 _center;
- sgVec3 _axis;
+ class UpdateCallback;
};
+\f
+//////////////////////////////////////////////////////////////////////
+// Shadow animation installer
+//////////////////////////////////////////////////////////////////////
-/**
- * Animation to draw objects for a specific amount of time each.
- */
-class SGTimedAnimation : public SGAnimation
-{
+class SGShadowAnimation : public SGAnimation {
public:
- SGTimedAnimation (SGPropertyNode_ptr props);
- virtual ~SGTimedAnimation ();
- virtual void update();
+ SGShadowAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
private:
- double _duration_sec;
- double _last_time_sec;
- int _step;
+ class UpdateCallback;
};
+\f
+//////////////////////////////////////////////////////////////////////
+// TextureTransform animation
+//////////////////////////////////////////////////////////////////////
-/**
- * Animation to rotate an object around a center point.
- *
- * This animation rotates to a specific position.
- */
-class SGRotateAnimation : public SGAnimation
-{
+class SGTexTransformAnimation : public SGAnimation {
public:
- SGRotateAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props );
- virtual ~SGRotateAnimation ();
- virtual void update();
+ SGTexTransformAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
private:
- SGPropertyNode_ptr _prop;
- double _offset_deg;
- double _factor;
- SGInterpTable * _table;
- bool _has_min;
- double _min_deg;
- bool _has_max;
- double _max_deg;
- double _position_deg;
- sgMat4 _matrix;
- sgVec3 _center;
- sgVec3 _axis;
-};
-
-
-/**
- * Animation to slide along an axis.
- */
-class SGTranslateAnimation : public SGAnimation
-{
-public:
- SGTranslateAnimation( SGPropertyNode *prop_root,
- SGPropertyNode_ptr props );
- virtual ~SGTranslateAnimation ();
- virtual void update();
+ class Transform;
+ class Translation;
+ class Rotation;
+ class UpdateCallback;
+ void appendTexTranslate(const SGPropertyNode* config,
+ UpdateCallback* updateCallback);
+ void appendTexRotate(const SGPropertyNode* config,
+ UpdateCallback* updateCallback);
+};
+
+\f
+//////////////////////////////////////////////////////////////////////
+// Shader animation
+//////////////////////////////////////////////////////////////////////
+
+class SGShaderAnimation : public SGAnimation {
+public:
+ SGShaderAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot,
+ const osgDB::ReaderWriter::Options* options);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
private:
- SGPropertyNode_ptr _prop;
- double _offset_m;
- double _factor;
- SGInterpTable * _table;
- bool _has_min;
- double _min_m;
- bool _has_max;
- double _max_m;
- double _position_m;
- sgMat4 _matrix;
- sgVec3 _axis;
+ class UpdateCallback;
+ osg::ref_ptr<osg::Texture2D> _effect_texture;
};
+\f
+//////////////////////////////////////////////////////////////////////
+// Pick animation
+//////////////////////////////////////////////////////////////////////
+
+class SGPickAnimation : public SGAnimation {
+public:
+ SGPickAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot);
+ virtual osg::Group* createAnimationGroup(osg::Group& parent);
+private:
+ class PickCallback;
+ class VncCallback;
+};
#endif // _SG_ANIMATION_HXX