]> git.mxchange.org Git - simgear.git/commitdiff
Frederic Bouvier:
authorehofman <ehofman>
Fri, 7 May 2004 16:42:59 +0000 (16:42 +0000)
committerehofman <ehofman>
Fri, 7 May 2004 16:42:59 +0000 (16:42 +0000)
this patch introduce a new kind of animation and ssg branch.
I called them flash animation, because they help me to
enhance the look of the rotating beacon and possible future
lighthouse. It computes the cosine of the angle between an
arbitrary axis, transformed by the current modelview matrix,
and the view direction. No trig involved, just a dot/scalar
product.

The computed value can be modified by three parameters,
power, factor and offset, according to the formulae :

 value = factor * pow( cosine, power ) + offset.

It is clamped between a minimum and a maximum.
This value is then used as the scale factor of a matrix
transformation applied to the children of the SGFlash
branch.

The xml syntax, with default values, is :

<animation>
 <type>flash</type>
 <object-name>HaloObject</object-name>
 <center>
  <x-m>0</x-m>
  <y-m>0</y-m>
  <z-m>0</z-m>
 </center>
 <axis>
  <x>0</x>
  <y>0</y>
  <z>1</z>
 </axis>
 <power>1</power>
 <factor>1</factor>
 <offset>0</offset>
 <min>0</min>
 <max>1</max>
 <two-sides>false</two-sides>
</animation>

simgear/scene/model/Makefile.am
simgear/scene/model/animation.cxx
simgear/scene/model/animation.hxx
simgear/scene/model/flash.cxx [new file with mode: 0755]
simgear/scene/model/flash.hxx [new file with mode: 0755]
simgear/scene/model/model.cxx

index 3734733b38b54f4ea0a0ff0541091b40933d84e3..4ab768d6f828d1a9ca3daaf5371838b572a4743d 100644 (file)
@@ -6,6 +6,7 @@ noinst_HEADERS =
 
 include_HEADERS = \
        animation.hxx \
+       flash.hxx \
        location.hxx \
        model.hxx \
        modellib.hxx \
@@ -13,6 +14,7 @@ include_HEADERS = \
 
 libsgmodel_a_SOURCES = \
        animation.cxx \
+       flash.cxx \
        location.cxx \
        model.cxx \
        modellib.cxx \
index ac305760289689e026d0026e0e6dedbba9b7bcf7..6ced085855e3ac2b8e603a84640803792d6300e2 100644 (file)
@@ -16,7 +16,7 @@
 #include <simgear/props/props.hxx>
 
 #include "animation.hxx"
-
+#include "flash.hxx"
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -190,8 +190,14 @@ SGAnimation::init ()
 {
 }
 
-void
+int
 SGAnimation::update()
+{
+    return 1;
+}
+
+void
+SGAnimation::restore()
 {
 }
 
@@ -255,7 +261,7 @@ SGRangeAnimation::~SGRangeAnimation ()
 {
 }
 
-void
+int
 SGRangeAnimation::update()
 {
     float ranges[2];
@@ -275,6 +281,7 @@ SGRangeAnimation::update()
     if (upd) {
        ((ssgRangeSelector *)_branch)->setRanges(ranges, 2);
     }
+  return 1;
 }
 
 
@@ -313,13 +320,14 @@ SGSelectAnimation::~SGSelectAnimation ()
   delete _condition;
 }
 
-void
+int
 SGSelectAnimation::update()
 {
   if (_condition != 0 && _condition->test()) 
       ((ssgSelector *)_branch)->select(0xffff);
   else
       ((ssgSelector *)_branch)->select(0x0000);
+  return 1;
 }
 
 
@@ -372,7 +380,7 @@ SGSpinAnimation::~SGSpinAnimation ()
 {
 }
 
-void
+int
 SGSpinAnimation::update()
 {
   double dt = sim_time_sec - _last_time_sec;
@@ -386,6 +394,7 @@ SGSpinAnimation::update()
     _position_deg -= 360.0;
   set_rotation(_matrix, _position_deg, _center, _axis);
   ((ssgTransform *)_branch)->setTransform(_matrix);
+  return 1;
 }
 
 
@@ -406,7 +415,7 @@ SGTimedAnimation::~SGTimedAnimation ()
 {
 }
 
-void
+int
 SGTimedAnimation::update()
 {
     if ((sim_time_sec - _last_time_sec) >= _duration_sec) {
@@ -416,6 +425,7 @@ SGTimedAnimation::update()
             _step = 0;
         ((ssgSelector *)getBranch())->selectStep(_step);
     }
+  return 1;
 }
 
 
@@ -473,7 +483,7 @@ SGRotateAnimation::~SGRotateAnimation ()
   delete _table;
 }
 
-void
+int
 SGRotateAnimation::update()
 {
   if (_table == 0) {
@@ -487,6 +497,7 @@ SGRotateAnimation::update()
   }
   set_rotation(_matrix, _position_deg, _center, _axis);
   ((ssgTransform *)_branch)->setTransform(_matrix);
+  return 1;
 }
 
 \f
@@ -514,7 +525,7 @@ SGBlendAnimation::~SGBlendAnimation ()
     delete _table;
 }
 
-void
+int
 SGBlendAnimation::update()
 {
   double _blend;
@@ -534,6 +545,7 @@ SGBlendAnimation::update()
     _prev_value = _blend;
     change_alpha( _branch, _blend );
   }
+  return 1;
 }
 
 
@@ -566,7 +578,7 @@ SGTranslateAnimation::~SGTranslateAnimation ()
   delete _table;
 }
 
-void
+int
 SGTranslateAnimation::update()
 {
   if (_table == 0) {
@@ -580,6 +592,7 @@ SGTranslateAnimation::update()
   }
   set_translation(_matrix, _position_m, _axis);
   ((ssgTransform *)_branch)->setTransform(_matrix);
+  return 1;
 }
 
 
@@ -619,7 +632,7 @@ SGScaleAnimation::~SGScaleAnimation ()
   delete _table;
 }
 
-void
+int
 SGScaleAnimation::update()
 {
   if (_table == 0) {
@@ -654,6 +667,7 @@ SGScaleAnimation::update()
 
   set_scale(_matrix, _x_scale, _y_scale, _z_scale );
   ((ssgTransform *)_branch)->setTransform(_matrix);
+  return 1;
 }
 
 
@@ -688,7 +702,7 @@ SGTexRotateAnimation::~SGTexRotateAnimation ()
   delete _table;
 }
 
-void
+int
 SGTexRotateAnimation::update()
 {
   if (_table == 0) {
@@ -702,6 +716,7 @@ SGTexRotateAnimation::update()
   }
   set_rotation(_matrix, _position_deg, _center, _axis);
   ((ssgTexTrans *)_branch)->setTransform(_matrix);
+  return 1;
 }
 
 
@@ -735,7 +750,7 @@ SGTexTranslateAnimation::~SGTexTranslateAnimation ()
   delete _table;
 }
 
-void
+int
 SGTexTranslateAnimation::update()
 {
   if (_table == 0) {
@@ -749,6 +764,7 @@ SGTexTranslateAnimation::update()
   }
   set_translation(_matrix, _position, _axis);
   ((ssgTexTrans *)_branch)->setTransform(_matrix);
+  return 1;
 }
 
 
@@ -825,7 +841,7 @@ SGTexMultipleAnimation::~SGTexMultipleAnimation ()
   delete _transform;
 }
 
-void
+int
 SGTexMultipleAnimation::update()
 {
   int i;
@@ -866,6 +882,7 @@ SGTexMultipleAnimation::update()
     }
   }
   ((ssgTexTrans *)_branch)->setTransform(tmatrix);
+  return 1;
 }
 
 
@@ -904,4 +921,39 @@ void SGAlphaTestAnimation::setAlphaClampToBranch(ssgBranch *b, float clamp)
   }
 }
 
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of SGFlashAnimation
+////////////////////////////////////////////////////////////////////////
+SGFlashAnimation::SGFlashAnimation(SGPropertyNode_ptr props)
+  : SGAnimation( props, new SGFlash )
+{
+  sgVec3 axis;
+  axis[0] = props->getFloatValue("axis/x", 0);
+  axis[1] = props->getFloatValue("axis/y", 0);
+  axis[2] = props->getFloatValue("axis/z", 1);
+  ((SGFlash *)_branch)->setAxis( axis );
+
+  sgVec3 center;
+  center[0] = props->getFloatValue("center/x-m", 0);
+  center[1] = props->getFloatValue("center/y-m", 0);
+  center[2] = props->getFloatValue("center/z-m", 0);
+  ((SGFlash *)_branch)->setCenter( center );
+
+  float offset = props->getFloatValue("offset", 0.0);
+  float factor = props->getFloatValue("factor", 1.0);
+  float power = props->getFloatValue("power", 1.0);
+  bool two_sides = props->getBoolValue("two-sides", false);
+  ((SGFlash *)_branch)->setParameters( power, factor, offset, two_sides );
+
+  float v_min = props->getFloatValue("min", 0.0);
+  float v_max = props->getFloatValue("max", 1.0);
+  ((SGFlash *)_branch)->setClampValues( v_min, v_max );
+}
+
+SGFlashAnimation::~SGFlashAnimation()
+{
+}
+
 // end of animation.cxx
index c0c7fc3964982bd52d1fc564e936e8dd34a796ff..76259c980f3423e4ed28c05fb64ce0537a33d2ed 100644 (file)
@@ -65,7 +65,12 @@ public:
   /**
    * Update the animation.
    */
-  virtual void update();
+  virtual int update();
+
+  /**
+   * Restore the state after the animation.
+   */
+  virtual void restore();
 
   /**
    * Set the value of sim_time_sec.  This needs to be called every
@@ -102,7 +107,7 @@ public:
   SGRangeAnimation (SGPropertyNode *prop_root,
                     SGPropertyNode_ptr props);
   virtual ~SGRangeAnimation ();
-  virtual void update();
+  virtual int update();
 private:
   SGPropertyNode_ptr _min_prop;
   SGPropertyNode_ptr _max_prop;
@@ -133,7 +138,7 @@ public:
   SGSelectAnimation( SGPropertyNode *prop_root,
                    SGPropertyNode_ptr props );
   virtual ~SGSelectAnimation ();
-  virtual void update();
+  virtual int update();
 private:
   SGCondition * _condition;
 };
@@ -151,7 +156,7 @@ public:
                  SGPropertyNode_ptr props,
                  double sim_time_sec );
   virtual ~SGSpinAnimation ();
-  virtual void update();
+  virtual int update();
 private:
   SGPropertyNode_ptr _prop;
   double _factor;
@@ -171,7 +176,7 @@ class SGTimedAnimation : public SGAnimation
 public:
     SGTimedAnimation (SGPropertyNode_ptr props);
     virtual ~SGTimedAnimation ();
-    virtual void update();
+    virtual int update();
 private:
     double _duration_sec;
     double _last_time_sec;
@@ -189,7 +194,7 @@ class SGRotateAnimation : public SGAnimation
 public:
   SGRotateAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props );
   virtual ~SGRotateAnimation ();
-  virtual void update();
+  virtual int update();
 private:
   SGPropertyNode_ptr _prop;
   double _offset_deg;
@@ -215,7 +220,7 @@ public:
   SGTranslateAnimation( SGPropertyNode *prop_root,
                       SGPropertyNode_ptr props );
   virtual ~SGTranslateAnimation ();
-  virtual void update();
+  virtual int update();
 private:
   SGPropertyNode_ptr _prop;
   double _offset_m;
@@ -239,7 +244,7 @@ public:
   SGBlendAnimation( SGPropertyNode *prop_root,
                       SGPropertyNode_ptr props );
   virtual ~SGBlendAnimation ();
-  virtual void update();
+  virtual int update();
 private:
   SGPropertyNode_ptr _prop;
   SGInterpTable * _table;
@@ -261,7 +266,7 @@ public:
   SGScaleAnimation( SGPropertyNode *prop_root,
                         SGPropertyNode_ptr props );
   virtual ~SGScaleAnimation ();
-  virtual void update();
+  virtual int update();
 private:
   SGPropertyNode_ptr _prop;
   double _x_factor;
@@ -299,7 +304,7 @@ class SGTexRotateAnimation : public SGAnimation
 public:
   SGTexRotateAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props );
   virtual ~SGTexRotateAnimation ();
-  virtual void update();
+  virtual int update();
 private:
   SGPropertyNode_ptr _prop;
   double _offset_deg;
@@ -325,7 +330,7 @@ public:
   SGTexTranslateAnimation( SGPropertyNode *prop_root,
                       SGPropertyNode_ptr props );
   virtual ~SGTexTranslateAnimation ();
-  virtual void update();
+  virtual int update();
 private:
   SGPropertyNode_ptr _prop;
   double _offset;
@@ -354,7 +359,7 @@ public:
   SGTexMultipleAnimation( SGPropertyNode *prop_root,
                       SGPropertyNode_ptr props );
   virtual ~SGTexMultipleAnimation ();
-  virtual void update();
+  virtual int update();
 private:
   class TexTransform
     {
@@ -382,7 +387,7 @@ private:
 
 
 /**
- * An animation to enable the alpha test 
+ * An "animation" to enable the alpha test 
  */
 class SGAlphaTestAnimation : public SGAnimation
 {
@@ -396,4 +401,16 @@ private:
 };
 
 
+/**
+ * An "animation" that compute a scale according to 
+ * the angle between an axis and the view direction
+ */
+class SGFlashAnimation : public SGAnimation
+{
+public:
+  SGFlashAnimation(SGPropertyNode_ptr props);
+  virtual ~SGFlashAnimation ();
+};
+
+
 #endif // _SG_ANIMATION_HXX
diff --git a/simgear/scene/model/flash.cxx b/simgear/scene/model/flash.cxx
new file mode 100755 (executable)
index 0000000..9e75421
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+     $Id$
+*/
+
+#include "plib/ssg.h"
+#include "flash.hxx"
+void _ssgPushMatrix ( sgMat4 m );
+void _ssgPopMatrix  ();
+void _ssgReadInt     ( FILE *fd,                int   *var );
+void _ssgWriteInt    ( FILE *fd, const          int    var );
+extern sgMat4 _ssgOpenGLAxisSwapMatrix;
+
+void SGFlash::copy_from( SGFlash *src, int clone_flags )
+{
+  ssgBranch::copy_from( src, clone_flags );
+  sgCopyVec3( _center, src->_center );
+  sgCopyVec3( _axis, src->_axis );
+  _power = src->_power;
+  _factor = src->_factor;
+  _offset = src->_offset;
+  _min_v = src->_min_v;
+  _max_v = src->_max_v;
+  _two_sides = src->_two_sides;
+}
+
+ssgBase *SGFlash::clone( int clone_flags )
+{
+  SGFlash *b = new SGFlash;
+  b -> copy_from( this, clone_flags );
+  return b;
+}
+
+
+SGFlash::SGFlash()
+{
+  type = ssgTypeBranch();
+}
+
+SGFlash::~SGFlash()
+{
+}
+
+void SGFlash::setAxis( sgVec3 axis )
+{
+  sgCopyVec3( _axis, axis );
+  sgNormalizeVec3( _axis );
+}
+
+void SGFlash::setCenter( sgVec3 center )
+{
+  sgCopyVec3( _center, center );
+}
+
+void SGFlash::setParameters( float power, float factor, float offset, bool two_sides )
+{
+  _power = power;
+  _factor = factor;
+  _offset = offset;
+  _two_sides = two_sides;
+}
+
+void SGFlash::setClampValues( float min_v, float max_v )
+{
+  _min_v = min_v;
+  _max_v = max_v;
+}
+
+void SGFlash::cull( sgFrustum *f, sgMat4 m, int test_needed )
+{
+  if ( ! preTravTests( &test_needed, SSGTRAV_CULL ) )
+    return;
+
+  sgVec3 transformed_axis;
+  sgXformVec3( transformed_axis, _axis, m );
+  sgNormalizeVec3( transformed_axis );
+
+  float cos_angle = transformed_axis[ 2 ]; // z component, through the screen
+  float scale_factor = 0.f;
+  if ( _two_sides && cos_angle < 0 )
+    scale_factor = _factor * (float)pow( -cos_angle, _power ) + _offset;
+  else if ( cos_angle > 0 )
+    scale_factor = _factor * (float)pow( cos_angle, _power ) + _offset;
+
+  if ( scale_factor < _min_v )
+      scale_factor = _min_v;
+  if ( scale_factor > _max_v )
+      scale_factor = _max_v;
+
+  sgMat4 tmp, transform;
+  sgMakeIdentMat4( transform );
+  transform[0][0] = scale_factor;
+  transform[1][1] = scale_factor;
+  transform[2][2] = scale_factor;
+  transform[3][0] = _center[0] * ( 1 - scale_factor );
+  transform[3][1] = _center[1] * ( 1 - scale_factor );
+  transform[3][2] = _center[2] * ( 1 - scale_factor );
+
+  sgCopyMat4( tmp, m );
+  sgPreMultMat4( tmp, transform );
+
+  _ssgPushMatrix( tmp );
+  glPushMatrix();
+  glLoadMatrixf( (float *) tmp );
+
+  for ( ssgEntity *e = getKid ( 0 ); e != NULL; e = getNextKid() )
+    e -> cull( f, tmp, test_needed );
+
+  glPopMatrix();
+  _ssgPopMatrix();
+
+  postTravTests( SSGTRAV_CULL );
+}
+
+
+void SGFlash::hot( sgVec3 s, sgMat4 m, int test_needed )
+{
+  ssgBranch::hot( s, m, test_needed );
+}
+
+void SGFlash::los( sgVec3 s, sgMat4 m, int test_needed )
+{
+  ssgBranch::los( s, m, test_needed );
+}
+
+
+void SGFlash::isect( sgSphere *s, sgMat4 m, int test_needed )
+{
+  ssgBranch::isect( s, m, test_needed );
+}
+
+
+
+int SGFlash::load( FILE *fd )
+{
+//  _ssgReadInt( fd, & point_rotate );
+
+  return ssgBranch::load(fd);
+}
+
+int SGFlash::save( FILE *fd )
+{
+//  _ssgWriteInt( fd, point_rotate );
+
+  return ssgBranch::save(fd);
+}
+
+const char *SGFlash::getTypeName (void) { return "SGFlash"; }
diff --git a/simgear/scene/model/flash.hxx b/simgear/scene/model/flash.hxx
new file mode 100755 (executable)
index 0000000..f94fef0
--- /dev/null
@@ -0,0 +1,29 @@
+
+class SGFlash : public ssgBranch
+{
+public:
+    virtual ssgBase *clone( int clone_flags = 0 );
+    SGFlash();
+    virtual ~SGFlash(void);
+
+    void setAxis( sgVec3 axis );
+    void setCenter( sgVec3 center );
+    void setParameters( float power, float factor, float offset, bool two_sides );
+    void setClampValues( float min_v, float max_v );
+
+    virtual const char *getTypeName(void);
+    virtual int load( FILE *fd );
+    virtual int save( FILE *fd );
+    virtual void cull( sgFrustum *f, sgMat4 m, int test_needed );
+    virtual void isect( sgSphere *s, sgMat4 m, int test_needed );
+    virtual void hot( sgVec3 s, sgMat4 m, int test_needed );
+    virtual void los( sgVec3 s, sgMat4 m, int test_needed );
+
+protected:
+    virtual void copy_from( SGFlash *src, int clone_flags );
+
+private:
+    sgVec3 _axis, _center;
+    float _power, _factor, _offset, _min_v, _max_v;
+    bool _two_sides;
+};
index be5d9f48014e1b1c45b0dc838529b42d4a87a82f..3e6d508b602af01843197387299ddf7e13304cc9 100644 (file)
@@ -52,8 +52,17 @@ model_filter_callback (ssgEntity * entity, int mask)
 static int
 animation_callback (ssgEntity * entity, int mask)
 {
-    ((SGAnimation *)entity->getUserData())->update();
-    return true;
+    return ((SGAnimation *)entity->getUserData())->update();
+}
+
+/**
+ * Callback to restore the state after an animation.
+ */
+static int
+restore_callback (ssgEntity * entity, int mask)
+{
+    ((SGAnimation *)entity->getUserData())->restore();
+    return 1;
 }
 
 
@@ -145,6 +154,8 @@ sgMakeAnimation( ssgBranch * model,
     animation = new SGBlendAnimation(prop_root, node);
   } else if (!strcmp("alpha-test", type)) {
     animation = new SGAlphaTestAnimation(node);
+  } else if (!strcmp("flash", type)) {
+    animation = new SGFlashAnimation(node);
   } else {
     animation = new SGNullAnimation(node);
     SG_LOG(SG_INPUT, SG_WARN, "Unknown animation type " << type);
@@ -188,6 +199,7 @@ sgMakeAnimation( ssgBranch * model,
   animation->init();
   branch->setUserData(animation);
   branch->setTravCallback(SSG_CALLBACK_PRETRAV, animation_callback);
+  branch->setTravCallback(SSG_CALLBACK_POSTTRAV, restore_callback);
 }