]> git.mxchange.org Git - simgear.git/blob - simgear/scene/model/animation.hxx
Modified Files:
[simgear.git] / simgear / scene / model / animation.hxx
1
2 // animation.hxx - classes to manage model animation.
3 // Written by David Megginson, started 2002.
4 //
5 // This file is in the Public Domain, and comes with no warranty.
6
7 #ifndef _SG_ANIMATION_HXX
8 #define _SG_ANIMATION_HXX 1
9
10 #ifndef __cplusplus
11 # error This library requires C++
12 #endif
13
14 #include <vector>
15 #include <map>
16
17 #include <osg/Vec3>
18 #include <osg/Vec4>
19
20 #include <osg/ref_ptr>
21 #include <osg/AlphaFunc>
22 #include <osg/ColorMatrix>
23 #include <osg/Group>
24 #include <osg/Material>
25 #include <osg/Node>
26 #include <osg/NodeCallback>
27 #include <osg/NodeVisitor>
28 #include <osg/StateSet>
29 #include <osg/Texture2D>
30 #include <osg/TexMat>
31
32 #include <simgear/props/props.hxx>
33 #include <simgear/misc/sg_path.hxx>
34
35 #include <simgear/scene/model/persparam.hxx>
36 #include <simgear/scene/util/SGNodeMasks.hxx>
37
38 SG_USING_STD(vector);
39 SG_USING_STD(map);
40
41 // Don't pull in the headers, since we don't need them here.
42 class SGInterpTable;
43 class SGCondition;
44 class SGPersonalityBranch;
45
46 // Has anyone done anything *really* stupid, like making min and max macros?
47 #ifdef min
48 #undef min
49 #endif
50 #ifdef max
51 #undef max
52 #endif
53
54
55 \f
56 //////////////////////////////////////////////////////////////////////
57 // Animation classes
58 //////////////////////////////////////////////////////////////////////
59
60 /**
61  * Abstract base class for all animations.
62  */
63 class SGAnimation :  public osg::NodeCallback
64 {
65 public:
66   enum PersonalityVar { INIT_SPIN, LAST_TIME_SEC_SPIN, FACTOR_SPIN, 
67                             POSITION_DEG_SPIN, 
68                         INIT_TIMED, LAST_TIME_SEC_TIMED, TOTAL_DURATION_SEC_TIMED, 
69                             BRANCH_DURATION_SEC_TIMED, STEP_TIMED,
70                         INIT_TRANSLATE, FACTOR_TRANSLATE, OFFSET_TRANSLATE,
71                         INIT_BLEND, FACTOR_BLEND, OFFSET_BLEND,
72                         INIT_SCALE, X_FACTOR_SCALE, Y_FACTOR_SCALE, Z_FACTOR_SCALE,
73                             X_OFFSET_SCALE, Y_OFFSET_SCALE, Z_OFFSET_SCALE };
74
75   SGAnimation (SGPropertyNode_ptr props, osg::Group * branch);
76
77   virtual ~SGAnimation ();
78
79   /**
80    * Get the SSG branch holding the animation.
81    */
82   virtual osg::Group * getBranch () { return _branch; }
83
84   /**
85    * Initialize the animation, after children have been added.
86    */
87   virtual void init ();
88
89   /**
90    * Update the animation.
91    */
92   virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
93   { 
94     // note, callback is responsible for scenegraph traversal so
95     // should always include call traverse(node,nv) to ensure 
96     // that the rest of cullbacks and the scene graph are traversed.
97     update();
98     traverse(node, nv);
99   }
100   virtual int update();
101
102   /**
103    * Restore the state after the animation.
104    */
105   virtual void restore();
106
107   /**
108    * Set the value of sim_time_sec.  This needs to be called every
109    * frame in order for the time based animations to work correctly.
110    */
111   static void set_sim_time_sec( double val ) { sim_time_sec = val; }
112
113   /**
114    * Current personality branch : enable animation to behave differently
115    * for similar objects
116    */
117   static SGPersonalityBranch *current_object;
118
119   int get_animation_type(void) { return animation_type; }
120
121 protected:
122
123   static double sim_time_sec;
124
125   osg::Group* _branch;
126
127   int animation_type;
128 };
129
130
131 /**
132  * A no-op animation.
133  */
134 class SGNullAnimation : public SGAnimation
135 {
136 public:
137   SGNullAnimation (SGPropertyNode_ptr props);
138   virtual ~SGNullAnimation ();
139 };
140
141
142 /**
143  * A range, or level-of-detail (LOD) animation.
144  */
145 class SGRangeAnimation : public SGAnimation
146 {
147 public:
148   SGRangeAnimation (SGPropertyNode *prop_root,
149                     SGPropertyNode_ptr props);
150   virtual ~SGRangeAnimation ();
151   virtual int update();
152 private:
153   SGPropertyNode_ptr _min_prop;
154   SGPropertyNode_ptr _max_prop;
155   float _min;
156   float _max;
157   float _min_factor;
158   float _max_factor;
159   SGCondition * _condition;
160 };
161
162
163 /**
164  * Animation to turn and face the screen.
165  */
166 class SGBillboardAnimation : public SGAnimation
167 {
168 public:
169   SGBillboardAnimation (SGPropertyNode_ptr props);
170   virtual ~SGBillboardAnimation ();
171 };
172
173
174 /**
175  * Animation to select alternative versions of the same object.
176  */
177 class SGSelectAnimation : public SGAnimation
178 {
179 public:
180   SGSelectAnimation( SGPropertyNode *prop_root,
181                    SGPropertyNode_ptr props );
182   virtual ~SGSelectAnimation ();
183   virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
184 private:
185   SGCondition * _condition;
186 };
187
188
189 /**
190  * Animation to spin an object around a center point.
191  *
192  * This animation rotates at a specific velocity.
193  */
194 class SGSpinAnimation : public SGAnimation
195 {
196 public:
197   SGSpinAnimation( SGPropertyNode *prop_root,
198                  SGPropertyNode_ptr props,
199                  double sim_time_sec );
200   virtual ~SGSpinAnimation ();
201   virtual int update();
202 private:
203   bool _use_personality;
204   SGPropertyNode_ptr _prop;
205   SGPersonalityParameter<double> _factor;
206   SGPersonalityParameter<double> _position_deg;
207   double _last_time_sec;
208   osg::Vec3 _center;
209   osg::Vec3 _axis;
210   SGCondition * _condition;
211 };
212
213
214 /**
215  * Animation to draw objects for a specific amount of time each.
216  */
217 class SGTimedAnimation : public SGAnimation
218 {
219 public:
220     SGTimedAnimation (SGPropertyNode_ptr props);
221     virtual ~SGTimedAnimation ();
222     virtual void init();
223     virtual int update();
224 private:
225     bool _use_personality;
226     double _duration_sec;
227     double _last_time_sec;
228     double _total_duration_sec;
229     unsigned _step;
230     struct DurationSpec {
231         DurationSpec( double m = 0.0 ) : _min(m), _max(m) {}
232         DurationSpec( double m1, double m2 ) : _min(m1), _max(m2) {}
233         double _min, _max;
234     };
235     vector<DurationSpec> _branch_duration_specs;
236     vector<double> _branch_duration_sec;
237 };
238
239
240 /**
241  * Animation to rotate an object around a center point.
242  *
243  * This animation rotates to a specific position.
244  */
245 class SGRotateAnimation : public SGAnimation
246 {
247 public:
248   SGRotateAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props );
249   virtual ~SGRotateAnimation ();
250   virtual int update();
251 private:
252   SGPropertyNode_ptr _prop;
253   double _offset_deg;
254   double _factor;
255   SGInterpTable * _table;
256   bool _has_min;
257   double _min_deg;
258   bool _has_max;
259   double _max_deg;
260   double _position_deg;
261   osg::Vec3 _center;
262   osg::Vec3 _axis;
263   SGCondition * _condition;
264 };
265
266
267 /**
268  * Animation to slide along an axis.
269  */
270 class SGTranslateAnimation : public SGAnimation
271 {
272 public:
273   SGTranslateAnimation( SGPropertyNode *prop_root,
274                       SGPropertyNode_ptr props );
275   virtual ~SGTranslateAnimation ();
276   virtual int update();
277 private:
278   bool _use_personality;
279   SGPropertyNode_ptr _prop;
280   SGPersonalityParameter<double> _offset_m;
281   SGPersonalityParameter<double> _factor;
282   SGInterpTable * _table;
283   bool _has_min;
284   double _min_m;
285   bool _has_max;
286   double _max_m;
287   double _position_m;
288   osg::Vec3 _axis;
289   SGCondition * _condition;
290 };
291
292 /**
293  * Animation to blend an object.
294  */
295 class SGBlendAnimation : public SGAnimation
296 {
297 public:
298   SGBlendAnimation( SGPropertyNode *prop_root,
299                       SGPropertyNode_ptr props );
300   virtual ~SGBlendAnimation ();
301   virtual int update();
302 private:
303   bool _use_personality;
304   SGPropertyNode_ptr _prop;
305   SGInterpTable * _table;
306   double _prev_value;
307   SGPersonalityParameter<double> _offset;
308   SGPersonalityParameter<double> _factor;
309   bool _has_min;
310   double _min;
311   bool _has_max;
312   double _max;
313   osg::ref_ptr<osg::ColorMatrix> _colorMatrix;
314 };
315
316 /**
317  * Animation to scale an object.
318  */
319 class SGScaleAnimation : public SGAnimation
320 {
321 public:
322   SGScaleAnimation( SGPropertyNode *prop_root,
323                         SGPropertyNode_ptr props );
324   virtual ~SGScaleAnimation ();
325   virtual int update();
326 private:
327   bool _use_personality;
328   SGPropertyNode_ptr _prop;
329   SGPersonalityParameter<double> _x_factor;
330   SGPersonalityParameter<double> _y_factor;
331   SGPersonalityParameter<double> _z_factor;
332   SGPersonalityParameter<double> _x_offset;
333   SGPersonalityParameter<double> _y_offset;
334   SGPersonalityParameter<double> _z_offset;
335   SGInterpTable * _table;
336   bool _has_min_x;
337   bool _has_min_y;
338   bool _has_min_z;
339   double _min_x;
340   double _min_y;
341   double _min_z;
342   bool _has_max_x;
343   bool _has_max_y;
344   bool _has_max_z;
345   double _max_x;
346   double _max_y;
347   double _max_z;
348   double _x_scale;
349   double _y_scale;
350   double _z_scale;
351 };
352
353 /**
354  * Animation to rotate texture mappings around a center point.
355  *
356  * This animation rotates to a specific position.
357  */
358 class SGTexRotateAnimation : public SGAnimation
359 {
360 public:
361   SGTexRotateAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props );
362   virtual ~SGTexRotateAnimation ();
363   virtual int update();
364 private:
365   SGPropertyNode_ptr _prop;
366   double _offset_deg;
367   double _factor;
368   SGInterpTable * _table;
369   bool _has_min;
370   double _min_deg;
371   bool _has_max;
372   double _max_deg;
373   double _position_deg;
374   osg::Vec3 _center;
375   osg::Vec3 _axis;
376   SGCondition * _condition;
377   osg::ref_ptr<osg::TexMat> _texMat;
378 };
379
380
381 /**
382  * Animation to slide texture mappings along an axis.
383  */
384 class SGTexTranslateAnimation : public SGAnimation
385 {
386 public:
387   SGTexTranslateAnimation( SGPropertyNode *prop_root,
388                       SGPropertyNode_ptr props );
389   virtual ~SGTexTranslateAnimation ();
390   virtual int update();
391 private:
392   SGPropertyNode_ptr _prop;
393   double _offset;
394   double _factor;
395   double _step;
396   double _scroll;
397   SGInterpTable * _table;
398   bool _has_min;
399   double _min;
400   bool _has_max;
401   double _max;
402   double _position;
403   osg::Vec3 _axis;
404   SGCondition * _condition;
405   osg::ref_ptr<osg::TexMat> _texMat;
406 };
407
408
409
410 /**
411  * Classes for handling multiple types of Texture translations on one object
412  */
413
414 class SGTexMultipleAnimation : public SGAnimation
415 {
416 public:
417   SGTexMultipleAnimation( SGPropertyNode *prop_root,
418                       SGPropertyNode_ptr props );
419   virtual ~SGTexMultipleAnimation ();
420   virtual int update();
421 private:
422   class TexTransform
423     {
424     public:
425     SGPropertyNode_ptr prop;
426     int subtype; //  0=translation, 1=rotation
427     double offset;
428     double factor;
429     double step;
430     double scroll;
431     SGInterpTable * table;
432     bool has_min;
433     double min;
434     bool has_max;
435     double max;
436     double position;
437     osg::Vec3 center;
438     osg::Vec3 axis;
439   };
440   SGPropertyNode_ptr _prop;
441   TexTransform* _transform;
442   int _num_transforms;
443   osg::ref_ptr<osg::TexMat> _texMat;
444 };
445
446
447 /**
448  * An "animation" to enable the alpha test 
449  */
450 class SGAlphaTestAnimation : public SGAnimation
451 {
452 public:
453   SGAlphaTestAnimation(SGPropertyNode_ptr props);
454   virtual ~SGAlphaTestAnimation ();
455   virtual void init();
456 private:
457   float _alpha_clamp;
458 };
459
460
461 /**
462  * An "animation" to modify material properties
463  */
464 class SGMaterialAnimation : public SGAnimation
465 {
466 public:
467     SGMaterialAnimation(SGPropertyNode *prop_root, SGPropertyNode_ptr props,
468             const SGPath &texpath);
469     virtual ~SGMaterialAnimation() {}
470     virtual void init();
471     virtual int update();
472 private:
473     enum {
474         DIFFUSE = 1,
475         AMBIENT = 2,
476         SPECULAR = 4,
477         EMISSION = 8,
478         SHININESS = 16,
479         TRANSPARENCY = 32,
480         THRESHOLD = 64,
481         TEXTURE = 128,
482     };
483     struct ColorSpec {
484         float red, green, blue;
485         float factor;
486         float offset;
487         SGPropertyNode_ptr red_prop;
488         SGPropertyNode_ptr green_prop;
489         SGPropertyNode_ptr blue_prop;
490         SGPropertyNode_ptr factor_prop;
491         SGPropertyNode_ptr offset_prop;
492         osg::Vec4 v;
493         inline bool dirty() {
494             return red >= 0.0 || green >= 0.0 || blue >= 0.0;
495         }
496         inline bool live() {
497             return red_prop || green_prop || blue_prop
498                     || factor_prop || offset_prop;
499         }
500         inline bool operator!=(ColorSpec& a) {
501             return red != a.red || green != a.green || blue != a.blue
502                     || factor != a.factor || offset != a.offset;
503         }
504         osg::Vec4 &rgba() {
505             v[0] = clamp(red * factor + offset);
506             v[1] = clamp(green * factor + offset);
507             v[2] = clamp(blue * factor + offset);
508             v[3] = 1.0;
509             return v;
510         }
511         inline float clamp(float val) {
512             return val < 0.0 ? 0.0 : val > 1.0 ? 1.0 : val;
513         }
514     };
515     struct PropSpec {
516         float value;
517         float factor;
518         float offset;
519         float min;
520         float max;
521         SGPropertyNode_ptr value_prop;
522         SGPropertyNode_ptr factor_prop;
523         SGPropertyNode_ptr offset_prop;
524         inline bool dirty() { return value >= 0.0; }
525         inline bool live() { return value_prop || factor_prop || offset_prop; }
526         inline bool operator!=(PropSpec& a) {
527             return value != a.value || factor != a.factor || offset != a.offset;
528         }
529     };
530     SGCondition *_condition;
531     bool _last_condition;
532     SGPropertyNode_ptr _prop_root;
533     string _prop_base;
534     SGPath _texture_base;
535     SGPath _texture;
536     string _texture_str;
537     unsigned _read;
538     unsigned _update;
539     unsigned _static_update;
540     bool _global;
541     ColorSpec _diff;
542     ColorSpec _amb;
543     ColorSpec _emis;
544     ColorSpec _spec;
545     float _shi;
546     PropSpec _trans;
547     float _thresh;      // alpha_clamp (see man glAlphaFunc)
548     string _tex;
549     string _tmpstr;
550     SGPropertyNode_ptr _shi_prop;
551     SGPropertyNode_ptr _thresh_prop;
552     SGPropertyNode_ptr _tex_prop;
553     std::vector<osg::Material*> _materialList;
554     osg::ref_ptr<osg::AlphaFunc> _alphaFunc;
555     osg::ref_ptr<osg::Texture2D> _texture2D;
556
557     void cloneMaterials(osg::Group *b);
558     void setMaterialBranch(osg::Group *b);
559     void initColorGroup(SGPropertyNode_ptr, ColorSpec *, int flag);
560     void updateColorGroup(ColorSpec *, int flag);
561     inline float clamp(float val, float min = 0.0, float max = 1.0) {
562         return val < min ? min : val > max ? max : val;
563     }
564     const char *path(const char *rel) {
565         return (_tmpstr = _prop_base + rel).c_str();
566     }
567 };
568
569
570 /**
571  * An "animation" that compute a scale according to 
572  * the angle between an axis and the view direction
573  */
574 class SGFlashAnimation : public SGAnimation
575 {
576 public:
577   SGFlashAnimation(SGPropertyNode_ptr props);
578   virtual ~SGFlashAnimation ();
579 };
580
581
582 /**
583  * An animation that compute a scale according to 
584  * the distance from a point and the viewer
585  */
586 class SGDistScaleAnimation : public SGAnimation
587 {
588 public:
589   SGDistScaleAnimation(SGPropertyNode_ptr props);
590   virtual ~SGDistScaleAnimation ();
591 };
592
593 /**
594  * An animation to tell wich objects don't cast shadows.
595  */
596 class SGShadowAnimation : public SGAnimation
597 {
598 public:
599   SGShadowAnimation ( SGPropertyNode *prop_root,
600                    SGPropertyNode_ptr props );
601   virtual ~SGShadowAnimation ();
602   virtual int update();
603   bool get_condition_value(void);
604 private:
605   SGCondition * _condition;
606   bool _condition_value;
607 };
608
609 /**
610 + * An "animation" that replace fixed opengl pipeline by shaders
611 + */
612 class SGShaderAnimation : public SGAnimation
613 {
614 public:
615   SGShaderAnimation ( SGPropertyNode *prop_root,
616                    SGPropertyNode_ptr props );
617   virtual ~SGShaderAnimation ();
618   virtual void init();
619   virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
620   bool get_condition_value(void);
621 private:
622   SGCondition * _condition;
623   bool _condition_value;
624   int _shader_type;
625   float _param_1;
626   osg::Vec4 _param_color;
627 public:
628   bool _depth_test;
629   float _factor;
630   SGPropertyNode_ptr _factor_prop;
631   float _speed;
632   float totalTime;
633   SGPropertyNode_ptr _speed_prop;
634   osg::ref_ptr<osg::Texture2D> _effectTexture;
635   unsigned char *_textureData;
636   GLint _texWidth, _texHeight;
637   osg::Vec4 _envColor;
638 };
639
640
641 #endif // _SG_ANIMATION_HXX