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

Revision 10660, 17.5 kB (checked in by robert, 4 years ago)

Removed remaining glBegin/glEnd usage

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