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.
This commit is contained in:
@@ -10,6 +10,7 @@ include_HEADERS = \
|
|||||||
location.hxx \
|
location.hxx \
|
||||||
model.hxx \
|
model.hxx \
|
||||||
modellib.hxx \
|
modellib.hxx \
|
||||||
|
personality.hxx \
|
||||||
placement.hxx
|
placement.hxx
|
||||||
|
|
||||||
libsgmodel_a_SOURCES = \
|
libsgmodel_a_SOURCES = \
|
||||||
@@ -18,6 +19,7 @@ libsgmodel_a_SOURCES = \
|
|||||||
location.cxx \
|
location.cxx \
|
||||||
model.cxx \
|
model.cxx \
|
||||||
modellib.cxx \
|
modellib.cxx \
|
||||||
|
personality.cxx \
|
||||||
placement.cxx
|
placement.cxx
|
||||||
|
|
||||||
INCLUDES = -I$(top_srcdir)
|
INCLUDES = -I$(top_srcdir)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "animation.hxx"
|
#include "animation.hxx"
|
||||||
#include "flash.hxx"
|
#include "flash.hxx"
|
||||||
|
#include "personality.hxx"
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
@@ -175,7 +176,7 @@ read_interpolation_table (SGPropertyNode_ptr props)
|
|||||||
|
|
||||||
// Initialize the static data member
|
// Initialize the static data member
|
||||||
double SGAnimation::sim_time_sec = 0.0;
|
double SGAnimation::sim_time_sec = 0.0;
|
||||||
ssgBranch *SGAnimation::current_object = 0;
|
SGPersonalityBranch *SGAnimation::current_object = 0;
|
||||||
|
|
||||||
SGAnimation::SGAnimation (SGPropertyNode_ptr props, ssgBranch * branch)
|
SGAnimation::SGAnimation (SGPropertyNode_ptr props, ssgBranch * branch)
|
||||||
: _branch(branch)
|
: _branch(branch)
|
||||||
@@ -418,9 +419,12 @@ SGSpinAnimation::update()
|
|||||||
|
|
||||||
SGTimedAnimation::SGTimedAnimation (SGPropertyNode_ptr props)
|
SGTimedAnimation::SGTimedAnimation (SGPropertyNode_ptr props)
|
||||||
: SGAnimation(props, new ssgSelector),
|
: SGAnimation(props, new ssgSelector),
|
||||||
|
_use_personality( props->getBoolValue("use-personality",false) ),
|
||||||
_duration_sec(props->getDoubleValue("duration-sec", 1.0)),
|
_duration_sec(props->getDoubleValue("duration-sec", 1.0)),
|
||||||
_step( 0 ),
|
_last_time_sec( sim_time_sec ),
|
||||||
_use_personality( props->getBoolValue("use-personality",false) )
|
_total_duration_sec( 0 ),
|
||||||
|
_step( 0 )
|
||||||
|
|
||||||
{
|
{
|
||||||
vector<SGPropertyNode_ptr> nodes = props->getChildren( "branch-duration-sec" );
|
vector<SGPropertyNode_ptr> nodes = props->getChildren( "branch-duration-sec" );
|
||||||
size_t nb = nodes.size();
|
size_t nb = nodes.size();
|
||||||
@@ -437,6 +441,14 @@ SGTimedAnimation::SGTimedAnimation (SGPropertyNode_ptr props)
|
|||||||
rNode->getDoubleValue( "max", 1.0 ) );
|
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);
|
((ssgSelector *)getBranch())->selectStep(_step);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -447,35 +459,56 @@ SGTimedAnimation::~SGTimedAnimation ()
|
|||||||
int
|
int
|
||||||
SGTimedAnimation::update()
|
SGTimedAnimation::update()
|
||||||
{
|
{
|
||||||
ssgBranch *key = ( _use_personality ? current_object : 0 );
|
if ( _use_personality ) {
|
||||||
PersonalityMap::iterator it = _branch_duration_sec.find( key );
|
SGPersonalityBranch *key = current_object;
|
||||||
if ( it == _branch_duration_sec.end() ) {
|
if ( !key->getIntValue( this, INIT ) ) {
|
||||||
vector<double> durations;
|
double total = 0;
|
||||||
double total = 0;
|
for ( size_t i = 0; i < _branch_duration_specs.size(); i++ ) {
|
||||||
for ( size_t i = 0; i < _branch_duration_specs.size(); i++ ) {
|
DurationSpec &sp = _branch_duration_specs[ i ];
|
||||||
DurationSpec &sp = _branch_duration_specs[ i ];
|
double v = sp._min + sg_random() * ( sp._max - sp._min );
|
||||||
double v = sp._min + sg_random() * ( sp._max - sp._min );
|
key->setDoubleValue( v, this, BRANCH_DURATION_SEC, i );
|
||||||
durations.push_back( v );
|
total += v;
|
||||||
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 ] ) {
|
_step = key->getIntValue( this, STEP );
|
||||||
_last_time_sec[ key ] += _total_duration_sec[ key ];
|
_last_time_sec = key->getDoubleValue( this, LAST_TIME_SEC );
|
||||||
}
|
_total_duration_sec = key->getDoubleValue( this, TOTAL_DURATION_SEC );
|
||||||
double duration = _duration_sec;
|
while ( ( sim_time_sec - _last_time_sec ) >= _total_duration_sec ) {
|
||||||
if ( _step < (int)it->second.size() ) {
|
_last_time_sec += _total_duration_sec;
|
||||||
duration = it->second[ _step ];
|
}
|
||||||
}
|
double duration = _duration_sec;
|
||||||
if ( ( sim_time_sec - _last_time_sec[ key ] ) >= duration ) {
|
if ( _step < (int)_branch_duration_specs.size() ) {
|
||||||
_last_time_sec[ key ] += duration;
|
duration = key->getDoubleValue( this, BRANCH_DURATION_SEC, _step );
|
||||||
_step += 1;
|
}
|
||||||
if ( _step >= getBranch()->getNumKids() )
|
if ( ( sim_time_sec - _last_time_sec ) >= duration ) {
|
||||||
_step = 0;
|
_last_time_sec += duration;
|
||||||
|
_step += 1;
|
||||||
|
if ( _step >= getBranch()->getNumKids() )
|
||||||
|
_step = 0;
|
||||||
|
}
|
||||||
((ssgSelector *)getBranch())->selectStep( _step );
|
((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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ SG_USING_STD(map);
|
|||||||
// Don't pull in the headers, since we don't need them here.
|
// Don't pull in the headers, since we don't need them here.
|
||||||
class SGInterpTable;
|
class SGInterpTable;
|
||||||
class SGCondition;
|
class SGCondition;
|
||||||
|
class SGPersonalityBranch;
|
||||||
|
|
||||||
|
|
||||||
// Has anyone done anything *really* stupid, like making min and max macros?
|
// 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
|
* Current personality branch : enable animation to behave differently
|
||||||
* for similar objects
|
* for similar objects
|
||||||
*/
|
*/
|
||||||
static ssgBranch *current_object;
|
static SGPersonalityBranch *current_object;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@@ -188,9 +189,11 @@ public:
|
|||||||
virtual ~SGTimedAnimation ();
|
virtual ~SGTimedAnimation ();
|
||||||
virtual int update();
|
virtual int update();
|
||||||
private:
|
private:
|
||||||
|
bool _use_personality;
|
||||||
|
enum PersonalityVar { INIT, LAST_TIME_SEC, TOTAL_DURATION_SEC, BRANCH_DURATION_SEC, STEP };
|
||||||
double _duration_sec;
|
double _duration_sec;
|
||||||
map<ssgBranch *,double> _last_time_sec;
|
double _last_time_sec;
|
||||||
map<ssgBranch *,double> _total_duration_sec;
|
double _total_duration_sec;
|
||||||
int _step;
|
int _step;
|
||||||
struct DurationSpec {
|
struct DurationSpec {
|
||||||
DurationSpec( double m = 0.0 ) : _min(m), _max(m) {}
|
DurationSpec( double m = 0.0 ) : _min(m), _max(m) {}
|
||||||
@@ -198,9 +201,7 @@ private:
|
|||||||
double _min, _max;
|
double _min, _max;
|
||||||
};
|
};
|
||||||
vector<DurationSpec> _branch_duration_specs;
|
vector<DurationSpec> _branch_duration_specs;
|
||||||
bool _use_personality;
|
vector<double> _branch_duration_sec;
|
||||||
typedef map<ssgBranch *,vector<double> > PersonalityMap;
|
|
||||||
PersonalityMap _branch_duration_sec;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
* $Id$
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef _SG_FLASH_HXX
|
||||||
|
#define _SG_FLASH_HXX 1
|
||||||
|
|
||||||
class SGFlash : public ssgBranch
|
class SGFlash : public ssgBranch
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -30,3 +33,5 @@ private:
|
|||||||
float _power, _factor, _offset, _min_v, _max_v;
|
float _power, _factor, _offset, _min_v, _max_v;
|
||||||
bool _two_sides;
|
bool _two_sides;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // _SG_FLASH_HXX
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "model.hxx"
|
#include "model.hxx"
|
||||||
#include "animation.hxx"
|
#include "animation.hxx"
|
||||||
|
#include "personality.hxx"
|
||||||
|
|
||||||
#include "modellib.hxx"
|
#include "modellib.hxx"
|
||||||
|
|
||||||
@@ -61,15 +62,11 @@ SGModelLib::flush1()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SGPersonalityBranch : public ssgBranch {
|
|
||||||
ssgBranch *_old_current;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
personality_pretrav_callback(ssgEntity * entity, int mask)
|
personality_pretrav_callback(ssgEntity * entity, int mask)
|
||||||
{
|
{
|
||||||
((SGPersonalityBranch *)entity)->_old_current = SGAnimation::current_object;
|
((SGPersonalityBranch *)entity)->_old_current = SGAnimation::current_object;
|
||||||
SGAnimation::current_object = (ssgBranch *)entity;
|
SGAnimation::current_object = (SGPersonalityBranch *)entity;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Executable
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
|
||||||
|
#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<Key,double>::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<Key,int>::const_iterator it = _intValues.find( Key( anim, var_id, var_num ) );
|
||||||
|
if ( it != _intValues.end() ) {
|
||||||
|
return it->second;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+41
@@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SG_PERSONALITY_HXX
|
||||||
|
#define _SG_PERSONALITY_HXX 1
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
SG_USING_STD(map);
|
||||||
|
|
||||||
|
#include <plib/ssg.h>
|
||||||
|
|
||||||
|
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<Key,double> _doubleValues;
|
||||||
|
map<Key,int> _intValues;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _SG_PERSONALITY_HXX
|
||||||
Reference in New Issue
Block a user