From d3db963dceaa1b27bb5541cc385df5dedb3c726c Mon Sep 17 00:00:00 2001 From: ehofman Date: Fri, 5 Sep 2003 12:36:01 +0000 Subject: [PATCH] Add a blend animation --- simgear/scene/model/animation.cxx | 72 +++++++++++++++++++++++++++++++ simgear/scene/model/animation.hxx | 22 ++++++++++ simgear/scene/model/model.cxx | 2 + 3 files changed, 96 insertions(+) diff --git a/simgear/scene/model/animation.cxx b/simgear/scene/model/animation.cxx index 517e8f56..928d90f1 100644 --- a/simgear/scene/model/animation.cxx +++ b/simgear/scene/model/animation.cxx @@ -91,6 +91,31 @@ set_scale (sgMat4 &matrix, double x, double y, double z) matrix[2][2] = z; } +/** + * Recursively process all kids to change the alpha values + */ +static void +change_alpha( ssgBase *_branch, float _blend ) +{ + unsigned int i; + + for (i = 0; i < ((ssgBranch *)_branch)->getNumKids(); i++) + change_alpha( ((ssgBranch *)_branch)->getKid(i), _blend ); + + if ( strcmp("ssgLeaf", _branch->getTypeName()) && + strcmp("ssgVtxTable", _branch->getTypeName()) && + strcmp("ssgVTable", _branch->getTypeName()) ) + return; + + int num_colors = ((ssgLeaf *)_branch)->getNumColours(); + + for (i = 0; i < num_colors; i++) + { + float *color = ((ssgLeaf *)_branch)->getColour(i); + color[3] = _blend; + } +} + /** * Modify property value by step and scroll settings in texture translations */ @@ -414,6 +439,53 @@ SGRotateAnimation::update() ((ssgTransform *)_branch)->setTransform(_matrix); } + +//////////////////////////////////////////////////////////////////////// +// Implementation of SGBlendAnimation +//////////////////////////////////////////////////////////////////////// + +SGBlendAnimation::SGBlendAnimation( SGPropertyNode *prop_root, + SGPropertyNode_ptr props ) + : SGAnimation(props, new ssgTransform), + _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)), + _offset(props->getDoubleValue("offset", 0.0)), + _factor(props->getDoubleValue("factor", 1.0)), + _table(read_interpolation_table(props)), + _has_min(props->hasValue("min")), + _min(props->getDoubleValue("min", 0.0)), + _has_max(props->hasValue("max")), + _max(props->getDoubleValue("max", 1.0)), + _prev_value(1.0) +{ +} + +SGBlendAnimation::~SGBlendAnimation () +{ + delete _table; +} + +void +SGBlendAnimation::update() +{ + double _blend; + + if (_table == 0) { + _blend = 1.0 - (_prop->getDoubleValue() * _factor + _offset); + + if (_has_min && (_blend < _min)) + _blend = _min; + if (_has_max && (_blend > _max)) + _blend = _max; + } else { + _blend = _table->interpolate(_prop->getDoubleValue()); + } + + if (_blend != _prev_value) { + _prev_value = _blend; + change_alpha( _branch, _blend ); + } +} + //////////////////////////////////////////////////////////////////////// diff --git a/simgear/scene/model/animation.hxx b/simgear/scene/model/animation.hxx index 0e61500c..c5079b59 100644 --- a/simgear/scene/model/animation.hxx +++ b/simgear/scene/model/animation.hxx @@ -221,6 +221,28 @@ private: sgVec3 _axis; }; +/** + * Animation to blend an object. + */ +class SGBlendAnimation : public SGAnimation +{ +public: + SGBlendAnimation( SGPropertyNode *prop_root, + SGPropertyNode_ptr props ); + virtual ~SGBlendAnimation (); + virtual void update(); +private: + SGPropertyNode_ptr _prop; + SGInterpTable * _table; + double _prev_value; + double _offset; + double _factor; + bool _has_min; + double _min; + bool _has_max; + double _max; +}; + /** * Animation to scale an object. */ diff --git a/simgear/scene/model/model.cxx b/simgear/scene/model/model.cxx index 853e41be..0b699ee0 100644 --- a/simgear/scene/model/model.cxx +++ b/simgear/scene/model/model.cxx @@ -129,6 +129,8 @@ sgMakeAnimation( ssgBranch * model, animation = new SGTexTranslateAnimation(prop_root, node); } else if (!strcmp("texmultiple", type)) { animation = new SGTexMultipleAnimation(prop_root, node); + } else if (!strcmp("blend", type)) { + animation = new SGBlendAnimation(prop_root, node); } else { animation = new SGNullAnimation(node); SG_LOG(SG_INPUT, SG_WARN, "Unknown animation type " << type); -- 2.39.5