diff --git a/panda/src/particlesystem/Sources.pp b/panda/src/particlesystem/Sources.pp index c1f5540b22..929501623b 100644 --- a/panda/src/particlesystem/Sources.pp +++ b/panda/src/particlesystem/Sources.pp @@ -14,7 +14,8 @@ config_particlesystem.cxx config_particlesystem.h discEmitter.I \ discEmitter.cxx discEmitter.h geomParticleRenderer.I \ geomParticleRenderer.cxx geomParticleRenderer.h lineEmitter.I \ - lineEmitter.cxx lineEmitter.h orientedParticle.I \ + lineEmitter.cxx lineEmitter.h lineParticleRenderer.I \ + lineParticleRenderer.cxx lineParticleRenderer.h orientedParticle.I \ orientedParticle.cxx orientedParticle.h orientedParticleFactory.I \ orientedParticleFactory.cxx orientedParticleFactory.h \ particleSystem.I particleSystem.cxx particleSystem.h \ @@ -41,7 +42,8 @@ baseParticleRenderer.I baseParticleRenderer.h boxEmitter.I \ boxEmitter.h config_particlesystem.h discEmitter.I discEmitter.h \ emitters.h geomParticleRenderer.I geomParticleRenderer.h \ - lineEmitter.I lineEmitter.h orientedParticle.I orientedParticle.h \ + lineEmitter.I lineEmitter.h lineParticleRenderer.I \ + lineParticleRenderer.h orientedParticle.I orientedParticle.h \ orientedParticleFactory.I orientedParticleFactory.h \ particleSystem.I particleSystem.h particleSystemManager.I \ particleSystemManager.h particlefactories.h particles.h \ diff --git a/panda/src/particlesystem/baseParticle.I b/panda/src/particlesystem/baseParticle.I index 705521f3ec..0d2e9e78da 100644 --- a/panda/src/particlesystem/baseParticle.I +++ b/panda/src/particlesystem/baseParticle.I @@ -12,7 +12,7 @@ INLINE void BaseParticle::set_lifespan(float lifespan) { } INLINE void BaseParticle::set_alive(bool alive) { - _alive = alive; + _alive = alive; } INLINE float BaseParticle::get_age(void) const { diff --git a/panda/src/particlesystem/baseParticle.cxx b/panda/src/particlesystem/baseParticle.cxx index 627decfada..3fd3629029 100644 --- a/panda/src/particlesystem/baseParticle.cxx +++ b/panda/src/particlesystem/baseParticle.cxx @@ -1,4 +1,4 @@ -// Filename: baseParticle.cxx +// Filename: baseParticle.C // Created by: charles (14Jun00) // //////////////////////////////////////////////////////////////////// diff --git a/panda/src/particlesystem/baseParticle.h b/panda/src/particlesystem/baseParticle.h index e45616e890..e1c764febd 100644 --- a/panda/src/particlesystem/baseParticle.h +++ b/panda/src/particlesystem/baseParticle.h @@ -1,6 +1,6 @@ // Filename: baseParticle.h // Created by: charles (14Jun00) -// +// //////////////////////////////////////////////////////////////////// #ifndef BASEPARTICLE_H @@ -21,6 +21,8 @@ private: float _lifespan; bool _alive; + LPoint3f _last_position; + protected: BaseParticle(int lifespan = 0, bool alive = false); BaseParticle(const BaseParticle ©); diff --git a/panda/src/particlesystem/baseParticleEmitter.I b/panda/src/particlesystem/baseParticleEmitter.I index a566b24bfb..93f0ef7ce4 100644 --- a/panda/src/particlesystem/baseParticleEmitter.I +++ b/panda/src/particlesystem/baseParticleEmitter.I @@ -4,15 +4,63 @@ //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// -// Function : generate +// Function : set_emission_type // Access : Public -// Description : parent generation function +// Description : emission type assignment //////////////////////////////////////////////////////////////////// INLINE void BaseParticleEmitter:: -generate(LPoint3f& pos, LVector3f& vel) { - assign_initial_values(pos, vel); - vel *= _amplitude; - vel += _offset_force; +set_emission_type(emissionType et) { + _emission_type = et; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_emission_type +// Access : Public +// Description : emission type query +//////////////////////////////////////////////////////////////////// +INLINE BaseParticleEmitter::emissionType BaseParticleEmitter:: +get_emission_type(void) const { + return _emission_type; +} + +//////////////////////////////////////////////////////////////////// +// Function : set_explicit_launch_vector +// Access : Public +// Description : assignment of explicit emission launch vector +//////////////////////////////////////////////////////////////////// +INLINE void BaseParticleEmitter:: +set_explicit_launch_vector(const LVector3f& elv) { + _explicit_launch_vector = elv; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_explicit_launch_vector +// Access : Public +// Description : query for explicit emission launch vector +//////////////////////////////////////////////////////////////////// +INLINE LVector3f BaseParticleEmitter:: +get_explicit_launch_vector(void) const { + return _explicit_launch_vector; +} + +//////////////////////////////////////////////////////////////////// +// Function : set_radiate_origin +// Access : Public +// Description : assignment of radiate emission origin point +//////////////////////////////////////////////////////////////////// +INLINE void BaseParticleEmitter:: +set_radiate_origin(const LPoint3f& ro) { + _radiate_origin = ro; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_radiate_origin +// Access : Public +// Description : query for explicit emission launch vector +//////////////////////////////////////////////////////////////////// +INLINE LPoint3f BaseParticleEmitter:: +get_radiate_origin(void) const { + return _radiate_origin; } //////////////////////////////////////////////////////////////////// @@ -35,6 +83,26 @@ get_amplitude(void) const { return _amplitude; } +//////////////////////////////////////////////////////////////////// +// Function : set_amplitude_spread +// Access : Public +// Description : amplitude spread assignment +//////////////////////////////////////////////////////////////////// +INLINE void BaseParticleEmitter:: +set_amplitude_spread(float as) { + _amplitude_spread = as; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_amplitude_spread +// Access : Public +// Description : amplitude spread query +//////////////////////////////////////////////////////////////////// +INLINE float BaseParticleEmitter:: +get_amplitude_spread(void) const { + return _amplitude_spread; +} + //////////////////////////////////////////////////////////////////// // Function : set_offset_force // Access : Public diff --git a/panda/src/particlesystem/baseParticleEmitter.cxx b/panda/src/particlesystem/baseParticleEmitter.cxx index 9d21e93733..4abdcfae5f 100644 --- a/panda/src/particlesystem/baseParticleEmitter.cxx +++ b/panda/src/particlesystem/baseParticleEmitter.cxx @@ -1,4 +1,4 @@ -// Filename: baseParticleEmitter.cxx +// Filename: baseParticleEmitter.C // Created by: charles (14Jun00) // //////////////////////////////////////////////////////////////////// @@ -14,7 +14,11 @@ //////////////////////////////////////////////////////////////////// BaseParticleEmitter:: BaseParticleEmitter(void) { + _emission_type = ET_RADIATE; + _explicit_launch_vector.set(1,0,0); + _radiate_origin.set(0,0,0); _amplitude = 1.0f; + _amplitude_spread = 0.0f; _offset_force.set(0,0,0); } @@ -25,8 +29,12 @@ BaseParticleEmitter(void) { //////////////////////////////////////////////////////////////////// BaseParticleEmitter:: BaseParticleEmitter(const BaseParticleEmitter ©) { - _offset_force = copy._offset_force; + _emission_type = copy._emission_type; + _explicit_launch_vector = copy._explicit_launch_vector; + _radiate_origin = copy._radiate_origin; _amplitude = copy._amplitude; + _amplitude_spread = copy._amplitude_spread; + _offset_force = copy._offset_force; } //////////////////////////////////////////////////////////////////// @@ -39,15 +47,30 @@ BaseParticleEmitter:: } //////////////////////////////////////////////////////////////////// -// Function : BaseParticleEmitter::bounded_rand -// Access : Private -// Description : Random number in [0, 1] +// Function : generate +// Access : Public +// Description : parent generation function //////////////////////////////////////////////////////////////////// -float BaseParticleEmitter::bounded_rand(void) -{ - int value = rand() & 0x7fffffff; - float f_value = (float) value / (float) 0x7fffffff; +void BaseParticleEmitter:: +generate(LPoint3f& pos, LVector3f& vel) { + assign_initial_position(pos); - return f_value; + switch(_emission_type) + { + case ET_EXPLICIT: + vel = _explicit_launch_vector; + break; + + case ET_RADIATE: + vel = pos - _radiate_origin; + vel.normalize(); + break; + + case ET_CUSTOM: + assign_initial_velocity(vel); + break; + } + + vel *= _amplitude + SPREAD(_amplitude_spread); + vel += _offset_force; } - diff --git a/panda/src/particlesystem/baseParticleEmitter.h b/panda/src/particlesystem/baseParticleEmitter.h index c1edae414b..8dd741a308 100644 --- a/panda/src/particlesystem/baseParticleEmitter.h +++ b/panda/src/particlesystem/baseParticleEmitter.h @@ -1,6 +1,6 @@ // Filename: baseParticleEmitter.h // Created by: charles (14Jun00) -// +// //////////////////////////////////////////////////////////////////// #ifndef BASEPARTICLEEMITTER_H @@ -10,6 +10,8 @@ #include #include +#include "particleCommonFuncs.h" + #include //////////////////////////////////////////////////////////////////// @@ -18,28 +20,49 @@ // particles are randomly generated. //////////////////////////////////////////////////////////////////// class EXPCL_PANDAPHYSICS BaseParticleEmitter : public ReferenceCount { -private: - virtual void assign_initial_values(LPoint3f& pos, LVector3f& vel) = 0; - LVector3f _offset_force; +public: + enum emissionType { + ET_EXPLICIT, // all particles are emitted in the same direction + ET_RADIATE, // all particles radiate away from a single point + ET_CUSTOM // particle launch vectors are dependent on particular emitter + }; + + virtual ~BaseParticleEmitter(void); + virtual BaseParticleEmitter *make_copy(void) = 0; + + void generate(LPoint3f& pos, LVector3f& vel); + + INLINE void set_emission_type(emissionType et); + INLINE void set_amplitude(float a); + INLINE void set_amplitude_spread(float as); + INLINE void set_offset_force(const LVector3f& of); // this is a constant force applied to all particles + INLINE void set_explicit_launch_vector(const LVector3f& elv); + INLINE void set_radiate_origin(const LPoint3f& ro); + + INLINE emissionType get_emission_type(void) const; + INLINE float get_amplitude(void) const; + INLINE float get_amplitude_spread(void) const; + INLINE LVector3f get_offset_force(void) const; + INLINE LVector3f get_explicit_launch_vector(void) const; + INLINE LPoint3f get_radiate_origin(void) const; protected: BaseParticleEmitter(void); BaseParticleEmitter(const BaseParticleEmitter ©); + emissionType _emission_type; + LVector3f _explicit_launch_vector; + LPoint3f _radiate_origin; + float _amplitude; - float bounded_rand(void); + float _amplitude_spread; -public: - virtual ~BaseParticleEmitter(void); - virtual BaseParticleEmitter *make_copy(void) = 0; +private: + // these should be called in sequence (pos, then vel) + virtual void assign_initial_position(LPoint3f& pos) = 0; + virtual void assign_initial_velocity(LVector3f& vel) = 0; - INLINE void set_offset_force(const LVector3f& of); - INLINE LVector3f get_offset_force(void) const; - - INLINE void set_amplitude(float a); - INLINE float get_amplitude(void) const; - - INLINE void generate(LPoint3f& pos, LVector3f& vel); + LVector3f _offset_force; }; #include "baseParticleEmitter.I" diff --git a/panda/src/particlesystem/baseParticleFactory.I b/panda/src/particlesystem/baseParticleFactory.I index 0f0a8f76bf..6682eca9cb 100644 --- a/panda/src/particlesystem/baseParticleFactory.I +++ b/panda/src/particlesystem/baseParticleFactory.I @@ -13,12 +13,12 @@ set_lifespan_base(float lb) { } //////////////////////////////////////////////////////////////////// -// Function : set_lifespan_delta +// Function : set_lifespan_spread // Description : public //////////////////////////////////////////////////////////////////// INLINE void BaseParticleFactory:: -set_lifespan_delta(float ld) { - _lifespan_delta = ld; +set_lifespan_spread(float ld) { + _lifespan_spread = ld; } //////////////////////////////////////////////////////////////////// @@ -31,12 +31,12 @@ set_mass_base(float mb) { } //////////////////////////////////////////////////////////////////// -// Function : set_mass_delta +// Function : set_mass_spread // Description : public //////////////////////////////////////////////////////////////////// INLINE void BaseParticleFactory:: -set_mass_delta(float md) { - _mass_delta = md; +set_mass_spread(float md) { + _mass_spread = md; } //////////////////////////////////////////////////////////////////// @@ -49,12 +49,12 @@ set_terminal_velocity_base(float tvb) { } //////////////////////////////////////////////////////////////////// -// Function : set_terminal_velocity_delta +// Function : set_terminal_velocity_spread // Description : public //////////////////////////////////////////////////////////////////// INLINE void BaseParticleFactory:: -set_terminal_velocity_delta(float tvd) { - _terminal_velocity_delta = tvd; +set_terminal_velocity_spread(float tvd) { + _terminal_velocity_spread = tvd; } //////////////////////////////////////////////////////////////////// @@ -67,12 +67,12 @@ get_lifespan_base(void) const { } //////////////////////////////////////////////////////////////////// -// Function : get_lifespan_delta +// Function : get_lifespan_spread // Description : public //////////////////////////////////////////////////////////////////// INLINE float BaseParticleFactory:: -get_lifespan_delta(void) const { - return _lifespan_delta; +get_lifespan_spread(void) const { + return _lifespan_spread; } //////////////////////////////////////////////////////////////////// @@ -85,12 +85,12 @@ get_mass_base(void) const { } //////////////////////////////////////////////////////////////////// -// Function : get_mass_delta +// Function : get_mass_spread // Description : public //////////////////////////////////////////////////////////////////// INLINE float BaseParticleFactory:: -get_mass_delta(void) const { - return _mass_delta; +get_mass_spread(void) const { + return _mass_spread; } //////////////////////////////////////////////////////////////////// @@ -103,19 +103,11 @@ get_terminal_velocity_base(void) const { } //////////////////////////////////////////////////////////////////// -// Function : get_terminal_velocity_delta +// Function : get_terminal_velocity_spread // Description : public //////////////////////////////////////////////////////////////////// INLINE float BaseParticleFactory:: -get_terminal_velocity_delta(void) const { - return _terminal_velocity_delta; +get_terminal_velocity_spread(void) const { + return _terminal_velocity_spread; } -//////////////////////////////////////////////////////////////////// -// Function : bounded_rand -// Description : public -//////////////////////////////////////////////////////////////////// -INLINE float BaseParticleFactory:: -bounded_rand(void) const { - return ((float) (rand() % 0x7fffffff) / (float) 0x7fffffff); -} diff --git a/panda/src/particlesystem/baseParticleFactory.cxx b/panda/src/particlesystem/baseParticleFactory.cxx index 2b61f4b285..002d5f7f68 100644 --- a/panda/src/particlesystem/baseParticleFactory.cxx +++ b/panda/src/particlesystem/baseParticleFactory.cxx @@ -1,4 +1,4 @@ -// Filename: baseParticleFactory.cxx +// Filename: baseParticleFactory.C // Created by: charles (05Jul00) // //////////////////////////////////////////////////////////////////// @@ -12,11 +12,14 @@ //////////////////////////////////////////////////////////////////// BaseParticleFactory:: BaseParticleFactory(void) { + _mass_base = 1.0f; + _mass_spread = 0.0f; + _terminal_velocity_base = PhysicsObject::_default_terminal_velocity; - _terminal_velocity_delta = 0.0f; + _terminal_velocity_spread = 0.0f; _lifespan_base = 1.0f; - _lifespan_delta = 0.0f; + _lifespan_spread = 0.0f; } //////////////////////////////////////////////////////////////////// @@ -27,9 +30,9 @@ BaseParticleFactory(void) { BaseParticleFactory:: BaseParticleFactory(const BaseParticleFactory ©) { _terminal_velocity_base = copy._terminal_velocity_base; - _terminal_velocity_delta = copy._terminal_velocity_delta; + _terminal_velocity_spread = copy._terminal_velocity_spread; _lifespan_base = copy._lifespan_base; - _lifespan_delta = copy._lifespan_delta; + _lifespan_spread = copy._lifespan_spread; } //////////////////////////////////////////////////////////////////// @@ -50,19 +53,15 @@ populate_particle(BaseParticle *bp) { float lifespan = _lifespan_base; float mass = _mass_base; float tv = _terminal_velocity_base; - float t; // lifespan - t = bounded_rand(); - lifespan += _lifespan_delta - (2.0f * t * _lifespan_delta); + lifespan += SPREAD(_lifespan_spread); // mass - t = bounded_rand(); - mass += _mass_delta - (2.0f * t * _mass_delta); + mass += SPREAD(_mass_spread); // tv - t = bounded_rand(); - tv += _terminal_velocity_delta - (2.0f * t * _terminal_velocity_delta); + tv += SPREAD(_terminal_velocity_spread); bp->set_lifespan(lifespan); bp->set_mass(mass); diff --git a/panda/src/particlesystem/baseParticleFactory.h b/panda/src/particlesystem/baseParticleFactory.h index 0d33e0971c..3b54d8a98a 100644 --- a/panda/src/particlesystem/baseParticleFactory.h +++ b/panda/src/particlesystem/baseParticleFactory.h @@ -1,6 +1,6 @@ // Filename: baseParticleFactory.h // Created by: charles (05Jul00) -// +// //////////////////////////////////////////////////////////////////// #ifndef BASEPARTICLEFACTORY_H @@ -10,21 +10,24 @@ #include #include "baseParticle.h" +#include "particleCommonFuncs.h" + +#include //////////////////////////////////////////////////////////////////// -// Class : BaseParticleFactory +// Class : BaseParticleFactory // Description : Pure Virtual base class for creating particles //////////////////////////////////////////////////////////////////// class EXPCL_PANDAPHYSICS BaseParticleFactory : public ReferenceCount { private: float _lifespan_base; - float _lifespan_delta; + float _lifespan_spread; float _mass_base; - float _mass_delta; + float _mass_spread; float _terminal_velocity_base; - float _terminal_velocity_delta; + float _terminal_velocity_spread; virtual void populate_child_particle(BaseParticle *bp) const = 0; @@ -32,24 +35,22 @@ protected: BaseParticleFactory(void); BaseParticleFactory(const BaseParticleFactory ©); - INLINE float bounded_rand(void) const; - public: virtual ~BaseParticleFactory(void); INLINE void set_lifespan_base(float lb); - INLINE void set_lifespan_delta(float ld); + INLINE void set_lifespan_spread(float ls); INLINE void set_mass_base(float mb); - INLINE void set_mass_delta(float md); + INLINE void set_mass_spread(float ms); INLINE void set_terminal_velocity_base(float tvb); - INLINE void set_terminal_velocity_delta(float tvd); + INLINE void set_terminal_velocity_spread(float tvs); INLINE float get_lifespan_base(void) const; - INLINE float get_lifespan_delta(void) const; + INLINE float get_lifespan_spread(void) const; INLINE float get_mass_base(void) const; - INLINE float get_mass_delta(void) const; + INLINE float get_mass_spread(void) const; INLINE float get_terminal_velocity_base(void) const; - INLINE float get_terminal_velocity_delta(void) const; + INLINE float get_terminal_velocity_spread(void) const; virtual BaseParticle *alloc_particle(void) const = 0; diff --git a/panda/src/particlesystem/baseParticleRenderer.I b/panda/src/particlesystem/baseParticleRenderer.I index c967b62551..546af84e7a 100644 --- a/panda/src/particlesystem/baseParticleRenderer.I +++ b/panda/src/particlesystem/baseParticleRenderer.I @@ -8,28 +8,16 @@ // Class : Public // Description : Query the geomnode pointer //////////////////////////////////////////////////////////////////// - INLINE GeomNode *BaseParticleRenderer:: get_render_node(void) const { return _render_node; } -//////////////////////////////////////////////////////////////////// -// Function : get_alpha_decay -// Access : Public -//////////////////////////////////////////////////////////////////// - -INLINE ParticleRendererAlphaDecay BaseParticleRenderer:: -get_alpha_decay(void) const { - return _alpha_decay; -} - //////////////////////////////////////////////////////////////////// // Function : disable_alpha // Access : Private // Description : kills the intermediate alpha node/arc //////////////////////////////////////////////////////////////////// - INLINE void BaseParticleRenderer:: disable_alpha(void) { _alpha_node.clear(); @@ -43,56 +31,63 @@ disable_alpha(void) { } //////////////////////////////////////////////////////////////////// -// Function : set_alpha_decay +// Function : set_alpha_mode // Access : public //////////////////////////////////////////////////////////////////// - INLINE void BaseParticleRenderer:: -set_alpha_decay(ParticleRendererAlphaDecay ad) { - update_alpha_state(ad); +set_alpha_mode(ParticleRendererAlphaMode am) { + update_alpha_mode(am); init_geoms(); } //////////////////////////////////////////////////////////////////// -// Function : color_lerp -// Access : Protected -// Description : Linear interpolate 2 color vectors +// Function : get_alpha_mode +// Access : public //////////////////////////////////////////////////////////////////// - -INLINE Colorf BaseParticleRenderer:: -color_lerp(float t, const Colorf& c1, const Colorf& c2) { - return (c1 + (c2 - c1) * t); +INLINE ParticleRendererAlphaMode BaseParticleRenderer:: +get_alpha_mode(void) const { + return _alpha_mode; } //////////////////////////////////////////////////////////////////// -// Function : color_clerp -// Access : Protected -// Description : Cubic interpolation between 2 color vectors. +// Function : set_user_alpha +// Access : public +// Description : sets alpha for "user" alpha mode //////////////////////////////////////////////////////////////////// - -INLINE Colorf BaseParticleRenderer:: -color_clerp(float t, const Colorf& c1, const Colorf& c2) { - float cubic_t = t * t * ((2 * t) - 3); - return color_lerp(cubic_t, c1, c2); +INLINE void BaseParticleRenderer:: +set_user_alpha(float ua) { + _user_alpha = ua; } //////////////////////////////////////////////////////////////////// -// Function : cubic_smooth -// Access : Protected -// Description : smooths out a linear parameterized t in [0,1] +// Function : get_user_alpha +// Access : public +// Description : gets alpha for "user" alpha mode //////////////////////////////////////////////////////////////////// - INLINE float BaseParticleRenderer:: -cubic_smooth(float t) { - return t * t * (3 - (2 * t)); +get_user_alpha(void) const { + return _user_alpha; } //////////////////////////////////////////////////////////////////// -// Function : lerp -// Access : Protected +// Function : get_cur_alpha +// Access : public +// Description : gets current alpha for a particle //////////////////////////////////////////////////////////////////// - INLINE float BaseParticleRenderer:: -lerp(float t, float x0, float x1) { - return x0 + (t * (x1 - x0)); +get_cur_alpha(BaseParticle* bp) { + switch(_alpha_mode) + { + case PR_ALPHA_OUT: + return 1.0f - bp->get_parameterized_age(); + break; + case PR_ALPHA_IN: + return bp->get_parameterized_age(); + break; + case PR_ALPHA_USER: + return _user_alpha; + break; + } + + return 1.0; // should not get here } diff --git a/panda/src/particlesystem/baseParticleRenderer.cxx b/panda/src/particlesystem/baseParticleRenderer.cxx index 20c6173b0d..b65e764bbf 100644 --- a/panda/src/particlesystem/baseParticleRenderer.cxx +++ b/panda/src/particlesystem/baseParticleRenderer.cxx @@ -1,6 +1,6 @@ -// Filename: baseParticleRenderer.cxx +// Filename: baseParticleRenderer.C // Created by: charles (20Jun00) -// +// //////////////////////////////////////////////////////////////////// #include @@ -14,12 +14,14 @@ // Description : Default Constructor //////////////////////////////////////////////////////////////////// BaseParticleRenderer:: -BaseParticleRenderer(ParticleRendererAlphaDecay alpha_decay) : - _alpha_arc((RenderRelation *) NULL), - _alpha_decay(PR_ALPHA_INVALID) { +BaseParticleRenderer(ParticleRendererAlphaMode alpha_mode) : + _alpha_arc((RenderRelation *) NULL), + _alpha_mode(PR_NOT_INITIALIZED_YET) { _render_node = new GeomNode("BaseParticleRenderer render node"); - update_alpha_state(alpha_decay); + _user_alpha = 1.0; + + update_alpha_mode(alpha_mode); } //////////////////////////////////////////////////////////////////// @@ -30,10 +32,12 @@ BaseParticleRenderer(ParticleRendererAlphaDecay alpha_decay) : BaseParticleRenderer:: BaseParticleRenderer(const BaseParticleRenderer& copy) : _alpha_arc((RenderRelation *) NULL), - _alpha_decay(PR_ALPHA_INVALID) { + _alpha_mode(PR_ALPHA_NONE) { _render_node = new GeomNode("BaseParticleRenderer render node"); - update_alpha_state(copy._alpha_decay); + _user_alpha = copy._user_alpha; + + update_alpha_mode(copy._alpha_mode); } //////////////////////////////////////////////////////////////////// @@ -43,7 +47,7 @@ BaseParticleRenderer(const BaseParticleRenderer& copy) : //////////////////////////////////////////////////////////////////// BaseParticleRenderer:: ~BaseParticleRenderer(void) { - if (_alpha_decay == PR_ALPHA_OUT || _alpha_decay == PR_ALPHA_IN) + if(_alpha_mode != PR_ALPHA_NONE) remove_arc(_alpha_arc); } @@ -71,16 +75,14 @@ enable_alpha(void) { // Description : handles the base class part of alpha updating. //////////////////////////////////////////////////////////////////// void BaseParticleRenderer:: -update_alpha_state(ParticleRendererAlphaDecay ad) { - if (_alpha_decay == ad) +update_alpha_mode(ParticleRendererAlphaMode am) { + if (_alpha_mode == am) return; - if (ad == PR_NO_ALPHA && _alpha_decay != PR_NO_ALPHA) + if ((am == PR_ALPHA_NONE) && (_alpha_mode != PR_ALPHA_NONE)) disable_alpha(); - else if ((_alpha_decay == PR_ALPHA_INVALID || _alpha_decay == PR_NO_ALPHA) && - ad != PR_NO_ALPHA) + else if ((am != PR_ALPHA_NONE) && (_alpha_mode == PR_ALPHA_NONE)) enable_alpha(); - _alpha_decay = ad; + _alpha_mode = am; } - diff --git a/panda/src/particlesystem/baseParticleRenderer.h b/panda/src/particlesystem/baseParticleRenderer.h index 3cab3082d2..86610733c1 100644 --- a/panda/src/particlesystem/baseParticleRenderer.h +++ b/panda/src/particlesystem/baseParticleRenderer.h @@ -1,6 +1,6 @@ // Filename: baseParticleRenderer.h // Created by: charles (20Jun00) -// +// //////////////////////////////////////////////////////////////////// #ifndef BASEPARTICLERENDERER_H @@ -14,14 +14,17 @@ #include #include +#include "particleCommonFuncs.h" +#include "baseParticle.h" + #include -enum ParticleRendererAlphaDecay { - PR_NO_ALPHA, +enum ParticleRendererAlphaMode { + PR_ALPHA_NONE, PR_ALPHA_OUT, PR_ALPHA_IN, PR_ALPHA_USER, - PR_ALPHA_INVALID + PR_NOT_INITIALIZED_YET }; enum ParticleRendererBlendMethod { @@ -45,6 +48,8 @@ private: PT(GeomNode) _alpha_node; PT(RenderRelation) _alpha_arc; + float _user_alpha; + // birth and kill particle are for renderers that might do maintenance // faster if it was notified on a per-event basis. An example: // geomParticleRenderer maintains an arc for every particle. Instead @@ -57,26 +62,24 @@ private: virtual void init_geoms(void) = 0; - virtual void render(vector< PT(PhysicsObject) >& po_vector, - int ttl_particles) = 0; + virtual void render(vector< PT(PhysicsObject) >& po_vector, + int ttl_particles) = 0; protected: GeomNode *_interface_node; - ParticleRendererAlphaDecay _alpha_decay; - BaseParticleRenderer(ParticleRendererAlphaDecay alpha_decay); + ParticleRendererAlphaMode _alpha_mode; + + BaseParticleRenderer(ParticleRendererAlphaMode alpha_decay = PR_ALPHA_NONE); BaseParticleRenderer(const BaseParticleRenderer& copy); - void update_alpha_state(ParticleRendererAlphaDecay ad); - - INLINE Colorf color_lerp(float t, const Colorf& c1, const Colorf& c2); - INLINE Colorf color_clerp(float t, const Colorf& c1, const Colorf& c2); - INLINE float cubic_smooth(float t); - INLINE float lerp(float t, float x0, float x1); + void update_alpha_mode(ParticleRendererAlphaMode am); void enable_alpha(void); INLINE void disable_alpha(void); + INLINE float get_cur_alpha(BaseParticle* bp); + virtual void resize_pool(int new_size) = 0; public: @@ -84,8 +87,12 @@ public: virtual ~BaseParticleRenderer(void); INLINE GeomNode *get_render_node(void) const; - INLINE ParticleRendererAlphaDecay get_alpha_decay(void) const; - INLINE void set_alpha_decay(ParticleRendererAlphaDecay ad); + + INLINE void set_alpha_mode(ParticleRendererAlphaMode am); + INLINE ParticleRendererAlphaMode get_alpha_mode(void) const; + + INLINE void set_user_alpha(float ua); + INLINE float get_user_alpha(void) const; virtual BaseParticleRenderer *make_copy(void) = 0; diff --git a/panda/src/particlesystem/boxEmitter.I b/panda/src/particlesystem/boxEmitter.I index b36f62628f..68160bd692 100644 --- a/panda/src/particlesystem/boxEmitter.I +++ b/panda/src/particlesystem/boxEmitter.I @@ -4,23 +4,41 @@ //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// -// Function : set_boundaries +// Function : set_min_bound // Access : Public // Description : boundary assignment //////////////////////////////////////////////////////////////////// - INLINE void BoxEmitter:: -set_boundaries(const LPoint3f& vmin, const LPoint3f& vmax) { - _vmin = vmin; _vmax = vmax; +set_min_bound(const LPoint3f& vmin) { + _vmin = vmin; } //////////////////////////////////////////////////////////////////// -// Function : set_launch_vec +// Function : set_max_bound // Access : Public -// Description : launch vec assignment +// Description : boundary assignment //////////////////////////////////////////////////////////////////// - INLINE void BoxEmitter:: -set_launch_vec(const LVector3f& lv) { - _launch_vec = lv; +set_max_bound(const LPoint3f& vmax) { + _vmax = vmax; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_min_bound +// Access : Public +// Description : boundary accessor +//////////////////////////////////////////////////////////////////// +INLINE LPoint3f BoxEmitter:: +get_min_bound(void) const { + return _vmin; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_max_bound +// Access : Public +// Description : boundary accessor +//////////////////////////////////////////////////////////////////// +INLINE LPoint3f BoxEmitter:: +get_max_bound(void) const { + return _vmax; } diff --git a/panda/src/particlesystem/boxEmitter.cxx b/panda/src/particlesystem/boxEmitter.cxx index 6da023dec3..cb58749005 100644 --- a/panda/src/particlesystem/boxEmitter.cxx +++ b/panda/src/particlesystem/boxEmitter.cxx @@ -1,4 +1,4 @@ -// Filename: boxEmitter.cxx +// Filename: boxEmitter.C // Created by: charles (22Jun00) // //////////////////////////////////////////////////////////////////// @@ -15,7 +15,6 @@ BoxEmitter(void) : BaseParticleEmitter() { _vmin.set(0.0f, 0.0f, 0.0f); _vmax.set(0.0f, 0.0f, 0.0f); - _launch_vec.set(0.0f, 0.0f, 0.0f); } //////////////////////////////////////////////////////////////////// @@ -28,7 +27,6 @@ BoxEmitter(const BoxEmitter ©) : BaseParticleEmitter(copy) { _vmin = copy._vmin; _vmax = copy._vmax; - _launch_vec = copy._launch_vec; } //////////////////////////////////////////////////////////////////// @@ -51,16 +49,15 @@ make_copy(void) { } //////////////////////////////////////////////////////////////////// -// Function : BoxEmitter::create_particle_location +// Function : BoxEmitter::assign_initial_position // Access : Public -// Description : Generates a location in the box +// Description : Generates a location for a new particle //////////////////////////////////////////////////////////////////// void BoxEmitter:: -assign_initial_values(LPoint3f& pos, LVector3f& vel) -{ - float t_x = bounded_rand(); - float t_y = bounded_rand(); - float t_z = bounded_rand(); +assign_initial_position(LPoint3f& pos) { + float t_x = NORMALIZED_RAND(); + float t_y = NORMALIZED_RAND(); + float t_z = NORMALIZED_RAND(); LVector3f v_diff = _vmax - _vmin; @@ -69,5 +66,14 @@ assign_initial_values(LPoint3f& pos, LVector3f& vel) float lerp_z = _vmin[2] + t_z * v_diff[2]; pos.set(lerp_x, lerp_y, lerp_z); - vel = _launch_vec; +} + +//////////////////////////////////////////////////////////////////// +// Function : BoxEmitter::assign_initial_velocity +// Access : Public +// Description : Generates a velocity for a new particle +//////////////////////////////////////////////////////////////////// +void BoxEmitter:: +assign_initial_velocity(LVector3f& vel) { + vel.set(0,0,0); } diff --git a/panda/src/particlesystem/boxEmitter.h b/panda/src/particlesystem/boxEmitter.h index eded10f1be..f4feec127a 100644 --- a/panda/src/particlesystem/boxEmitter.h +++ b/panda/src/particlesystem/boxEmitter.h @@ -16,9 +16,9 @@ class EXPCL_PANDAPHYSICS BoxEmitter : public BaseParticleEmitter { private: LPoint3f _vmin, _vmax; - LVector3f _launch_vec; - virtual void assign_initial_values(LPoint3f& pos, LVector3f& vel); + virtual void assign_initial_position(LPoint3f& pos); + virtual void assign_initial_velocity(LVector3f& vel); public: BoxEmitter(void); @@ -26,8 +26,12 @@ public: virtual ~BoxEmitter(void); virtual BaseParticleEmitter *make_copy(void); - INLINE void set_boundaries(const LPoint3f& vmin, const LPoint3f& vmax); - INLINE void set_launch_vec(const LVector3f& lv); + + INLINE void set_min_bound(const LPoint3f& vmin); + INLINE void set_max_bound(const LPoint3f& vmax); + + INLINE LPoint3f get_min_bound(void) const; + INLINE LPoint3f get_max_bound(void) const; }; #include "boxEmitter.I" diff --git a/panda/src/particlesystem/config_particlesystem.cxx b/panda/src/particlesystem/config_particlesystem.cxx index 219dd8f1b5..ada402ca4d 100644 --- a/panda/src/particlesystem/config_particlesystem.cxx +++ b/panda/src/particlesystem/config_particlesystem.cxx @@ -1,4 +1,4 @@ -// Filename: config_particlesystem.cxx +// Filename: config_particlesystem.C // Created by: charles (05Jul00) // //////////////////////////////////////////////////////////////////// @@ -6,7 +6,7 @@ #include "config_particlesystem.h" #include "particleSystem.h" #include "geomParticleRenderer.h" -#include +#include ConfigureDef(config_particlesystem); NotifyCategoryDef(particlesystem, ""); diff --git a/panda/src/particlesystem/config_particlesystem.h b/panda/src/particlesystem/config_particlesystem.h index 37db8fecfb..2fc2a50732 100644 --- a/panda/src/particlesystem/config_particlesystem.h +++ b/panda/src/particlesystem/config_particlesystem.h @@ -1,6 +1,6 @@ // Filename: config_particlesystem.h // Created by: charles (05Jul00) -// +// //////////////////////////////////////////////////////////////////// #ifndef CONFIG_PARTICLESYSTEM_H @@ -8,7 +8,7 @@ #include #include -#include +#include ConfigureDecl(config_particlesystem, EXPCL_PANDAPHYSICS, EXPTP_PANDAPHYSICS); NotifyCategoryDecl(particlesystem, EXPCL_PANDAPHYSICS, EXPTP_PANDAPHYSICS); diff --git a/panda/src/particlesystem/discEmitter.I b/panda/src/particlesystem/discEmitter.I index 02b198e606..bd856fd110 100644 --- a/panda/src/particlesystem/discEmitter.I +++ b/panda/src/particlesystem/discEmitter.I @@ -15,25 +15,25 @@ set_radius(float r) { } //////////////////////////////////////////////////////////////////// -// Function : set_outer_aoe +// Function : set_outer_angle // Access : Public // Description : aoe assignement //////////////////////////////////////////////////////////////////// INLINE void DiscEmitter:: -set_outer_aoe(float o_aoe) { - _outer_aoe = o_aoe; +set_outer_angle(float o_angle) { + _outer_aoe = o_angle; } //////////////////////////////////////////////////////////////////// -// Function : set_inner_aoe +// Function : set_inner_angle // Access : Public // Description : aoe assignment //////////////////////////////////////////////////////////////////// INLINE void DiscEmitter:: -set_inner_aoe(float i_aoe) { - _inner_aoe = i_aoe; +set_inner_angle(float i_angle) { + _inner_aoe = i_angle; } //////////////////////////////////////////////////////////////////// @@ -70,23 +70,67 @@ set_cubic_lerping(bool clerp) { } //////////////////////////////////////////////////////////////////// -// Function : lerp -// Access : private -// Description : yali +// Function : get_radius +// Access : Public +// Description : radius accessor //////////////////////////////////////////////////////////////////// INLINE float DiscEmitter:: -lerp(float t, float x0, float x1) { - return x0 + (t * (x1 - x0)); +get_radius(void) const { + return _radius; } //////////////////////////////////////////////////////////////////// -// Function : cubic_lerp -// Access : private -// Description : yaci +// Function : get_outer_angle +// Access : Public +// Description : aoe accessor //////////////////////////////////////////////////////////////////// INLINE float DiscEmitter:: -cubic_lerp(float t, float x0, float x1) { - return x0 + ((t * t * (3 - (2 * t))) * (x1 - x0)); +get_outer_angle(void) const { + return _outer_aoe; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_inner_angle +// Access : Public +// Description : aoe accessor +//////////////////////////////////////////////////////////////////// + +INLINE float DiscEmitter:: +get_inner_angle(void) const { + return _inner_aoe; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_outer_magnitude +// Access : public +// Description : mag accessor +//////////////////////////////////////////////////////////////////// + +INLINE float DiscEmitter:: +get_outer_magnitude(void) const { + return _outer_magnitude; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_inner_magnitude +// Access : public +// Description : mag accessor +//////////////////////////////////////////////////////////////////// + +INLINE float DiscEmitter:: +get_inner_magnitude(void) const { + return _inner_magnitude; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_cubic_lerping +// Access : public +// Description : clerp flag accessor +//////////////////////////////////////////////////////////////////// + +INLINE bool DiscEmitter:: +get_cubic_lerping(void) const { + return _cubic_lerping; } diff --git a/panda/src/particlesystem/discEmitter.cxx b/panda/src/particlesystem/discEmitter.cxx index 0ac9997131..12d4d796f4 100644 --- a/panda/src/particlesystem/discEmitter.cxx +++ b/panda/src/particlesystem/discEmitter.cxx @@ -1,4 +1,4 @@ -// Filename: discEmitter.cxx +// Filename: discEmitter.C // Created by: charles (22Jun00) // //////////////////////////////////////////////////////////////////// @@ -32,6 +32,10 @@ DiscEmitter(const DiscEmitter ©) : _inner_magnitude = copy._inner_magnitude; _outer_magnitude = copy._outer_magnitude; _cubic_lerping = copy._cubic_lerping; + + _distance_from_center = copy._distance_from_center; + _sinf_theta = copy._sinf_theta; + _cosf_theta = copy._cosf_theta; } //////////////////////////////////////////////////////////////////// @@ -54,44 +58,59 @@ make_copy(void) { } //////////////////////////////////////////////////////////////////// -// Function : DiscEmitter::create_particle_location -// Access : Public -// Description : Generates a location on the disc +// Function : DiscEmitter::assign_initial_position +// Access : Public +// Description : Generates a location for a new particle //////////////////////////////////////////////////////////////////// void DiscEmitter:: -assign_initial_values(LPoint3f& pos, LVector3f& vel) { +assign_initial_position(LPoint3f& pos) { // position - float theta = bounded_rand() * 2.0f * MathNumbers::pi; + float theta = NORMALIZED_RAND() * 2.0f * MathNumbers::pi; - float t = bounded_rand(); - float r_scalar = t * _radius; + _distance_from_center = NORMALIZED_RAND(); + float r_scalar = _distance_from_center * _radius; - float sinf_theta = sinf(theta); - float cosf_theta = cosf(theta); + _sinf_theta = sinf(theta); + _cosf_theta = cosf(theta); - float new_x = cosf_theta * r_scalar; - float new_y = sinf_theta * r_scalar; + float new_x = _cosf_theta * r_scalar; + float new_y = _sinf_theta * r_scalar; pos.set(new_x, new_y, 0.0f); +} - // lerp type +//////////////////////////////////////////////////////////////////// +// Function : DiscEmitter::assign_initial_velocity +// Access : Public +// Description : Generates a velocity for a new particle +//////////////////////////////////////////////////////////////////// +void DiscEmitter:: +assign_initial_velocity(LVector3f& vel) { float aoe, mag; + // lerp type if (_cubic_lerping == true) { - aoe = cubic_lerp(t, _inner_aoe, _outer_aoe); - mag = cubic_lerp(t, _inner_magnitude, _outer_magnitude); + aoe = CLERP(_distance_from_center, _inner_aoe, _outer_aoe); + mag = CLERP(_distance_from_center, _inner_magnitude, _outer_magnitude); } else { - aoe = lerp(t, _inner_aoe, _outer_aoe); - mag = lerp(t, _inner_magnitude, _outer_magnitude); + aoe = LERP(_distance_from_center, _inner_aoe, _outer_aoe); + mag = LERP(_distance_from_center, _inner_magnitude, _outer_magnitude); } // velocity float vel_z = mag * sinf(aoe * (MathNumbers::pi / 180.0f)); float abs_diff = fabs((mag * mag) - (vel_z * vel_z)); float root_mag_minus_z_squared = sqrtf(abs_diff); - float vel_x = cosf_theta * root_mag_minus_z_squared; - float vel_y = sinf_theta * root_mag_minus_z_squared; + float vel_x = _cosf_theta * root_mag_minus_z_squared; + float vel_y = _sinf_theta * root_mag_minus_z_squared; + + // quick and dirty + if((aoe > 90.0f) && (aoe < 270.0f)) + { + vel_x = -vel_x; + vel_y = -vel_y; + } vel.set(vel_x, vel_y, vel_z); } diff --git a/panda/src/particlesystem/discEmitter.h b/panda/src/particlesystem/discEmitter.h index b16fbf9927..072e6b67ce 100644 --- a/panda/src/particlesystem/discEmitter.h +++ b/panda/src/particlesystem/discEmitter.h @@ -20,11 +20,16 @@ private: float _outer_magnitude, _inner_magnitude; bool _cubic_lerping; - virtual void assign_initial_values(LPoint3f& pos, LVector3f& vel); + /////////////////////////////// + // scratch variables that carry over from position calc to velocity calc + float _distance_from_center; + float _sinf_theta; + float _cosf_theta; + /////////////////////////////// + + virtual void assign_initial_position(LPoint3f& pos); + virtual void assign_initial_velocity(LVector3f& vel); - INLINE float lerp(float t, float x0, float x1); - INLINE float cubic_lerp(float t, float x0, float x1); - public: DiscEmitter(void); DiscEmitter(const DiscEmitter ©); @@ -33,11 +38,18 @@ public: virtual BaseParticleEmitter *make_copy(void); INLINE void set_radius(float r); - INLINE void set_outer_aoe(float o_aoe); - INLINE void set_inner_aoe(float i_aoe); + INLINE void set_outer_angle(float o_angle); + INLINE void set_inner_angle(float i_angle); INLINE void set_outer_magnitude(float o_mag); INLINE void set_inner_magnitude(float i_mag); INLINE void set_cubic_lerping(bool clerp); + + INLINE float get_radius(void) const; + INLINE float get_outer_angle(void) const; + INLINE float get_inner_angle(void) const; + INLINE float get_outer_magnitude(void) const; + INLINE float get_inner_magnitude(void) const; + INLINE bool get_cubic_lerping(void) const; }; #include "discEmitter.I" diff --git a/panda/src/particlesystem/geomParticleRenderer.cxx b/panda/src/particlesystem/geomParticleRenderer.cxx index edca0b7387..1829c4680e 100644 --- a/panda/src/particlesystem/geomParticleRenderer.cxx +++ b/panda/src/particlesystem/geomParticleRenderer.cxx @@ -1,4 +1,4 @@ -// Filename: geomParticleRenderer.cxx +// Filename: geomParticleRenderer.C // Created by: charles (05Jul00) // //////////////////////////////////////////////////////////////////// @@ -16,8 +16,8 @@ //////////////////////////////////////////////////////////////////// GeomParticleRenderer:: -GeomParticleRenderer(ParticleRendererAlphaDecay ad, Node *geom_node) : - _geom_node(geom_node), _pool_size(0), BaseParticleRenderer(ad) { +GeomParticleRenderer(ParticleRendererAlphaMode am, Node *geom_node) : + _geom_node(geom_node), _pool_size(0), BaseParticleRenderer(am) { _dead_particle_parent_node = new Node; @@ -148,15 +148,14 @@ render(vector< PT(PhysicsObject) >& po_vector, int ttl_particles) { PT(ColorTransition) alpha; xform = new TransformTransition(LMatrix4f::translate_mat(pos)); - if ((_alpha_decay != PR_ALPHA_INVALID) && (_alpha_decay != PR_NO_ALPHA) && - (_alpha_decay != PR_ALPHA_USER)) { + if ((_alpha_mode != PR_ALPHA_NONE) && (_alpha_mode != PR_ALPHA_USER)) { float alpha_scalar = cur_particle->get_parameterized_age(); - if (_alpha_decay == PR_ALPHA_IN) { + if (_alpha_mode == PR_ALPHA_IN) { alpha = new ColorTransition(1.0f, 1.0f, 1.0f, alpha_scalar); } - else if (_alpha_decay == PR_ALPHA_OUT) { + else if (_alpha_mode == PR_ALPHA_OUT) { alpha = new ColorTransition(1.0f, 1.0f, 1.0f, 1.0f - alpha_scalar); } diff --git a/panda/src/particlesystem/geomParticleRenderer.h b/panda/src/particlesystem/geomParticleRenderer.h index 9eb7e0b75e..ffc3cf41de 100644 --- a/panda/src/particlesystem/geomParticleRenderer.h +++ b/panda/src/particlesystem/geomParticleRenderer.h @@ -41,7 +41,7 @@ private: public: - GeomParticleRenderer(ParticleRendererAlphaDecay ad = PR_NO_ALPHA, + GeomParticleRenderer(ParticleRendererAlphaMode am = PR_ALPHA_NONE, Node *geom_node = (Node *) NULL); GeomParticleRenderer(const GeomParticleRenderer& copy); virtual ~GeomParticleRenderer(void); diff --git a/panda/src/particlesystem/lineEmitter.I b/panda/src/particlesystem/lineEmitter.I index d924f849da..f0e296d2ce 100644 --- a/panda/src/particlesystem/lineEmitter.I +++ b/panda/src/particlesystem/lineEmitter.I @@ -4,24 +4,41 @@ //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// -// Function : set_endpoints +// Function : set_endpoint1 // Access : Public // Description : endpoint assignment //////////////////////////////////////////////////////////////////// - INLINE void LineEmitter:: -set_endpoints(const LPoint3f& vmin, const LPoint3f& vmax) { - _vmin = vmin; _vmax = vmax; +set_endpoint1(const LPoint3f& point) { + _endpoint1 = point; } //////////////////////////////////////////////////////////////////// -// Function : set_launch_vec +// Function : set_endpoint2 // Access : Public -// Description : launch assignment +// Description : endpoint assignment //////////////////////////////////////////////////////////////////// - INLINE void LineEmitter:: -set_launch_vec(const LVector3f& lv) { - _launch_vec = lv; +set_endpoint2(const LPoint3f& point) { + _endpoint2 = point; } +//////////////////////////////////////////////////////////////////// +// Function : get_endpoint1 +// Access : Public +// Description : endpoint accessor +//////////////////////////////////////////////////////////////////// +INLINE LPoint3f LineEmitter:: +get_endpoint1(void) const { + return _endpoint1; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_endpoint2 +// Access : Public +// Description : endpoint accessor +//////////////////////////////////////////////////////////////////// +INLINE LPoint3f LineEmitter:: +get_endpoint2(void) const { + return _endpoint2; +} diff --git a/panda/src/particlesystem/lineEmitter.cxx b/panda/src/particlesystem/lineEmitter.cxx index a1c1f83b29..239bebb42a 100644 --- a/panda/src/particlesystem/lineEmitter.cxx +++ b/panda/src/particlesystem/lineEmitter.cxx @@ -1,4 +1,4 @@ -// Filename: lineEmitter.cxx +// Filename: lineEmitter.C // Created by: charles (22Jun00) // //////////////////////////////////////////////////////////////////// @@ -13,9 +13,8 @@ LineEmitter:: LineEmitter(void) : BaseParticleEmitter() { - _vmin.set(0.0f, 0.0f, 0.0f); - _vmax.set(0.0f, 0.0f, 0.0f); - _launch_vec.set(0,0,0); + _endpoint1.set(0.0f, 0.0f, 0.0f); + _endpoint2.set(0.0f, 0.0f, 0.0f); } //////////////////////////////////////////////////////////////////// @@ -26,9 +25,8 @@ LineEmitter(void) : LineEmitter:: LineEmitter(const LineEmitter ©) : BaseParticleEmitter(copy) { - _vmin = copy._vmin; - _vmax = copy._vmax; - _launch_vec = copy._launch_vec; + _endpoint1 = copy._endpoint1; + _endpoint2 = copy._endpoint2; } //////////////////////////////////////////////////////////////////// @@ -51,21 +49,29 @@ make_copy(void) { } //////////////////////////////////////////////////////////////////// -// Function : LineEmitter::create_particle_location +// Function : LineEmitter::assign_initial_position // Access : Public -// Description : Generates a location on the line +// Description : Generates a location for a new particle //////////////////////////////////////////////////////////////////// void LineEmitter:: -assign_initial_values(LPoint3f& pos, LVector3f& vel) -{ - float t = bounded_rand(); +assign_initial_position(LPoint3f& pos) { + float t = NORMALIZED_RAND(); - LVector3f v_diff = _vmax - _vmin; + LVector3f v_diff = _endpoint2 - _endpoint1; - float lerp_x = _vmin[0] + t * v_diff[0]; - float lerp_y = _vmin[1] + t * v_diff[1]; - float lerp_z = _vmin[2] + t * v_diff[2]; + float lerp_x = _endpoint1[0] + t * v_diff[0]; + float lerp_y = _endpoint1[1] + t * v_diff[1]; + float lerp_z = _endpoint1[2] + t * v_diff[2]; pos.set(lerp_x, lerp_y, lerp_z); - vel = _launch_vec; +} + +//////////////////////////////////////////////////////////////////// +// Function : LineEmitter::assign_initial_velocity +// Access : Public +// Description : Generates a velocity for a new particle +//////////////////////////////////////////////////////////////////// +void LineEmitter:: +assign_initial_velocity(LVector3f& vel) { + vel.set(0,0,0); } diff --git a/panda/src/particlesystem/lineEmitter.h b/panda/src/particlesystem/lineEmitter.h index b088e8ff37..0eee1d5cc0 100644 --- a/panda/src/particlesystem/lineEmitter.h +++ b/panda/src/particlesystem/lineEmitter.h @@ -15,11 +15,11 @@ //////////////////////////////////////////////////////////////////// class EXPCL_PANDAPHYSICS LineEmitter : public BaseParticleEmitter { private: - LPoint3f _vmin, _vmax; - LVector3f _launch_vec; + LPoint3f _endpoint1, _endpoint2; + + virtual void assign_initial_position(LPoint3f& pos); + virtual void assign_initial_velocity(LVector3f& vel); - virtual void assign_initial_values(LPoint3f& pos, LVector3f& vel); - public: LineEmitter(void); LineEmitter(const LineEmitter ©); @@ -27,8 +27,11 @@ public: virtual BaseParticleEmitter *make_copy(void); - INLINE void set_endpoints(const LPoint3f& vmin, const LPoint3f& vmax); - INLINE void set_launch_vec(const LVector3f& lv); + INLINE void set_endpoint1(const LPoint3f& point); + INLINE void set_endpoint2(const LPoint3f& point); + + INLINE LPoint3f get_endpoint1(void) const; + INLINE LPoint3f get_endpoint2(void) const; }; #include "lineEmitter.I" diff --git a/panda/src/particlesystem/orientedParticle.cxx b/panda/src/particlesystem/orientedParticle.cxx index cbd737959d..0c3a14c25a 100644 --- a/panda/src/particlesystem/orientedParticle.cxx +++ b/panda/src/particlesystem/orientedParticle.cxx @@ -1,4 +1,4 @@ -// Filename: orientedParticle.cxx +// Filename: orientedParticle.C // Created by: charles (19Jun00) // //////////////////////////////////////////////////////////////////// diff --git a/panda/src/particlesystem/orientedParticleFactory.cxx b/panda/src/particlesystem/orientedParticleFactory.cxx index e4e0a9ad17..17bdf6b7a2 100644 --- a/panda/src/particlesystem/orientedParticleFactory.cxx +++ b/panda/src/particlesystem/orientedParticleFactory.cxx @@ -1,4 +1,4 @@ -// Filename: orientedParticleFactory.cxx +// Filename: orientedParticleFactory.C // Created by: charles (05Jul00) // //////////////////////////////////////////////////////////////////// diff --git a/panda/src/particlesystem/particleSystem.I b/panda/src/particlesystem/particleSystem.I index 207ce96034..6f69219b93 100644 --- a/panda/src/particlesystem/particleSystem.I +++ b/panda/src/particlesystem/particleSystem.I @@ -39,6 +39,7 @@ set_pool_size(int size) { INLINE void ParticleSystem:: set_birth_rate(float new_br) { _birth_rate = new_br; + if(IS_NEARLY_ZERO(_birth_rate)) _birth_rate = NEARLY_ZERO(float); } //////////////////////////////////////////////////////////////////// @@ -52,13 +53,13 @@ set_litter_size(int new_ls) { } //////////////////////////////////////////////////////////////////// -// Function : set_litter_delta +// Function : set_litter_spread // Access : Public //////////////////////////////////////////////////////////////////// INLINE void ParticleSystem:: -set_litter_delta(int new_ld) { - _litter_delta = new_ld; +set_litter_spread(int new_ld) { + _litter_spread = new_ld; } //////////////////////////////////////////////////////////////////// @@ -246,12 +247,12 @@ get_litter_size(void) const { } //////////////////////////////////////////////////////////////////// -// Function : get_litter_delta +// Function : get_litter_spread // Access : Public //////////////////////////////////////////////////////////////////// INLINE int ParticleSystem:: -get_litter_delta(void) const { - return _litter_delta; +get_litter_spread(void) const { + return _litter_spread; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/particlesystem/particleSystem.cxx b/panda/src/particlesystem/particleSystem.cxx index 5cf7c5dc94..90f7d7b782 100644 --- a/panda/src/particlesystem/particleSystem.cxx +++ b/panda/src/particlesystem/particleSystem.cxx @@ -1,4 +1,4 @@ -// Filename: particleSystem.cxx +// Filename: particleSystem.C // Created by: charles (14Jun00) // //////////////////////////////////////////////////////////////////// @@ -13,6 +13,7 @@ #include #include #include +#include #include "config_particlesystem.h" #include "particleSystem.h" @@ -31,8 +32,9 @@ ParticleSystem(int pool_size) : _particle_pool_size(pool_size), Physical(pool_size, false) { _birth_rate = 0.0f; + _tics_since_birth = _birth_rate; _litter_size = 0; - _litter_delta = 0; + _litter_spread = 0; _living_particles = 0; _active_system_flag = true; _local_velocity_flag = true; @@ -69,7 +71,7 @@ ParticleSystem(const ParticleSystem& copy) : _particle_pool_size = copy._particle_pool_size; _birth_rate = copy._birth_rate; _litter_size = copy._litter_size; - _litter_delta = copy._litter_delta; + _litter_spread = copy._litter_spread; _active_system_flag = copy._active_system_flag; _local_velocity_flag = copy._local_velocity_flag; _spawn_on_death_flag = copy._spawn_on_death_flag; @@ -117,8 +119,8 @@ ParticleSystem:: bool ParticleSystem:: birth_particle(void) { int pool_index; - float lifespan; - float mass, t; +// float lifespan; +// float mass, t; // cout << "ParticleSystem::birth_particle" << endl; @@ -158,7 +160,7 @@ birth_particle(void) { if (_local_velocity_flag == false) new_vel = new_vel * birth_to_render_xform; - bp->set_position(world_pos); + bp->set_position_HandOfGod(world_pos/* + (NORMALIZED_RAND() * new_vel)*/); bp->set_velocity(new_vel); _living_particles++; @@ -180,8 +182,8 @@ birth_litter(void) { litter_size = _litter_size; - if (_litter_delta != 0) - litter_size += _litter_delta - (rand() % (2 * _litter_delta)); + if (_litter_spread != 0) + litter_size += _litter_spread - (rand() % (2 * _litter_spread)); int i; @@ -265,7 +267,7 @@ spawn_child_system(BaseParticle *bp) { //////////////////////////////////////////////////////////////////// void ParticleSystem:: kill_particle(int pool_index) { - vector< PT(PhysicsObject) >::iterator cur; +// vector< PT(PhysicsObject) >::iterator cur; // get a handle on our particle BaseParticle *bp = (BaseParticle *) _physics_objects[pool_index].p(); @@ -384,11 +386,13 @@ update(float dt) { ttl_updates_left--; } + // generate new particles if necessary. _tics_since_birth += dt; - if (_tics_since_birth >= _birth_rate) { + while (_tics_since_birth >= _birth_rate) { birth_litter(); - _tics_since_birth = 0.0f; + _tics_since_birth -= _birth_rate; } + } diff --git a/panda/src/particlesystem/particleSystem.h b/panda/src/particlesystem/particleSystem.h index 68e73e7ca8..ca2be40778 100644 --- a/panda/src/particlesystem/particleSystem.h +++ b/panda/src/particlesystem/particleSystem.h @@ -1,6 +1,6 @@ // Filename: particleSystem.h // Created by: charles (14Jun00) -// +// //////////////////////////////////////////////////////////////////// #ifndef PARTICLESYSTEM_H @@ -40,7 +40,7 @@ private: float _birth_rate; float _tics_since_birth; int _litter_size; - int _litter_delta; + int _litter_spread; float _system_age; float _system_lifespan; @@ -83,56 +83,40 @@ public: ~ParticleSystem(void); // access/queries - INLINE void set_pool_size(int size); - INLINE int get_pool_size(void) const; - INLINE void set_birth_rate(float new_br); - INLINE float get_birth_rate(void) const; - INLINE void set_litter_size(int new_ls); - INLINE int get_litter_size(void) const; - - INLINE void set_litter_delta(int new_ld); - INLINE int get_litter_delta(void) const; - - INLINE void set_renderer(BaseParticleRenderer *r); - INLINE BaseParticleRenderer *get_renderer(void) const; - - INLINE void set_emitter(BaseParticleEmitter *e); - INLINE BaseParticleEmitter *get_emitter(void) const; - - INLINE void set_factory(BaseParticleFactory *f); - INLINE BaseParticleFactory *get_factory(void) const; - - INLINE void set_active_system_flag(bool a); - INLINE bool get_active_system_flag(void) const; - + INLINE void set_litter_spread(int new_ld); INLINE void set_local_velocity_flag(bool lv); - INLINE bool get_local_velocity_flag(void) const; - - INLINE void set_spawn_on_death_flag(bool sod); - INLINE bool get_spawn_on_death_flag(void) const; - INLINE void set_system_grows_older_flag(bool sgo); - INLINE bool get_system_grows_older_flag(void) const; - INLINE void set_system_lifespan(float sl); - INLINE float get_system_lifespan(void) const; - INLINE void set_system_age(float age); - INLINE float get_system_age(void) const; - + INLINE void set_active_system_flag(bool a); + INLINE void set_spawn_on_death_flag(bool sod); INLINE void set_spawn_render_node(Node *node); - INLINE Node *get_spawn_render_node(void) const; + INLINE void set_template_system_flag(bool tsf); + INLINE void set_render_parent(Node *node); + INLINE void set_renderer(BaseParticleRenderer *r); + INLINE void set_emitter(BaseParticleEmitter *e); + INLINE void set_factory(BaseParticleFactory *f); + INLINE int get_pool_size(void) const; + INLINE float get_birth_rate(void) const; + INLINE int get_litter_size(void) const; + INLINE int get_litter_spread(void) const; + INLINE bool get_local_velocity_flag(void) const; + INLINE bool get_system_grows_older_flag(void) const; + INLINE float get_system_lifespan(void) const; + INLINE float get_system_age(void) const; + INLINE bool get_active_system_flag(void) const; + INLINE bool get_spawn_on_death_flag(void) const; + INLINE Node *get_spawn_render_node(void) const; INLINE bool get_i_was_spawned_flag(void) const; INLINE int get_living_particles(void) const; - - INLINE void set_template_system_flag(bool tsf); - INLINE Node *get_render_parent(void) const; - INLINE void set_render_parent(Node *node); + INLINE BaseParticleRenderer *get_renderer(void) const; + INLINE BaseParticleEmitter *get_emitter(void) const; + INLINE BaseParticleFactory *get_factory(void) const; // particle template vector diff --git a/panda/src/particlesystem/particleSystemManager.cxx b/panda/src/particlesystem/particleSystemManager.cxx index d2d8bd9511..b4f349be22 100644 --- a/panda/src/particlesystem/particleSystemManager.cxx +++ b/panda/src/particlesystem/particleSystemManager.cxx @@ -1,6 +1,6 @@ -// Filename: particleSystemManager.cxx +// Filename: particleSystemManager.C // Created by: charles (28Jun00) -// +// //////////////////////////////////////////////////////////////////// #include "particleSystemManager.h" @@ -80,22 +80,22 @@ do_particles(float dt) { // handle age if (cur_ps->get_system_grows_older_flag() == true) { - float age = cur_ps->get_system_age() + dt; - cur_ps->set_system_age(age); + float age = cur_ps->get_system_age() + dt; + cur_ps->set_system_age(age); - // handle death - if (age >= cur_ps->get_system_lifespan()) { - list< PT(ParticleSystem) >::iterator kill = cur; - cur++; + // handle death + if (age >= cur_ps->get_system_lifespan()) { + list< PT(ParticleSystem) >::iterator kill = cur; + cur++; - _ps_list.erase(kill); - render_due = false; - } + _ps_list.erase(kill); + render_due = false; + } } // handle render if (render_due) { - cur_ps->render(); + cur_ps->render(); } } diff --git a/panda/src/particlesystem/particleSystemManager.h b/panda/src/particlesystem/particleSystemManager.h index a70af3f0ef..e798219a16 100644 --- a/panda/src/particlesystem/particleSystemManager.h +++ b/panda/src/particlesystem/particleSystemManager.h @@ -1,6 +1,6 @@ // Filename: particleSystemManager.h // Created by: charles (28Jun00) -// +// //////////////////////////////////////////////////////////////////// #ifndef PARTICLESYSTEMMANAGER_H diff --git a/panda/src/particlesystem/particle_system_parameters.txt b/panda/src/particlesystem/particle_system_parameters.txt new file mode 100644 index 0000000000..4a094781bd --- /dev/null +++ b/panda/src/particlesystem/particle_system_parameters.txt @@ -0,0 +1,368 @@ +========================== +Particle System Parameters +========================== +rev. 2 +Darren Ranalli, 10.10.2000 + +=========== +Conventions +=========== +In this document, parameters are presented in the following format: + + PandaType Name : Range/Value Set // comment + +If "Range/Value Set" is not present, any value is valid. "inf" is infinity. + +A "Value Set" {VALUE1, VALUE2...} is analogous to a C++ enum; it is a set of discrete values. + +LINEAR means an even, linear interpolation. CUBIC means interpolation with ease-in and ease-out. + +All "Spread" parameters specify the maximum amount by which a value can vary above or below the +base value. + +Parameter names ("Name" above) are presented with every word but the first word capitalized +for readability, e.g. "blueWidgetLength", but their corresponding accessor class member +functions have no capital letters and an underscore between each word, e.g. +"get_blue_widget_length()" and "set_blue_widget_length()". + + +================ +Particle Systems +================ +CLASS: ParticleSystem + +Particle systems have the following methods: + void render(void); // renders the particle system's particles* + void update(float dt); // updates the state of the particle system for "dt" seconds of elapsed time* + +*NOTE: render() and update() should not be called for a particle system that is attached to a + ParticleSystemManager. (see below) Use the corresponding ParticleSystemManager methods instead. + +Every particle system has the following parameters: + int poolSize : [0,inf) // size of particle pool; this is the maximum number of simultaneous particles + float birthRate : (0,inf) // period of time in seconds between particle births + int litterSize : [1,inf) // number of particles to create at each birth + int litterSpread : [0,inf) // variation above and below litterSize + bool localVelocityFlag : // if true, velocities are absolute; if false, velocities are relative (TODO: relative to what?) + bool systemGrowsOlder : // if true, system has a lifespan + float systemLifespan : [0,inf) // age in seconds at which system should die -- only used if systemGrowsOlder is true + BaseParticleRenderer* renderer : // pointer to particle renderer (see below) + BaseParticleEmitter* emitter : // pointer to particle emitter (see below) + BaseParticleFactory* factory : // pointer to particle factory (see below) + Node* renderParent : // scene graph node relative to which particles will be emitted/rendered (TODO: i think) + +TODO: what about particle system spawn-on-death? Is that useful, or should it be done external to the particle system? + + +========================== +Particle System Components +========================== +A particle system is characterized by three components. Each particle +system has one of each of the following components: + +1) particle factory +2) particle emitter +3) particle renderer + +Particle factories are responsible for generating particles, and assigning +values for their internal attributes (lifespan, mass, etc.). Different +particle factories produce particles with specific orientation/rotation +capabilities. + +Particle emitters are used to assign initial locations and velocity vectors +for particles. + +Particle renderers are responsible for translating a particle object into +a visible object in the scene graph. + + +================== +Particle Factories +================== + +All factories have the following parameters: + float lifespanBase : [0,inf) // average lifespan in seconds + float lifespanSpread : [0,inf) // spread == variation above and below base value + float massBase : [0,inf) // average particle mass + float massSpread : [0,inf) + float terminalVelocityBase : [0,inf) // average particle terminal velocity + float terminalVelocitySpread : [0,inf) + +-------------------- +PointParticleFactory +-------------------- +CLASS: PointParticleFactory + +generates simple particles + +no additional parameters + +-------------------- +ZSpinParticleFactory +-------------------- +CLASS: ZSpinParticleFactory + +generates particles that spin around the "Z" axis (pointing straight into the screen) + +parameters: + float initialAngle : // starting angle in degrees + float finalAngle : // final angle in degrees + float initialAngleSpread : // spread of initial angle + float finalAngleSpread : // spread of final angle + +----------------------- +OrientedParticleFactory +----------------------- +CLASS: OrientedParticleFactory + +generates particles that can have any arbitrary orientation + +not yet implemented + + +================= +Particle Emitters +================= +Particle emitters are generally categorized by the volume of space they represent, +in which particles are generated. + +All particle emitters can function in one of three emission modes: Explicit, Radiate, and Custom. +These modes affect the velocity with which particles are emitted. + +Explicit emission: particles are all emitted in parallel, in the same direction +Radiate emission: particles are emitted away from a specific point +Custom emission: particles are emitted with a velocity that is determined by the particular emitter + +Regardless of the current emission mode, all emitters have the following parameters: + enum emissionType : {ET_EXPLICIT, ET_RADIATE, ET_CUSTOM} // emission mode + LVector3f explicitLaunchVector : // all particles launch with this velocity in Explicit mode + LPoint3f radiateOrigin : // particles launch away from this point in Radiate mode + float amplitude : (-inf,inf) // launch velocity multiplier (all emission modes) + float amplitudeSpread : [0,inf) // spread for launch velocity multiplier (all emission modes) + +---------- +BoxEmitter +---------- +CLASS: BoxEmitter + +parameters: + LPoint3f minBound, maxBound : // two points that define the box volume + +Custom emission description: + particles have no initial velocity + +----------- +DiscEmitter +----------- +CLASS: DiscEmitter + +parameters: + float radius : [0,inf) // radius of disc, in world coord units + float outerAngle : [0,360] // Custom emission: particle launch angle at outer edge of disc * + float innerAngle : [0,360] // Custom emission: particle launch angle at center of disc * + float outerMagnitude : // Custom emission: launch velocity multiplier at outer edge of disc + float innerMagnitude : // Custom emission: launch velocity multiplier at center of disc + bool cubicLerping : // Custom emission: if true, magnitude/angle interpolation from center + to edge is cubic (ease-in, ease-out) + +Custom emission description: + particles are emitted according to center/edge velocity magnitudes, and center/edge angles. particles + emitted from areas on the inside of the disc use interpolated magnitudes and angles; interpolation is + either linear or cubic. + +* 0 degrees emits particles away from the disc center, 180 emits particles back towards the disc center. + these angles do not quite work correctly yet for angles < 0 and > 360 + +----------- +LineEmitter +----------- +CLASS: LineEmitter + +parameters: + LPoint3f endpoint1, endpoint2 : // two points that define the line + +Custom emission description: + particles have no initial velocity + +------------ +PointEmitter +------------ +CLASS: PointEmitter + +parameters: + LVector3f location : // location of emitter point + +Custom emission description: + particles have no initial velocity + +---------------- +RectangleEmitter +---------------- +CLASS: RectangleEmitter + +parameters: + LPoint2f minBound, maxBound : // two 2D co-planar (duh) points that define the rectangle + +Custom emission description: + particles have no initial velocity + +----------- +RingEmitter +----------- +CLASS: RingEmitter + +parameters: + float radius : [0,inf) // radius of disc, in world coord units + float angle : [0,360] // Custom emission: particle launch angle * + +Custom emission description: + particles are emitted from the ring at an angle with respect to the vector from the ring center + to the spawn point + +* 0 degrees emits particles away from the center of the ring, 180 emits particles back towards the ring center. + these angles do not quite work correctly yet for angles < 0 and > 360 + +-------------------- +SphereSurfaceEmitter +-------------------- +CLASS: SphereSurfaceEmitter + +parameters: + float radius : [0,inf) // radius of sphere, in world coord units + +Custom emission description: + particles have no initial velocity + +------------------- +SphereVolumeEmitter +------------------- +CLASS: SphereVolumeEmitter + +parameters: + float radius : [0,inf) // radius of sphere, in world coord units + +Custom emission description: + particles are emitted away from the sphere center. Their velocity is dependent + on their spawn location within the sphere: it is 0 at the center, of magnitude + 1 at the outer edge of the sphere, and linearly interpolated in between. + +------------------ +TangentRingEmitter +------------------ +CLASS: TangentRingEmitter + +parameters: + float radius : [0,inf) // radius of ring, in world coord units + +Custom emission description: + particles are emitted tangentially to the ring edge, with velocity magnitude of 1 + + +================== +Particle Renderers +================== +Particle renderers add particles to the visible scene graph according to the information +stored in the particle objects (position, orientation, velocity, etc.) and according to +the type of the renderer. + +All particle renderers have the following parameters: + enum alphaMode : {NO_ALPHA,ALPHA_OUT,ALPHA_IN,ALPHA_USER} // alpha setting over particles' lifetime + float userAlpha : [0,1] // alpha value for ALPHA_USER alpha mode + +--------------------- +PointParticleRenderer +--------------------- +CLASS: PointParticleRenderer + +renders particles as points (pixels/squares) + +parameters: + float pointSize : [0,inf) // width and height of points, in pixels + Colorf startColor : 4-vector(RGBA), ([0,1], [0,1], [0,1], [0,1]) // starting color of point + Colorf endColor : 4-vector(RGBA), ([0,1], [0,1], [0,1], [0,1]) // ending color of point + enum blendType : {ONE_COLOR, BLEND_LIFE, BLEND_VEL} // see note below + enum blendMethod : {LINEAR, CUBIC} // interpolation method between colors + +NOTE: blendType: + ONE_COLOR -> point is always startColor + BLEND_LIFE -> color is interp'd from start to endColor according to age/lifespan + BLEND_VEL -> color is interp'd between start and endColor according to velocity/terminal velocity + +-------------------- +LineParticleRenderer +-------------------- +CLASS: LineParticleRenderer + +renders particles as lines (between current position and last position) + +parameters: + Colorf headColor : 4-vector(RGBA), ([0,1], [0,1], [0,1], [0,1]) // color of leading end (head) + Colorf tailColor : 4-vector(RGBA), ([0,1], [0,1], [0,1], [0,1]) // color of trailing end (tail) + +----------------------- +SparkleParticleRenderer +----------------------- +CLASS: SparkleParticleRenderer + +renders particles as "star" / "sparkle" objects (three equal-length perpendicular axial lines +crossing at their midpoints... kind of like jacks) +sparkle particles appear to "sparkle" when they are viewed as being smaller than a pixel. + +parameters: + Colorf centerColor : 4-vector(RGBA), ([0,1], [0,1], [0,1], [0,1]) // color of sparkle center + Colorf edgeColor : 4-vector(RGBA), ([0,1], [0,1], [0,1], [0,1]) // color of sparkle line endpoints + float birthRadius : [0,inf) // initial sparkle radius in world coord units + float deathRadius : [0,inf) // final sparkle radius in world coord units + enum lifeScale : {NO_SCALE, SCALE} // if NO_SCALE, sparkle is always of radius birthRadius + +---------------------- +SpriteParticleRenderer +---------------------- +CLASS: SpriteParticleRenderer + +renders particles as an image, using a Panda "Texture" object. The image is always facing the +viewer. + +parameters: + Texture texture : // a Panda "Texture" object to use as the sprite image + Colorf color : 4-vector(RGBA), ([0,1], [0,1], [0,1], [0,1]) // TODO: what is this for? maybe alpha... + bool xScaleFlag : // if true, x scale is interpolated over particle's life; if false, stays as start_X_Scale + bool yScaleFlag : // if true, y scale is interpolated over particle's life; if false, stays as start_Y_Scale + bool animAngleFlag : // if true, particles that are set to spin on the Z axis will spin appropriately + float initial_X_Scale : [0,inf) // initial X scaling factor + float final_X_Scale : [0,inf) // final X scaling factor, if interpolation is enabled (see xScaleFlag) + float initial_Y_Scale : [0,inf) // initial Y scaling factor + float final_Y_Scale : [0,inf) // final Y scaling factor, if interpolation is enabled (see yScaleFlag) + float nonAnimatedTheta : // if animAngleFlag is false, this sets the counterclockwise Z rotation of all sprites, in degrees + enum alphaBlendMethod : {LINEAR, CUBIC} // sets the interpolation blend method for X and Y scaling + bool alphaDisable : // if true, alpha blending is disabled + +-------------------- +GeomParticleRenderer +-------------------- +CLASS: GeomParticleRenderer + +renders particles as full 3D objects + +parameters: + Node* geomNode : a geometry scene graph node (?) + + +======================== +Particle System Managers +======================== +CLASS: ParticleSystemManager + +Particle system managers hide the details of using particle systems from the application. Once a particle +system is created, it is recommended to attach it to a ParticleSystemManager object. Any number of particle +systems can be attached to a single ParticleSystemManager. + +Particle system managers have the following methods: + void attach_particlesystem(ParticleSystem *ps); // attach a particle system to this manager + void remove_particlesystem(ParticleSystem *ps); // un-attach a particle system from this manager + void clear(void); // un-attach all particle systems from this manager + void do_particles(float dt); // update all attached particle systems for "dt" seconds of elapsed time + +Particle system managers have the following parameter: + int frameStepping : [1..inf) // particle systems will be rendered once every frameStepping calls to do_particles() + // (automatic default is 1, or "render on every call to do_particles()") diff --git a/panda/src/particlesystem/pointEmitter.I b/panda/src/particlesystem/pointEmitter.I index b1425946ad..ef5719f7ff 100644 --- a/panda/src/particlesystem/pointEmitter.I +++ b/panda/src/particlesystem/pointEmitter.I @@ -9,16 +9,11 @@ // Description : point setting //////////////////////////////////////////////////////////////////// INLINE void PointEmitter:: -set_point(const LPoint3f& p) { - _point = p; +set_location(const LPoint3f& p) { + _location = p; } -//////////////////////////////////////////////////////////////////// -// Function : set_launch_vec -// Access : public -// Description : launch_vec setting -//////////////////////////////////////////////////////////////////// -INLINE void PointEmitter:: -set_launch_vec(const LVector3f &v) { - _launch_vec = v; +INLINE LPoint3f PointEmitter:: +get_location(void) const { + return _location; } diff --git a/panda/src/particlesystem/pointEmitter.cxx b/panda/src/particlesystem/pointEmitter.cxx index beb1e3392a..2bf618afee 100644 --- a/panda/src/particlesystem/pointEmitter.cxx +++ b/panda/src/particlesystem/pointEmitter.cxx @@ -1,4 +1,4 @@ -// Filename: pointEmitter.cxx +// Filename: pointEmitter.C // Created by: charles (22Jun00) // //////////////////////////////////////////////////////////////////// @@ -13,8 +13,7 @@ PointEmitter:: PointEmitter(void) : BaseParticleEmitter() { - _point.set(0.0f, 0.0f, 0.0f); - _launch_vec.set(0, 0, 0); + _location.set(0.0f, 0.0f, 0.0f); } //////////////////////////////////////////////////////////////////// @@ -25,8 +24,7 @@ PointEmitter(void) : PointEmitter:: PointEmitter(const PointEmitter ©) : BaseParticleEmitter(copy) { - _point = copy._point; - _launch_vec = copy._launch_vec; + _location = copy._location; } //////////////////////////////////////////////////////////////////// @@ -49,13 +47,21 @@ make_copy(void) { } //////////////////////////////////////////////////////////////////// -// Function : PointEmitter::create_particle_location +// Function : PointEmitter::assign_initial_position // Access : Public -// Description : Generates a location on the point +// Description : Generates a location for a new particle //////////////////////////////////////////////////////////////////// void PointEmitter:: -assign_initial_values(LPoint3f& pos, LVector3f& vel) -{ - pos = _point; - vel = _launch_vec; +assign_initial_position(LPoint3f& pos) { + pos = _location; +} + +//////////////////////////////////////////////////////////////////// +// Function : PointEmitter::assign_initial_velocity +// Access : Public +// Description : Generates a velocity for a new particle +//////////////////////////////////////////////////////////////////// +void PointEmitter:: +assign_initial_velocity(LVector3f& vel) { + vel.set(0,0,0); } diff --git a/panda/src/particlesystem/pointEmitter.h b/panda/src/particlesystem/pointEmitter.h index 725e626ac8..c011caabe0 100644 --- a/panda/src/particlesystem/pointEmitter.h +++ b/panda/src/particlesystem/pointEmitter.h @@ -15,10 +15,10 @@ //////////////////////////////////////////////////////////////////// class EXPCL_PANDAPHYSICS PointEmitter : public BaseParticleEmitter { private: - LPoint3f _point; - LVector3f _launch_vec; - - virtual void assign_initial_values(LPoint3f& pos, LVector3f& vel); + LPoint3f _location; + + virtual void assign_initial_position(LPoint3f& pos); + virtual void assign_initial_velocity(LVector3f& vel); public: PointEmitter(void); @@ -26,9 +26,9 @@ public: virtual ~PointEmitter(void); virtual BaseParticleEmitter *make_copy(void); - - INLINE void set_point(const LPoint3f& p); - INLINE void set_launch_vec(const LVector3f &v); + + INLINE void set_location(const LPoint3f& p); + INLINE LPoint3f get_location(void) const; }; #include "pointEmitter.I" diff --git a/panda/src/particlesystem/pointParticle.cxx b/panda/src/particlesystem/pointParticle.cxx index d1258922ab..7e4c92095a 100644 --- a/panda/src/particlesystem/pointParticle.cxx +++ b/panda/src/particlesystem/pointParticle.cxx @@ -1,4 +1,4 @@ -// Filename: pointParticle.cxx +// Filename: pointParticle.C // Created by: charles (19Jun00) // //////////////////////////////////////////////////////////////////// diff --git a/panda/src/particlesystem/pointParticleFactory.cxx b/panda/src/particlesystem/pointParticleFactory.cxx index c9e285128b..bed3773694 100644 --- a/panda/src/particlesystem/pointParticleFactory.cxx +++ b/panda/src/particlesystem/pointParticleFactory.cxx @@ -1,4 +1,4 @@ -// Filename: pointParticleFactory.cxx +// Filename: pointParticleFactory.C // Created by: charles (05Jul00) // //////////////////////////////////////////////////////////////////// diff --git a/panda/src/particlesystem/pointParticleRenderer.I b/panda/src/particlesystem/pointParticleRenderer.I index 404cefbce1..71d1866874 100644 --- a/panda/src/particlesystem/pointParticleRenderer.I +++ b/panda/src/particlesystem/pointParticleRenderer.I @@ -7,7 +7,6 @@ // Function : set_point_size // Access : Public //////////////////////////////////////////////////////////////////// - INLINE void PointParticleRenderer:: set_point_size(float point_size) { _point_primitive->set_size(point_size); @@ -15,30 +14,27 @@ set_point_size(float point_size) { } //////////////////////////////////////////////////////////////////// -// Function : set_color1 +// Function : set_start_color // Access : Public //////////////////////////////////////////////////////////////////// - INLINE void PointParticleRenderer:: -set_color1(const Colorf& c1) { - _color1 = c1; +set_start_color(const Colorf& sc) { + _start_color = sc; } //////////////////////////////////////////////////////////////////// -// Function : set_color2 +// Function : set_end_color // Access : Public //////////////////////////////////////////////////////////////////// - INLINE void PointParticleRenderer:: -set_color2(const Colorf& c2) { - _color2 = c2; +set_end_color(const Colorf& ec) { + _end_color = ec; } //////////////////////////////////////////////////////////////////// // Function : set_blend_type // Access : Public //////////////////////////////////////////////////////////////////// - INLINE void PointParticleRenderer:: set_blend_type(PointParticleBlendType bt) { _blend_type = bt; @@ -48,7 +44,6 @@ set_blend_type(PointParticleBlendType bt) { // Function : set_blend_method // Access : Public //////////////////////////////////////////////////////////////////// - INLINE void PointParticleRenderer:: set_blend_method(ParticleRendererBlendMethod bm) { _blend_method = bm; @@ -58,37 +53,33 @@ set_blend_method(ParticleRendererBlendMethod bm) { // Function : get_point_size // Access : Public //////////////////////////////////////////////////////////////////// - INLINE float PointParticleRenderer:: get_point_size(void) const { return _point_size; } //////////////////////////////////////////////////////////////////// -// Function : get_color1 +// Function : get_start_color // Access : Public //////////////////////////////////////////////////////////////////// - INLINE const Colorf& PointParticleRenderer:: -get_color1(void) const { - return _color1; +get_start_color(void) const { + return _start_color; } //////////////////////////////////////////////////////////////////// -// Function : get_color2 +// Function : get_end_color // Access : Public //////////////////////////////////////////////////////////////////// - INLINE const Colorf& PointParticleRenderer:: -get_color2(void) const { - return _color2; +get_end_color(void) const { + return _end_color; } //////////////////////////////////////////////////////////////////// // Function : get_blend_type // Access : Public //////////////////////////////////////////////////////////////////// - INLINE PointParticleBlendType PointParticleRenderer:: get_blend_type(void) const { return _blend_type; @@ -98,7 +89,6 @@ get_blend_type(void) const { // Function : get_blend_method // Access : Public //////////////////////////////////////////////////////////////////// - INLINE ParticleRendererBlendMethod PointParticleRenderer:: get_blend_method(void) const { return _blend_method; diff --git a/panda/src/particlesystem/pointParticleRenderer.cxx b/panda/src/particlesystem/pointParticleRenderer.cxx index ca6093406c..96255c8fd6 100644 --- a/panda/src/particlesystem/pointParticleRenderer.cxx +++ b/panda/src/particlesystem/pointParticleRenderer.cxx @@ -1,4 +1,4 @@ -// Filename: pointParticleRenderer.cxx +// Filename: pointParticleRenderer.C // Created by: charles (20Jun00) // //////////////////////////////////////////////////////////////////// @@ -13,15 +13,15 @@ //////////////////////////////////////////////////////////////////// PointParticleRenderer:: -PointParticleRenderer(ParticleRendererAlphaDecay ad, +PointParticleRenderer(ParticleRendererAlphaMode am, float point_size, PointParticleBlendType bt, ParticleRendererBlendMethod bm, - const Colorf& c1, const Colorf& c2) : + const Colorf& sc, const Colorf& ec) : _point_size(point_size), - _blend_type(bt), _blend_method(bm), - _color1(c1), _color2(c2), - BaseParticleRenderer(ad) { + _blend_type(bt), _blend_method(bm), + _start_color(sc), _end_color(ec), + BaseParticleRenderer(am) { _point_primitive = new GeomPoint; init_geoms(); @@ -40,8 +40,8 @@ PointParticleRenderer(const PointParticleRenderer& copy) : _blend_type = copy._blend_type; _blend_method = copy._blend_method; - _color1 = copy._color1; - _color2 = copy._color2; + _start_color = copy._start_color; + _end_color = copy._end_color; _point_primitive = new GeomPoint; init_geoms(); } @@ -141,7 +141,7 @@ create_color(const BaseParticle *p) { //// Constant solid color case PP_ONE_COLOR: - color = _color1; + color = _start_color; break; //// Blending colors based on life @@ -152,9 +152,9 @@ create_color(const BaseParticle *p) { have_alpha_t = true; if (_blend_method == PP_BLEND_CUBIC) - life_t = cubic_smooth(life_t); + life_t = CUBIC_T(life_t); - color = color_lerp(life_t, _color1, _color2); + color = LERP(life_t, _start_color, _end_color); break; @@ -164,21 +164,20 @@ create_color(const BaseParticle *p) { vel_t = p->get_parameterized_vel(); if (_blend_method == PP_BLEND_CUBIC) - vel_t = cubic_smooth(vel_t); + vel_t = CUBIC_T(vel_t); - color = color_lerp(vel_t, _color1, _color2); + color = LERP(vel_t, _start_color, _end_color); break; } // handle alpha channel - if (!((_alpha_decay == PR_NO_ALPHA) || (_alpha_decay == PR_ALPHA_USER) || - (_alpha_decay == PR_ALPHA_INVALID))) { + if (!((_alpha_mode == PR_ALPHA_NONE) || (_alpha_mode == PR_ALPHA_USER))) { if (have_alpha_t == false) alpha_linear_t = p->get_parameterized_age(); - if (_alpha_decay == PR_ALPHA_OUT) + if (_alpha_mode == PR_ALPHA_OUT) color[3] = 1.0f - alpha_linear_t; else color[3] = alpha_linear_t; diff --git a/panda/src/particlesystem/pointParticleRenderer.h b/panda/src/particlesystem/pointParticleRenderer.h index 14c798c00f..d8be80cef9 100644 --- a/panda/src/particlesystem/pointParticleRenderer.h +++ b/panda/src/particlesystem/pointParticleRenderer.h @@ -31,7 +31,7 @@ enum PointParticleBlendType { class EXPCL_PANDAPHYSICS PointParticleRenderer : public BaseParticleRenderer { private: - Colorf _color1, _color2; + Colorf _start_color, _end_color; float _point_size; PT(GeomPoint) _point_primitive; @@ -58,26 +58,26 @@ private: public: PointParticleRenderer(const PointParticleRenderer& copy); - PointParticleRenderer(ParticleRendererAlphaDecay ad = PR_NO_ALPHA, + PointParticleRenderer(ParticleRendererAlphaMode ad = PR_ALPHA_NONE, float point_size = 1.0f, PointParticleBlendType bt = PP_ONE_COLOR, ParticleRendererBlendMethod bm = PP_NO_BLEND, - const Colorf& c1 = Colorf(1.0f, 1.0f, 1.0f, 1.0f), - const Colorf& c2 = Colorf(1.0f, 1.0f, 1.0f, 1.0f)); + const Colorf& sc = Colorf(1.0f, 1.0f, 1.0f, 1.0f), + const Colorf& ec = Colorf(1.0f, 1.0f, 1.0f, 1.0f)); virtual ~PointParticleRenderer(void); virtual BaseParticleRenderer *make_copy(void); INLINE void set_point_size(float point_size); - INLINE void set_color1(const Colorf& c1); - INLINE void set_color2(const Colorf& c2); + INLINE void set_start_color(const Colorf& sc); + INLINE void set_end_color(const Colorf& ec); INLINE void set_blend_type(PointParticleBlendType bt); INLINE void set_blend_method(ParticleRendererBlendMethod bm); INLINE float get_point_size(void) const; - INLINE const Colorf& get_color1(void) const; - INLINE const Colorf& get_color2(void) const; + INLINE const Colorf& get_start_color(void) const; + INLINE const Colorf& get_end_color(void) const; INLINE PointParticleBlendType get_blend_type(void) const; INLINE ParticleRendererBlendMethod get_blend_method(void) const; }; diff --git a/panda/src/particlesystem/rectangleEmitter.I b/panda/src/particlesystem/rectangleEmitter.I index d9bb830bc8..7bd0849998 100644 --- a/panda/src/particlesystem/rectangleEmitter.I +++ b/panda/src/particlesystem/rectangleEmitter.I @@ -4,23 +4,41 @@ //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// -// Function : set_boundaries +// Function : set_min_bound // Access : public // Description : boundary set //////////////////////////////////////////////////////////////////// - INLINE void RectangleEmitter:: -set_boundaries(const LPoint2f& vmin, const LPoint2f& vmax) { - _vmin = vmin; _vmax = vmax; +set_min_bound(const LPoint2f& vmin) { + _vmin = vmin; } //////////////////////////////////////////////////////////////////// -// Function : set_launch_vec +// Function : set_max_bound // Access : public // Description : boundary set //////////////////////////////////////////////////////////////////// - INLINE void RectangleEmitter:: -set_launch_vec(const LVector3f& lv) { - _launch_vec = lv; +set_max_bound(const LPoint2f& vmax) { + _vmax = vmax; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_min_bound +// Access : public +// Description : boundary get +//////////////////////////////////////////////////////////////////// +INLINE LPoint2f RectangleEmitter:: +get_min_bound(void) const { + return _vmin; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_max_bound +// Access : public +// Description : boundary get +//////////////////////////////////////////////////////////////////// +INLINE LPoint2f RectangleEmitter:: +get_max_bound(void) const { + return _vmax; } diff --git a/panda/src/particlesystem/rectangleEmitter.cxx b/panda/src/particlesystem/rectangleEmitter.cxx index dbd9a794b2..ca6138862f 100644 --- a/panda/src/particlesystem/rectangleEmitter.cxx +++ b/panda/src/particlesystem/rectangleEmitter.cxx @@ -1,4 +1,4 @@ -// Filename: rectangleEmitter.cxx +// Filename: rectangleEmitter.C // Created by: charles (22Jun00) // //////////////////////////////////////////////////////////////////// @@ -15,7 +15,6 @@ RectangleEmitter(void) : BaseParticleEmitter() { _vmin.set(0.0f, 0.0f); _vmax.set(0.0f, 0.0f); - _launch_vec.set(0.0f, 0.0f, 0.0f); } //////////////////////////////////////////////////////////////////// @@ -28,7 +27,6 @@ RectangleEmitter(const RectangleEmitter ©) : BaseParticleEmitter(copy) { _vmin = copy._vmin; _vmax = copy._vmax; - _launch_vec = copy._launch_vec; } //////////////////////////////////////////////////////////////////// @@ -51,15 +49,14 @@ make_copy(void) { } //////////////////////////////////////////////////////////////////// -// Function : RectangleEmitter::create_particle_location +// Function : RectangleEmitter::assign_initial_position // Access : Public -// Description : Generates a location on the rectangle +// Description : Generates a location for a new particle //////////////////////////////////////////////////////////////////// void RectangleEmitter:: -assign_initial_values(LPoint3f& pos, LVector3f& vel) -{ - float t_x = bounded_rand(); - float t_y = bounded_rand(); +assign_initial_position(LPoint3f& pos) { + float t_x = NORMALIZED_RAND(); + float t_y = NORMALIZED_RAND(); LVector2f v_diff = _vmax - _vmin; @@ -67,5 +64,14 @@ assign_initial_values(LPoint3f& pos, LVector3f& vel) float lerp_y = _vmin[1] + t_y * v_diff[1]; pos.set(lerp_x, lerp_y, 0.0f); - vel = _launch_vec; +} + +//////////////////////////////////////////////////////////////////// +// Function : RectangleEmitter::assign_initial_velocity +// Access : Public +// Description : Generates a velocity for a new particle +//////////////////////////////////////////////////////////////////// +void RectangleEmitter:: +assign_initial_velocity(LVector3f& vel) { + vel.set(0.0f,0.0f,0.0f); } diff --git a/panda/src/particlesystem/rectangleEmitter.h b/panda/src/particlesystem/rectangleEmitter.h index c772e46a74..9acdea79a5 100644 --- a/panda/src/particlesystem/rectangleEmitter.h +++ b/panda/src/particlesystem/rectangleEmitter.h @@ -16,9 +16,9 @@ class EXPCL_PANDAPHYSICS RectangleEmitter : public BaseParticleEmitter { private: LPoint2f _vmin, _vmax; - LVector3f _launch_vec; - - virtual void assign_initial_values(LPoint3f& pos, LVector3f& vel); + + virtual void assign_initial_position(LPoint3f& pos); + virtual void assign_initial_velocity(LVector3f& vel); public: RectangleEmitter(void); @@ -26,9 +26,12 @@ public: virtual ~RectangleEmitter(void); virtual BaseParticleEmitter *make_copy(void); - - INLINE void set_boundaries(const LPoint2f& vmin, const LPoint2f& vmax); - INLINE void set_launch_vec(const LVector3f& lv); + + INLINE void set_min_bound(const LPoint2f& vmin); + INLINE void set_max_bound(const LPoint2f& vmax); + + INLINE LPoint2f get_min_bound(void) const; + INLINE LPoint2f get_max_bound(void) const; }; #include "rectangleEmitter.I" diff --git a/panda/src/particlesystem/ringEmitter.I b/panda/src/particlesystem/ringEmitter.I index ccb0139b48..1fc2e14344 100644 --- a/panda/src/particlesystem/ringEmitter.I +++ b/panda/src/particlesystem/ringEmitter.I @@ -1,6 +1,6 @@ // Filename: ringEmitter.I // Created by: charles (26Jun00) -// +// //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// @@ -10,28 +10,39 @@ //////////////////////////////////////////////////////////////////// INLINE void RingEmitter:: -set_radius(float r) { - _radius = r; +set_radius(float r) { + _radius = r; } //////////////////////////////////////////////////////////////////// -// Function : set_aoe +// Function : set_angle // Access : public // Description : angle of elevation set //////////////////////////////////////////////////////////////////// INLINE void RingEmitter:: -set_aoe(float aoe) { - _aoe = aoe; +set_angle(float angle) { + _aoe = angle; } //////////////////////////////////////////////////////////////////// -// Function : set_magnitude +// Function : get_radius // Access : public -// Description : magnitude set +// Description : radius get //////////////////////////////////////////////////////////////////// -INLINE void RingEmitter:: -set_magnitude(float m) { - _mag = m; +INLINE float RingEmitter:: +get_radius(void) const { + return _radius; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_angle +// Access : public +// Description : angle of elevation get +//////////////////////////////////////////////////////////////////// + +INLINE float RingEmitter:: +get_angle(void) const { + return _aoe; } diff --git a/panda/src/particlesystem/ringEmitter.cxx b/panda/src/particlesystem/ringEmitter.cxx index b4a76edd2c..82e10280e9 100644 --- a/panda/src/particlesystem/ringEmitter.cxx +++ b/panda/src/particlesystem/ringEmitter.cxx @@ -1,4 +1,4 @@ -// Filename: ringEmitter.cxx +// Filename: ringEmitter.C // Created by: charles (22Jun00) // //////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ //////////////////////////////////////////////////////////////////// RingEmitter:: RingEmitter(void) : - _radius(0.0f), _aoe(0.0f), _mag(0.0f) { + _radius(0.0f), _aoe(0.0f) { } //////////////////////////////////////////////////////////////////// @@ -25,7 +25,9 @@ RingEmitter(const RingEmitter ©) : BaseParticleEmitter(copy) { _radius = copy._radius; _aoe = copy._aoe; - _mag = copy._mag; + + _sin_theta = copy._sin_theta; + _cos_theta = copy._cos_theta; } //////////////////////////////////////////////////////////////////// @@ -48,28 +50,42 @@ make_copy(void) { } //////////////////////////////////////////////////////////////////// -// Function : RingEmitter::create_particle_location +// Function : DiscEmitter::assign_initial_position // Access : Public -// Description : Generates a location on the ring +// Description : Generates a location for a new particle //////////////////////////////////////////////////////////////////// void RingEmitter:: -assign_initial_values(LPoint3f& pos, LVector3f& vel) -{ - float theta = bounded_rand() * 2.0f * MathNumbers::pi; - float cos_theta = cosf(theta); - float sin_theta = sinf(theta); +assign_initial_position(LPoint3f& pos) { + float theta = NORMALIZED_RAND() * 2.0f * MathNumbers::pi; + _cos_theta = cosf(theta); + _sin_theta = sinf(theta); - float new_x = cos_theta * _radius; - float new_y = sin_theta * _radius; + float new_x = _cos_theta * _radius; + float new_y = _sin_theta * _radius; pos.set(new_x, new_y, 0.0f); +} - float vel_z = _mag * sinf(_aoe * (MathNumbers::pi / 180.0f)); - float abs_diff = fabs((_mag *_mag) - (vel_z * vel_z)); +//////////////////////////////////////////////////////////////////// +// Function : DiscEmitter::assign_initial_velocity +// Access : Public +// Description : Generates a velocity for a new particle +//////////////////////////////////////////////////////////////////// +void RingEmitter:: +assign_initial_velocity(LVector3f& vel) { + float vel_z = sinf(_aoe * (MathNumbers::pi / 180.0f)); + float abs_diff = fabs(1.0f - (vel_z * vel_z)); float root_mag_minus_z_squared = sqrtf(abs_diff); - float vel_x = cos_theta * root_mag_minus_z_squared; - float vel_y = sin_theta * root_mag_minus_z_squared; + float vel_x = _cos_theta * root_mag_minus_z_squared; + float vel_y = _sin_theta * root_mag_minus_z_squared; + + // quick and dirty + if((_aoe > 90.0f) && (_aoe < 270.0f)) + { + vel_x = -vel_x; + vel_y = -vel_y; + } vel.set(vel_x, vel_y, vel_z); } diff --git a/panda/src/particlesystem/ringEmitter.h b/panda/src/particlesystem/ringEmitter.h index 5af3eec64c..08edbafc1d 100644 --- a/panda/src/particlesystem/ringEmitter.h +++ b/panda/src/particlesystem/ringEmitter.h @@ -19,7 +19,14 @@ private: float _aoe; // angle of elevation float _mag; - virtual void assign_initial_values(LPoint3f& pos, LVector3f& vel); + /////////////////////////////// + // scratch variables that carry over from position calc to velocity calc + float _sin_theta; + float _cos_theta; + /////////////////////////////// + + virtual void assign_initial_position(LPoint3f& pos); + virtual void assign_initial_velocity(LVector3f& vel); public: RingEmitter(void); @@ -29,8 +36,10 @@ public: virtual BaseParticleEmitter *make_copy(void); INLINE void set_radius(float r); - INLINE void set_aoe(float aoe); - INLINE void set_magnitude(float m); + INLINE void set_angle(float angle); + + INLINE float get_radius(void) const; + INLINE float get_angle(void) const; }; #include "ringEmitter.I" diff --git a/panda/src/particlesystem/sparkleParticleRenderer.I b/panda/src/particlesystem/sparkleParticleRenderer.I index ad5af90093..fc2a13a8b1 100644 --- a/panda/src/particlesystem/sparkleParticleRenderer.I +++ b/panda/src/particlesystem/sparkleParticleRenderer.I @@ -31,21 +31,21 @@ set_life_scale(SparkleParticleLifeScale ls) { } //////////////////////////////////////////////////////////////////// -// Function : set_birth_mag +// Function : set_birth_radius // Access : public //////////////////////////////////////////////////////////////////// INLINE void SparkleParticleRenderer:: -set_birth_mag(float mag) { - _birth_mag = mag; +set_birth_radius(float radius) { + _birth_radius = radius; } //////////////////////////////////////////////////////////////////// -// Function : set_death_mag +// Function : set_death_radius // Access : public //////////////////////////////////////////////////////////////////// INLINE void SparkleParticleRenderer:: -set_death_mag(float mag) { - _death_mag = mag; +set_death_radius(float radius) { + _death_radius = radius; } //////////////////////////////////////////////////////////////////// @@ -76,33 +76,33 @@ get_life_scale(void) const { } //////////////////////////////////////////////////////////////////// -// Function : get_birth_mag +// Function : get_birth_radius // Access : public //////////////////////////////////////////////////////////////////// INLINE float SparkleParticleRenderer:: -get_birth_mag(void) const { - return _birth_mag; +get_birth_radius(void) const { + return _birth_radius; } //////////////////////////////////////////////////////////////////// -// Function : get_death_mag +// Function : get_death_radius // Access : public //////////////////////////////////////////////////////////////////// INLINE float SparkleParticleRenderer:: -get_death_mag(void) const { - return _death_mag; +get_death_radius(void) const { + return _death_radius; } //////////////////////////////////////////////////////////////////// -// Function : get_magnitude +// Function : get_radius // Access : public //////////////////////////////////////////////////////////////////// INLINE float SparkleParticleRenderer:: -get_magnitude(BaseParticle *bp) { +get_radius(BaseParticle *bp) { if (_life_scale == SP_NO_SCALE) - return _birth_mag; + return _birth_radius; else { - float s_x = cubic_smooth(bp->get_parameterized_age()); - return lerp(s_x, _birth_mag, _death_mag); + float s_x = CUBIC_T(bp->get_parameterized_age()); + return LERP(s_x, _birth_radius, _death_radius); } } diff --git a/panda/src/particlesystem/sparkleParticleRenderer.cxx b/panda/src/particlesystem/sparkleParticleRenderer.cxx index 2b0dede881..0f8681e37c 100644 --- a/panda/src/particlesystem/sparkleParticleRenderer.cxx +++ b/panda/src/particlesystem/sparkleParticleRenderer.cxx @@ -1,4 +1,4 @@ -// Filename: sparkleParticleRenderer.cxx +// Filename: sparkleParticleRenderer.C // Created by: charles (27Jun00) // //////////////////////////////////////////////////////////////////// @@ -17,8 +17,8 @@ SparkleParticleRenderer:: SparkleParticleRenderer(void) : _center_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f)), _edge_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f)), - _birth_mag(0.1f), _death_mag(0.1f), - BaseParticleRenderer(PR_NO_ALPHA) { + _birth_radius(0.1f), _death_radius(0.1f), + BaseParticleRenderer(PR_ALPHA_NONE) { _line_primitive = new GeomLine; init_geoms(); } @@ -31,12 +31,12 @@ SparkleParticleRenderer(void) : SparkleParticleRenderer:: SparkleParticleRenderer(const Colorf& center, const Colorf& edge, - float birth_mag, float death_mag, + float birth_radius, float death_radius, SparkleParticleLifeScale life_scale, - ParticleRendererAlphaDecay alpha_decay) : - _center_color(center), _edge_color(edge), _birth_mag(birth_mag), - _death_mag(death_mag), _life_scale(life_scale), - BaseParticleRenderer(alpha_decay) { + ParticleRendererAlphaMode alpha_mode) : + _center_color(center), _edge_color(edge), _birth_radius(birth_radius), + _death_radius(death_radius), _life_scale(life_scale), + BaseParticleRenderer(alpha_mode) { _line_primitive = new GeomLine; init_geoms(); } @@ -52,8 +52,8 @@ SparkleParticleRenderer(const SparkleParticleRenderer& copy) : BaseParticleRenderer(copy) { _center_color = copy._center_color; _edge_color = copy._edge_color; - _birth_mag = copy._birth_mag; - _death_mag = copy._death_mag; + _birth_radius = copy._birth_radius; + _death_radius = copy._death_radius; _life_scale = copy._life_scale; _line_primitive = new GeomLine; @@ -186,8 +186,8 @@ render(vector< PT(PhysicsObject) >& po_vector, int ttl_particles) { // draw the particle. - float mag = get_magnitude(cur_particle); - float neg_mag = -mag; + float radius = get_radius(cur_particle); + float neg_radius = -radius; float alpha; LPoint3f pos = cur_particle->get_position(); @@ -196,10 +196,10 @@ render(vector< PT(PhysicsObject) >& po_vector, int ttl_particles) { // handle alpha - if (_alpha_decay != PR_NO_ALPHA) { + if (_alpha_mode != PR_ALPHA_NONE) { alpha = cur_particle->get_parameterized_age(); - if (_alpha_decay == PR_ALPHA_OUT) + if (_alpha_mode == PR_ALPHA_OUT) alpha = 1.0f - alpha; center_color[3] = alpha; @@ -209,17 +209,17 @@ render(vector< PT(PhysicsObject) >& po_vector, int ttl_particles) { // 6 lines coming from the center point. *cur_vert++ = pos; - *cur_vert++ = pos + Vertexf(mag, 0.0f, 0.0f); + *cur_vert++ = pos + Vertexf(radius, 0.0f, 0.0f); *cur_vert++ = pos; - *cur_vert++ = pos + Vertexf(neg_mag, 0.0f, 0.0f); + *cur_vert++ = pos + Vertexf(neg_radius, 0.0f, 0.0f); *cur_vert++ = pos; - *cur_vert++ = pos + Vertexf(0.0f, mag, 0.0f); + *cur_vert++ = pos + Vertexf(0.0f, radius, 0.0f); *cur_vert++ = pos; - *cur_vert++ = pos + Vertexf(0.0f, neg_mag, 0.0f); + *cur_vert++ = pos + Vertexf(0.0f, neg_radius, 0.0f); *cur_vert++ = pos; - *cur_vert++ = pos + Vertexf(0.0f, 0.0f, mag); + *cur_vert++ = pos + Vertexf(0.0f, 0.0f, radius); *cur_vert++ = pos; - *cur_vert++ = pos + Vertexf(0.0f, 0.0f, neg_mag); + *cur_vert++ = pos + Vertexf(0.0f, 0.0f, neg_radius); *cur_color++ = center_color; *cur_color++ = edge_color; diff --git a/panda/src/particlesystem/sparkleParticleRenderer.h b/panda/src/particlesystem/sparkleParticleRenderer.h index 8db5ed611a..c80f8fbb33 100644 --- a/panda/src/particlesystem/sparkleParticleRenderer.h +++ b/panda/src/particlesystem/sparkleParticleRenderer.h @@ -30,8 +30,8 @@ private: Colorf _center_color; Colorf _edge_color; - float _birth_mag; - float _death_mag; + float _birth_radius; + float _death_radius; PT(GeomLine) _line_primitive; @@ -43,7 +43,7 @@ private: SparkleParticleLifeScale _life_scale; LPoint3f _aabb_min, _aabb_max; - INLINE float get_magnitude(BaseParticle *bp); + INLINE float get_radius(BaseParticle *bp); virtual void birth_particle(int index); virtual void kill_particle(int index); @@ -58,10 +58,10 @@ public: SparkleParticleRenderer(const SparkleParticleRenderer& copy); SparkleParticleRenderer(const Colorf& center, const Colorf& edge, - float birth_mag, - float death_mag, + float birth_radius, + float death_radius, SparkleParticleLifeScale life_scale, - ParticleRendererAlphaDecay alpha_decay); + ParticleRendererAlphaMode alpha_mode); virtual ~SparkleParticleRenderer(void); @@ -69,15 +69,15 @@ public: INLINE void set_center_color(const Colorf& c); INLINE void set_edge_color(const Colorf& c); + INLINE void set_birth_radius(float radius); + INLINE void set_death_radius(float radius); INLINE void set_life_scale(SparkleParticleLifeScale); - INLINE void set_birth_mag(float mag); - INLINE void set_death_mag(float mag); INLINE const Colorf& get_center_color(void) const; INLINE const Colorf& get_edge_color(void) const; + INLINE float get_birth_radius(void) const; + INLINE float get_death_radius(void) const; INLINE SparkleParticleLifeScale get_life_scale(void) const; - INLINE float get_birth_mag(void) const; - INLINE float get_death_mag(void) const; }; #include "sparkleParticleRenderer.I" diff --git a/panda/src/particlesystem/sphereSurfaceEmitter.I b/panda/src/particlesystem/sphereSurfaceEmitter.I index 202ffd4f90..d961a51b90 100644 --- a/panda/src/particlesystem/sphereSurfaceEmitter.I +++ b/panda/src/particlesystem/sphereSurfaceEmitter.I @@ -13,9 +13,16 @@ INLINE void SphereSurfaceEmitter:: set_radius(float r) { - if (r == 0.0f) - particlesystem_cat.error() << "SphereSurfaceEmitter cannot have " - << "radius of 0." << endl; - else - _radius = r; + _radius = r; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_radius +// Access : public +// Description : radius get +//////////////////////////////////////////////////////////////////// + +INLINE float SphereSurfaceEmitter:: +get_radius(void) const { + return _radius; } diff --git a/panda/src/particlesystem/sphereSurfaceEmitter.cxx b/panda/src/particlesystem/sphereSurfaceEmitter.cxx index b4495732c0..84ff57658f 100644 --- a/panda/src/particlesystem/sphereSurfaceEmitter.cxx +++ b/panda/src/particlesystem/sphereSurfaceEmitter.cxx @@ -1,4 +1,4 @@ -// Filename: sphereSurfaceEmitter.cxx +// Filename: sphereSurfaceEmitter.C // Created by: charles (22Jun00) // //////////////////////////////////////////////////////////////////// @@ -46,20 +46,27 @@ make_copy(void) { } //////////////////////////////////////////////////////////////////// -// Function : SphereSurfaceEmitter::create_particle_location +// Function : SphereSurfaceEmitter::assign_initial_position // Access : Public -// Description : Generates a location on the sphere +// Description : Generates a location for a new particle //////////////////////////////////////////////////////////////////// void SphereSurfaceEmitter:: -assign_initial_values(LPoint3f& pos, LVector3f& vel) -{ +assign_initial_position(LPoint3f& pos) { float z, theta, r; - float t; - z = _radius - (2.0f * _radius * bounded_rand()); + z = SPREAD(_radius); r = sqrtf((_radius * _radius) - (z * z)); - theta = bounded_rand() * 2.0f * MathNumbers::pi; + theta = NORMALIZED_RAND() * 2.0f * MathNumbers::pi; pos.set(r * cosf(theta), r * sinf(theta), z); - vel = pos / _radius; +} + +//////////////////////////////////////////////////////////////////// +// Function : SphereSurfaceEmitter::assign_initial_velocity +// Access : Public +// Description : Generates a velocity for a new particle +//////////////////////////////////////////////////////////////////// +void SphereSurfaceEmitter:: +assign_initial_velocity(LVector3f& vel) { + vel.set(0,0,0); } diff --git a/panda/src/particlesystem/sphereSurfaceEmitter.h b/panda/src/particlesystem/sphereSurfaceEmitter.h index 17bb326791..df30ab579f 100644 --- a/panda/src/particlesystem/sphereSurfaceEmitter.h +++ b/panda/src/particlesystem/sphereSurfaceEmitter.h @@ -17,7 +17,8 @@ class EXPCL_PANDAPHYSICS SphereSurfaceEmitter : public BaseParticleEmitter { private: float _radius; - virtual void assign_initial_values(LPoint3f& pos, LVector3f& vel); + virtual void assign_initial_position(LPoint3f& pos); + virtual void assign_initial_velocity(LVector3f& vel); public: SphereSurfaceEmitter(void); @@ -27,6 +28,7 @@ public: virtual BaseParticleEmitter *make_copy(void); INLINE void set_radius(float r); + INLINE float get_radius(void) const; }; #include "sphereSurfaceEmitter.I" diff --git a/panda/src/particlesystem/sphereVolumeEmitter.I b/panda/src/particlesystem/sphereVolumeEmitter.I index d4e9915670..f5c97d3f02 100644 --- a/panda/src/particlesystem/sphereVolumeEmitter.I +++ b/panda/src/particlesystem/sphereVolumeEmitter.I @@ -13,9 +13,16 @@ INLINE void SphereVolumeEmitter:: set_radius(float r) { - if (r == 0.0f) - particlesystem_cat.error() << "SphereVolumeEmitter can not have " - << "radius of 0." << endl; - else - _radius = r; + _radius = r; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_radius +// Access : public +// Description : radius get +//////////////////////////////////////////////////////////////////// + +INLINE float SphereVolumeEmitter:: +get_radius(void) const { + return _radius; } diff --git a/panda/src/particlesystem/sphereVolumeEmitter.cxx b/panda/src/particlesystem/sphereVolumeEmitter.cxx index eadce01ce3..6758ebb23f 100644 --- a/panda/src/particlesystem/sphereVolumeEmitter.cxx +++ b/panda/src/particlesystem/sphereVolumeEmitter.cxx @@ -1,4 +1,4 @@ -// Filename: sphereVolumeEmitter.cxx +// Filename: sphereVolumeEmitter.C // Created by: charles (22Jun00) // //////////////////////////////////////////////////////////////////// @@ -24,6 +24,7 @@ SphereVolumeEmitter:: SphereVolumeEmitter(const SphereVolumeEmitter ©) : BaseParticleEmitter(copy) { _radius = copy._radius; + _particle_pos = copy._particle_pos; } //////////////////////////////////////////////////////////////////// @@ -46,29 +47,40 @@ make_copy(void) { } //////////////////////////////////////////////////////////////////// -// Function : SphereVolumeEmitter::create_particle_location +// Function : SphereVolumeEmitter::assign_initial_position // Access : Public -// Description : Generates a location in the sphere +// Description : Generates a location for a new particle //////////////////////////////////////////////////////////////////// void SphereVolumeEmitter:: -assign_initial_values(LPoint3f& pos, LVector3f& vel) -{ +assign_initial_position(LPoint3f& pos) { float z, theta, r; float t; - z = _radius - (2.0f * _radius * bounded_rand()); + z = SPREAD(_radius); r = sqrtf((_radius * _radius) - (z * z)); - theta = bounded_rand() * 2.0f * MathNumbers::pi; + theta = NORMALIZED_RAND() * 2.0f * MathNumbers::pi; - t = bounded_rand(); + t = NORMALIZED_RAND(); while (t == 0.0f) - t = bounded_rand(); + t = NORMALIZED_RAND(); float pos_x = r * cosf(theta) * t; float pos_y = r * sinf(theta) * t; float pos_z = z * t; - pos.set(pos_x, pos_y, pos_z); - vel = pos / _radius; + _particle_pos.set(pos_x, pos_y, pos_z); + pos = _particle_pos; +} + +//////////////////////////////////////////////////////////////////// +// Function : SphereVolumeEmitter::assign_initial_velocity +// Access : Public +// Description : Generates a velocity for a new particle +//////////////////////////////////////////////////////////////////// +void SphereVolumeEmitter:: +assign_initial_velocity(LVector3f& vel) { + // set velocity to [0..1] according to distance from center, + // along vector from center to position + vel = _particle_pos / _radius; } diff --git a/panda/src/particlesystem/sphereVolumeEmitter.h b/panda/src/particlesystem/sphereVolumeEmitter.h index bcd665e1d4..8bc2074147 100644 --- a/panda/src/particlesystem/sphereVolumeEmitter.h +++ b/panda/src/particlesystem/sphereVolumeEmitter.h @@ -17,15 +17,23 @@ class EXPCL_PANDAPHYSICS SphereVolumeEmitter : public BaseParticleEmitter { private: float _radius; - virtual void assign_initial_values(LPoint3f& pos, LVector3f& vel); - + /////////////////////////////// + // scratch variables that carry over from position calc to velocity calc + LPoint3f _particle_pos; + /////////////////////////////// + + virtual void assign_initial_position(LPoint3f& pos); + virtual void assign_initial_velocity(LVector3f& vel); + public: SphereVolumeEmitter(void); SphereVolumeEmitter(const SphereVolumeEmitter ©); virtual ~SphereVolumeEmitter(void); virtual BaseParticleEmitter *make_copy(void); + INLINE void set_radius(float r); + INLINE float get_radius(void) const; }; #include "sphereVolumeEmitter.I" diff --git a/panda/src/particlesystem/spriteParticleRenderer.I b/panda/src/particlesystem/spriteParticleRenderer.I index 0636393ded..0e69ff6665 100644 --- a/panda/src/particlesystem/spriteParticleRenderer.I +++ b/panda/src/particlesystem/spriteParticleRenderer.I @@ -12,50 +12,21 @@ set_texture(Texture *tex) { _sprite_primitive->set_texture(tex); } -//////////////////////////////////////////////////////////////////// -// Function : get_texture -// Access : public -//////////////////////////////////////////////////////////////////// -INLINE Texture *SpriteParticleRenderer:: -get_texture(void) const { - return _sprite_primitive->get_texture(); -} - -//////////////////////////////////////////////////////////////////// -// Function : set_alpha_disable -// Access : public -//////////////////////////////////////////////////////////////////// -INLINE void SpriteParticleRenderer:: -set_alpha_disable(bool ad) { - _sprite_primitive->set_alpha_disable(ad); -} - -//////////////////////////////////////////////////////////////////// -// Function : get_alpha_disable -// Access : public -//////////////////////////////////////////////////////////////////// -INLINE bool SpriteParticleRenderer:: -get_alpha_disable(void) const { - return _sprite_primitive->get_alpha_disable(); -} - //////////////////////////////////////////////////////////////////// // Function : set_color // Access : public //////////////////////////////////////////////////////////////////// INLINE void SpriteParticleRenderer:: -set_color(const Colorf& color) { +set_color(const Colorf &color) { _color = color; } //////////////////////////////////////////////////////////////////// -// Function : set_animation_flags +// Function : set_x_scale_flag // Access : public //////////////////////////////////////////////////////////////////// INLINE void SpriteParticleRenderer:: -set_animation_flags(bool animate_x_ratio, - bool animate_y_ratio, - bool animate_theta) { +set_x_scale_flag(bool animate_x_ratio) { if (animate_x_ratio == true && _animate_x_ratio == false) { _x_texel_array = PTA_float(_pool_size); _sprite_primitive->set_x_texel_ratio(_x_texel_array, G_PER_PRIM); @@ -66,7 +37,14 @@ set_animation_flags(bool animate_x_ratio, } _animate_x_ratio = animate_x_ratio; +} +//////////////////////////////////////////////////////////////////// +// Function : set_y_scale_flag +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE void SpriteParticleRenderer:: +set_y_scale_flag(bool animate_y_ratio) { if (animate_y_ratio == true && _animate_y_ratio == false) { _y_texel_array = PTA_float(_pool_size); _sprite_primitive->set_y_texel_ratio(_y_texel_array, G_PER_PRIM); @@ -77,7 +55,14 @@ set_animation_flags(bool animate_x_ratio, } _animate_y_ratio = animate_y_ratio; +} +//////////////////////////////////////////////////////////////////// +// Function : set_anim_angle_flag +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE void SpriteParticleRenderer:: +set_anim_angle_flag(bool animate_theta) { if (animate_theta == true && _animate_theta == false) { _theta_array = PTA_float(_pool_size); _sprite_primitive->set_thetas(_theta_array, G_PER_PRIM); @@ -91,25 +76,39 @@ set_animation_flags(bool animate_x_ratio, } //////////////////////////////////////////////////////////////////// -// Function : set_x_ratios +// Function : set_initial_x_scale // Access : public //////////////////////////////////////////////////////////////////// INLINE void SpriteParticleRenderer:: -set_x_ratios(float initial_x_texel_ratio, - float final_x_texel_ratio) { - _initial_x_texel_ratio = initial_x_texel_ratio; - _final_x_texel_ratio = final_x_texel_ratio; +set_initial_x_scale(float initial_x_scale) { + _initial_x_texel_ratio = initial_x_scale; } //////////////////////////////////////////////////////////////////// -// Function : set_y_ratios +// Function : set_final_x_scale // Access : public //////////////////////////////////////////////////////////////////// INLINE void SpriteParticleRenderer:: -set_y_ratios(float initial_y_texel_ratio, - float final_y_texel_ratio) { - _initial_y_texel_ratio = initial_y_texel_ratio; - _final_y_texel_ratio = final_y_texel_ratio; +set_final_x_scale(float final_x_scale) { + _final_x_texel_ratio = final_x_scale; +} + +//////////////////////////////////////////////////////////////////// +// Function : set_initial_y_scale +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE void SpriteParticleRenderer:: +set_initial_y_scale(float initial_y_scale) { + _initial_y_texel_ratio = initial_y_scale; +} + +//////////////////////////////////////////////////////////////////// +// Function : set_final_y_scale +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE void SpriteParticleRenderer:: +set_final_y_scale(float final_y_scale) { + _final_y_texel_ratio = final_y_scale; } //////////////////////////////////////////////////////////////////// @@ -122,10 +121,127 @@ set_nonanimated_theta(float theta) { } //////////////////////////////////////////////////////////////////// -// Function : set_blend_type +// Function : set_alpha_blend_method // Access : public //////////////////////////////////////////////////////////////////// INLINE void SpriteParticleRenderer:: -set_blend_type(ParticleRendererBlendMethod bm) { +set_alpha_blend_method(ParticleRendererBlendMethod bm) { _blend_method = bm; } + +//////////////////////////////////////////////////////////////////// +// Function : set_alpha_disable +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE void SpriteParticleRenderer:: +set_alpha_disable(bool ad) { + _sprite_primitive->set_alpha_disable(ad); +} + +//////////////////////////////////////////////////////////////////// +// Function : get_texture +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE Texture *SpriteParticleRenderer:: +get_texture(void) const { + return _sprite_primitive->get_texture(); +} + +//////////////////////////////////////////////////////////////////// +// Function : get_color +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE Colorf SpriteParticleRenderer:: +get_color(void) const { + return _color; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_x_scale_flag +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE bool SpriteParticleRenderer:: +get_x_scale_flag(void) const { + return _animate_x_ratio; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_y_scale_flag +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE bool SpriteParticleRenderer:: +get_y_scale_flag(void) const { + return _animate_y_ratio; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_anim_angle_flag +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE bool SpriteParticleRenderer:: +get_anim_angle_flag(void) const { + return _animate_theta; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_initial_x_scale +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE float SpriteParticleRenderer:: +get_initial_x_scale(void) const { + return _initial_x_texel_ratio; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_final_x_scale +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE float SpriteParticleRenderer:: +get_final_x_scale(void) const { + return _final_x_texel_ratio; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_initial_y_scale +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE float SpriteParticleRenderer:: +get_initial_y_scale(void) const { + return _initial_y_texel_ratio; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_final_y_scale +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE float SpriteParticleRenderer:: +get_final_y_scale(void) const { + return _final_y_texel_ratio; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_nonanimated_theta +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE float SpriteParticleRenderer:: +get_nonanimated_theta(void) const { + return _theta; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_alpha_blend_method +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE ParticleRendererBlendMethod SpriteParticleRenderer:: +get_alpha_blend_method(void) const { + return _blend_method; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_alpha_disable +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE bool SpriteParticleRenderer:: +get_alpha_disable(void) const { + return _sprite_primitive->get_alpha_disable(); +} diff --git a/panda/src/particlesystem/spriteParticleRenderer.cxx b/panda/src/particlesystem/spriteParticleRenderer.cxx index 35d4c1b405..b8abe4d57b 100644 --- a/panda/src/particlesystem/spriteParticleRenderer.cxx +++ b/panda/src/particlesystem/spriteParticleRenderer.cxx @@ -1,6 +1,6 @@ -// Filename: spriteParticleRenderer.cxx +// Filename: spriteParticleRenderer.C // Created by: charles (13Jul00) -// +// //////////////////////////////////////////////////////////////////// #include @@ -15,16 +15,18 @@ //////////////////////////////////////////////////////////////////// SpriteParticleRenderer:: SpriteParticleRenderer(Texture *tex) : - _animate_x_ratio(false), + _animate_x_ratio(false), _animate_y_ratio(false), _animate_theta(false), _blend_method(PP_BLEND_LINEAR), - _pool_size(0), + _pool_size(0), _initial_x_texel_ratio(0.02f), + _final_x_texel_ratio(0.02f), _initial_y_texel_ratio(0.02f), + _final_y_texel_ratio(0.02f), _theta(0.0f), _color(Colorf(1.0f, 1.0f, 1.0f, 1.0f)), - BaseParticleRenderer(PR_NO_ALPHA) { + BaseParticleRenderer(PR_ALPHA_NONE) { _sprite_primitive = new GeomSprite(tex); init_geoms(); } @@ -222,16 +224,13 @@ render(vector< PT(PhysicsObject) >& po_vector, int ttl_particles) { // put the current color into the array Colorf c = _color; - if (!(get_alpha_decay() == PR_NO_ALPHA || - get_alpha_decay() == PR_ALPHA_INVALID)) { + if (!(get_alpha_mode() == PR_ALPHA_NONE)) { float t = cur_particle->get_parameterized_age(); - if (get_alpha_decay() == PR_ALPHA_OUT) - c[3] = 1.0f - t; - else { - if (get_alpha_decay() == PR_ALPHA_IN) - c[3] = t; - } + if (get_alpha_mode() == PR_ALPHA_OUT) + c[3] = 1.0f - t; + else if (get_alpha_mode() == PR_ALPHA_IN) + c[3] = t; } *cur_color++ = c; @@ -240,24 +239,22 @@ render(vector< PT(PhysicsObject) >& po_vector, int ttl_particles) { if (_animate_x_ratio == true) { float t = cur_particle->get_parameterized_age(); - // this ... isn't pretty. (ghetto cubic) if (_blend_method == PP_BLEND_CUBIC) - t = t * t * (3 - (2 * t)); + t = CUBIC_T(t); - *cur_x_texel++ = (_initial_x_texel_ratio + - (t * (_final_x_texel_ratio - _initial_x_texel_ratio))); + *cur_x_texel++ = (_initial_x_texel_ratio + + (t * (_final_x_texel_ratio - _initial_x_texel_ratio))); } // handle y scaling if (_animate_y_ratio == true) { float t = cur_particle->get_parameterized_age(); - // this ... isn't pretty either. if (_blend_method == PP_BLEND_CUBIC) - t = t * t * (3 - (2 * t)); + t = CUBIC_T(t); *cur_y_texel++ = (_initial_y_texel_ratio + - (t * (_final_y_texel_ratio - _initial_y_texel_ratio))); + (t * (_final_y_texel_ratio - _initial_y_texel_ratio))); } // handle theta diff --git a/panda/src/particlesystem/spriteParticleRenderer.h b/panda/src/particlesystem/spriteParticleRenderer.h index 56779d31d9..2f2eee6f37 100644 --- a/panda/src/particlesystem/spriteParticleRenderer.h +++ b/panda/src/particlesystem/spriteParticleRenderer.h @@ -1,6 +1,6 @@ // Filename: spriteParticleRenderer.h // Created by: charles (13Jul00) -// +// //////////////////////////////////////////////////////////////////// #ifndef SPRITEPARTICLERENDERER_H @@ -61,26 +61,29 @@ public: virtual BaseParticleRenderer *make_copy(void); INLINE void set_texture(Texture *tex); - INLINE Texture *get_texture(void) const; - INLINE void set_color(const Colorf &color); - - // this is the main interface for whether or not you want the sizes - // to change over the course of the particle's lifetime. - INLINE void set_animation_flags(bool animate_x_ratio, - bool animate_y_ratio, - bool animate_theta); - - INLINE void set_x_ratios(float initial_x_texel_ratio, - float final_x_texel_ratio = 0.0f); - INLINE void set_y_ratios(float initial_y_texel_ratio, - float final_y_texel_ratio = 0.0f); + INLINE void set_x_scale_flag(bool animate_x_ratio); + INLINE void set_y_scale_flag(bool animate_y_ratio); + INLINE void set_anim_angle_flag(bool animate_theta); + INLINE void set_initial_x_scale(float initial_x_scale); + INLINE void set_final_x_scale(float final_x_scale); + INLINE void set_initial_y_scale(float initial_y_scale); + INLINE void set_final_y_scale(float final_y_scale); INLINE void set_nonanimated_theta(float theta); - - // alpha - INLINE void set_blend_type(ParticleRendererBlendMethod bm); - + INLINE void set_alpha_blend_method(ParticleRendererBlendMethod bm); INLINE void set_alpha_disable(bool ad); + + INLINE Texture *get_texture(void) const; + INLINE Colorf get_color(void) const; + INLINE bool get_x_scale_flag(void) const; + INLINE bool get_y_scale_flag(void) const; + INLINE bool get_anim_angle_flag(void) const; + INLINE float get_initial_x_scale(void) const; + INLINE float get_final_x_scale(void) const; + INLINE float get_initial_y_scale(void) const; + INLINE float get_final_y_scale(void) const; + INLINE float get_nonanimated_theta(void) const; + INLINE ParticleRendererBlendMethod get_alpha_blend_method(void) const; INLINE bool get_alpha_disable(void) const; }; diff --git a/panda/src/particlesystem/tangentRingEmitter.cxx b/panda/src/particlesystem/tangentRingEmitter.cxx index 735342c723..b4463567d2 100644 --- a/panda/src/particlesystem/tangentRingEmitter.cxx +++ b/panda/src/particlesystem/tangentRingEmitter.cxx @@ -1,4 +1,4 @@ -// Filename: tangentRingEmitter.cxx +// Filename: tangentRingEmitter.C // Created by: charles (25Jul00) // //////////////////////////////////////////////////////////////////// @@ -46,17 +46,26 @@ make_copy(void) { } //////////////////////////////////////////////////////////////////// -// Function : assign_initial_values -// Access : private, virtual -// Description : fills in a newly-born particle +// Function : TangentRingEmitter::assign_initial_position +// Access : Public +// Description : Generates a location for a new particle //////////////////////////////////////////////////////////////////// void TangentRingEmitter:: -assign_initial_values(LPoint3f& pos, LVector3f& vel) { - float theta = bounded_rand() * 2.0f * MathNumbers::pi; +assign_initial_position(LPoint3f& pos) { + float theta = NORMALIZED_RAND() * 2.0f * MathNumbers::pi; - float x = _radius * cosf(theta); - float y = _radius * sinf(theta); + _x = cosf(theta); + _y = sinf(theta); - pos.set(x, y, 0); - vel.set(-y, x, 0); + pos.set(_radius * _x, _radius * _y, 0); +} + +//////////////////////////////////////////////////////////////////// +// Function : TangentRingEmitter::assign_initial_velocity +// Access : Public +// Description : Generates a velocity for a new particle +//////////////////////////////////////////////////////////////////// +void TangentRingEmitter:: +assign_initial_velocity(LVector3f& vel) { + vel.set(-_y, _x, 0); } diff --git a/panda/src/particlesystem/tangentRingEmitter.h b/panda/src/particlesystem/tangentRingEmitter.h index e36253b061..bad2d92e91 100644 --- a/panda/src/particlesystem/tangentRingEmitter.h +++ b/panda/src/particlesystem/tangentRingEmitter.h @@ -11,13 +11,20 @@ //////////////////////////////////////////////////////////////////// // Class : TangentRingEmitter // Description : Describes a planar ring region in which -// tangent particles are generated. +// tangent particles are generated, and particles +// fly off tangential to the ring. //////////////////////////////////////////////////////////////////// class EXPCL_PANDAPHYSICS TangentRingEmitter : public BaseParticleEmitter { private: float _radius; - virtual void assign_initial_values(LPoint3f& pos, LVector3f& vel); + /////////////////////////////// + // scratch variables that carry over from position calc to velocity calc + float _x, _y; + /////////////////////////////// + + virtual void assign_initial_position(LPoint3f& pos); + virtual void assign_initial_velocity(LVector3f& vel); public: TangentRingEmitter(void); diff --git a/panda/src/particlesystem/zSpinParticle.I b/panda/src/particlesystem/zSpinParticle.I index 711945abdd..8994a1fbe4 100644 --- a/panda/src/particlesystem/zSpinParticle.I +++ b/panda/src/particlesystem/zSpinParticle.I @@ -1,32 +1,40 @@ // Filename: zSpinParticle.I // Created by: charles (16Aug00) -// +// //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// -// Class : set_thetas -// Description : public +// Function : set_initial_angle +// Description : accessor //////////////////////////////////////////////////////////////////// INLINE void ZSpinParticle:: -set_thetas(float cur, float target) { - _initial_theta = cur; - _cur_theta = cur; - _target_theta = target; - - float diff = _target_theta - _initial_theta; - - // figure out which way to spin. - if (diff < 0) { - if (fabs(diff) >= 180) - _positive_increment = true; - else - _positive_increment = false; - } - else { - if (fabs(diff) >= 180) - _positive_increment = false; - else - _positive_increment = true; - } +set_initial_angle(float t) { + _initial_angle = t; } +//////////////////////////////////////////////////////////////////// +// Function : get_initial_angle +// Description : accessor +//////////////////////////////////////////////////////////////////// +INLINE float ZSpinParticle:: +get_initial_angle(void) const { + return _initial_angle; +} + +//////////////////////////////////////////////////////////////////// +// Function : set_final_angle +// Description : accessor +//////////////////////////////////////////////////////////////////// +INLINE void ZSpinParticle:: +set_final_angle(float t) { + _final_angle = t; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_final_angle +// Description : accessor +//////////////////////////////////////////////////////////////////// +INLINE float ZSpinParticle:: +get_final_angle(void) const { + return _final_angle; +} diff --git a/panda/src/particlesystem/zSpinParticle.cxx b/panda/src/particlesystem/zSpinParticle.cxx index 8620be0bca..4385963fdd 100644 --- a/panda/src/particlesystem/zSpinParticle.cxx +++ b/panda/src/particlesystem/zSpinParticle.cxx @@ -1,6 +1,6 @@ -// Filename: zSpinParticle.cxx +// Filename: zSpinParticle.C // Created by: charles (16Aug00) -// +// //////////////////////////////////////////////////////////////////// #include "zSpinParticle.h" @@ -13,10 +13,9 @@ ZSpinParticle:: ZSpinParticle(void) : BaseParticle() { - _cur_theta = 0.0f; - _initial_theta = 0.0f; - _target_theta = 0.0f; - _positive_increment = true; + _initial_angle = 0.0f; + _final_angle = 0.0f; + _cur_angle = 0.0f; } //////////////////////////////////////////////////////////////////// @@ -27,10 +26,9 @@ ZSpinParticle(void) : ZSpinParticle:: ZSpinParticle(const ZSpinParticle ©) : BaseParticle(copy) { - _cur_theta = copy._cur_theta; - _initial_theta = copy._initial_theta; - _target_theta = copy._target_theta; - _positive_increment = copy._positive_increment; + _initial_angle = copy._initial_angle; + _final_angle = copy._final_angle; + _cur_angle = copy._cur_angle; } //////////////////////////////////////////////////////////////////// @@ -55,7 +53,7 @@ make_copy(void) const { //////////////////////////////////////////////////////////////////// // Function : init // Access : public, virtual -// Description : +// Description : //////////////////////////////////////////////////////////////////// void ZSpinParticle:: init(void) { @@ -70,15 +68,17 @@ void ZSpinParticle:: update(void) { float t = get_parameterized_age(); - if (_positive_increment) - _cur_theta = _initial_theta + (t * (fabs(_target_theta - _initial_theta))); - else - _cur_theta = _initial_theta - (t * (fabs(_target_theta - _initial_theta))); + // interpolate the current orientation + _cur_angle = _initial_angle + (t * (_final_angle - _initial_angle)); - if (_cur_theta >= 360.0f) - _cur_theta -= 360.0f; - else if (_cur_theta < 0.0f) - _cur_theta += 360.0f; + // normalize the result to [0..360) + _cur_angle = fmod(_cur_angle, 360.0f); + + // if _cur_angle was negative, it is still negative after fmod, + // but greater than -360. + // wrap it around by adding 360 + if(_cur_angle < 0.0f) + _cur_angle += 360.0f; } //////////////////////////////////////////////////////////////////// @@ -91,11 +91,11 @@ die(void) { } //////////////////////////////////////////////////////////////////// -// Function : get_theta +// Function : get_angle // Access : public, virtual // Description : //////////////////////////////////////////////////////////////////// float ZSpinParticle:: -get_theta(void) const { - return _cur_theta; +get_angle(void) const { + return _cur_angle; } diff --git a/panda/src/particlesystem/zSpinParticle.h b/panda/src/particlesystem/zSpinParticle.h index 0d01d098ef..6372bcc3e8 100644 --- a/panda/src/particlesystem/zSpinParticle.h +++ b/panda/src/particlesystem/zSpinParticle.h @@ -1,6 +1,6 @@ // Filename: zSpinParticle.h // Created by: charles (16Aug00) -// +// //////////////////////////////////////////////////////////////////// #ifndef ZSPINPARTICLE_H @@ -18,11 +18,9 @@ //////////////////////////////////////////////////////////////////// class EXPCL_PANDAPHYSICS ZSpinParticle : public BaseParticle { private: - float _initial_theta; - float _cur_theta; - float _target_theta; - float _dtheta; - bool _positive_increment; + float _initial_angle; + float _final_angle; + float _cur_angle; public: ZSpinParticle(void); @@ -35,11 +33,13 @@ public: virtual void update(void); virtual void die(void); - virtual float get_theta(void) const; + virtual float get_angle(void) const; - // these are dumped into one function so that the direction - // of rotation can be calculated at this time. - INLINE void set_thetas(float cur, float target); + INLINE void set_initial_angle(float t); + INLINE float get_initial_angle(void) const; + + INLINE void set_final_angle(float t); + INLINE float get_final_angle(void) const; }; #include "zSpinParticle.I" diff --git a/panda/src/particlesystem/zSpinParticleFactory.I b/panda/src/particlesystem/zSpinParticleFactory.I index 48eb5e0789..3cdc024a8b 100644 --- a/panda/src/particlesystem/zSpinParticleFactory.I +++ b/panda/src/particlesystem/zSpinParticleFactory.I @@ -1,59 +1,77 @@ // Filename: zSpinParticleFactory.I // Created by: charles (16Aug00) -// +// //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// -// Function : set_initial_theta +// Function : set_initial_angle // Access : public //////////////////////////////////////////////////////////////////// INLINE void ZSpinParticleFactory:: -set_initial_theta(float theta) { - _initial_theta = theta; +set_initial_angle(float angle) { + _initial_angle = angle; } //////////////////////////////////////////////////////////////////// -// Function : set_final_theta +// Function : set_final_angle // Access : public //////////////////////////////////////////////////////////////////// INLINE void ZSpinParticleFactory:: -set_final_theta(float theta) { - _final_theta = theta; +set_final_angle(float angle) { + _final_angle = angle; } //////////////////////////////////////////////////////////////////// -// Function : set_theta_delta +// Function : set_initial_angle_spread // Access : public //////////////////////////////////////////////////////////////////// INLINE void ZSpinParticleFactory:: -set_theta_delta(float delta) { - _theta_delta = delta; +set_initial_angle_spread(float spread) { + _initial_angle_spread = spread; } //////////////////////////////////////////////////////////////////// -// Function : get_initial_theta +// Function : set_final_angle_spread // Access : public //////////////////////////////////////////////////////////////////// -INLINE float ZSpinParticleFactory:: -get_initial_theta(void) const { - return _initial_theta; +INLINE void ZSpinParticleFactory:: +set_final_angle_spread(float spread) { + _final_angle_spread = spread; } //////////////////////////////////////////////////////////////////// -// Function : get_final_theta +// Function : get_initial_angle // Access : public //////////////////////////////////////////////////////////////////// INLINE float ZSpinParticleFactory:: -get_final_theta(void) const { - return _final_theta; +get_initial_angle(void) const { + return _initial_angle; } //////////////////////////////////////////////////////////////////// -// Function : get_theta_delta +// Function : get_final_angle // Access : public //////////////////////////////////////////////////////////////////// INLINE float ZSpinParticleFactory:: -get_theta_delta(void) const { - return _theta_delta; +get_final_angle(void) const { + return _final_angle; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_initial_angle_spread +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE float ZSpinParticleFactory:: +get_initial_angle_spread(void) const { + return _initial_angle_spread; +} + +//////////////////////////////////////////////////////////////////// +// Function : get_final_angle_spread +// Access : public +//////////////////////////////////////////////////////////////////// +INLINE float ZSpinParticleFactory:: +get_final_angle_spread(void) const { + return _final_angle_spread; } diff --git a/panda/src/particlesystem/zSpinParticleFactory.cxx b/panda/src/particlesystem/zSpinParticleFactory.cxx index 980b8b0d75..9f66de62dd 100644 --- a/panda/src/particlesystem/zSpinParticleFactory.cxx +++ b/panda/src/particlesystem/zSpinParticleFactory.cxx @@ -1,6 +1,6 @@ -// Filename: zSpinParticleFactory.cxx +// Filename: zSpinParticleFactory.C // Created by: charles (16Aug00) -// +// //////////////////////////////////////////////////////////////////// #include "zSpinParticleFactory.h" @@ -14,9 +14,10 @@ ZSpinParticleFactory:: ZSpinParticleFactory(void) : BaseParticleFactory() { - _initial_theta = 0.0f; - _final_theta = 0.0f; - _theta_delta = 0.0f; + _initial_angle = 0.0f; + _final_angle = 0.0f; + _initial_angle_spread = 0.0f; + _final_angle_spread = 0.0f; } //////////////////////////////////////////////////////////////////// @@ -27,9 +28,10 @@ ZSpinParticleFactory(void) : ZSpinParticleFactory:: ZSpinParticleFactory(const ZSpinParticleFactory ©) : BaseParticleFactory(copy) { - _initial_theta = copy._initial_theta; - _final_theta = copy._final_theta; - _theta_delta = copy._theta_delta; + _initial_angle = copy._initial_angle; + _final_angle = copy._final_angle; + _initial_angle_spread = copy._initial_angle_spread; + _final_angle_spread = copy._final_angle_spread; } //////////////////////////////////////////////////////////////////// @@ -60,9 +62,6 @@ void ZSpinParticleFactory:: populate_child_particle(BaseParticle *bp) const { ZSpinParticle *zsp = (ZSpinParticle *) bp; - float final_theta = _final_theta; - if (_theta_delta != 0.0f) - final_theta += _theta_delta - (bounded_rand() * 2.0f * _theta_delta); - - zsp->set_thetas(_initial_theta, final_theta); + zsp->set_initial_angle(_initial_angle + SPREAD(_initial_angle_spread)); + zsp->set_final_angle(_final_angle + SPREAD(_final_angle_spread)); } diff --git a/panda/src/particlesystem/zSpinParticleFactory.h b/panda/src/particlesystem/zSpinParticleFactory.h index eca9d6158d..6b12944fa6 100644 --- a/panda/src/particlesystem/zSpinParticleFactory.h +++ b/panda/src/particlesystem/zSpinParticleFactory.h @@ -1,6 +1,6 @@ // Filename: zSpinParticleFactory.h // Created by: charles (16Aug00) -// +// //////////////////////////////////////////////////////////////////// #ifndef ZSPINPARTICLEFACTORY_H @@ -10,30 +10,33 @@ //////////////////////////////////////////////////////////////////// // Class : ZSpinParticleFactory -// Description : see filename +// Description : //////////////////////////////////////////////////////////////////// -class EXPCL_PANDAPHYSICS ZSpinParticleFactory : +class EXPCL_PANDAPHYSICS ZSpinParticleFactory : public BaseParticleFactory { private: virtual void populate_child_particle(BaseParticle *bp) const; virtual BaseParticle *alloc_particle(void) const; - float _initial_theta; - float _final_theta; - float _theta_delta; + float _initial_angle; + float _final_angle; + float _initial_angle_spread; + float _final_angle_spread; public: ZSpinParticleFactory(void); ZSpinParticleFactory(const ZSpinParticleFactory ©); virtual ~ZSpinParticleFactory(void); - INLINE void set_initial_theta(float theta); - INLINE void set_final_theta(float theta); - INLINE void set_theta_delta(float delta); + INLINE void set_initial_angle(float angle); + INLINE void set_final_angle(float angle); + INLINE void set_initial_angle_spread(float spread); + INLINE void set_final_angle_spread(float spread); - INLINE float get_initial_theta(void) const; - INLINE float get_final_theta(void) const; - INLINE float get_theta_delta(void) const; + INLINE float get_initial_angle(void) const; + INLINE float get_final_angle(void) const; + INLINE float get_initial_angle_spread(void) const; + INLINE float get_final_angle_spread(void) const; }; #include "zSpinParticleFactory.I"