]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/model/animation.cxx
Updates to the alpha-test animation class
[simgear.git] / simgear / scene / model / animation.cxx
index dc4ffc695b90fdcb7f858b05e3d23d7c362b1351..67c69cb08d8b3d7fdf1470a2bb9a944bf2ae15d2 100644 (file)
@@ -79,6 +79,43 @@ set_translation (sgMat4 &matrix, double position_m, sgVec3 &axis)
   sgMakeTransMat4(matrix, xyz);
 }
 
+/**
+ * Set up the transform matrix for a scale operation.
+ */
+static void
+set_scale (sgMat4 &matrix, double x, double y, double z)
+{
+  sgMakeIdentMat4( matrix );
+  matrix[0][0] = x;
+  matrix[1][1] = y;
+  matrix[2][2] = z;
+}
+
+/**
+ * Recursively process all kids to change the alpha values
+ */
+static void
+change_alpha( ssgBase *_branch, float _blend )
+{
+  int i;
+
+  for (i = 0; i < ((ssgBranch *)_branch)->getNumKids(); i++)
+    change_alpha( ((ssgBranch *)_branch)->getKid(i), _blend );
+
+  if ( !_branch->isAKindOf(ssgTypeLeaf())
+       && !_branch->isAKindOf(ssgTypeVtxTable())
+       && !_branch->isAKindOf(ssgTypeVTable()) )
+    return;
+
+  int num_colors = ((ssgLeaf *)_branch)->getNumColours();
+
+  for (i = 0; i < num_colors; i++)
+  {
+    float *color =  ((ssgLeaf *)_branch)->getColour(i);
+    color[3] = _blend;
+  }
+}
+
 /**
  * Modify property value by step and scroll settings in texture translations
  */
@@ -177,19 +214,67 @@ SGNullAnimation::~SGNullAnimation ()
 // Implementation of SGRangeAnimation
 ////////////////////////////////////////////////////////////////////////
 
-SGRangeAnimation::SGRangeAnimation (SGPropertyNode_ptr props)
-  : SGAnimation(props, new ssgRangeSelector)
+SGRangeAnimation::SGRangeAnimation (SGPropertyNode *prop_root,
+                                    SGPropertyNode_ptr props)
+  : SGAnimation(props, new ssgRangeSelector),
+    _min(0.0), _max(0.0), _min_factor(1.0), _max_factor(1.0)
+
 {
-    float ranges[] = { props->getFloatValue("min-m", 0),
-                       props->getFloatValue("max-m", 5000) };
+    float ranges[2];
+
+    SGPropertyNode_ptr node = props->getChild( "min-factor" );
+    if (node != 0) {
+       _min_factor = props->getFloatValue("min-factor", 1.0);
+    }
+    node = props->getChild( "max-factor" );
+    if (node != 0) {
+       _max_factor = props->getFloatValue("max-factor", 1.0);
+    }
+    node = props->getChild( "min-property" );
+    if (node != 0) {
+       _min_prop = (SGPropertyNode *)prop_root->getNode(node->getStringValue(), true);
+       ranges[0] = _min_prop->getFloatValue() * _min_factor;
+    } else {
+       _min = props->getFloatValue("min-m", 0);
+       ranges[0] = _min * _min_factor;
+    }
+    node = props->getChild( "max-property" );
+    if (node != 0) {
+       _max_prop = (SGPropertyNode *)prop_root->getNode(node->getStringValue(), true);
+       ranges[1] = _max_prop->getFloatValue() * _max_factor;
+    } else {
+       _max = props->getFloatValue("max-m", 0);
+       ranges[1] = _max * _max_factor;
+    }
     ((ssgRangeSelector *)_branch)->setRanges(ranges, 2);
-                       
 }
 
 SGRangeAnimation::~SGRangeAnimation ()
 {
 }
 
+void
+SGRangeAnimation::update()
+{
+    float ranges[2];
+    bool upd = false;
+    if (_min_prop != 0) {
+       ranges[0] = _min_prop->getFloatValue() * _min_factor;
+       upd = true;
+    } else {
+       ranges[0] = _min * _min_factor;
+    }
+    if (_max_prop != 0) {
+       ranges[1] = _max_prop->getFloatValue() * _max_factor;
+       upd = true;
+    } else {
+       ranges[1] = _max * _max_factor;
+    }
+    if (upd) {
+       ((ssgRangeSelector *)_branch)->setRanges(ranges, 2);
+    }
+}
+
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -402,6 +487,53 @@ SGRotateAnimation::update()
   ((ssgTransform *)_branch)->setTransform(_matrix);
 }
 
+\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)),
+    _offset(props->getDoubleValue("offset", 0.0)),
+    _factor(props->getDoubleValue("factor", 1.0)),
+    _table(read_interpolation_table(props)),
+    _has_min(props->hasValue("min")),
+    _min(props->getDoubleValue("min", 0.0)),
+    _has_max(props->hasValue("max")),
+    _max(props->getDoubleValue("max", 1.0)),
+    _prev_value(1.0)
+{
+}
+
+SGBlendAnimation::~SGBlendAnimation ()
+{
+    delete _table;
+}
+
+void
+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 );
+  }
+}
+
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -449,6 +581,80 @@ SGTranslateAnimation::update()
 }
 
 
+\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;
+}
+
+void
+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);
+}
+
+
 ////////////////////////////////////////////////////////////////////////
 // Implementation of SGTexRotateAnimation
 ////////////////////////////////////////////////////////////////////////
@@ -553,7 +759,7 @@ SGTexMultipleAnimation::SGTexMultipleAnimation( SGPropertyNode *prop_root,
   : SGAnimation(props, new ssgTexTrans),
       _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true))
 {
-  int i;
+  unsigned int i;
   // Load animations
   vector<SGPropertyNode_ptr> transform_nodes = props->getChildren("transform");
   _transform = new TexTransform [transform_nodes.size()];
@@ -660,4 +866,40 @@ SGTexMultipleAnimation::update()
   ((ssgTexTrans *)_branch)->setTransform(tmatrix);
 }
 
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of SGAlphaTestAnimation
+////////////////////////////////////////////////////////////////////////
+
+SGAlphaTestAnimation::SGAlphaTestAnimation(SGPropertyNode_ptr props)
+  : SGAnimation(props, new ssgBranch)
+{
+  _alpha_clamp = props->getFloatValue("alpha-factor", 0.0);
+}
+
+SGAlphaTestAnimation::~SGAlphaTestAnimation ()
+{
+}
+
+void SGAlphaTestAnimation::init()
+{
+  setAlphaClampToBranch(_branch,_alpha_clamp);
+}
+
+void SGAlphaTestAnimation::setAlphaClampToBranch(ssgBranch *b, float clamp)
+{
+  int nb = b->getNumKids();
+  for (int i = 0; i<nb; i++) {
+    ssgEntity *e = b->getKid(i);
+    if (e->isAKindOf(ssgTypeLeaf())) {
+      ssgSimpleState*s = (ssgSimpleState*)((ssgLeaf*)e)->getState();
+      s->enable( GL_ALPHA_TEST );
+      s->setAlphaClamp( clamp );
+    } else if (e->isAKindOf(ssgTypeBranch())) {
+      setAlphaClampToBranch( (ssgBranch*)e, clamp );
+    }
+  }
+}
+
 // end of animation.cxx