From: curt Date: Mon, 10 May 2004 14:59:02 +0000 (+0000) Subject: Frederic Bouvier: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=2866d1ace9549f75d529a799088ee6df609b17d2;p=simgear.git Frederic Bouvier: Fix a memory leak, and brownian animation, if not motion. I have 2 new files : personality.[ch]xx . They store the personality data that would be deleted when the object is destroyed, instead of staying in the animation maps. I also manage the current animation step better and the towers are not flashing randomly now. Makefile.am is updated. --- diff --git a/simgear/scene/model/Makefile.am b/simgear/scene/model/Makefile.am index 4ab768d6..e9b91a7d 100644 --- a/simgear/scene/model/Makefile.am +++ b/simgear/scene/model/Makefile.am @@ -10,6 +10,7 @@ include_HEADERS = \ location.hxx \ model.hxx \ modellib.hxx \ + personality.hxx \ placement.hxx libsgmodel_a_SOURCES = \ @@ -18,6 +19,7 @@ libsgmodel_a_SOURCES = \ location.cxx \ model.cxx \ modellib.cxx \ + personality.cxx \ placement.cxx INCLUDES = -I$(top_srcdir) diff --git a/simgear/scene/model/animation.cxx b/simgear/scene/model/animation.cxx index 317df8e1..a068d4c1 100644 --- a/simgear/scene/model/animation.cxx +++ b/simgear/scene/model/animation.cxx @@ -18,6 +18,7 @@ #include "animation.hxx" #include "flash.hxx" +#include "personality.hxx" //////////////////////////////////////////////////////////////////////// @@ -175,7 +176,7 @@ read_interpolation_table (SGPropertyNode_ptr props) // Initialize the static data member double SGAnimation::sim_time_sec = 0.0; -ssgBranch *SGAnimation::current_object = 0; +SGPersonalityBranch *SGAnimation::current_object = 0; SGAnimation::SGAnimation (SGPropertyNode_ptr props, ssgBranch * branch) : _branch(branch) @@ -418,9 +419,12 @@ SGSpinAnimation::update() SGTimedAnimation::SGTimedAnimation (SGPropertyNode_ptr props) : SGAnimation(props, new ssgSelector), + _use_personality( props->getBoolValue("use-personality",false) ), _duration_sec(props->getDoubleValue("duration-sec", 1.0)), - _step( 0 ), - _use_personality( props->getBoolValue("use-personality",false) ) + _last_time_sec( sim_time_sec ), + _total_duration_sec( 0 ), + _step( 0 ) + { vector nodes = props->getChildren( "branch-duration-sec" ); size_t nb = nodes.size(); @@ -437,6 +441,14 @@ SGTimedAnimation::SGTimedAnimation (SGPropertyNode_ptr props) rNode->getDoubleValue( "max", 1.0 ) ); } } + if ( !_use_personality ) { + for ( size_t i = 0; i < _branch_duration_specs.size(); i++ ) { + DurationSpec &sp = _branch_duration_specs[ i ]; + double v = sp._min + sg_random() * ( sp._max - sp._min ); + _branch_duration_sec.push_back( v ); + _total_duration_sec += v; + } + } ((ssgSelector *)getBranch())->selectStep(_step); } @@ -447,35 +459,56 @@ SGTimedAnimation::~SGTimedAnimation () int SGTimedAnimation::update() { - ssgBranch *key = ( _use_personality ? current_object : 0 ); - PersonalityMap::iterator it = _branch_duration_sec.find( key ); - if ( it == _branch_duration_sec.end() ) { - vector durations; - double total = 0; - for ( size_t i = 0; i < _branch_duration_specs.size(); i++ ) { - DurationSpec &sp = _branch_duration_specs[ i ]; - double v = sp._min + sg_random() * ( sp._max - sp._min ); - durations.push_back( v ); - total += v; + if ( _use_personality ) { + SGPersonalityBranch *key = current_object; + if ( !key->getIntValue( this, INIT ) ) { + double total = 0; + for ( size_t i = 0; i < _branch_duration_specs.size(); i++ ) { + DurationSpec &sp = _branch_duration_specs[ i ]; + double v = sp._min + sg_random() * ( sp._max - sp._min ); + key->setDoubleValue( v, this, BRANCH_DURATION_SEC, i ); + total += v; + } + key->setDoubleValue( sim_time_sec, this, LAST_TIME_SEC ); + key->setDoubleValue( total, this, TOTAL_DURATION_SEC ); + key->setIntValue( 0, this, STEP ); + key->setIntValue( 1, this, INIT ); } - it = _branch_duration_sec.insert( PersonalityMap::value_type( key, durations ) ).first; - _last_time_sec[ key ] = sim_time_sec; - _total_duration_sec[ key ] = total; - } - while ( ( sim_time_sec - _last_time_sec[ key ] ) >= _total_duration_sec[ key ] ) { - _last_time_sec[ key ] += _total_duration_sec[ key ]; - } - double duration = _duration_sec; - if ( _step < (int)it->second.size() ) { - duration = it->second[ _step ]; - } - if ( ( sim_time_sec - _last_time_sec[ key ] ) >= duration ) { - _last_time_sec[ key ] += duration; - _step += 1; - if ( _step >= getBranch()->getNumKids() ) - _step = 0; + _step = key->getIntValue( this, STEP ); + _last_time_sec = key->getDoubleValue( this, LAST_TIME_SEC ); + _total_duration_sec = key->getDoubleValue( this, TOTAL_DURATION_SEC ); + while ( ( sim_time_sec - _last_time_sec ) >= _total_duration_sec ) { + _last_time_sec += _total_duration_sec; + } + double duration = _duration_sec; + if ( _step < (int)_branch_duration_specs.size() ) { + duration = key->getDoubleValue( this, BRANCH_DURATION_SEC, _step ); + } + if ( ( sim_time_sec - _last_time_sec ) >= duration ) { + _last_time_sec += duration; + _step += 1; + if ( _step >= getBranch()->getNumKids() ) + _step = 0; + } ((ssgSelector *)getBranch())->selectStep( _step ); + key->setDoubleValue( _last_time_sec, this, LAST_TIME_SEC ); + key->setIntValue( _step, this, STEP ); + } else { + while ( ( sim_time_sec - _last_time_sec ) >= _total_duration_sec ) { + _last_time_sec += _total_duration_sec; + } + double duration = _duration_sec; + if ( _step < (int)_branch_duration_sec.size() ) { + duration = _branch_duration_sec[ _step ]; + } + if ( ( sim_time_sec - _last_time_sec ) >= duration ) { + _last_time_sec += duration; + _step += 1; + if ( _step >= getBranch()->getNumKids() ) + _step = 0; + ((ssgSelector *)getBranch())->selectStep( _step ); + } } return 1; } diff --git a/simgear/scene/model/animation.hxx b/simgear/scene/model/animation.hxx index cac47686..98193fce 100644 --- a/simgear/scene/model/animation.hxx +++ b/simgear/scene/model/animation.hxx @@ -27,6 +27,7 @@ SG_USING_STD(map); // Don't pull in the headers, since we don't need them here. class SGInterpTable; class SGCondition; +class SGPersonalityBranch; // Has anyone done anything *really* stupid, like making min and max macros? @@ -84,7 +85,7 @@ public: * Current personality branch : enable animation to behave differently * for similar objects */ - static ssgBranch *current_object; + static SGPersonalityBranch *current_object; protected: @@ -188,9 +189,11 @@ public: virtual ~SGTimedAnimation (); virtual int update(); private: + bool _use_personality; + enum PersonalityVar { INIT, LAST_TIME_SEC, TOTAL_DURATION_SEC, BRANCH_DURATION_SEC, STEP }; double _duration_sec; - map _last_time_sec; - map _total_duration_sec; + double _last_time_sec; + double _total_duration_sec; int _step; struct DurationSpec { DurationSpec( double m = 0.0 ) : _min(m), _max(m) {} @@ -198,9 +201,7 @@ private: double _min, _max; }; vector _branch_duration_specs; - bool _use_personality; - typedef map > PersonalityMap; - PersonalityMap _branch_duration_sec; + vector _branch_duration_sec; }; diff --git a/simgear/scene/model/flash.hxx b/simgear/scene/model/flash.hxx index 3ca3b6fe..47d4fe33 100755 --- a/simgear/scene/model/flash.hxx +++ b/simgear/scene/model/flash.hxx @@ -2,6 +2,9 @@ * $Id$ */ +#ifndef _SG_FLASH_HXX +#define _SG_FLASH_HXX 1 + class SGFlash : public ssgBranch { public: @@ -30,3 +33,5 @@ private: float _power, _factor, _offset, _min_v, _max_v; bool _two_sides; }; + +#endif // _SG_FLASH_HXX diff --git a/simgear/scene/model/modellib.cxx b/simgear/scene/model/modellib.cxx index 8733f448..49073d63 100644 --- a/simgear/scene/model/modellib.cxx +++ b/simgear/scene/model/modellib.cxx @@ -5,6 +5,7 @@ #include "model.hxx" #include "animation.hxx" +#include "personality.hxx" #include "modellib.hxx" @@ -61,15 +62,11 @@ SGModelLib::flush1() } } -struct SGPersonalityBranch : public ssgBranch { - ssgBranch *_old_current; -}; - static int personality_pretrav_callback(ssgEntity * entity, int mask) { ((SGPersonalityBranch *)entity)->_old_current = SGAnimation::current_object; - SGAnimation::current_object = (ssgBranch *)entity; + SGAnimation::current_object = (SGPersonalityBranch *)entity; return 1; } diff --git a/simgear/scene/model/personality.cxx b/simgear/scene/model/personality.cxx new file mode 100755 index 00000000..622137e8 --- /dev/null +++ b/simgear/scene/model/personality.cxx @@ -0,0 +1,37 @@ +/** + * $Id$ + */ + +#include + +#include "personality.hxx" + +void SGPersonalityBranch::setDoubleValue( double value, SGAnimation *anim, int var_id, int var_num ) +{ + _doubleValues[ Key( anim, var_id, var_num ) ] = value; +} + +void SGPersonalityBranch::setIntValue( int value, SGAnimation *anim, int var_id, int var_num ) +{ + _intValues[ Key( anim, var_id, var_num ) ] = value; +} + +double SGPersonalityBranch::getDoubleValue( SGAnimation *anim, int var_id, int var_num ) const +{ + map::const_iterator it = _doubleValues.find( Key( anim, var_id, var_num ) ); + if ( it != _doubleValues.end() ) { + return it->second; + } else { + return 0; + } +} + +int SGPersonalityBranch::getIntValue( SGAnimation *anim, int var_id, int var_num ) const +{ + map::const_iterator it = _intValues.find( Key( anim, var_id, var_num ) ); + if ( it != _intValues.end() ) { + return it->second; + } else { + return 0; + } +} diff --git a/simgear/scene/model/personality.hxx b/simgear/scene/model/personality.hxx new file mode 100755 index 00000000..468d1e9c --- /dev/null +++ b/simgear/scene/model/personality.hxx @@ -0,0 +1,41 @@ +/** + * $Id$ + */ + +#ifndef _SG_PERSONALITY_HXX +#define _SG_PERSONALITY_HXX 1 + +#include + +SG_USING_STD(map); + +#include + +class SGAnimation; + +class SGPersonalityBranch : public ssgBranch { +public: + void setDoubleValue( double value, SGAnimation *anim, int var_id, int var_num = 0 ); + void setIntValue( int value, SGAnimation *anim, int var_id, int var_num = 0 ); + double getDoubleValue( SGAnimation *anim, int var_id, int var_num = 0 ) const; + int getIntValue( SGAnimation *anim, int var_id, int var_num = 0 ) const; + + SGPersonalityBranch *_old_current; + +private: + struct Key { + Key( SGAnimation *a, int i, int n = 0 ) : anim(a), var_id(i), var_num(n) {} + SGAnimation *anim; + int var_id; + int var_num; + bool operator<( const Key &r ) const { + return anim < r.anim || + ( anim == r.anim && ( var_id < r.var_id || + ( var_id == r.var_id && var_num < r.var_num ) ) ); + } + }; + map _doubleValues; + map _intValues; +}; + +#endif // _SG_PERSONALITY_HXX