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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user