From 17e247852231f83d9c5c5d02f789e789ea40763b Mon Sep 17 00:00:00 2001 From: ehofman Date: Sun, 8 Jun 2003 13:19:34 +0000 Subject: [PATCH] Jim Wilson: 1. Added support for defining arbitrary rotation axes using (x1,y1,z1), (x2,y2,z2). The center is calculated automatically (midpoint on line) or you may specify an alternate "center" using the current scheme. This makes it about 100 times easier to animate flaps, ailerons, etc. 2. Added support for plib's ssgTexTrans. This will allow more sophisticated 3D instrument features by allowing the texture mapping itself to be animated. Included function for "texrotate" and "textranslate". They configure the same as the geometry, except the arbitrary axis definition is not necessary (textures are flat). --- simgear/scene/model/animation.cxx | 165 +++++++++++++++++++++++++++--- simgear/scene/model/animation.hxx | 50 +++++++++ simgear/scene/model/model.cxx | 4 + 3 files changed, 205 insertions(+), 14 deletions(-) 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); -- 2.39.5