Browse Source

*** empty log message ***

Darren Ranalli 25 years ago
parent
commit
75c69b0943

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

@@ -33,6 +33,6 @@ INLINE float BaseParticle::get_parameterized_age(void) const {
 }
 
 INLINE float BaseParticle::get_parameterized_vel(void) const {
-  if (0 == get_terminal_velocity()) return 0.0;
+  if (IS_NEARLY_ZERO(get_terminal_velocity())) return 0.0;
   return (get_velocity().length()) / get_terminal_velocity();
 }

+ 1 - 0
panda/src/particlesystem/baseParticle.h

@@ -29,6 +29,7 @@ protected:
   virtual ~BaseParticle(void);
 
 public:
+
   // local methods
   INLINE void set_age(float age);
   INLINE void set_lifespan(float lifespan);

+ 2 - 2
panda/src/particlesystem/baseParticleEmitter.h

@@ -22,9 +22,9 @@
 class EXPCL_PANDAPHYSICS BaseParticleEmitter : public ReferenceCount {
 PUBLISHED:
   enum emissionType {
-    ET_EXPLICIT, // all particles are emitted in the same direction
+    ET_EXPLICIT, // all particles are emitted in parallel along the same vector
     ET_RADIATE,  // all particles radiate away from a single point
-    ET_CUSTOM    // particle launch vectors are dependent on particular emitter
+    ET_CUSTOM    // particle launch vectors are dependent on particular derived emitter
   };
 
   virtual ~BaseParticleEmitter(void);

+ 3 - 15
panda/src/particlesystem/baseParticleFactory.cxx

@@ -50,22 +50,10 @@ BaseParticleFactory::
 ////////////////////////////////////////////////////////////////////
 void BaseParticleFactory::
 populate_particle(BaseParticle *bp) {
-  float lifespan = _lifespan_base;
-  float mass = _mass_base;
-  float tv = _terminal_velocity_base;
+  bp->set_lifespan(_lifespan_base + SPREAD(_lifespan_spread));
+  bp->set_mass(_mass_base + SPREAD(_mass_spread));
+  bp->set_terminal_velocity(_terminal_velocity_base + SPREAD(_terminal_velocity_spread));
 
-  // lifespan
-  lifespan += SPREAD(_lifespan_spread);
-
-  // mass
-  mass += SPREAD(_mass_spread);
-
-  // tv
-  tv += SPREAD(_terminal_velocity_spread);
-
-  bp->set_lifespan(lifespan);
-  bp->set_mass(mass);
-  bp->set_terminal_velocity(tv);
   bp->set_active(false);
   bp->set_alive(false);
   bp->set_age(0.0f);

+ 9 - 9
panda/src/particlesystem/geomParticleRenderer.cxx

@@ -150,16 +150,16 @@ render(vector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
 
       if ((_alpha_mode != PR_ALPHA_NONE) && (_alpha_mode != PR_ALPHA_USER)) {
 
-	float alpha_scalar = cur_particle->get_parameterized_age();
+        float alpha_scalar = cur_particle->get_parameterized_age();
 
-	if (_alpha_mode == PR_ALPHA_IN) {
-	  alpha = new ColorTransition(1.0f, 1.0f, 1.0f, alpha_scalar);
-	}
-	else if (_alpha_mode == PR_ALPHA_OUT) {
-	  alpha = new ColorTransition(1.0f, 1.0f, 1.0f, 1.0f - alpha_scalar);
-	}
+        if (_alpha_mode == PR_ALPHA_IN) {
+          alpha = new ColorTransition(1.0f, 1.0f, 1.0f, alpha_scalar);
+        }
+        else if (_alpha_mode == PR_ALPHA_OUT) {
+          alpha = new ColorTransition(1.0f, 1.0f, 1.0f, 1.0f - alpha_scalar);
+        }
 
-	cur_arc->set_transition(alpha);
+        cur_arc->set_transition(alpha);
       }
 
       cur_arc->set_transition(xform);
@@ -169,7 +169,7 @@ render(vector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
       remaining_particles--;
 
       if (remaining_particles == 0)
-	break;
+        break;
     }
 
     cur_arc_iter++;

+ 23 - 17
panda/src/particlesystem/lineParticleRenderer.cxx

@@ -111,6 +111,8 @@ resize_pool(int new_size) {
   _line_primitive->set_colors(_color_array, G_PER_VERTEX);
 
   _max_pool_size = new_size;
+
+  init_geoms();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -143,6 +145,7 @@ render(vector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
 
   int remaining_particles = ttl_particles;
   int i;
+  int num_lines_drawn = 0;
 
   Vertexf *cur_vert = &_vertex_array[0];
   Colorf *cur_color = &_color_array[0];
@@ -160,26 +163,27 @@ render(vector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
     if (cur_particle->get_alive() == false)
       continue;
 
+    LPoint3f pos = cur_particle->get_position();
+
     // adjust the aabb
 
-    if (cur_particle->get_position().get_x() > _aabb_max.get_x())
-      _aabb_max[0] = cur_particle->get_position().get_x();
-    else if (cur_particle->get_position().get_x() < _aabb_min.get_x())
-      _aabb_min[0] = cur_particle->get_position().get_x();
+    if (pos.get_x() > _aabb_max.get_x())
+      _aabb_max[0] = pos.get_x();
+    if (pos.get_x() < _aabb_min.get_x())
+      _aabb_min[0] = pos.get_x();
 
-    if (cur_particle->get_position().get_y() > _aabb_max.get_y())
-      _aabb_max[1] = cur_particle->get_position().get_y();
-    else if (cur_particle->get_position().get_y() < _aabb_min.get_y())
-      _aabb_min[1] = cur_particle->get_position().get_y();
+    if (pos.get_y() > _aabb_max.get_y())
+      _aabb_max[1] = pos.get_y();
+    if (pos.get_y() < _aabb_min.get_y())
+      _aabb_min[1] = pos.get_y();
 
-    if (cur_particle->get_position().get_z() > _aabb_max.get_z())
-      _aabb_max[2] = cur_particle->get_position().get_z();
-    else if (cur_particle->get_position().get_z() < _aabb_min.get_z())
-      _aabb_min[2] = cur_particle->get_position().get_z();
+    if (pos.get_z() > _aabb_max.get_z())
+      _aabb_max[2] = pos.get_z();
+    if (pos.get_z() < _aabb_min.get_z())
+      _aabb_min[2] = pos.get_z();
 
     // draw the particle.
 
-    LPoint3f pos = cur_particle->get_position();
     Colorf head_color = _head_color;
     Colorf tail_color = _tail_color;
 
@@ -195,24 +199,26 @@ render(vector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
       tail_color[3] = alpha;
     }
 
-    // 1 line from current position to last position
+    // one line from current position to last position
 
-    *cur_vert++ = cur_particle->get_position();
+    *cur_vert++ = pos;
     *cur_vert++ = cur_particle->get_last_position();
 
     *cur_color++ = head_color;
     *cur_color++ = tail_color;
 
+    num_lines_drawn++;
+
     remaining_particles--;
     if (remaining_particles == 0)
       break;
   }
 
-  _line_primitive->set_num_prims(ttl_particles);
+  _line_primitive->set_num_prims(num_lines_drawn);
 
   // done filling geomline node, now do the bb stuff
 
-  LPoint3f aabb_center = _aabb_min + ((_aabb_max - _aabb_min) * 0.5f);
+  LPoint3f aabb_center = (_aabb_min + _aabb_max) * 0.5f;
   float radius = (aabb_center - _aabb_min).length();
 
   _interface_node->set_bound(BoundingSphere(aabb_center, radius));

+ 5 - 0
panda/src/particlesystem/particleCommonFuncs.h

@@ -29,4 +29,9 @@
 // result is in [-spread,spread]
 #define SPREAD(magnitude) ((magnitude) - (NORMALIZED_RAND() * 2.0f * (magnitude)))
 
+// integer spread calculator
+// spread is non-negative spread magnitude (integer)
+// result is in [-spread,spread]
+#define I_SPREAD(magnitude) ((magnitude) - ((int)rand() % ((2*(magnitude))+1)))
+
 #endif // PARTICLECOMMONFUNCS_H

+ 2 - 2
panda/src/particlesystem/particleSystem.I

@@ -58,8 +58,8 @@ set_litter_size(int new_ls) {
 ////////////////////////////////////////////////////////////////////
 
 INLINE void ParticleSystem::
-set_litter_spread(int new_ld) {
-  _litter_spread = new_ld;
+set_litter_spread(int new_ls) {
+  _litter_spread = new_ls;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 106 - 31
panda/src/particlesystem/particleSystem.cxx

@@ -100,6 +100,8 @@ ParticleSystem(const ParticleSystem& copy) :
 ////////////////////////////////////////////////////////////////////
 ParticleSystem::
 ~ParticleSystem(void) {
+  set_pool_size(0);
+
   if (_template_system_flag == false) {
     _renderer.clear();
 
@@ -120,14 +122,23 @@ ParticleSystem::
 bool ParticleSystem::
 birth_particle(void) {
   int pool_index;
-//  float lifespan;
-//  float mass, t;
-
-  //  cout << "ParticleSystem::birth_particle" << endl;
 
   // make sure there's room for a new particle
-  if (_living_particles == _particle_pool_size)
+  if (_living_particles >= _particle_pool_size) {
+#ifdef PSDEBUG
+    if (_living_particles > _particle_pool_size) {
+      cout << "_living_particles > _particle_pool_size" << endl;
+    }
+#endif
+    return false;
+  }
+
+#ifdef PSDEBUG
+  if (0 == _free_particle_fifo.size()) {
+    cout << "Error: _free_particle_fifo is empty, but _living_particles < _particle_pool_size" << endl;
     return false;
+  }
+#endif
 
   pool_index = _free_particle_fifo.back();
   _free_particle_fifo.pop_back();
@@ -179,14 +190,12 @@ birth_particle(void) {
 ////////////////////////////////////////////////////////////////////
 void ParticleSystem::
 birth_litter(void) {
-  int litter_size;
+  int litter_size, i;
 
   litter_size = _litter_size;
 
   if (_litter_spread != 0)
-    litter_size += _litter_spread - (rand() % (2 * _litter_spread));
-
-  int i;
+    litter_size += I_SPREAD(_litter_spread);
 
   for (i = 0; i < litter_size; i++) {
     if (birth_particle() == false)
@@ -268,8 +277,6 @@ spawn_child_system(BaseParticle *bp) {
 ////////////////////////////////////////////////////////////////////
 void ParticleSystem::
 kill_particle(int pool_index) {
-//  vector< PT(PhysicsObject) >::iterator cur;
-
   // get a handle on our particle
   BaseParticle *bp = (BaseParticle *) _physics_objects[pool_index].p();
 
@@ -286,6 +293,7 @@ kill_particle(int pool_index) {
 
   // tell renderer
   _renderer->kill_particle(pool_index);
+
   _living_particles--;
 }
 
@@ -294,11 +302,19 @@ kill_particle(int pool_index) {
 //      Access : Private
 // Description : Resizes the particle pool according to _particle_pool_size
 ////////////////////////////////////////////////////////////////////
+#ifdef PSDEBUG
+#define PARTICLE_SYSTEM_RESIZE_POOL_SENTRIES
+#endif
 void ParticleSystem::
 resize_pool(void) {
   int i;
   int delta = _particle_pool_size - _physics_objects.size();
 
+#ifdef PARTICLE_SYSTEM_RESIZE_POOL_SENTRIES
+  cout << "resizing particle pool from " << _physics_objects.size()
+       << " to " << _particle_pool_size << endl;
+#endif
+
   if (_factory.is_null()) {
     particlesystem_cat.error() << "ParticleSystem::resize_pool"
 			       << " called with null _factory." << endl;
@@ -308,12 +324,9 @@ resize_pool(void) {
   if (_renderer.is_null()) {
     particlesystem_cat.error() << "ParticleSystem::resize_pool"
 			       << " called with null _renderer." << endl;
-
     return;
   }
 
-  _renderer->resize_pool(_particle_pool_size);
-
   // disregard no change
   if (delta == 0)
     return;
@@ -326,26 +339,64 @@ resize_pool(void) {
       int free_index = _physics_objects.size();
 
       BaseParticle *new_particle = _factory->alloc_particle();
-      _factory->populate_particle(new_particle);
-
-      _physics_objects.push_back(new_particle);
-      _free_particle_fifo.push_front(free_index);
+      if (new_particle) {
+        _factory->populate_particle(new_particle);
+
+        _physics_objects.push_back(new_particle);
+        _free_particle_fifo.push_back(free_index);
+      } else {
+#ifdef PSDEBUG
+        cout << "Error allocating new particle" << endl;
+        _particle_pool_size--;
+#endif
+      }
     }
-  }
-  else {
+  } else {
     // subtract elements
-    if (delta > _particle_pool_size) {
+    delta = -delta;
+    if (delta >= _physics_objects.size()) {
+#ifdef PSDEBUG
+      cout << "Weird... do we have a negative pool size??" << endl;
+#endif
       _physics_objects.erase(_physics_objects.begin(), _physics_objects.end());
       _free_particle_fifo.clear();
-    }
-    else {
+    } else {
       for (i = 0; i < delta; i++) {
-	_physics_objects.pop_back();
-	if (_free_particle_fifo.empty() == false)
-	  _free_particle_fifo.pop_back();
+        int delete_index = _physics_objects.size()-1;
+        BaseParticle *bp = (BaseParticle *) _physics_objects[delete_index].p();
+
+        if (bp->get_alive()) {
+#ifdef PSDEBUG
+          cout << "WAS ALIVE" << endl;
+#endif
+          kill_particle(delete_index);
+          _free_particle_fifo.pop_back();
+        } else {
+#ifdef PSDEBUG
+          cout << "WAS NOT ALIVE" << endl;
+#endif
+          deque<int>::iterator i;
+          i = find(_free_particle_fifo.begin(), _free_particle_fifo.end(), delete_index);
+          if (i != _free_particle_fifo.end()) {
+            _free_particle_fifo.erase(i);
+          }
+#ifdef PSDEBUG
+          else {
+            cout << "particle not found in free FIFO!!!!!!!!" << endl;
+          }
+#endif
+        }
+
+        _physics_objects.pop_back();
       }
     }
   }
+
+  _renderer->resize_pool(_particle_pool_size);
+
+#ifdef PARTICLE_SYSTEM_RESIZE_POOL_SENTRIES
+  cout << "particle pool resized" << endl;
+#endif
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -353,25 +404,46 @@ resize_pool(void) {
 //      Access : Public
 // Description : Updates the particle system.  Call once per frame.
 //////////////////////////////////////////////////////////////////////
+#ifdef PSDEBUG
+//#define PARTICLE_SYSTEM_UPDATE_SENTRIES
+#endif
 void ParticleSystem::
 update(float dt) {
   int ttl_updates_left = _living_particles;
   int current_index = 0, index_counter = 0;
   BaseParticle *bp;
-  bool done = false;
   float age;
 
-  // run through the particle array
-  while (!done) {
-    if (ttl_updates_left == 0)
-      break;
+#ifdef PARTICLE_SYSTEM_UPDATE_SENTRIES
+  cout << "UPDATE: pool size: " << _particle_pool_size
+       << ", live particles: " << _living_particles << endl;
+#endif
 
+  // run through the particle array
+  while (ttl_updates_left) {
     current_index = index_counter;
     index_counter++;
 
+#ifdef PSDEBUG
+    if (current_index >= _particle_pool_size) {
+      cout << "ERROR: _living_particles is out of sync (too large)" << endl;
+      cout << "pool size: " << _particle_pool_size
+           << ", live particles: " << _living_particles
+           << ", updates left: " << ttl_updates_left << endl;
+      break;
+    }
+#endif
+
     // get the current particle.
     bp = (BaseParticle *) _physics_objects[current_index].p();
 
+#ifdef PSDEBUG
+    if (!bp) {
+      cout << "NULL ptr at index " << current_index << endl;
+      continue;
+    }
+#endif
+
     if (bp->get_alive() == false)
       continue;
 
@@ -396,4 +468,7 @@ update(float dt) {
     _tics_since_birth -= _birth_rate;
   }
 
+#ifdef PARTICLE_SYSTEM_UPDATE_SENTRIES
+  cout << "particle update complete" << endl;
+#endif
 }

+ 5 - 1
panda/src/particlesystem/particleSystem.h

@@ -3,6 +3,10 @@
 //
 ////////////////////////////////////////////////////////////////////
 
+#ifndef NDEBUG
+//#define PSDEBUG
+#endif
+
 #ifndef PARTICLESYSTEM_H
 #define PARTICLESYSTEM_H
 
@@ -85,7 +89,7 @@ PUBLISHED:
   INLINE void set_pool_size(int size);
   INLINE void set_birth_rate(float new_br);
   INLINE void set_litter_size(int new_ls);
-  INLINE void set_litter_spread(int new_ld);
+  INLINE void set_litter_spread(int new_ls);
   INLINE void set_local_velocity_flag(bool lv);
   INLINE void set_system_grows_older_flag(bool sgo);
   INLINE void set_system_lifespan(float sl);

+ 46 - 8
panda/src/testbed/test_particles.cxx

@@ -53,8 +53,8 @@
 #define PARTICLE_SYSTEM_MANAGER_FRAME_STEPPING 1
 
 // particle system params
-#define PARTICLE_SYSTEM_POOL_SIZE 1024
-#define PARTICLE_SYSTEM_BIRTH_RATE  0.02f
+#define PARTICLE_SYSTEM_POOL_SIZE 1000
+#define PARTICLE_SYSTEM_BIRTH_RATE  0.01f
 //#define PARTICLE_SYSTEM_BIRTH_RATE  0.5f
 #define PARTICLE_SYSTEM_LITTER_SIZE 10
 #define PARTICLE_SYSTEM_LITTER_SPREAD 0
@@ -91,7 +91,7 @@
 /////////////////////////////////////////////////
 
 // particle factory params
-#define PARTICLE_FACTORY_LIFESPAN_BASE   0.5f
+#define PARTICLE_FACTORY_LIFESPAN_BASE   10.0f
 //#define PARTICLE_FACTORY_LIFESPAN_BASE   3.0f
 //#define PARTICLE_FACTORY_LIFESPAN_SPREAD 1.0f
 //#define PARTICLE_FACTORY_MASS_BASE       1.0f
@@ -110,8 +110,8 @@
 //#define PARTICLE_RENDERER_ALPHA_MODE  PR_ALPHA_NONE
 //#define PARTICLE_RENDERER_ALPHA_MODE  PR_ALPHA_IN
 //#define PARTICLE_RENDERER_ALPHA_MODE  PR_ALPHA_OUT
-#define PARTICLE_RENDERER_ALPHA_MODE  BaseParticleRenderer::PR_ALPHA_USER
-#define PARTICLE_RENDERER_USER_ALPHA  1.0
+//#define PARTICLE_RENDERER_ALPHA_MODE  BaseParticleRenderer::PR_ALPHA_USER
+//#define PARTICLE_RENDERER_USER_ALPHA  1.0
 
 #ifdef GEOM_PARTICLE_RENDERER
 #elif defined POINT_PARTICLE_RENDERER
@@ -132,7 +132,8 @@
 //  #define SPARKLE_PARTICLE_RENDERER_LIFE_SCALE    SP_SCALE
 #elif defined SPRITE_PARTICLE_RENDERER
 //  #define SPRITE_PARTICLE_RENDERER_TEXTURE_FILE       "smoke.rgba"
-  #define SPRITE_PARTICLE_RENDERER_TEXTURE_FILE       "lilsmiley.rgba"
+//  #define SPRITE_PARTICLE_RENDERER_TEXTURE_FILE       "lilsmiley.rgba"
+  #define SPRITE_PARTICLE_RENDERER_TEXTURE_FILE       "rock-floor.rgb"
   #define SPRITE_PARTICLE_RENDERER_COLOR              Colorf(1.0f, 1.0f, 1.0f, 1.0f)
 //  #define SPRITE_PARTICLE_RENDERER_X_SCALE_FLAG       true
 //  #define SPRITE_PARTICLE_RENDERER_Y_SCALE_FLAG       true
@@ -142,8 +143,8 @@
 //  #define SPRITE_PARTICLE_RENDERER_INITIAL_Y_SCALE    0.0
 //  #define SPRITE_PARTICLE_RENDERER_FINAL_Y_SCALE      0.5
   #define SPRITE_PARTICLE_RENDERER_NONANIMATED_THETA  45.0f
-  #define SPRITE_PARTICLE_RENDERER_BLEND_METHOD       PP_BLEND_LINEAR
-//  #define SPRITE_PARTICLE_RENDERER_BLEND_METHOD       PP_BLEND_CUBIC
+  #define SPRITE_PARTICLE_RENDERER_BLEND_METHOD       BaseParticleRenderer::PP_BLEND_LINEAR
+//  #define SPRITE_PARTICLE_RENDERER_BLEND_METHOD       BaseParticleRenderer::PP_BLEND_CUBIC
 //  #define SPRITE_PARTICLE_RENDERER_ALPHA_DISABLE      false
 #endif
 
@@ -532,11 +533,48 @@ event_add_particles(CPT_Event) {
   event_handler.add_hook("NewFrame", event_csn_update);
 }
 
+static void set_pool_size(int size) {
+  nout << "setting pool size to " << size << endl;
+  particle_system->set_pool_size(size);
+}
+
+static void
+event_more_particles(CPT_Event) {
+  static int index = 0;
+  static int sizes[] = {
+    999,
+    1000,
+    0,
+    0,
+    10,
+    999,
+    998,
+    999,
+    1000,
+    1001,
+    1002,
+    1003,
+    1004,
+    1000,
+    16*1000,
+    4*1000,
+    3*1000,
+    2*1000,
+    1000,
+    0,
+  };
+
+  if (0 == sizes[index]) index = 0;
+  set_pool_size(sizes[index]);
+  index++;
+}
+
 void demo_keys(EventHandler&) {
   new RenderRelation( lights, dlight );
   have_dlight = true;
 
   event_handler.add_hook("p", event_add_particles);
+  event_handler.add_hook("m", event_more_particles);
 }
 
 int main(int argc, char *argv[]) {