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