]> git.mxchange.org Git - simgear.git/blob - simgear/scene/model/animation.hxx
Melchior FRANZ:
[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 protected:
96
97   static double sim_time_sec;
98
99   ssgBranch * _branch;
100
101 };
102
103
104 /**
105  * A no-op animation.
106  */
107 class SGNullAnimation : public SGAnimation
108 {
109 public:
110   SGNullAnimation (SGPropertyNode_ptr props);
111   virtual ~SGNullAnimation ();
112 };
113
114
115 /**
116  * A range, or level-of-detail (LOD) animation.
117  */
118 class SGRangeAnimation : public SGAnimation
119 {
120 public:
121   SGRangeAnimation (SGPropertyNode *prop_root,
122                     SGPropertyNode_ptr props);
123   virtual ~SGRangeAnimation ();
124   virtual int update();
125 private:
126   SGPropertyNode_ptr _min_prop;
127   SGPropertyNode_ptr _max_prop;
128   float _min;
129   float _max;
130   float _min_factor;
131   float _max_factor;
132   SGCondition * _condition;
133 };
134
135
136 /**
137  * Animation to turn and face the screen.
138  */
139 class SGBillboardAnimation : public SGAnimation
140 {
141 public:
142   SGBillboardAnimation (SGPropertyNode_ptr props);
143   virtual ~SGBillboardAnimation ();
144 };
145
146
147 /**
148  * Animation to select alternative versions of the same object.
149  */
150 class SGSelectAnimation : public SGAnimation
151 {
152 public:
153   SGSelectAnimation( SGPropertyNode *prop_root,
154                    SGPropertyNode_ptr props );
155   virtual ~SGSelectAnimation ();
156   virtual int update();
157 private:
158   SGCondition * _condition;
159 };
160
161
162 /**
163  * Animation to spin an object around a center point.
164  *
165  * This animation rotates at a specific velocity.
166  */
167 class SGSpinAnimation : public SGAnimation
168 {
169 public:
170   SGSpinAnimation( SGPropertyNode *prop_root,
171                  SGPropertyNode_ptr props,
172                  double sim_time_sec );
173   virtual ~SGSpinAnimation ();
174   virtual int update();
175 private:
176   bool _use_personality;
177   SGPropertyNode_ptr _prop;
178   double _factor;
179   double _factor_min;
180   double _factor_max;
181   double _position_deg;
182   double _position_deg_min;
183   double _position_deg_max;
184   double _last_time_sec;
185   sgMat4 _matrix;
186   sgVec3 _center;
187   sgVec3 _axis;
188   SGCondition * _condition;
189 };
190
191
192 /**
193  * Animation to draw objects for a specific amount of time each.
194  */
195 class SGTimedAnimation : public SGAnimation
196 {
197 public:
198     SGTimedAnimation (SGPropertyNode_ptr props);
199     virtual ~SGTimedAnimation ();
200     virtual void init();
201     virtual int update();
202 private:
203     bool _use_personality;
204     double _duration_sec;
205     double _last_time_sec;
206     double _total_duration_sec;
207     int _step;
208     struct DurationSpec {
209         DurationSpec( double m = 0.0 ) : _min(m), _max(m) {}
210         DurationSpec( double m1, double m2 ) : _min(m1), _max(m2) {}
211         double _min, _max;
212     };
213     vector<DurationSpec> _branch_duration_specs;
214     vector<double> _branch_duration_sec;
215 };
216
217
218 /**
219  * Animation to rotate an object around a center point.
220  *
221  * This animation rotates to a specific position.
222  */
223 class SGRotateAnimation : public SGAnimation
224 {
225 public:
226   SGRotateAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props );
227   virtual ~SGRotateAnimation ();
228   virtual int update();
229 private:
230   SGPropertyNode_ptr _prop;
231   double _offset_deg;
232   double _factor;
233   SGInterpTable * _table;
234   bool _has_min;
235   double _min_deg;
236   bool _has_max;
237   double _max_deg;
238   double _position_deg;
239   sgMat4 _matrix;
240   sgVec3 _center;
241   sgVec3 _axis;
242   SGCondition * _condition;
243 };
244
245
246 /**
247  * Animation to slide along an axis.
248  */
249 class SGTranslateAnimation : public SGAnimation
250 {
251 public:
252   SGTranslateAnimation( SGPropertyNode *prop_root,
253                       SGPropertyNode_ptr props );
254   virtual ~SGTranslateAnimation ();
255   virtual int update();
256 private:
257   SGPropertyNode_ptr _prop;
258   double _offset_m;
259   double _factor;
260   SGInterpTable * _table;
261   bool _has_min;
262   double _min_m;
263   bool _has_max;
264   double _max_m;
265   double _position_m;
266   sgMat4 _matrix;
267   sgVec3 _axis;
268   SGCondition * _condition;
269 };
270
271 /**
272  * Animation to blend an object.
273  */
274 class SGBlendAnimation : public SGAnimation
275 {
276 public:
277   SGBlendAnimation( SGPropertyNode *prop_root,
278                       SGPropertyNode_ptr props );
279   virtual ~SGBlendAnimation ();
280   virtual int update();
281 private:
282   SGPropertyNode_ptr _prop;
283   SGInterpTable * _table;
284   double _prev_value;
285   double _offset;
286   double _factor;
287   bool _has_min;
288   double _min;
289   bool _has_max;
290   double _max;
291 };
292
293 /**
294  * Animation to scale an object.
295  */
296 class SGScaleAnimation : public SGAnimation
297 {
298 public:
299   SGScaleAnimation( SGPropertyNode *prop_root,
300                         SGPropertyNode_ptr props );
301   virtual ~SGScaleAnimation ();
302   virtual int update();
303 private:
304   SGPropertyNode_ptr _prop;
305   double _x_factor;
306   double _y_factor;
307   double _z_factor;
308   double _x_offset;
309   double _y_offset;
310   double _z_offset;
311   SGInterpTable * _table;
312   bool _has_min_x;
313   bool _has_min_y;
314   bool _has_min_z;
315   double _min_x;
316   double _min_y;
317   double _min_z;
318   bool _has_max_x;
319   bool _has_max_y;
320   bool _has_max_z;
321   double _max_x;
322   double _max_y;
323   double _max_z;
324   double _x_scale;
325   double _y_scale;
326   double _z_scale;
327   sgMat4 _matrix;
328 };
329
330 /**
331  * Animation to rotate texture mappings around a center point.
332  *
333  * This animation rotates to a specific position.
334  */
335 class SGTexRotateAnimation : public SGAnimation
336 {
337 public:
338   SGTexRotateAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props );
339   virtual ~SGTexRotateAnimation ();
340   virtual int update();
341 private:
342   SGPropertyNode_ptr _prop;
343   double _offset_deg;
344   double _factor;
345   SGInterpTable * _table;
346   bool _has_min;
347   double _min_deg;
348   bool _has_max;
349   double _max_deg;
350   double _position_deg;
351   sgMat4 _matrix;
352   sgVec3 _center;
353   sgVec3 _axis;
354 };
355
356
357 /**
358  * Animation to slide texture mappings along an axis.
359  */
360 class SGTexTranslateAnimation : public SGAnimation
361 {
362 public:
363   SGTexTranslateAnimation( SGPropertyNode *prop_root,
364                       SGPropertyNode_ptr props );
365   virtual ~SGTexTranslateAnimation ();
366   virtual int update();
367 private:
368   SGPropertyNode_ptr _prop;
369   double _offset;
370   double _factor;
371   double _step;
372   double _scroll;
373   SGInterpTable * _table;
374   bool _has_min;
375   double _min;
376   bool _has_max;
377   double _max;
378   double _position;
379   sgMat4 _matrix;
380   sgVec3 _axis;
381 };
382
383
384
385 /**
386  * Classes for handling multiple types of Texture translations on one object
387  */
388
389 class SGTexMultipleAnimation : public SGAnimation
390 {
391 public:
392   SGTexMultipleAnimation( SGPropertyNode *prop_root,
393                       SGPropertyNode_ptr props );
394   virtual ~SGTexMultipleAnimation ();
395   virtual int update();
396 private:
397   class TexTransform
398     {
399     public:
400     SGPropertyNode_ptr prop;
401     int subtype; //  0=translation, 1=rotation
402     double offset;
403     double factor;
404     double step;
405     double scroll;
406     SGInterpTable * table;
407     bool has_min;
408     double min;
409     bool has_max;
410     double max;
411     double position;
412     sgMat4 matrix;
413     sgVec3 center;
414     sgVec3 axis;
415   };
416   SGPropertyNode_ptr _prop;
417   TexTransform* _transform;
418   int _num_transforms;
419 };
420
421
422 /**
423  * An "animation" to enable the alpha test 
424  */
425 class SGAlphaTestAnimation : public SGAnimation
426 {
427 public:
428   SGAlphaTestAnimation(SGPropertyNode_ptr props);
429   virtual ~SGAlphaTestAnimation ();
430   virtual void init();
431 private:
432   void setAlphaClampToBranch(ssgBranch *b, float clamp);
433   float _alpha_clamp;
434 };
435
436
437 /**
438  * An "animation" to modify material properties
439  */
440 class SGMaterialAnimation : public SGAnimation
441 {
442 public:
443     SGMaterialAnimation(SGPropertyNode *prop_root, SGPropertyNode_ptr props,
444             const SGPath &texpath);
445     virtual ~SGMaterialAnimation() {}
446     virtual void init();
447     virtual int update();
448 private:
449     enum {
450         DIFFUSE = 1,
451         AMBIENT = 2,
452         SPECULAR = 4,
453         EMISSION = 8,
454         SHININESS = 16,
455         TRANSPARENCY = 32,
456         THRESHOLD = 64,
457         TEXTURE = 128,
458     };
459     struct ColorSpec {
460         float red, green, blue;
461         float factor;
462         float offset;
463         SGPropertyNode_ptr red_prop;
464         SGPropertyNode_ptr green_prop;
465         SGPropertyNode_ptr blue_prop;
466         SGPropertyNode_ptr factor_prop;
467         SGPropertyNode_ptr offset_prop;
468         sgVec4 v;
469         bool dirty() {
470             return red >= 0.0 || green >= 0.0 || blue >= 0.0;
471         }
472         bool live() {
473             return red_prop || green_prop || blue_prop
474                     || factor_prop || offset_prop;
475         }
476         bool operator!=(ColorSpec& a) {
477             return red != a.red || green != a.green || blue != a.blue
478                     || factor != a.factor || offset != a.offset;
479         }
480         sgVec4 &rgba() {
481             v[0] = clamp(red * factor + offset);
482             v[1] = clamp(green * factor + offset);
483             v[2] = clamp(blue * factor + offset);
484             v[3] = 1.0;
485             return v;
486         }
487         float clamp(float val) {
488             return val < 0.0 ? 0.0 : val > 1.0 ? 1.0 : val;
489         }
490     };
491     SGCondition *_condition;
492     SGPath _base_dir;
493     SGPath _texture;
494     string _texture_str;
495     ssgSimpleState* _cached_material;
496     ssgSimpleState* _cloned_material;
497     unsigned _read;
498     unsigned _update;
499     bool _global;
500     ColorSpec _diff;
501     ColorSpec _amb;
502     ColorSpec _emis;
503     ColorSpec _spec;
504     float _shi;
505     float _trans;
506     float _thresh;      // alpha_clamp (see man glAlphaFunc)
507     string _tex;
508     SGPropertyNode_ptr _shi_prop;
509     SGPropertyNode_ptr _trans_prop;
510     SGPropertyNode_ptr _thresh_prop;
511     SGPropertyNode_ptr _tex_prop;
512
513     void cloneMaterials(ssgBranch *b);
514     void setMaterialBranch(ssgBranch *b);
515     float clamp(float val, float min = 0.0, float max = 1.0) {
516         return val < min ? min : val > max ? max : val;
517     }
518 };
519
520
521 /**
522  * An "animation" that compute a scale according to 
523  * the angle between an axis and the view direction
524  */
525 class SGFlashAnimation : public SGAnimation
526 {
527 public:
528   SGFlashAnimation(SGPropertyNode_ptr props);
529   virtual ~SGFlashAnimation ();
530
531   static void flashCallback( sgMat4 r, sgFrustum *f, sgMat4 m, void *d );
532   void flashCallback( sgMat4 r, sgFrustum *f, sgMat4 m );
533
534 private:
535   sgVec3 _axis, _center;
536   float _power, _factor, _offset, _min_v, _max_v;
537   bool _two_sides;
538 };
539
540
541 /**
542  * An animation that compute a scale according to 
543  * the distance from a point and the viewer
544  */
545 class SGDistScaleAnimation : public SGAnimation
546 {
547 public:
548   SGDistScaleAnimation(SGPropertyNode_ptr props);
549   virtual ~SGDistScaleAnimation ();
550
551   static void distScaleCallback( sgMat4 r, sgFrustum *f, sgMat4 m, void *d );
552   void distScaleCallback( sgMat4 r, sgFrustum *f, sgMat4 m );
553
554 private:
555   sgVec3 _center;
556   float _factor, _offset, _min_v, _max_v;
557   bool _has_min, _has_max;
558   SGInterpTable * _table;
559 };
560
561
562 #endif // _SG_ANIMATION_HXX