root/OpenSceneGraph/trunk/include/osgParticle/Particle @ 13041

Revision 13041, 18.7 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13//osgParticle - Copyright (C) 2002 Marco Jez
14
15#ifndef OSGPARTICLE_PARTICLE
16#define OSGPARTICLE_PARTICLE 1
17
18#include <osgParticle/Export>
19#include <osgParticle/Interpolator>
20#include <osgParticle/range>
21
22#include <osg/ref_ptr>
23#include <osg/Vec3>
24#include <osg/Vec4>
25#include <osg/Matrix>
26#include <osg/Drawable>
27#include <osg/GL>
28#include <osg/GLBeginEndAdapter>
29
30namespace osgParticle
31{
32
33    // forward declare so we can reference it
34    class ParticleSystem;
35
36    /**    Implementation of a <B>particle</B>.
37        Objects of this class are particles, they have some graphical properties
38        and some physical properties. Particles are created by emitters and then placed
39        into Particle Systems, where they live and get updated at each frame.
40        Particles can either live forever (lifeTime < 0), or die after a specified
41        time (lifeTime >= 0). For each property which is defined as a range of values, a
42        "current" value will be evaluated at each frame by interpolating the <I>min</I>
43        and <I>max</I> values so that <I>curr_value = min</I> when <I>t == 0</I>, and
44        <I>curr_value = max</I> when <I>t == lifeTime</I>.
45        You may customize the interpolator objects to achieve any kind of transition.
46        If you want the particle to live forever, set its lifetime to any value <= 0;
47        in that case, no interpolation is done to compute real-time properties, and only
48        minimum values are used.
49    */
50    class OSGPARTICLE_EXPORT Particle {
51        friend class ParticleSystem;
52    public:
53
54        enum
55        {
56            INVALID_INDEX = -1
57        };
58
59        /**
60         Shape of particles.
61         NOTE: the LINE shape should be used in conjunction with FIXED alignment mode (see ParticleSystem).
62        */
63        enum Shape {
64            POINT,            // uses GL_POINTS as primitive
65            QUAD,            // uses GL_QUADS as primitive
66            QUAD_TRIANGLESTRIP,    // uses GL_TRI_angleSTRIP as primitive, but each particle needs a glBegin/glEnd pair
67            HEXAGON,            // may save some filling time, but uses more triangles
68            LINE,               // uses GL_LINES to draw line segments that point to the direction of motion
69            USER               // uses a user-defined drawable as primitive
70        };
71
72        Particle();
73
74        /// Get the shape of the particle.
75        inline Shape getShape() const;
76
77        /// Set the shape of the particle.
78        inline void setShape(Shape s);
79
80        /// Get whether the particle is still alive.
81        inline bool isAlive() const;
82
83        /// Get the life time of the particle (in seconds).
84        inline double getLifeTime() const;
85
86        /// Get the age of the particle (in seconds).
87        inline double getAge() const;
88
89        /// Get the minimum and maximum values for polygon size.
90        inline const rangef& getSizeRange() const;
91
92        /// Get the minimum and maximum values for alpha.
93        inline const rangef& getAlphaRange() const;
94
95        /// Get the minimum and maximum values for color.
96        inline const rangev4& getColorRange() const;
97
98        /// Get the interpolator for computing the size of polygons.
99        inline const Interpolator* getSizeInterpolator() const;
100
101        /// Get the interpolator for computing alpha values.
102        inline const Interpolator* getAlphaInterpolator() const;
103
104        /// Get the interpolator for computing color values.
105        inline const Interpolator* getColorInterpolator() const;
106
107        /** Get the physical radius of the particle.
108            For built-in operators to work correctly, lengths must be expressed in meters.
109        */
110        inline float getRadius() const;
111
112        /** Get the mass of the particle.
113            For built-in operators to work correctly, remember that the mass is expressed in kg.
114        */
115        inline float getMass() const;
116
117        /// Get <CODE>1 / getMass()</CODE>.
118        inline float getMassInv() const;
119
120        /// Get the position vector.
121        inline const osg::Vec3& getPosition() const;
122
123        /**    Get the velocity vector.
124            For built-in operators to work correctly, remember that velocity components are expressed
125            in meters per second.
126        */
127        inline const osg::Vec3& getVelocity() const;
128
129        /// Get the previous position (the position before last update).
130        inline const osg::Vec3& getPreviousPosition() const;
131
132        /// Get the angle vector.
133        inline const osg::Vec3& getAngle() const;
134
135        /// Get the rotational velocity vector.
136        inline const osg::Vec3& getAngularVelocity() const;
137
138        /// Get the previous angle vector.
139        inline const osg::Vec3& getPreviousAngle() const;
140
141        /// Get the current color
142        inline const osg::Vec4& getCurrentColor() const { return _current_color; }
143
144        /// Get the current alpha
145        inline float getCurrentAlpha() const { return _current_alpha; }
146
147        /// Get the s texture coordinate of the bottom left of the particle
148        inline float getSTexCoord() const { return _s_coord; }
149
150        /// Get the t texture coordinate of the bottom left of the particle
151        inline float getTTexCoord() const { return _t_coord; }
152
153        /// Get width of texture tile
154        inline int getTileS() const;
155
156        /// Get height of texture tile
157        inline int getTileT() const;
158
159        /// Get number of texture tiles
160        inline int getNumTiles() const { return _end_tile - _start_tile + 1; }
161
162        /** Kill the particle on next update
163            NOTE: after calling this function, the <CODE>isAlive()</CODE> method will still
164            return true until the particle is updated again.
165        */
166        inline void kill();
167
168        /// Set the life time of the particle.
169        inline void setLifeTime(double t);
170
171        /// Set the minimum and maximum values for polygon size.
172        inline void setSizeRange(const rangef& r);
173
174        /// Set the minimum and maximum values for alpha.
175        inline void setAlphaRange(const rangef& r);
176
177        /// Set the minimum and maximum values for color.
178        inline void setColorRange(const rangev4& r);
179
180        /// Set the interpolator for computing size values.
181        inline void setSizeInterpolator(Interpolator* ri);
182
183        /// Set the interpolator for computing alpha values.
184        inline void setAlphaInterpolator(Interpolator* ai);
185
186        /// Set the interpolator for computing color values.
187        inline void setColorInterpolator(Interpolator* ci);
188
189        /** Set the physical radius of the particle.
190            For built-in operators to work correctly, lengths must be expressed in meters.
191        */
192        inline void setRadius(float r);
193
194        /** Set the mass of the particle.
195            For built-in operators to work correctly, remember that the mass is expressed in kg.
196        */
197        inline void setMass(float m);
198
199        /// Set the position vector.
200        inline void setPosition(const osg::Vec3& p);
201
202        /**    Set the velocity vector.
203            For built-in operators to work correctly, remember that velocity components are expressed
204            in meters per second.
205        */
206        inline void setVelocity(const osg::Vec3& v);
207
208        /// Add a vector to the velocity vector.
209        inline void addVelocity(const osg::Vec3& dv);
210
211        /// Transform position and velocity vectors by a matrix.
212        inline void transformPositionVelocity(const osg::Matrix& xform);
213
214        /// Transform position and velocity vectors by a combination of two matrices
215        void transformPositionVelocity(const osg::Matrix& xform1, const osg::Matrix& xform2, float r);
216
217        /// Set the angle vector.
218        inline void setAngle(const osg::Vec3& a);
219
220        /**
221          Set the angular velocity vector.
222          Components x, y and z are angles of rotation around the respective axis (in radians).
223        */
224        inline void setAngularVelocity(const osg::Vec3& v);
225
226        /// Add a vector to the angular velocity vector.
227        inline void addAngularVelocity(const osg::Vec3& dv);
228
229        /// Transform angle and angularVelocity vectors by a matrix.
230        inline void transformAngleVelocity(const osg::Matrix& xform);
231
232        /** Update the particle (don't call this method manually).
233            This method is called automatically by <CODE>ParticleSystem::update()</CODE>; it
234            updates the graphical properties of the particle for the current time,
235            checks whether the particle is still alive, and then updates its position
236            by computing <I>P = P + V * dt</I> (where <I>P</I> is the position and <I>V</I> is the velocity).
237        */
238        bool update(double dt, bool onlyTimeStamp);
239
240        /// Perform some pre-rendering tasks. Called automatically by particle systems.
241        inline void beginRender(osg::GLBeginEndAdapter* gl) const;
242
243        /// Render the particle. Called automatically by particle systems.
244        void render(osg::GLBeginEndAdapter* gl, const osg::Vec3& xpos, const osg::Vec3& px, const osg::Vec3& py, float scale = 1.0f) const;
245
246        /// Render the particle with user-defined drawable
247        void render(osg::RenderInfo& renderInfo, const osg::Vec3& xpos, const osg::Vec3& xrot) const;
248
249        /// Perform some post-rendering tasks. Called automatically by particle systems.
250        inline void endRender(osg::GLBeginEndAdapter* gl) const;
251
252        /// Get the current (interpolated) polygon size. Valid only after the first call to update().
253        inline float getCurrentSize() const;
254
255        /// Specify how the particle texture is tiled.
256        /// All tiles in the given range are sequentially displayed during the lifetime
257        /// of the particle. When no range is given, all tiles are displayed during the lifetime.
258        inline void setTextureTileRange(int sTile, int tTile, int startTile, int endTile);
259
260        /// Same as above, range starts at 0 and ends at end
261        inline void setTextureTile(int sTile, int tTile, int end = -1);
262
263        /// Set the previous particle
264        inline void setPreviousParticle(int previous) { _previousParticle = previous; }
265
266        /// Get the previous particle
267        inline int getPreviousParticle() const { return _previousParticle; }
268
269        /// Set the next particle
270        inline void setNextParticle(int next) { _nextParticle = next; }
271
272        /// Get the const next particle
273        inline int getNextParticle() const { return _nextParticle; }
274
275        /// Set the depth of the particle
276        inline void setDepth(double d) { _depth = d; }
277
278        /// Get the depth of the particle
279        inline double getDepth() const { return _depth; }
280
281        /// Set the user-defined particle drawable
282        inline void setDrawable(osg::Drawable* d) { _drawable = d; }
283
284        /// Get the user-defined particle drawable
285        inline osg::Drawable* getDrawable() const { return _drawable.get(); }
286
287        /// Sorting operator
288        bool operator<(const Particle &P) const { return _depth < P._depth; }
289
290        /// Method for initializing a particles texture coords as part of a connected particle system.
291        void setUpTexCoordsAsPartOfConnectedParticleSystem(ParticleSystem* ps);
292
293    protected:
294
295        Shape _shape;
296
297        rangef _sr;
298        rangef _ar;
299        rangev4 _cr;
300
301        osg::ref_ptr<Interpolator> _si;
302        osg::ref_ptr<Interpolator> _ai;
303        osg::ref_ptr<Interpolator> _ci;
304
305        bool _mustdie;
306        double _lifeTime;
307
308        float _radius;
309        float _mass;
310        float _massinv;
311        osg::Vec3 _prev_pos;
312        osg::Vec3 _position;
313        osg::Vec3 _velocity;
314
315        osg::Vec3 _prev_angle;
316        osg::Vec3 _angle;
317        osg::Vec3 _angul_arvel;
318
319        double _t0;
320
321        float _alive;
322        float _current_size;
323        float _current_alpha;
324        osg::Vec3 _base_prop;  // [0] _alive [1] _current_size [2] _current_alpha
325        osg::Vec4 _current_color;
326
327        float _s_tile;
328        float _t_tile;
329        int _start_tile;
330        int _end_tile;
331        int _cur_tile;
332        float _s_coord;
333        float _t_coord;
334
335        // previous and next Particles are only used in ConnectedParticleSystems
336        int _previousParticle;
337        int _nextParticle;
338
339        // the depth of the particle is used only when sorting is enabled
340        double _depth;
341
342        // the particle drawable is used only when USER shape is enabled
343        osg::ref_ptr<osg::Drawable> _drawable;
344    };
345
346    // INLINE FUNCTIONS
347
348    inline Particle::Shape Particle::getShape() const
349    {
350        return _shape;
351    }
352
353    inline void Particle::setShape(Shape s)
354    {
355        _shape = s;
356    }
357
358    inline bool Particle::isAlive() const
359    {
360        return _alive>0.0f;
361    }
362
363    inline double Particle::getLifeTime() const
364    {
365        return _lifeTime;
366    }
367
368    inline double Particle::getAge() const
369    {
370        return _t0;
371    }
372
373    inline float Particle::getRadius() const
374    {
375        return _radius;
376    }
377
378    inline void Particle::setRadius(float r)
379    {
380        _radius = r;
381    }
382
383    inline const rangef& Particle::getSizeRange() const
384    {
385        return _sr;
386    }
387
388    inline const rangef& Particle::getAlphaRange() const
389    {
390        return _ar;
391    }
392
393    inline const rangev4& Particle::getColorRange() const
394    {
395        return _cr;
396    }
397
398    inline const Interpolator* Particle::getSizeInterpolator() const
399    {
400        return _si.get();
401    }
402
403    inline const Interpolator* Particle::getAlphaInterpolator() const
404    {
405        return _ai.get();
406    }
407
408    inline const Interpolator* Particle::getColorInterpolator() const
409    {
410        return _ci.get();
411    }
412
413    inline const osg::Vec3& Particle::getPosition() const
414    {
415        return _position;
416    }
417
418    inline const osg::Vec3& Particle::getVelocity() const
419    {
420        return _velocity;
421    }
422
423    inline const osg::Vec3& Particle::getPreviousPosition() const
424    {
425        return _prev_pos;
426    }
427
428    inline const osg::Vec3& Particle::getAngle() const
429    {
430        return _angle;
431    }
432
433    inline const osg::Vec3& Particle::getAngularVelocity() const
434    {
435        return _angul_arvel;
436    }
437
438    inline const osg::Vec3& Particle::getPreviousAngle() const
439    {
440        return _prev_angle;
441    }
442
443    inline int Particle::getTileS() const
444    {
445        return (_s_tile>0.0f) ? static_cast<int>(1.0f / _s_tile) : 1;
446    }
447
448    inline int Particle::getTileT() const
449    {
450        return (_t_tile>0.0f) ? static_cast<int>(1.0f / _t_tile) : 1;
451    }
452
453    inline void Particle::kill()
454    {
455        _mustdie = true;
456    }
457
458    inline void Particle::setLifeTime(double t)
459    {
460        _lifeTime = t;
461    }
462
463    inline void Particle::setSizeRange(const rangef& r)
464    {
465        _sr = r;
466    }
467
468    inline void Particle::setAlphaRange(const rangef& r)
469    {
470        _ar = r;
471    }
472
473    inline void Particle::setColorRange(const rangev4& r)
474    {
475        _cr = r;
476    }
477
478    inline void Particle::setSizeInterpolator(Interpolator* ri)
479    {
480        _si = ri;
481    }
482
483    inline void Particle::setAlphaInterpolator(Interpolator* ai)
484    {
485        _ai = ai;
486    }
487
488    inline void Particle::setColorInterpolator(Interpolator* ci)
489    {
490        _ci = ci;
491    }
492
493    inline void Particle::setPosition(const osg::Vec3& p)
494    {
495        _position = p;
496    }
497
498    inline void Particle::setVelocity(const osg::Vec3& v)
499    {
500        _velocity = v;
501    }
502
503    inline void Particle::addVelocity(const osg::Vec3& dv)
504    {
505        _velocity += dv;
506    }
507
508    inline void Particle::transformPositionVelocity(const osg::Matrix& xform)
509    {
510        _position = xform.preMult(_position);
511        _velocity = osg::Matrix::transform3x3(_velocity, xform);
512    }
513
514    inline void Particle::transformPositionVelocity(const osg::Matrix& xform1, const osg::Matrix& xform2, float r)
515    {
516        osg::Vec3 position1 = xform1.preMult(_position);
517        osg::Vec3 velocity1 = osg::Matrix::transform3x3(_velocity, xform1);
518        osg::Vec3 position2 = xform2.preMult(_position);
519        osg::Vec3 velocity2 = osg::Matrix::transform3x3(_velocity, xform2);
520        float one_minus_r = 1.0f-r;
521        _position = position1*r + position2*one_minus_r;
522        _velocity = velocity1*r + velocity2*one_minus_r;
523    }
524
525    inline void Particle::setAngle(const osg::Vec3& a)
526    {
527        _angle = a;
528    }
529
530    inline void Particle::setAngularVelocity(const osg::Vec3& v)
531    {
532        _angul_arvel = v;
533    }
534
535    inline void Particle::addAngularVelocity(const osg::Vec3& dv)
536    {
537        _angul_arvel += dv;
538    }
539
540    inline void Particle::transformAngleVelocity(const osg::Matrix& xform)
541    {
542        // this should be optimized!
543
544        osg::Vec3 a1 = _angle + _angul_arvel;
545
546        _angle = xform.preMult(_angle);
547        a1 = xform.preMult(a1);
548
549        _angul_arvel = a1 - _angle;
550    }
551
552    inline float Particle::getMass() const
553    {
554        return _mass;
555    }
556
557    inline float Particle::getMassInv() const
558    {
559        return _massinv;
560    }
561
562    inline void Particle::setMass(float m)
563    {
564        _mass = m;
565        _massinv = 1 / m;
566    }
567
568    inline void Particle::beginRender(osg::GLBeginEndAdapter* gl) const
569    {
570        switch (_shape)
571        {
572        case POINT:
573            gl->Begin(GL_POINTS);
574            break;
575        case QUAD:
576            gl->Begin(GL_QUADS);
577            break;
578        case LINE:
579            gl->Begin(GL_LINES);
580            break;
581        default: ;
582        }
583    }
584
585    inline void Particle::endRender(osg::GLBeginEndAdapter* gl) const
586    {
587        switch (_shape)
588        {
589        case POINT:
590        case QUAD:
591        case LINE:
592            gl->End();
593            break;
594        default: ;
595        }
596    }
597
598    inline float Particle::getCurrentSize() const
599    {
600        return _current_size;
601    }
602
603
604    inline void Particle::setTextureTile(int sTile, int tTile, int end)
605    {
606        setTextureTileRange(sTile, tTile, -1, end);
607    }
608
609    inline void Particle::setTextureTileRange(int sTile, int tTile, int startTile, int endTile)
610    {
611       _s_tile = (sTile>0) ? 1.0f / static_cast<float>(sTile) : 1.0f;
612       _t_tile = (tTile>0) ? 1.0f / static_cast<float>(tTile) : 1.0f;
613
614       if(startTile == -1)
615       {
616          _start_tile = 0;
617       }
618       else
619       {
620          _start_tile = startTile;
621       }
622
623       if(endTile == -1)
624       {
625          _end_tile = sTile * tTile;
626       }
627       else
628       {
629          _end_tile = endTile;
630       }
631    }
632
633}
634
635#endif
636
Note: See TracBrowser for help on using the browser.