diff --git a/simgear/scene/model/animation.cxx b/simgear/scene/model/animation.cxx index a258a1c7..f9ebc188 100644 --- a/simgear/scene/model/animation.cxx +++ b/simgear/scene/model/animation.cxx @@ -1,4 +1,4 @@ -// animation.hxx - classes to manage model animation. +// animation.cxx - classes to manage model animation. // Written by David Megginson, started 2002. // // This file is in the Public Domain, and comes with no warranty. @@ -221,12 +221,34 @@ SGSpinAnimation::SGSpinAnimation( SGPropertyNode *prop_root, _position_deg(props->getDoubleValue("starting-position-deg", 0)), _last_time_sec( sim_time_sec ) { - _center[0] = props->getFloatValue("center/x-m", 0); - _center[1] = props->getFloatValue("center/y-m", 0); - _center[2] = props->getFloatValue("center/z-m", 0); - _axis[0] = props->getFloatValue("axis/x", 0); - _axis[1] = props->getFloatValue("axis/y", 0); - _axis[2] = props->getFloatValue("axis/z", 0); + _center[0] = 0; + _center[1] = 0; + _center[2] = 0; + if (props->hasValue("axis/x1-m")) { + double x1,y1,z1,x2,y2,z2; + x1 = props->getFloatValue("axis/x1-m"); + y1 = props->getFloatValue("axis/y1-m"); + z1 = props->getFloatValue("axis/z1-m"); + x2 = props->getFloatValue("axis/x2-m"); + y2 = props->getFloatValue("axis/y2-m"); + z2 = props->getFloatValue("axis/z2-m"); + _center[0] = (x1+x2)/2; + _center[1]= (y1+y2)/2; + _center[2] = (z1+z2)/2; + float vector_length = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1)); + _axis[0] = (x2-x1)/vector_length; + _axis[1] = (y2-y1)/vector_length; + _axis[2] = (z2-z1)/vector_length; + } else { + _axis[0] = props->getFloatValue("axis/x", 0); + _axis[1] = props->getFloatValue("axis/y", 0); + _axis[2] = props->getFloatValue("axis/z", 0); + } + if (props->hasValue("center/x-m")) { + _center[0] = props->getFloatValue("center/x-m", 0); + _center[1] = props->getFloatValue("center/y-m", 0); + _center[2] = props->getFloatValue("center/z-m", 0); + } sgNormalizeVec3(_axis); } @@ -299,13 +321,35 @@ SGRotateAnimation::SGRotateAnimation( SGPropertyNode *prop_root, _max_deg(props->getDoubleValue("max-deg")), _position_deg(props->getDoubleValue("starting-position-deg", 0)) { - _center[0] = props->getFloatValue("center/x-m", 0); - _center[1] = props->getFloatValue("center/y-m", 0); - _center[2] = props->getFloatValue("center/z-m", 0); - _axis[0] = props->getFloatValue("axis/x", 0); - _axis[1] = props->getFloatValue("axis/y", 0); - _axis[2] = props->getFloatValue("axis/z", 0); - sgNormalizeVec3(_axis); + _center[0] = 0; + _center[1] = 0; + _center[2] = 0; + if (props->hasValue("axis/x1-m")) { + double x1,y1,z1,x2,y2,z2; + x1 = props->getFloatValue("axis/x1-m"); + y1 = props->getFloatValue("axis/y1-m"); + z1 = props->getFloatValue("axis/z1-m"); + x2 = props->getFloatValue("axis/x2-m"); + y2 = props->getFloatValue("axis/y2-m"); + z2 = props->getFloatValue("axis/z2-m"); + _center[0] = (x1+x2)/2; + _center[1]= (y1+y2)/2; + _center[2] = (z1+z2)/2; + float vector_length = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1)); + _axis[0] = (x2-x1)/vector_length; + _axis[1] = (y2-y1)/vector_length; + _axis[2] = (z2-z1)/vector_length; + } else { + _axis[0] = props->getFloatValue("axis/x", 0); + _axis[1] = props->getFloatValue("axis/y", 0); + _axis[2] = props->getFloatValue("axis/z", 0); + } + if (props->hasValue("center/x-m")) { + _center[0] = props->getFloatValue("center/x-m", 0); + _center[1] = props->getFloatValue("center/y-m", 0); + _center[2] = props->getFloatValue("center/z-m", 0); + } + sgNormalizeVec3(_axis); } SGRotateAnimation::~SGRotateAnimation () @@ -376,4 +420,97 @@ SGTranslateAnimation::update() } +//////////////////////////////////////////////////////////////////////// +// Implementation of SGTexRotateAnimation +//////////////////////////////////////////////////////////////////////// + +SGTexRotateAnimation::SGTexRotateAnimation( SGPropertyNode *prop_root, + SGPropertyNode_ptr props ) + : SGAnimation(props, new ssgTexTrans), + _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)), + _offset_deg(props->getDoubleValue("offset-deg", 0.0)), + _factor(props->getDoubleValue("factor", 1.0)), + _table(read_interpolation_table(props)), + _has_min(props->hasValue("min-deg")), + _min_deg(props->getDoubleValue("min-deg")), + _has_max(props->hasValue("max-deg")), + _max_deg(props->getDoubleValue("max-deg")), + _position_deg(props->getDoubleValue("starting-position-deg", 0)) +{ + _center[0] = props->getFloatValue("center/x-m", 0); + _center[1] = props->getFloatValue("center/y-m", 0); + _center[2] = props->getFloatValue("center/z-m", 0); + _axis[0] = props->getFloatValue("axis/x", 0); + _axis[1] = props->getFloatValue("axis/y", 0); + _axis[2] = props->getFloatValue("axis/z", 0); + sgNormalizeVec3(_axis); +} + +SGTexRotateAnimation::~SGTexRotateAnimation () +{ + delete _table; +} + +void +SGTexRotateAnimation::update() +{ + if (_table == 0) { + _position_deg = _prop->getDoubleValue() * _factor + _offset_deg; + if (_has_min && _position_deg < _min_deg) + _position_deg = _min_deg; + if (_has_max && _position_deg > _max_deg) + _position_deg = _max_deg; + } else { + _position_deg = _table->interpolate(_prop->getDoubleValue()); + } + set_rotation(_matrix, _position_deg, _center, _axis); + ((ssgTexTrans *)_branch)->setTransform(_matrix); +} + + +//////////////////////////////////////////////////////////////////////// +// Implementation of SGTexTranslateAnimation +//////////////////////////////////////////////////////////////////////// + +SGTexTranslateAnimation::SGTexTranslateAnimation( SGPropertyNode *prop_root, + SGPropertyNode_ptr props ) + : SGAnimation(props, new ssgTexTrans), + _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)), + _offset_m(props->getDoubleValue("offset-m", 0.0)), + _factor(props->getDoubleValue("factor", 1.0)), + _table(read_interpolation_table(props)), + _has_min(props->hasValue("min-m")), + _min_m(props->getDoubleValue("min-m")), + _has_max(props->hasValue("max-m")), + _max_m(props->getDoubleValue("max-m")), + _position_m(props->getDoubleValue("starting-position-m", 0)) +{ + _axis[0] = props->getFloatValue("axis/x", 0); + _axis[1] = props->getFloatValue("axis/y", 0); + _axis[2] = props->getFloatValue("axis/z", 0); + sgNormalizeVec3(_axis); +} + +SGTexTranslateAnimation::~SGTexTranslateAnimation () +{ + delete _table; +} + +void +SGTexTranslateAnimation::update() +{ + if (_table == 0) { + _position_m = (_prop->getDoubleValue() + _offset_m) * _factor; + if (_has_min && _position_m < _min_m) + _position_m = _min_m; + if (_has_max && _position_m > _max_m) + _position_m = _max_m; + } else { + _position_m = _table->interpolate(_prop->getDoubleValue()); + } + set_translation(_matrix, _position_m, _axis); + ((ssgTexTrans *)_branch)->setTransform(_matrix); +} + + // end of animation.cxx diff --git a/simgear/scene/model/animation.hxx b/simgear/scene/model/animation.hxx index 4bbdf829..f365ec97 100644 --- a/simgear/scene/model/animation.hxx +++ b/simgear/scene/model/animation.hxx @@ -220,5 +220,55 @@ private: sgVec3 _axis; }; +/** + * Animation to rotate texture mappings around a center point. + * + * This animation rotates to a specific position. + */ +class SGTexRotateAnimation : public SGAnimation +{ +public: + SGTexRotateAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props ); + virtual ~SGTexRotateAnimation (); + virtual void update(); +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 texture mappings along an axis. + */ +class SGTexTranslateAnimation : public SGAnimation +{ +public: + SGTexTranslateAnimation( SGPropertyNode *prop_root, + SGPropertyNode_ptr props ); + virtual ~SGTexTranslateAnimation (); + virtual void update(); +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; +}; #endif // _SG_ANIMATION_HXX diff --git a/simgear/scene/model/model.cxx b/simgear/scene/model/model.cxx index 425d558d..1ece4c5b 100644 --- a/simgear/scene/model/model.cxx +++ b/simgear/scene/model/model.cxx @@ -121,6 +121,10 @@ sgMakeAnimation( ssgBranch * model, animation = new SGRotateAnimation(prop_root, node); } else if (!strcmp("translate", type)) { animation = new SGTranslateAnimation(prop_root, node); + } else if (!strcmp("texrotate", type)) { + animation = new SGTexRotateAnimation(prop_root, node); + } else if (!strcmp("textranslate", type)) { + animation = new SGTexTranslateAnimation(prop_root, node); } else { animation = new SGNullAnimation(node); SG_LOG(SG_INPUT, SG_WARN, "Unknown animation type " << type);