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