Add support for interpolation tables for non-linear animations.
Remove header dependencies where possible, to speed up rebuilds.
This commit is contained in:
parent
17cfbd2a7c
commit
1094206677
2 changed files with 67 additions and 21 deletions
|
@ -14,11 +14,13 @@
|
|||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/math/interpolater.hxx>
|
||||
#include <simgear/math/point3d.hxx>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/misc/exception.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <Main/globals.hxx>
|
||||
#include <Main/location.hxx>
|
||||
#include <Scenery/scenery.hxx>
|
||||
|
@ -123,6 +125,26 @@ set_translation (sgMat4 &matrix, double position_m, sgVec3 &axis)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read an interpolation table from properties.
|
||||
*/
|
||||
static SGInterpTable *
|
||||
read_interpolation_table (const SGPropertyNode * props)
|
||||
{
|
||||
const SGPropertyNode * table_node = props->getNode("interpolation");
|
||||
if (table_node != 0) {
|
||||
SGInterpTable * table = new SGInterpTable();
|
||||
vector<const SGPropertyNode *> entries = table_node->getChildren("entry");
|
||||
for (int i = 0; i < entries.size(); i++)
|
||||
table->addEntry(entries[i]->getDoubleValue("ind", 0.0),
|
||||
entries[i]->getDoubleValue("dep", 0.0));
|
||||
return table;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of FG3DModel
|
||||
|
@ -324,7 +346,7 @@ FG3DModel::setOrientation (double roll_deg, double pitch_deg,
|
|||
|
||||
FG3DModel::Animation *
|
||||
FG3DModel::make_animation (const char * object_name,
|
||||
SGPropertyNode * node)
|
||||
SGPropertyNode * node)
|
||||
{
|
||||
Animation * animation = 0;
|
||||
const char * type = node->getStringValue("type");
|
||||
|
@ -533,6 +555,7 @@ FG3DModel::RotateAnimation::RotateAnimation ()
|
|||
: _prop(0),
|
||||
_offset_deg(0.0),
|
||||
_factor(1.0),
|
||||
_table(0),
|
||||
_has_min(false),
|
||||
_min_deg(0.0),
|
||||
_has_max(false),
|
||||
|
@ -544,12 +567,13 @@ FG3DModel::RotateAnimation::RotateAnimation ()
|
|||
|
||||
FG3DModel::RotateAnimation::~RotateAnimation ()
|
||||
{
|
||||
delete _table;
|
||||
_transform = 0;
|
||||
}
|
||||
|
||||
void
|
||||
FG3DModel::RotateAnimation::init (ssgEntity * object,
|
||||
SGPropertyNode * props)
|
||||
SGPropertyNode * props)
|
||||
{
|
||||
// Splice in the new transform node
|
||||
splice_branch(_transform, object);
|
||||
|
@ -557,6 +581,7 @@ FG3DModel::RotateAnimation::init (ssgEntity * object,
|
|||
_prop = fgGetNode(props->getStringValue("property", "/null"), true);
|
||||
_offset_deg = props->getDoubleValue("offset-deg", 0.0);
|
||||
_factor = props->getDoubleValue("factor", 1.0);
|
||||
_table = read_interpolation_table(props);
|
||||
if (props->hasValue("min-deg")) {
|
||||
_has_min = true;
|
||||
_min_deg = props->getDoubleValue("min-deg");
|
||||
|
@ -578,11 +603,15 @@ FG3DModel::RotateAnimation::init (ssgEntity * object,
|
|||
void
|
||||
FG3DModel::RotateAnimation::update (int dt)
|
||||
{
|
||||
_position_deg = ((_prop->getDoubleValue() + _offset_deg) * _factor);
|
||||
if (_has_min && _position_deg < _min_deg)
|
||||
_position_deg = _min_deg;
|
||||
if (_has_max && _position_deg > _max_deg)
|
||||
_position_deg = _max_deg;
|
||||
if (_table == 0) {
|
||||
_position_deg = (_prop->getDoubleValue() + _offset_deg) * _factor;
|
||||
if (_has_min && _position_deg < _min_deg)
|
||||
_position_deg = _min_deg;
|
||||
if (_has_max && _position_deg > _max_deg)
|
||||
_position_deg = _max_deg;
|
||||
} else {
|
||||
_position_deg = _table->interpolate(_prop->getDoubleValue());
|
||||
}
|
||||
set_rotation(_matrix, _position_deg, _center, _axis);
|
||||
_transform->setTransform(_matrix);
|
||||
}
|
||||
|
@ -597,6 +626,7 @@ FG3DModel::TranslateAnimation::TranslateAnimation ()
|
|||
: _prop(0),
|
||||
_offset_m(0.0),
|
||||
_factor(1.0),
|
||||
_table(0),
|
||||
_has_min(false),
|
||||
_min_m(0.0),
|
||||
_has_max(false),
|
||||
|
@ -608,12 +638,13 @@ FG3DModel::TranslateAnimation::TranslateAnimation ()
|
|||
|
||||
FG3DModel::TranslateAnimation::~TranslateAnimation ()
|
||||
{
|
||||
delete _table;
|
||||
_transform = 0;
|
||||
}
|
||||
|
||||
void
|
||||
FG3DModel::TranslateAnimation::init (ssgEntity * object,
|
||||
SGPropertyNode * props)
|
||||
SGPropertyNode * props)
|
||||
{
|
||||
// Splice in the new transform node
|
||||
splice_branch(_transform, object);
|
||||
|
@ -621,6 +652,7 @@ FG3DModel::TranslateAnimation::init (ssgEntity * object,
|
|||
_prop = fgGetNode(props->getStringValue("property", "/null"), true);
|
||||
_offset_m = props->getDoubleValue("offset-m", 0.0);
|
||||
_factor = props->getDoubleValue("factor", 1.0);
|
||||
_table = read_interpolation_table(props);
|
||||
if (props->hasValue("min-m")) {
|
||||
_has_min = true;
|
||||
_min_m = props->getDoubleValue("min-m");
|
||||
|
@ -639,18 +671,18 @@ FG3DModel::TranslateAnimation::init (ssgEntity * object,
|
|||
void
|
||||
FG3DModel::TranslateAnimation::update (int dt)
|
||||
{
|
||||
_position_m = ((_prop->getDoubleValue() + _offset_m) * _factor);
|
||||
if (_has_min && _position_m < _min_m)
|
||||
_position_m = _min_m;
|
||||
if (_has_max && _position_m > _max_m)
|
||||
_position_m = _max_m;
|
||||
if (_table == 0) {
|
||||
_position_m = (_prop->getDoubleValue() + _offset_m) * _factor;
|
||||
if (_has_min && _position_m < _min_m)
|
||||
_position_m = _min_m;
|
||||
if (_has_max && _position_m > _max_m)
|
||||
_position_m = _max_m;
|
||||
} else {
|
||||
_position_m = _table->interpolate(_prop->getDoubleValue());
|
||||
}
|
||||
set_translation(_matrix, _position_m, _axis);
|
||||
_transform->setTransform(_matrix);
|
||||
}
|
||||
|
||||
|
||||
// end of model.cxx
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -11,12 +11,23 @@
|
|||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <plib/ssg.h>
|
||||
|
||||
SG_USING_STD(vector);
|
||||
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <Main/location.hxx>
|
||||
#include <plib/sg.h>
|
||||
|
||||
|
||||
// Don't pull in the headers, since we don't need them here.
|
||||
class ssgEntity;
|
||||
class ssgRangeSelector;
|
||||
class ssgSelector;
|
||||
class ssgTransform;
|
||||
|
||||
class SGPropertyNode;
|
||||
class SGInterpTable;
|
||||
class FGCondition;
|
||||
class FGLocation;
|
||||
|
||||
|
||||
// Has anyone done anything *really* stupid, like making min and max macros?
|
||||
#ifdef min
|
||||
|
@ -58,7 +69,7 @@ public:
|
|||
virtual void setOrientation (double roll_deg, double pitch_deg,
|
||||
double heading_deg);
|
||||
|
||||
virtual ssgEntity * getSceneGraph () const { return _selector; }
|
||||
virtual ssgEntity * getSceneGraph () const { return (ssgEntity *)_selector; }
|
||||
|
||||
virtual FGLocation * getFGLocation () const { return _location; }
|
||||
|
||||
|
@ -90,6 +101,7 @@ private:
|
|||
// Location
|
||||
FGLocation * _location;
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Internal classes for individual animations.
|
||||
|
@ -210,6 +222,7 @@ private:
|
|||
SGPropertyNode * _prop;
|
||||
double _offset_deg;
|
||||
double _factor;
|
||||
SGInterpTable * _table;
|
||||
bool _has_min;
|
||||
double _min_deg;
|
||||
bool _has_max;
|
||||
|
@ -236,6 +249,7 @@ private:
|
|||
SGPropertyNode * _prop;
|
||||
double _offset_m;
|
||||
double _factor;
|
||||
SGInterpTable * _table;
|
||||
bool _has_min;
|
||||
double _min_m;
|
||||
bool _has_max;
|
||||
|
|
Loading…
Add table
Reference in a new issue