]> git.mxchange.org Git - simgear.git/blob - simgear/scene/model/animation.hxx
Harald JOHNSEN:
[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 SG_USING_STD(vector);
18 SG_USING_STD(map);
19
20 #include <plib/sg.h>
21 #include <plib/ssg.h>
22
23 #include <simgear/math/point3d.hxx>
24 #include <simgear/props/props.hxx>
25 #include <simgear/misc/sg_path.hxx>
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 };
358
359
360 /**
361  * Animation to slide texture mappings along an axis.
362  */
363 class SGTexTranslateAnimation : public SGAnimation
364 {
365 public:
366   SGTexTranslateAnimation( SGPropertyNode *prop_root,
367                       SGPropertyNode_ptr props );
368   virtual ~SGTexTranslateAnimation ();
369   virtual int update();
370 private:
371   SGPropertyNode_ptr _prop;
372   double _offset;
373   double _factor;
374   double _step;
375   double _scroll;
376   SGInterpTable * _table;
377   bool _has_min;
378   double _min;
379   bool _has_max;
380   double _max;
381   double _position;
382   sgMat4 _matrix;
383   sgVec3 _axis;
384 };
385
386
387
388 /**
389  * Classes for handling multiple types of Texture translations on one object
390  */
391
392 class SGTexMultipleAnimation : public SGAnimation
393 {
394 public:
395   SGTexMultipleAnimation( SGPropertyNode *prop_root,
396                       SGPropertyNode_ptr props );
397   virtual ~SGTexMultipleAnimation ();
398   virtual int update();
399 private:
400   class TexTransform
401     {
402     public:
403     SGPropertyNode_ptr prop;
404     int subtype; //  0=translation, 1=rotation
405     double offset;
406     double factor;
407     double step;
408     double scroll;
409     SGInterpTable * table;
410     bool has_min;
411     double min;
412     bool has_max;
413     double max;
414     double position;
415     sgMat4 matrix;
416     sgVec3 center;
417     sgVec3 axis;
418   };
419   SGPropertyNode_ptr _prop;
420   TexTransform* _transform;
421   int _num_transforms;
422 };
423
424
425 /**
426  * An "animation" to enable the alpha test 
427  */
428 class SGAlphaTestAnimation : public SGAnimation
429 {
430 public:
431   SGAlphaTestAnimation(SGPropertyNode_ptr props);
432   virtual ~SGAlphaTestAnimation ();
433   virtual void init();
434 private:
435   void setAlphaClampToBranch(ssgBranch *b, float clamp);
436   float _alpha_clamp;
437 };
438
439
440 /**
441  * An "animation" to modify material properties
442  */
443 class SGMaterialAnimation : public SGAnimation
444 {
445 public:
446     SGMaterialAnimation(SGPropertyNode *prop_root, SGPropertyNode_ptr props,
447             const SGPath &texpath);
448     virtual ~SGMaterialAnimation() {}
449     virtual void init();
450     virtual int update();
451 private:
452     enum {
453         DIFFUSE = 1,
454         AMBIENT = 2,
455         SPECULAR = 4,
456         EMISSION = 8,
457         SHININESS = 16,
458         TRANSPARENCY = 32,
459         THRESHOLD = 64,
460         TEXTURE = 128,
461     };
462     struct ColorSpec {
463         float red, green, blue;
464         float factor;
465         float offset;
466         SGPropertyNode_ptr red_prop;
467         SGPropertyNode_ptr green_prop;
468         SGPropertyNode_ptr blue_prop;
469         SGPropertyNode_ptr factor_prop;
470         SGPropertyNode_ptr offset_prop;
471         sgVec4 v;
472         inline bool dirty() {
473             return red >= 0.0 || green >= 0.0 || blue >= 0.0;
474         }
475         inline bool live() {
476             return red_prop || green_prop || blue_prop
477                     || factor_prop || offset_prop;
478         }
479         inline bool operator!=(ColorSpec& a) {
480             return red != a.red || green != a.green || blue != a.blue
481                     || factor != a.factor || offset != a.offset;
482         }
483         sgVec4 &rgba() {
484             v[0] = clamp(red * factor + offset);
485             v[1] = clamp(green * factor + offset);
486             v[2] = clamp(blue * factor + offset);
487             v[3] = 1.0;
488             return v;
489         }
490         inline float clamp(float val) {
491             return val < 0.0 ? 0.0 : val > 1.0 ? 1.0 : val;
492         }
493     };
494     struct PropSpec {
495         float value;
496         float factor;
497         float offset;
498         float min;
499         float max;
500         SGPropertyNode_ptr value_prop;
501         SGPropertyNode_ptr factor_prop;
502         SGPropertyNode_ptr offset_prop;
503         inline bool dirty() { return value >= 0.0; }
504         inline bool live() { return value_prop || factor_prop || offset_prop; }
505         inline bool operator!=(PropSpec& a) {
506             return value != a.value || factor != a.factor || offset != a.offset;
507         }
508     };
509     SGCondition *_condition;
510     SGPropertyNode *_prop_root;
511     string _prop_base;
512     SGPath _texture_base;
513     SGPath _texture;
514     string _texture_str;
515     ssgSimpleState* _cached_material;
516     ssgSimpleState* _cloned_material;
517     unsigned _read;
518     unsigned _update;
519     bool _global;
520     ColorSpec _diff;
521     ColorSpec _amb;
522     ColorSpec _emis;
523     ColorSpec _spec;
524     float _shi;
525     PropSpec _trans;
526     float _thresh;      // alpha_clamp (see man glAlphaFunc)
527     string _tex;
528     string _tmpstr;
529     SGPropertyNode_ptr _shi_prop;
530     SGPropertyNode_ptr _thresh_prop;
531     SGPropertyNode_ptr _tex_prop;
532
533     void cloneMaterials(ssgBranch *b);
534     void setMaterialBranch(ssgBranch *b);
535     void initColorGroup(SGPropertyNode_ptr, ColorSpec *, int flag);
536     void updateColorGroup(ColorSpec *, int flag);
537     inline float clamp(float val, float min = 0.0, float max = 1.0) {
538         return val < min ? min : val > max ? max : val;
539     }
540     const char *path(const char *rel) {
541         return (_tmpstr = _prop_base + rel).c_str();
542     }
543 };
544
545
546 /**
547  * An "animation" that compute a scale according to 
548  * the angle between an axis and the view direction
549  */
550 class SGFlashAnimation : public SGAnimation
551 {
552 public:
553   SGFlashAnimation(SGPropertyNode_ptr props);
554   virtual ~SGFlashAnimation ();
555
556   static void flashCallback( sgMat4 r, sgFrustum *f, sgMat4 m, void *d );
557   void flashCallback( sgMat4 r, sgFrustum *f, sgMat4 m );
558
559 private:
560   sgVec3 _axis, _center;
561   float _power, _factor, _offset, _min_v, _max_v;
562   bool _two_sides;
563 };
564
565
566 /**
567  * An animation that compute a scale according to 
568  * the distance from a point and the viewer
569  */
570 class SGDistScaleAnimation : public SGAnimation
571 {
572 public:
573   SGDistScaleAnimation(SGPropertyNode_ptr props);
574   virtual ~SGDistScaleAnimation ();
575
576   static void distScaleCallback( sgMat4 r, sgFrustum *f, sgMat4 m, void *d );
577   void distScaleCallback( sgMat4 r, sgFrustum *f, sgMat4 m );
578
579 private:
580   sgVec3 _center;
581   float _factor, _offset, _min_v, _max_v;
582   bool _has_min, _has_max;
583   SGInterpTable * _table;
584 };
585
586 /**
587  * An animation to tell wich objects don't cast shadows.
588  */
589 class SGShadowAnimation : public SGAnimation
590 {
591 public:
592   SGShadowAnimation ( SGPropertyNode *prop_root,
593                    SGPropertyNode_ptr props );
594   virtual ~SGShadowAnimation ();
595   virtual int update();
596   bool get_condition_value(void);
597 private:
598   SGCondition * _condition;
599   bool _condition_value;
600 };
601
602 /**
603 + * An "animation" that replace fixed opengl pipeline by shaders
604 + */
605 class SGShaderAnimation : public SGAnimation
606 {
607 public:
608   SGShaderAnimation ( SGPropertyNode *prop_root,
609                    SGPropertyNode_ptr props );
610   virtual ~SGShaderAnimation ();
611   virtual void init();
612   virtual int update();
613   bool get_condition_value(void);
614 private:
615   SGCondition * _condition;
616   bool _condition_value;
617   int _shader_type;
618   float _param_1;
619   sgVec4 _param_color;
620 public:
621   bool _depth_test;
622   float _factor;
623   SGPropertyNode_ptr _factor_prop;
624   float _speed;
625   SGPropertyNode_ptr _speed_prop;
626   ssgTexture *_effectTexture;
627   unsigned char *_textureData;
628   GLint _texWidth, _texHeight;
629   sgVec4 _envColor;
630 };
631
632
633 #endif // _SG_ANIMATION_HXX