Browse Source

*** empty log message ***

Darren Ranalli 25 years ago
parent
commit
c90c20728e
68 changed files with 1595 additions and 740 deletions
  1. 4 2
      panda/src/particlesystem/Sources.pp
  2. 1 1
      panda/src/particlesystem/baseParticle.I
  3. 1 1
      panda/src/particlesystem/baseParticle.cxx
  4. 3 1
      panda/src/particlesystem/baseParticle.h
  5. 74 6
      panda/src/particlesystem/baseParticleEmitter.I
  6. 34 11
      panda/src/particlesystem/baseParticleEmitter.cxx
  7. 38 15
      panda/src/particlesystem/baseParticleEmitter.h
  8. 18 26
      panda/src/particlesystem/baseParticleFactory.I
  9. 11 12
      panda/src/particlesystem/baseParticleFactory.cxx
  10. 14 13
      panda/src/particlesystem/baseParticleFactory.h
  11. 37 42
      panda/src/particlesystem/baseParticleRenderer.I
  12. 18 16
      panda/src/particlesystem/baseParticleRenderer.cxx
  13. 23 16
      panda/src/particlesystem/baseParticleRenderer.h
  14. 26 8
      panda/src/particlesystem/boxEmitter.I
  15. 17 11
      panda/src/particlesystem/boxEmitter.cxx
  16. 8 4
      panda/src/particlesystem/boxEmitter.h
  17. 2 2
      panda/src/particlesystem/config_particlesystem.cxx
  18. 2 2
      panda/src/particlesystem/config_particlesystem.h
  19. 60 16
      panda/src/particlesystem/discEmitter.I
  20. 38 19
      panda/src/particlesystem/discEmitter.cxx
  21. 18 6
      panda/src/particlesystem/discEmitter.h
  22. 6 7
      panda/src/particlesystem/geomParticleRenderer.cxx
  23. 1 1
      panda/src/particlesystem/geomParticleRenderer.h
  24. 26 9
      panda/src/particlesystem/lineEmitter.I
  25. 23 17
      panda/src/particlesystem/lineEmitter.cxx
  26. 9 6
      panda/src/particlesystem/lineEmitter.h
  27. 1 1
      panda/src/particlesystem/orientedParticle.cxx
  28. 1 1
      panda/src/particlesystem/orientedParticleFactory.cxx
  29. 7 6
      panda/src/particlesystem/particleSystem.I
  30. 15 11
      panda/src/particlesystem/particleSystem.cxx
  31. 21 37
      panda/src/particlesystem/particleSystem.h
  32. 12 12
      panda/src/particlesystem/particleSystemManager.cxx
  33. 1 1
      panda/src/particlesystem/particleSystemManager.h
  34. 368 0
      panda/src/particlesystem/particle_system_parameters.txt
  35. 5 10
      panda/src/particlesystem/pointEmitter.I
  36. 17 11
      panda/src/particlesystem/pointEmitter.cxx
  37. 7 7
      panda/src/particlesystem/pointEmitter.h
  38. 1 1
      panda/src/particlesystem/pointParticle.cxx
  39. 1 1
      panda/src/particlesystem/pointParticleFactory.cxx
  40. 12 22
      panda/src/particlesystem/pointParticleRenderer.I
  41. 15 16
      panda/src/particlesystem/pointParticleRenderer.cxx
  42. 8 8
      panda/src/particlesystem/pointParticleRenderer.h
  43. 26 8
      panda/src/particlesystem/rectangleEmitter.I
  44. 16 10
      panda/src/particlesystem/rectangleEmitter.cxx
  45. 9 6
      panda/src/particlesystem/rectangleEmitter.h
  46. 22 11
      panda/src/particlesystem/ringEmitter.I
  47. 32 16
      panda/src/particlesystem/ringEmitter.cxx
  48. 12 3
      panda/src/particlesystem/ringEmitter.h
  49. 17 17
      panda/src/particlesystem/sparkleParticleRenderer.I
  50. 20 20
      panda/src/particlesystem/sparkleParticleRenderer.cxx
  51. 10 10
      panda/src/particlesystem/sparkleParticleRenderer.h
  52. 12 5
      panda/src/particlesystem/sphereSurfaceEmitter.I
  53. 16 9
      panda/src/particlesystem/sphereSurfaceEmitter.cxx
  54. 3 1
      panda/src/particlesystem/sphereSurfaceEmitter.h
  55. 12 5
      panda/src/particlesystem/sphereVolumeEmitter.I
  56. 23 11
      panda/src/particlesystem/sphereVolumeEmitter.cxx
  57. 10 2
      panda/src/particlesystem/sphereVolumeEmitter.h
  58. 160 44
      panda/src/particlesystem/spriteParticleRenderer.I
  59. 17 20
      panda/src/particlesystem/spriteParticleRenderer.cxx
  60. 21 18
      panda/src/particlesystem/spriteParticleRenderer.h
  61. 19 10
      panda/src/particlesystem/tangentRingEmitter.cxx
  62. 9 2
      panda/src/particlesystem/tangentRingEmitter.h
  63. 29 21
      panda/src/particlesystem/zSpinParticle.I
  64. 22 22
      panda/src/particlesystem/zSpinParticle.cxx
  65. 10 10
      panda/src/particlesystem/zSpinParticle.h
  66. 37 19
      panda/src/particlesystem/zSpinParticleFactory.I
  67. 12 13
      panda/src/particlesystem/zSpinParticleFactory.cxx
  68. 15 12
      panda/src/particlesystem/zSpinParticleFactory.h

+ 4 - 2
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 \

+ 1 - 1
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 {

+ 1 - 1
panda/src/particlesystem/baseParticle.cxx

@@ -1,4 +1,4 @@
-// Filename: baseParticle.cxx
+// Filename: baseParticle.C
 // Created by:  charles (14Jun00)
 // 
 ////////////////////////////////////////////////////////////////////

+ 3 - 1
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 &copy);

+ 74 - 6
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

+ 34 - 11
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 &copy) {
-  _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;
+}

+ 38 - 15
panda/src/particlesystem/baseParticleEmitter.h

@@ -1,6 +1,6 @@
 // Filename: baseParticleEmitter.h
 // Created by:  charles (14Jun00)
-// 
+//
 ////////////////////////////////////////////////////////////////////
 
 #ifndef BASEPARTICLEEMITTER_H
@@ -10,6 +10,8 @@
 #include <referenceCount.h>
 #include <luse.h>
 
+#include "particleCommonFuncs.h"
+
 #include <mathNumbers.h>
 
 ////////////////////////////////////////////////////////////////////
@@ -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;
-
-protected:
-  BaseParticleEmitter(void);
-  BaseParticleEmitter(const BaseParticleEmitter &copy);
-
-  float _amplitude;
-  float bounded_rand(void);
-
 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;
 
-  INLINE void set_offset_force(const LVector3f& of);
-  INLINE LVector3f get_offset_force(void) const;
+  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 &copy);
 
-  INLINE void generate(LPoint3f& pos, LVector3f& vel);
+  emissionType _emission_type;
+  LVector3f _explicit_launch_vector;
+  LPoint3f  _radiate_origin;
+
+  float _amplitude;
+  float _amplitude_spread;
+
+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;
+
+  LVector3f _offset_force;
 };
 
 #include "baseParticleEmitter.I"

+ 18 - 26
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);
-}

+ 11 - 12
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 &copy) {
   _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);

+ 14 - 13
panda/src/particlesystem/baseParticleFactory.h

@@ -1,6 +1,6 @@
 // Filename: baseParticleFactory.h
 // Created by:  charles (05Jul00)
-// 
+//
 ////////////////////////////////////////////////////////////////////
 
 #ifndef BASEPARTICLEFACTORY_H
@@ -10,21 +10,24 @@
 #include <referenceCount.h>
 
 #include "baseParticle.h"
+#include "particleCommonFuncs.h"
+
+#include <stdlib.h>
 
 ////////////////////////////////////////////////////////////////////
-//       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 &copy);
 
-  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;
 

+ 37 - 42
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
 }

+ 18 - 16
panda/src/particlesystem/baseParticleRenderer.cxx

@@ -1,6 +1,6 @@
-// Filename: baseParticleRenderer.cxx
+// Filename: baseParticleRenderer.C
 // Created by:  charles (20Jun00)
-// 
+//
 ////////////////////////////////////////////////////////////////////
 
 #include <pandabase.h>
@@ -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;
 }
-

+ 23 - 16
panda/src/particlesystem/baseParticleRenderer.h

@@ -1,6 +1,6 @@
 // Filename: baseParticleRenderer.h
 // Created by:  charles (20Jun00)
-// 
+//
 ////////////////////////////////////////////////////////////////////
 
 #ifndef BASEPARTICLERENDERER_H
@@ -14,14 +14,17 @@
 #include <nodeRelation.h>
 #include <transparencyTransition.h>
 
+#include "particleCommonFuncs.h"
+#include "baseParticle.h"
+
 #include <vector>
 
-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);
-  BaseParticleRenderer(const BaseParticleRenderer& copy);
+  ParticleRendererAlphaMode _alpha_mode;
 
-  void update_alpha_state(ParticleRendererAlphaDecay ad);
+  BaseParticleRenderer(ParticleRendererAlphaMode alpha_decay = PR_ALPHA_NONE);
+  BaseParticleRenderer(const BaseParticleRenderer& copy);
 
-  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;
 

+ 26 - 8
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_min_bound(const LPoint3f& vmin) {
+  _vmin = vmin;
+}
 
+////////////////////////////////////////////////////////////////////
+//    Function : set_max_bound
+//      Access : Public
+// Description : boundary assignment
+////////////////////////////////////////////////////////////////////
 INLINE void BoxEmitter::
-set_boundaries(const LPoint3f& vmin, const LPoint3f& vmax) {
-  _vmin = vmin; _vmax = vmax; 
+set_max_bound(const LPoint3f& vmax) {
+  _vmax = vmax;
 }
 
 ////////////////////////////////////////////////////////////////////
-//    Function : set_launch_vec
+//    Function : get_min_bound
 //      Access : Public
-// Description : launch vec assignment
+// Description : boundary accessor
 ////////////////////////////////////////////////////////////////////
+INLINE LPoint3f BoxEmitter::
+get_min_bound(void) const {
+  return _vmin;
+}
 
-INLINE void BoxEmitter::
-set_launch_vec(const LVector3f& lv) { 
-  _launch_vec = lv; 
+////////////////////////////////////////////////////////////////////
+//    Function : get_max_bound
+//      Access : Public
+// Description : boundary accessor
+////////////////////////////////////////////////////////////////////
+INLINE LPoint3f BoxEmitter::
+get_max_bound(void) const {
+  return _vmax;
 }

+ 17 - 11
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 &copy) :
   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);
 }

+ 8 - 4
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"

+ 2 - 2
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 <dconfig.h>
+#include <config.h>
 
 ConfigureDef(config_particlesystem);
 NotifyCategoryDef(particlesystem, "");

+ 2 - 2
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 <pandabase.h>
 #include <notifyCategoryProxy.h>
-#include <dconfig.h>
+#include <config.h>
 
 ConfigureDecl(config_particlesystem, EXPCL_PANDAPHYSICS, EXPTP_PANDAPHYSICS);
 NotifyCategoryDecl(particlesystem, EXPCL_PANDAPHYSICS, EXPTP_PANDAPHYSICS);

+ 60 - 16
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; 
 }

+ 38 - 19
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 &copy) :
   _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);
 }

+ 18 - 6
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 &copy);
@@ -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"

+ 6 - 7
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);
 	}
 

+ 1 - 1
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);

+ 26 - 9
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;
+}

+ 23 - 17
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 &copy) :
   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);
 }

+ 9 - 6
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 &copy);
@@ -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"

+ 1 - 1
panda/src/particlesystem/orientedParticle.cxx

@@ -1,4 +1,4 @@
-// Filename: orientedParticle.cxx
+// Filename: orientedParticle.C
 // Created by:  charles (19Jun00)
 // 
 ////////////////////////////////////////////////////////////////////

+ 1 - 1
panda/src/particlesystem/orientedParticleFactory.cxx

@@ -1,4 +1,4 @@
-// Filename: orientedParticleFactory.cxx
+// Filename: orientedParticleFactory.C
 // Created by:  charles (05Jul00)
 // 
 ////////////////////////////////////////////////////////////////////

+ 7 - 6
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;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 15 - 11
panda/src/particlesystem/particleSystem.cxx

@@ -1,4 +1,4 @@
-// Filename: particleSystem.cxx
+// Filename: particleSystem.C
 // Created by:  charles (14Jun00)
 // 
 ////////////////////////////////////////////////////////////////////
@@ -13,6 +13,7 @@
 #include <transformTransition.h>
 #include <physicsManager.h>
 #include <physicalNode.h>
+#include <nearly_zero.h>
 
 #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;
   }
+
 }

+ 21 - 37
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_litter_spread(int new_ld);
+  INLINE void set_local_velocity_flag(bool lv);
+  INLINE void set_system_grows_older_flag(bool sgo);
+  INLINE void set_system_lifespan(float sl);
+  INLINE void set_system_age(float age);
+  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 void set_template_system_flag(bool tsf);
+  INLINE void set_render_parent(Node *node);
   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_local_velocity_flag(bool lv);
+  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 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_spawn_render_node(Node *node);
+  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
 

+ 12 - 12
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();
       }
     }
 

+ 1 - 1
panda/src/particlesystem/particleSystemManager.h

@@ -1,6 +1,6 @@
 // Filename: particleSystemManager.h
 // Created by:  charles (28Jun00)
-// 
+//
 ////////////////////////////////////////////////////////////////////
 
 #ifndef PARTICLESYSTEMMANAGER_H

+ 368 - 0
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()")

+ 5 - 10
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;
 }

+ 17 - 11
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 &copy) :
   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);
 }

+ 7 - 7
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"

+ 1 - 1
panda/src/particlesystem/pointParticle.cxx

@@ -1,4 +1,4 @@
-// Filename: pointParticle.cxx
+// Filename: pointParticle.C
 // Created by:  charles (19Jun00)
 // 
 ////////////////////////////////////////////////////////////////////

+ 1 - 1
panda/src/particlesystem/pointParticleFactory.cxx

@@ -1,4 +1,4 @@
-// Filename: pointParticleFactory.cxx
+// Filename: pointParticleFactory.C
 // Created by:  charles (05Jul00)
 // 
 ////////////////////////////////////////////////////////////////////

+ 12 - 22
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;

+ 15 - 16
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;

+ 8 - 8
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;
 };

+ 26 - 8
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;
 }

+ 16 - 10
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 &copy) :
   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);
 }

+ 9 - 6
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"

+ 22 - 11
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;
 }

+ 32 - 16
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 &copy) :
   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);
 }

+ 12 - 3
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"

+ 17 - 17
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);
   }
 }

+ 20 - 20
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;

+ 10 - 10
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"

+ 12 - 5
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; 
 }

+ 16 - 9
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);
 }

+ 3 - 1
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"

+ 12 - 5
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; 
 }

+ 23 - 11
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 &copy) :
   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;
 }

+ 10 - 2
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 &copy);
   virtual ~SphereVolumeEmitter(void);
 
   virtual BaseParticleEmitter *make_copy(void);
+
   INLINE void set_radius(float r);
+  INLINE float get_radius(void) const;
 };
 
 #include "sphereVolumeEmitter.I"

+ 160 - 44
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_initial_x_scale(float initial_x_scale) {
+  _initial_x_texel_ratio = initial_x_scale;
+}
+
+////////////////////////////////////////////////////////////////////
+// Function : set_final_x_scale
+//   Access : public
+////////////////////////////////////////////////////////////////////
+INLINE void SpriteParticleRenderer::
+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_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_y_scale(float initial_y_scale) {
+  _initial_y_texel_ratio = initial_y_scale;
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : set_y_ratios
+// Function : set_final_y_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_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();
+}

+ 17 - 20
panda/src/particlesystem/spriteParticleRenderer.cxx

@@ -1,6 +1,6 @@
-// Filename: spriteParticleRenderer.cxx
+// Filename: spriteParticleRenderer.C
 // Created by:  charles (13Jul00)
-// 
+//
 ////////////////////////////////////////////////////////////////////
 
 #include <boundingSphere.h>
@@ -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

+ 21 - 18
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;
 };
 

+ 19 - 10
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);
 }

+ 9 - 2
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);

+ 29 - 21
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;
+set_initial_angle(float t) {
+  _initial_angle = t;
+}
 
-  float diff = _target_theta - _initial_theta;
+////////////////////////////////////////////////////////////////////
+//    Function : get_initial_angle
+// Description : accessor
+////////////////////////////////////////////////////////////////////
+INLINE float ZSpinParticle::
+get_initial_angle(void) const {
+  return _initial_angle;
+}
 
-  // 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;
-  }
+////////////////////////////////////////////////////////////////////
+//    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;
+}

+ 22 - 22
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 &copy) :
   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));
+
+  // normalize the result to [0..360)
+  _cur_angle = fmod(_cur_angle, 360.0f);
 
-  if (_cur_theta >= 360.0f)
-    _cur_theta -= 360.0f;
-  else if (_cur_theta < 0.0f)
-    _cur_theta += 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;
 }

+ 10 - 10
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"

+ 37 - 19
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 void ZSpinParticleFactory::
+set_final_angle_spread(float spread) {
+  _final_angle_spread = spread;
+}
+
+////////////////////////////////////////////////////////////////////
+// Function : get_initial_angle
+//   Access : public
+////////////////////////////////////////////////////////////////////
+INLINE float ZSpinParticleFactory::
+get_initial_angle(void) const {
+  return _initial_angle;
+}
+
+////////////////////////////////////////////////////////////////////
+// Function : get_final_angle
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE float ZSpinParticleFactory::
-get_initial_theta(void) const {
-  return _initial_theta;
+get_final_angle(void) const {
+  return _final_angle;
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : get_final_theta
+// Function : get_initial_angle_spread
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE float ZSpinParticleFactory::
-get_final_theta(void) const {
-  return _final_theta;
+get_initial_angle_spread(void) const {
+  return _initial_angle_spread;
 }
 
 ////////////////////////////////////////////////////////////////////
-// Function : get_theta_delta
+// Function : get_final_angle_spread
 //   Access : public
 ////////////////////////////////////////////////////////////////////
 INLINE float ZSpinParticleFactory::
-get_theta_delta(void) const {
-  return _theta_delta;
+get_final_angle_spread(void) const {
+  return _final_angle_spread;
 }

+ 12 - 13
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 &copy) :
   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));
 }

+ 15 - 12
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 &copy);
   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"