瀏覽代碼

*** empty log message ***

Darren Ranalli 25 年之前
父節點
當前提交
1432fb3408

+ 1 - 4
panda/src/particlesystem/lineParticleRenderer.cxx

@@ -145,7 +145,6 @@ 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];
@@ -207,14 +206,12 @@ render(vector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
     *cur_color++ = head_color;
     *cur_color++ = tail_color;
 
-    num_lines_drawn++;
-
     remaining_particles--;
     if (remaining_particles == 0)
       break;
   }
 
-  _line_primitive->set_num_prims(num_lines_drawn);
+  _line_primitive->set_num_prims(ttl_particles);
 
   // done filling geomline node, now do the bb stuff
 

+ 4 - 3
panda/src/particlesystem/particleSystem.I

@@ -27,8 +27,7 @@ render(void) {
 
 INLINE void ParticleSystem::
 set_pool_size(int size) {
-  _particle_pool_size = size;
-  resize_pool();
+  resize_pool(size);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -95,9 +94,11 @@ set_emitter(BaseParticleEmitter *e) {
 
 INLINE void ParticleSystem::
 set_factory(BaseParticleFactory *f) {
+  int pool_size = _particle_pool_size;
+  set_pool_size(0);
   _factory = f;
   clear_physics_objects();
-  resize_pool();
+  set_pool_size(pool_size);
 }
 
 ////////////////////////////////////////////////////////////////////

+ 208 - 9
panda/src/particlesystem/particleSystem.cxx

@@ -29,7 +29,7 @@
 ////////////////////////////////////////////////////////////////////
 ParticleSystem::
 ParticleSystem(int pool_size) :
-  Physical(pool_size, false), _particle_pool_size(pool_size)
+  Physical(pool_size, false)
 {
   _birth_rate = 0.5f;
   _tics_since_birth = _birth_rate;
@@ -42,6 +42,7 @@ ParticleSystem(int pool_size) :
   _system_grows_older_flag = false;
   _system_lifespan = 0.0f;
   _i_was_spawned_flag = false;
+  _particle_pool_size = 0;
 
   // just in case someone tries to do something that requires the
   // use of an emitter, renderer, or factory before they've actually
@@ -55,6 +56,8 @@ ParticleSystem(int pool_size) :
   set_emitter(new SphereSurfaceEmitter);
   set_renderer(new PointParticleRenderer);
   set_factory(new PointParticleFactory);
+
+  set_pool_size(pool_size);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -68,8 +71,6 @@ ParticleSystem(const ParticleSystem& copy) :
   _system_age(0.0f),
   _template_system_flag(false)
 {
-
-  _particle_pool_size = copy._particle_pool_size;
   _birth_rate = copy._birth_rate;
   _litter_size = copy._litter_size;
   _litter_spread = copy._litter_spread;
@@ -90,7 +91,7 @@ ParticleSystem(const ParticleSystem& copy) :
   _system_lifespan = copy._system_lifespan;
   _living_particles = 0;
 
-  resize_pool();
+  set_pool_size(copy._particle_pool_size);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -300,19 +301,20 @@ kill_particle(int pool_index) {
 ////////////////////////////////////////////////////////////////////
 //    Function : resize_pool
 //      Access : Private
-// Description : Resizes the particle pool according to _particle_pool_size
+// Description : Resizes the particle pool
 ////////////////////////////////////////////////////////////////////
 #ifdef PSDEBUG
 #define PARTICLE_SYSTEM_RESIZE_POOL_SENTRIES
 #endif
 void ParticleSystem::
-resize_pool(void) {
+resize_pool(int size) {
   int i;
-  int delta = _particle_pool_size - _physics_objects.size();
+  int delta = size - _particle_pool_size;
+  int po_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;
+  cout << "resizing particle pool from " << _particle_pool_size
+       << " to " << size << endl;
 #endif
 
   if (_factory.is_null()) {
@@ -327,6 +329,51 @@ resize_pool(void) {
     return;
   }
 
+  _particle_pool_size = size;
+
+  // make sure the physics_objects array is OK
+  if (po_delta) {
+    if (po_delta > 0) {
+      for (i = 0; i < po_delta; i++)
+      {
+        int free_index = _physics_objects.size();
+
+        BaseParticle *new_particle = _factory->alloc_particle();
+        if (new_particle) {
+          _factory->populate_particle(new_particle);
+
+          _physics_objects.push_back(new_particle);
+        } else {
+#ifdef PSDEBUG
+          cout << "Error allocating new particle" << endl;
+          _particle_pool_size--;
+#endif
+        }
+      }
+    } else {
+#ifdef PSDEBUG
+      cout << "physics_object array is too large??" << endl;
+      _particle_pool_size--;
+#endif
+      po_delta = -po_delta;
+      for (i = 0; i < po_delta; i++) {
+        int delete_index = _physics_objects.size()-1;
+        BaseParticle *bp = (BaseParticle *) _physics_objects[delete_index].p();
+        if (bp->get_alive()) {
+          kill_particle(delete_index);
+          _free_particle_fifo.pop_back();
+        } else {
+          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);
+          }
+        }
+        _physics_objects.pop_back();
+      }
+    }
+  }
+
   // disregard no change
   if (delta == 0)
     return;
@@ -414,6 +461,11 @@ update(float dt) {
   BaseParticle *bp;
   float age;
 
+#ifdef PSSANITYCHECK
+  // check up on things
+  if (sanity_check()) return;
+#endif
+
 #ifdef PARTICLE_SYSTEM_UPDATE_SENTRIES
   cout << "UPDATE: pool size: " << _particle_pool_size
        << ", live particles: " << _living_particles << endl;
@@ -472,3 +524,150 @@ update(float dt) {
   cout << "particle update complete" << endl;
 #endif
 }
+
+#ifdef PSSANITYCHECK
+//////////////////////////////////////////////////////////////////////
+//    Function : sanity_check
+//      Access : Private
+// Description : Checks consistency of live particle count, free
+//               particle list, etc. returns 0 if everything is normal
+//////////////////////////////////////////////////////////////////////
+#ifndef NDEBUG
+#define PSSCVERBOSE
+#endif
+
+class SC_valuenamepair : public ReferenceCount {
+public:
+  int value;
+  char *name;
+  SC_valuenamepair(int v, char *s) : value(v), name(s) {}
+};
+
+// returns 0 if OK, # of errors if not OK
+static int check_free_live_total_particles(vector<PT(SC_valuenamepair)> live_counts,
+  vector<PT(SC_valuenamepair)> dead_counts, vector<PT(SC_valuenamepair)> total_counts,
+  int print_all = 0) {
+
+  int val = 0;
+  int l, d, t;
+
+  for(l = 0; l < live_counts.size(); l++) {
+    for(d = 0; d < dead_counts.size(); d++) {
+      for(t = 0; t < total_counts.size(); t++) {
+        int live = live_counts[l]->value;
+        int dead = dead_counts[d]->value;
+        int total = total_counts[t]->value;
+        if ((live + dead) != total) {
+#ifdef PSSCVERBOSE
+          cout << "free/live/total count: "
+               << live_counts[l]->name << " (" << live << ") + "
+               << dead_counts[d]->name << " (" << dead << ") = "
+               << live + dead << ", != "
+               << total_counts[t]->name << " (" << total << ")"
+               << endl;
+#endif
+          val++;
+        }
+      }
+    }
+  }
+
+  return val;
+}
+
+int ParticleSystem::
+sanity_check() {
+  int result = 0;
+  int i;
+  BaseParticle *bp;
+  int pool_size;
+
+  ///////////////////////////////////////////////////////////////////
+  // check pool size
+  if (_particle_pool_size != _physics_objects.size()) {
+#ifdef PSSCVERBOSE
+    cout << "_particle_pool_size (" << _particle_pool_size
+         << ") != particle array size (" << _physics_objects.size() << ")" << endl;
+#endif
+    result++;
+  }
+  pool_size = min(_particle_pool_size, _physics_objects.size());
+  ///////////////////////////////////////////////////////////////////
+
+  ///////////////////////////////////////////////////////////////////
+  // find out how many particles are REALLY alive and dead
+  int real_live_particle_count = 0;
+  int real_dead_particle_count = 0;
+
+  for (i = 0; i < _physics_objects.size(); i++) {
+    bp = (BaseParticle *) _physics_objects[i].p();
+    if (true == bp->get_alive()) {
+      real_live_particle_count++;
+    } else {
+      real_dead_particle_count++;
+    }
+  }
+
+  if (real_live_particle_count != _living_particles) {
+#ifdef PSSCVERBOSE
+    cout << "manually counted live particle count (" << real_live_particle_count
+         << ") != _living_particles (" << _living_particles << ")" << endl;
+#endif
+    result++;
+  }
+
+  if (real_dead_particle_count != _free_particle_fifo.size()) {
+#ifdef PSSCVERBOSE
+    cout << "manually counted dead particle count (" << real_dead_particle_count
+         << ") != free particle fifo size (" << _free_particle_fifo.size() << ")" << endl;
+#endif
+    result++;
+  }
+  ///////////////////////////////////////////////////////////////////
+
+  ///////////////////////////////////////////////////////////////////
+  // check the free particle pool
+  for (i = 0; i < _free_particle_fifo.size(); i++) {
+    int index = _free_particle_fifo[i];
+
+    // check that we're in bounds
+    if (index >= pool_size) {
+#ifdef PSSCVERBOSE
+      cout << "index from free particle fifo (" << index
+           << ") is too large; pool size is " << pool_size << endl;
+#endif
+      result++;
+      continue;
+    }
+
+    // check that the particle is indeed dead
+    bp = (BaseParticle *) _physics_objects[index].p();
+    if (true == bp->get_alive()) {
+#ifdef PSSCVERBOSE
+      cout << "particle " << index << " in free fifo is not dead" << endl;
+#endif
+      result++;
+    }
+  }
+  ///////////////////////////////////////////////////////////////////
+
+  ///////////////////////////////////////////////////////////////////
+  // check the numbers of free particles, live particles, and total particles
+  vector<PT(SC_valuenamepair)> live_counts;
+  vector<PT(SC_valuenamepair)> dead_counts;
+  vector<PT(SC_valuenamepair)> total_counts;
+
+  live_counts.push_back(new SC_valuenamepair(real_live_particle_count, "real_live_particle_count"));
+
+  dead_counts.push_back(new SC_valuenamepair(real_dead_particle_count, "real_dead_particle_count"));
+  dead_counts.push_back(new SC_valuenamepair(_free_particle_fifo.size(), "free particle fifo size"));
+
+  total_counts.push_back(new SC_valuenamepair(_particle_pool_size, "_particle_pool_size"));
+  total_counts.push_back(new SC_valuenamepair(_physics_objects.size(), "actual particle pool size"));
+
+  result += check_free_live_total_particles(live_counts, dead_counts, total_counts);
+  ///////////////////////////////////////////////////////////////////
+
+  return result;
+}
+#endif

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

@@ -7,6 +7,10 @@
 //#define PSDEBUG
 #endif
 
+#define PSSANITYCHECK
+
+#define DYNAMIC_POOL_RESIZING
+
 #ifndef PARTICLESYSTEM_H
 #define PARTICLESYSTEM_H
 
@@ -32,10 +36,19 @@ class ParticleSystemManager;
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAPHYSICS ParticleSystem : public Physical {
 private:
+
+#ifdef PSSANITYCHECK
+  int sanity_check();
+#endif
+
+#ifndef DYNAMIC_POOL_RESIZING
+  INLINE void set_pool_size(int size);
+#endif
+
   bool birth_particle(void);
   void kill_particle(int pool_index);
   void birth_litter(void);
-  void resize_pool(void);
+  void resize_pool(int size);
 
   deque< int > _free_particle_fifo;
 
@@ -86,7 +99,9 @@ PUBLISHED:
   ~ParticleSystem(void);
 
   // access/queries
+#ifdef DYNAMIC_POOL_RESIZING
   INLINE void set_pool_size(int size);
+#endif
   INLINE void set_birth_rate(float new_br);
   INLINE void set_litter_size(int new_ls);
   INLINE void set_litter_spread(int new_ls);

+ 3 - 1
panda/src/particlesystem/pointParticleRenderer.cxx

@@ -18,7 +18,7 @@ PointParticleRenderer(ParticleRendererAlphaMode am,
 		      PointParticleBlendType bt,
 		      ParticleRendererBlendMethod bm,
 		      const Colorf& sc, const Colorf& ec) :
-  BaseParticleRenderer(am), 
+  BaseParticleRenderer(am),
   _start_color(sc), _end_color(ec),
   _point_size(point_size),
   _blend_type(bt), _blend_method(bm)
@@ -86,6 +86,8 @@ resize_pool(int new_size) {
 
   _point_primitive->set_coords(_vertex_array, G_PER_VERTEX);
   _point_primitive->set_colors(_color_array, G_PER_VERTEX);
+
+  init_geoms();
 }
 
 ////////////////////////////////////////////////////////////////////

+ 2 - 0
panda/src/particlesystem/sparkleParticleRenderer.cxx

@@ -119,6 +119,8 @@ resize_pool(int new_size) {
   _line_primitive->set_colors(_color_array, G_PER_VERTEX);
 
   _max_pool_size = new_size;
+
+  init_geoms();
 }
 
 ////////////////////////////////////////////////////////////////////

+ 2 - 0
panda/src/particlesystem/spriteParticleRenderer.cxx

@@ -125,6 +125,8 @@ resize_pool(int new_size) {
   _sprite_primitive->set_x_texel_ratio(_x_texel_array, _x_bind);
   _sprite_primitive->set_y_texel_ratio(_y_texel_array, _y_bind);
   _sprite_primitive->set_thetas(_theta_array, _theta_bind);
+
+  init_geoms();
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 1
panda/src/physics/linearIntegrator.cxx

@@ -37,7 +37,7 @@ LinearIntegrator::
 void LinearIntegrator::
 integrate(Physical *physical, vector< PT(LinearForce) > &forces,
 	  float dt) {
-/*// darren, 2000.10.06
+/* <-- darren, 2000.10.06
   // cap dt so physics don't go flying off on lags
   if (dt > _max_linear_dt)
     dt = _max_linear_dt;

+ 2 - 5
panda/src/physics/linearRandomForce.cxx

@@ -1,6 +1,6 @@
 // Filename: LinearRandomForce.cxx
 // Created by:  charles (19Jun00)
-// 
+//
 ////////////////////////////////////////////////////////////////////
 
 #include "linearRandomForce.h"
@@ -43,8 +43,5 @@ LinearRandomForce::
 ////////////////////////////////////////////////////////////////////
 float LinearRandomForce::
 bounded_rand(void) {
-  int val = rand() & 0x7fffffff;
-  float f_val = (float) val / (float) 0x7fffffff;
-
-  return f_val;
+  return ((float)rand() / (float)RAND_MAX);
 }

+ 1 - 5
panda/src/testbed/test_particles.cxx

@@ -91,7 +91,7 @@
 /////////////////////////////////////////////////
 
 // particle factory params
-#define PARTICLE_FACTORY_LIFESPAN_BASE   10.0f
+#define PARTICLE_FACTORY_LIFESPAN_BASE   5.0f
 //#define PARTICLE_FACTORY_LIFESPAN_BASE   3.0f
 //#define PARTICLE_FACTORY_LIFESPAN_SPREAD 1.0f
 //#define PARTICLE_FACTORY_MASS_BASE       1.0f
@@ -542,10 +542,6 @@ static void
 event_more_particles(CPT_Event) {
   static int index = 0;
   static int sizes[] = {
-    999,
-    1000,
-    0,
-    0,
     10,
     999,
     998,