+ : SGAnimation(props, new ssgTransform),
+ _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
+ _offset_deg(props->getDoubleValue("offset-deg", 0.0)),
+ _factor(props->getDoubleValue("factor", 1.0)),
+ _table(read_interpolation_table(props)),
+ _has_min(props->hasValue("min-deg")),
+ _min_deg(props->getDoubleValue("min-deg")),
+ _has_max(props->hasValue("max-deg")),
+ _max_deg(props->getDoubleValue("max-deg")),
+ _position_deg(props->getDoubleValue("starting-position-deg", 0)),
+ _condition(0)
+{
+ SGPropertyNode_ptr node = props->getChild("condition");
+ if (node != 0)
+ _condition = sgReadCondition(prop_root, node);
+
+ _center[0] = 0;
+ _center[1] = 0;
+ _center[2] = 0;
+ if (props->hasValue("axis/x1-m")) {
+ double x1,y1,z1,x2,y2,z2;
+ x1 = props->getFloatValue("axis/x1-m");
+ y1 = props->getFloatValue("axis/y1-m");
+ z1 = props->getFloatValue("axis/z1-m");
+ x2 = props->getFloatValue("axis/x2-m");
+ y2 = props->getFloatValue("axis/y2-m");
+ z2 = props->getFloatValue("axis/z2-m");
+ _center[0] = (x1+x2)/2;
+ _center[1]= (y1+y2)/2;
+ _center[2] = (z1+z2)/2;
+ float vector_length = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1));
+ _axis[0] = (x2-x1)/vector_length;
+ _axis[1] = (y2-y1)/vector_length;
+ _axis[2] = (z2-z1)/vector_length;
+ } else {
+ _axis[0] = props->getFloatValue("axis/x", 0);
+ _axis[1] = props->getFloatValue("axis/y", 0);
+ _axis[2] = props->getFloatValue("axis/z", 0);
+ }
+ if (props->hasValue("center/x-m")) {
+ _center[0] = props->getFloatValue("center/x-m", 0);
+ _center[1] = props->getFloatValue("center/y-m", 0);
+ _center[2] = props->getFloatValue("center/z-m", 0);
+ }
+ sgNormalizeVec3(_axis);
+}
+
+SGRotateAnimation::~SGRotateAnimation ()
+{
+ delete _table;
+}
+
+int
+SGRotateAnimation::update()
+{
+ if (_condition == 0 || _condition->test()) {
+ if (_table == 0) {
+ _position_deg = _prop->getDoubleValue() * _factor + _offset_deg;
+ 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);
+ ((ssgTransform *)_branch)->setTransform(_matrix);
+ }
+ return 1;
+}
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of SGBlendAnimation
+////////////////////////////////////////////////////////////////////////
+
+SGBlendAnimation::SGBlendAnimation( SGPropertyNode *prop_root,
+ SGPropertyNode_ptr props )
+ : SGAnimation(props, new ssgTransform),
+ _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
+ _table(read_interpolation_table(props)),
+ _prev_value(1.0),
+ _offset(props->getDoubleValue("offset", 0.0)),
+ _factor(props->getDoubleValue("factor", 1.0)),
+ _has_min(props->hasValue("min")),
+ _min(props->getDoubleValue("min", 0.0)),
+ _has_max(props->hasValue("max")),
+ _max(props->getDoubleValue("max", 1.0))
+{
+}
+
+SGBlendAnimation::~SGBlendAnimation ()
+{
+ delete _table;
+}
+
+int
+SGBlendAnimation::update()
+{
+ double _blend;
+
+ if (_table == 0) {
+ _blend = 1.0 - (_prop->getDoubleValue() * _factor + _offset);
+
+ if (_has_min && (_blend < _min))
+ _blend = _min;
+ if (_has_max && (_blend > _max))
+ _blend = _max;
+ } else {
+ _blend = _table->interpolate(_prop->getDoubleValue());
+ }
+
+ if (_blend != _prev_value) {
+ _prev_value = _blend;
+ change_alpha( _branch, _blend );
+ }
+ return 1;
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of SGTranslateAnimation
+////////////////////////////////////////////////////////////////////////
+
+SGTranslateAnimation::SGTranslateAnimation( SGPropertyNode *prop_root,
+ SGPropertyNode_ptr props )
+ : SGAnimation(props, new ssgTransform),
+ _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
+ _offset_m(props->getDoubleValue("offset-m", 0.0)),
+ _factor(props->getDoubleValue("factor", 1.0)),
+ _table(read_interpolation_table(props)),
+ _has_min(props->hasValue("min-m")),
+ _min_m(props->getDoubleValue("min-m")),
+ _has_max(props->hasValue("max-m")),
+ _max_m(props->getDoubleValue("max-m")),
+ _position_m(props->getDoubleValue("starting-position-m", 0)),
+ _condition(0)
+{
+ SGPropertyNode_ptr node = props->getChild("condition");
+ if (node != 0)
+ _condition = sgReadCondition(prop_root, node);
+
+ _axis[0] = props->getFloatValue("axis/x", 0);
+ _axis[1] = props->getFloatValue("axis/y", 0);
+ _axis[2] = props->getFloatValue("axis/z", 0);
+ sgNormalizeVec3(_axis);
+}
+
+SGTranslateAnimation::~SGTranslateAnimation ()
+{
+ delete _table;
+}
+
+int
+SGTranslateAnimation::update()
+{
+ if (_condition == 0 || _condition->test()) {
+ 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);
+ ((ssgTransform *)_branch)->setTransform(_matrix);
+ }
+ return 1;
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of SGScaleAnimation
+////////////////////////////////////////////////////////////////////////
+
+SGScaleAnimation::SGScaleAnimation( SGPropertyNode *prop_root,
+ SGPropertyNode_ptr props )
+ : SGAnimation(props, new ssgTransform),
+ _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
+ _x_factor(props->getDoubleValue("x-factor", 1.0)),
+ _y_factor(props->getDoubleValue("y-factor", 1.0)),
+ _z_factor(props->getDoubleValue("z-factor", 1.0)),
+ _x_offset(props->getDoubleValue("x-offset", 1.0)),
+ _y_offset(props->getDoubleValue("y-offset", 1.0)),
+ _z_offset(props->getDoubleValue("z-offset", 1.0)),
+ _table(read_interpolation_table(props)),
+ _has_min_x(props->hasValue("x-min")),
+ _has_min_y(props->hasValue("y-min")),
+ _has_min_z(props->hasValue("z-min")),
+ _min_x(props->getDoubleValue("x-min")),
+ _min_y(props->getDoubleValue("y-min")),
+ _min_z(props->getDoubleValue("z-min")),
+ _has_max_x(props->hasValue("x-max")),
+ _has_max_y(props->hasValue("y-max")),
+ _has_max_z(props->hasValue("z-max")),
+ _max_x(props->getDoubleValue("x-max")),
+ _max_y(props->getDoubleValue("y-max")),
+ _max_z(props->getDoubleValue("z-max"))
+{
+}
+
+SGScaleAnimation::~SGScaleAnimation ()
+{
+ delete _table;
+}
+
+int
+SGScaleAnimation::update()
+{
+ if (_table == 0) {
+ _x_scale = _prop->getDoubleValue() * _x_factor + _x_offset;
+ if (_has_min_x && _x_scale < _min_x)
+ _x_scale = _min_x;
+ if (_has_max_x && _x_scale > _max_x)
+ _x_scale = _max_x;
+ } else {
+ _x_scale = _table->interpolate(_prop->getDoubleValue());
+ }
+
+ if (_table == 0) {
+ _y_scale = _prop->getDoubleValue() * _y_factor + _y_offset;
+ if (_has_min_y && _y_scale < _min_y)
+ _y_scale = _min_y;
+ if (_has_max_y && _y_scale > _max_y)
+ _y_scale = _max_y;
+ } else {
+ _y_scale = _table->interpolate(_prop->getDoubleValue());
+ }
+
+ if (_table == 0) {
+ _z_scale = _prop->getDoubleValue() * _z_factor + _z_offset;
+ if (_has_min_z && _z_scale < _min_z)
+ _z_scale = _min_z;
+ if (_has_max_z && _z_scale > _max_z)
+ _z_scale = _max_z;
+ } else {
+ _z_scale = _table->interpolate(_prop->getDoubleValue());
+ }
+
+ set_scale(_matrix, _x_scale, _y_scale, _z_scale );
+ ((ssgTransform *)_branch)->setTransform(_matrix);
+ return 1;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// Implementation of SGTexRotateAnimation
+////////////////////////////////////////////////////////////////////////
+
+SGTexRotateAnimation::SGTexRotateAnimation( SGPropertyNode *prop_root,
+ SGPropertyNode_ptr props )
+ : SGAnimation(props, new ssgTexTrans),