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