Modified Files:

simgear/math/interpolater.cxx simgear/math/interpolater.hxx
	simgear/props/condition.cxx simgear/props/condition.hxx
	simgear/scene/model/animation.cxx
	simgear/scene/model/animation.hxx: Optimize interpolation table
	lookup by using a std::map.
This commit is contained in:
frohlich
2006-11-21 18:44:54 +00:00
parent 3059da5805
commit a3bc2eb836
6 changed files with 70 additions and 107 deletions

View File

@@ -25,8 +25,6 @@
#include <simgear/compiler.h>
#include <stdlib.h> // for exit()
#include STL_STRING
#include <simgear/debug/logstream.hxx>
@@ -38,7 +36,6 @@ SG_USING_STD(string);
// Constructor -- starts with an empty table.
SGInterpTable::SGInterpTable()
: size(0)
{
}
@@ -46,14 +43,13 @@ SGInterpTable::SGInterpTable()
// Constructor -- loads the interpolation table from the specified
// file
SGInterpTable::SGInterpTable( const string& file )
: size(0)
{
SG_LOG( SG_MATH, SG_INFO, "Initializing Interpolator for " << file );
sg_gzifstream in( file );
if ( !in.is_open() ) {
SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file );
exit(-1);
return;
}
in >> skipcomment;
@@ -61,8 +57,7 @@ SGInterpTable::SGInterpTable( const string& file )
double ind, dep;
in >> ind >> dep;
in >> skipws;
table.push_back(Entry(ind, dep));
size++;
_table[ind] = dep;
}
}
@@ -70,51 +65,42 @@ SGInterpTable::SGInterpTable( const string& file )
// Add an entry to the table.
void SGInterpTable::addEntry (double ind, double dep)
{
table.push_back(Entry(ind,dep));
size++;
_table[ind] = dep;
}
// Given an x value, linearly interpolate the y value from the table
double SGInterpTable::interpolate(double x) const
{
int i;
double y;
if (size == 0.0) {
return 0.0;
}
i = 0;
while ( (i < size) && (x > table[i].ind) ) {
// cout << " i = " << i << " table[i].ind = " << table[i].ind << endl;
// cout << " size = " << size << endl;
i++;
}
// printf ("i = %d ", i);
if ( i <= 0 ) {
SG_LOG( SG_MATH, SG_DEBUG,
"interpolate(): lookup error, x to small = " << x );
return table[0].dep;
}
// cout << " table[size-1].ind = " << table[size-1].ind << endl;
if ( i >= size ) {
SG_LOG( SG_MATH, SG_DEBUG,
"interpolate(): lookup error, x to big = " << x );
return table[size-1].dep;
}
// y = y1 + (y0 - y1)(x - x1) / (x0 - x1)
y = table[i].dep +
( (table[i-1].dep - table[i].dep) *
(x - table[i].ind) ) /
(table[i-1].ind - table[i].ind);
return(y);
// Empty table??
if (_table.empty())
return 0;
// Find the table bounds for the requested input.
Table::const_iterator upBoundIt = _table.upper_bound(x);
// points to a value outside the map. That is we are out of range.
// use the last entry
if (upBoundIt == _table.end())
return _table.rbegin()->second;
// points to the first key must be lower
// use the first entry
if (upBoundIt == _table.begin())
return upBoundIt->second;
// we know that we do not stand at the beginning, so it is safe to do so
Table::const_iterator loBoundIt = upBoundIt;
--loBoundIt;
// Just do linear interpolation.
double loBound = loBoundIt->first;
double upBound = upBoundIt->first;
double loVal = loBoundIt->second;
double upVal = upBoundIt->second;
// division by zero should not happen since the std::map
// has sorted out duplicate entries before. Also since we have a
// map, we know that we get different first values for different iterators
return loVal + (upVal - loVal)*(x - loBound)/(upBound - loBound);
}

View File

@@ -35,34 +35,20 @@
#include <simgear/compiler.h>
#include <vector>
SG_USING_STD(vector);
#include "simgear/structure/SGReferenced.hxx"
#include <map>
#include STL_STRING
SG_USING_STD(string);
/**
* A class that provids a simple linear 2d interpolation lookup table.
* The actual table is expected to be loaded from a file. The
* independant variable must be strictly ascending. The dependent
* variable can be anything.
*/
class SGInterpTable {
struct Entry
{
Entry ()
: ind(0.0L), dep(0.0L) {}
Entry (double independent, double dependent)
: ind(independent), dep(dependent) {}
double ind;
double dep;
};
int size;
vector<Entry> table;
class SGInterpTable : public SGReferenced {
public:
/**
@@ -95,6 +81,10 @@ public:
/** Destructor */
~SGInterpTable();
private:
typedef std::map<double, double> Table;
Table _table;
};

View File

@@ -65,7 +65,6 @@ SGNotCondition::SGNotCondition (SGCondition * condition)
SGNotCondition::~SGNotCondition ()
{
delete _condition;
}
bool
@@ -86,8 +85,6 @@ SGAndCondition::SGAndCondition ()
SGAndCondition::~SGAndCondition ()
{
for (unsigned int i = 0; i < _conditions.size(); i++)
delete _conditions[i];
}
bool
@@ -119,8 +116,6 @@ SGOrCondition::SGOrCondition ()
SGOrCondition::~SGOrCondition ()
{
for (unsigned int i = 0; i < _conditions.size(); i++)
delete _conditions[i];
}
bool
@@ -398,13 +393,11 @@ SGConditional::SGConditional ()
SGConditional::~SGConditional ()
{
delete _condition;
}
void
SGConditional::setCondition (SGCondition * condition)
{
delete _condition;
_condition = condition;
}

View File

@@ -13,6 +13,7 @@
#include <simgear/debug/logstream.hxx>
#include <simgear/props/props.hxx>
#include <simgear/props/props_io.hxx>
#include <simgear/structure/SGReferenced.hxx>
////////////////////////////////////////////////////////////////////////
@@ -28,7 +29,7 @@
*
* This class should migrate to somewhere more general.
*/
class SGCondition
class SGCondition : public SGReferenced
{
public:
SGCondition ();
@@ -63,12 +64,11 @@ private:
class SGNotCondition : public SGCondition
{
public:
// transfer pointer ownership
SGNotCondition (SGCondition * condition);
virtual ~SGNotCondition ();
virtual bool test () const;
private:
SGCondition * _condition;
SGSharedPtr<SGCondition> _condition;
};
@@ -87,7 +87,7 @@ public:
// transfer pointer ownership
virtual void addCondition (SGCondition * condition);
private:
vector<SGCondition *> _conditions;
std::vector<SGSharedPtr<SGCondition> > _conditions;
};
@@ -106,7 +106,7 @@ public:
// transfer pointer ownership
virtual void addCondition (SGCondition * condition);
private:
vector<SGCondition *> _conditions;
std::vector<SGSharedPtr<SGCondition> > _conditions;
};
@@ -156,7 +156,7 @@ public:
virtual const SGCondition * getCondition () const { return _condition; }
virtual bool test () const;
private:
SGCondition * _condition;
SGSharedPtr<SGCondition> _condition;
};

View File

@@ -322,7 +322,6 @@ SGSelectAnimation::SGSelectAnimation( SGPropertyNode *prop_root,
SGSelectAnimation::~SGSelectAnimation ()
{
delete _condition;
}
void
@@ -555,7 +554,6 @@ SGRotateAnimation::SGRotateAnimation( SGPropertyNode *prop_root,
SGRotateAnimation::~SGRotateAnimation ()
{
delete _table;
}
void
@@ -656,7 +654,6 @@ SGBlendAnimation::SGBlendAnimation( SGPropertyNode *prop_root,
SGBlendAnimation::~SGBlendAnimation ()
{
delete _table;
}
void
@@ -720,7 +717,6 @@ SGTranslateAnimation::SGTranslateAnimation( SGPropertyNode *prop_root,
SGTranslateAnimation::~SGTranslateAnimation ()
{
delete _table;
}
void
@@ -788,7 +784,6 @@ SGScaleAnimation::SGScaleAnimation( SGPropertyNode *prop_root,
SGScaleAnimation::~SGScaleAnimation ()
{
delete _table;
}
void
@@ -868,7 +863,6 @@ SGTexRotateAnimation::SGTexRotateAnimation( SGPropertyNode *prop_root,
SGTexRotateAnimation::~SGTexRotateAnimation ()
{
delete _table;
}
void
@@ -928,7 +922,6 @@ SGTexTranslateAnimation::SGTexTranslateAnimation( SGPropertyNode *prop_root,
SGTexTranslateAnimation::~SGTexTranslateAnimation ()
{
delete _table;
}
void
@@ -1186,6 +1179,10 @@ SGMaterialAnimation::SGMaterialAnimation( SGPropertyNode *prop_root,
_alphaFunc = new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0);
}
SGMaterialAnimation::~SGMaterialAnimation()
{
}
void SGMaterialAnimation::initColorGroup(SGPropertyNode_ptr group, ColorSpec *col, int flag)
{
if (!group)
@@ -1561,7 +1558,6 @@ public:
}
~SGDistScaleTransform()
{
delete _table;
}
virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,
@@ -1628,7 +1624,7 @@ private:
osg::Vec3 _center;
float _factor, _offset, _min_v, _max_v;
bool _has_min, _has_max;
SGInterpTable * _table;
SGSharedPtr<SGInterpTable> _table;
};
SGDistScaleAnimation::SGDistScaleAnimation(SGPropertyNode_ptr props)
@@ -1660,7 +1656,6 @@ SGShadowAnimation::SGShadowAnimation ( SGPropertyNode *prop_root,
SGShadowAnimation::~SGShadowAnimation ()
{
delete _condition;
}
void

View File

@@ -40,7 +40,6 @@ 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?
#ifdef min
@@ -124,7 +123,7 @@ private:
float _max;
float _min_factor;
float _max_factor;
SGCondition * _condition;
SGSharedPtr<SGCondition> _condition;
};
@@ -150,7 +149,7 @@ public:
virtual ~SGSelectAnimation ();
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
private:
SGCondition * _condition;
SGSharedPtr<SGCondition> _condition;
};
@@ -175,7 +174,7 @@ private:
double _last_time_sec;
osg::Vec3 _center;
osg::Vec3 _axis;
SGCondition * _condition;
SGSharedPtr<SGCondition> _condition;
};
@@ -220,7 +219,7 @@ private:
SGPropertyNode_ptr _prop;
double _offset_deg;
double _factor;
SGInterpTable * _table;
SGSharedPtr<SGInterpTable> _table;
bool _has_min;
double _min_deg;
bool _has_max;
@@ -228,7 +227,7 @@ private:
double _position_deg;
osg::Vec3 _center;
osg::Vec3 _axis;
SGCondition * _condition;
SGSharedPtr<SGCondition> _condition;
};
@@ -247,14 +246,14 @@ private:
SGPropertyNode_ptr _prop;
SGPersonalityParameter<double> _offset_m;
SGPersonalityParameter<double> _factor;
SGInterpTable * _table;
SGSharedPtr<SGInterpTable> _table;
bool _has_min;
double _min_m;
bool _has_max;
double _max_m;
double _position_m;
osg::Vec3 _axis;
SGCondition * _condition;
SGSharedPtr<SGCondition> _condition;
};
/**
@@ -270,7 +269,7 @@ public:
private:
bool _use_personality;
SGPropertyNode_ptr _prop;
SGInterpTable * _table;
SGSharedPtr<SGInterpTable> _table;
double _prev_value;
SGPersonalityParameter<double> _offset;
SGPersonalityParameter<double> _factor;
@@ -297,7 +296,7 @@ private:
SGPersonalityParameter<double> _x_offset;
SGPersonalityParameter<double> _y_offset;
SGPersonalityParameter<double> _z_offset;
SGInterpTable * _table;
SGSharedPtr<SGInterpTable> _table;
bool _has_min_x;
bool _has_min_y;
bool _has_min_z;
@@ -330,7 +329,7 @@ private:
SGPropertyNode_ptr _prop;
double _offset_deg;
double _factor;
SGInterpTable * _table;
SGSharedPtr<SGInterpTable> _table;
bool _has_min;
double _min_deg;
bool _has_max;
@@ -338,7 +337,7 @@ private:
double _position_deg;
osg::Vec3 _center;
osg::Vec3 _axis;
SGCondition * _condition;
SGSharedPtr<SGCondition> _condition;
osg::ref_ptr<osg::TexMat> _texMat;
};
@@ -359,14 +358,14 @@ private:
double _factor;
double _step;
double _scroll;
SGInterpTable * _table;
SGSharedPtr<SGInterpTable> _table;
bool _has_min;
double _min;
bool _has_max;
double _max;
double _position;
osg::Vec3 _axis;
SGCondition * _condition;
SGSharedPtr<SGCondition> _condition;
osg::ref_ptr<osg::TexMat> _texMat;
};
@@ -393,7 +392,7 @@ private:
double factor;
double step;
double scroll;
SGInterpTable * table;
SGSharedPtr<SGInterpTable> table;
bool has_min;
double min;
bool has_max;
@@ -431,7 +430,7 @@ class SGMaterialAnimation : public SGAnimation
public:
SGMaterialAnimation(SGPropertyNode *prop_root, SGPropertyNode_ptr props,
const SGPath &texpath);
virtual ~SGMaterialAnimation() {}
virtual ~SGMaterialAnimation();
virtual void init();
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
private:
@@ -492,7 +491,7 @@ private:
return value != a.value || factor != a.factor || offset != a.offset;
}
};
SGCondition *_condition;
SGSharedPtr<SGCondition> _condition;
bool _last_condition;
SGPropertyNode_ptr _prop_root;
string _prop_base;
@@ -567,7 +566,7 @@ public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
bool get_condition_value(void);
private:
SGCondition * _condition;
SGSharedPtr<SGCondition> _condition;
bool _condition_value;
};
@@ -584,7 +583,7 @@ public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
bool get_condition_value(void);
private:
SGCondition * _condition;
SGSharedPtr<SGCondition> _condition;
bool _condition_value;
int _shader_type;
float _param_1;