From 1094206677a8b7ad60adbf9842b0e4a13e95eb8c Mon Sep 17 00:00:00 2001 From: david Date: Sat, 20 Apr 2002 14:07:34 +0000 Subject: [PATCH] Add support for interpolation tables for non-linear animations. Remove header dependencies where possible, to speed up rebuilds. --- src/Model/model.cxx | 66 +++++++++++++++++++++++++++++++++------------ src/Model/model.hxx | 22 ++++++++++++--- 2 files changed, 67 insertions(+), 21 deletions(-) diff --git a/src/Model/model.cxx b/src/Model/model.cxx index 11ff6df1d..d8cea383f 100644 --- a/src/Model/model.cxx +++ b/src/Model/model.cxx @@ -14,11 +14,13 @@ #include #include +#include #include #include #include #include +#include
#include
#include
#include @@ -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 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 - - - - diff --git a/src/Model/model.hxx b/src/Model/model.hxx index ce4112ba9..82f7891c4 100644 --- a/src/Model/model.hxx +++ b/src/Model/model.hxx @@ -11,12 +11,23 @@ #endif #include -#include SG_USING_STD(vector); -#include
-#include
+#include + + +// 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; -- 2.39.5