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