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