[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [27376] trunk/blender/source/blender/ blenkernel: Fix for [#21411] Particles jitter when resting on a collision object

Janne Karhu jhkarh at gmail.com
Wed Mar 10 04:41:44 CET 2010


Revision: 27376
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27376
Author:   jhk
Date:     2010-03-10 04:41:41 +0100 (Wed, 10 Mar 2010)

Log Message:
-----------
Fix for [#21411] Particles jitter when resting on a collision object
* Particle now take particle acceleration during collisions into account.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_particle.h
    trunk/blender/source/blender/blenkernel/intern/particle_system.c

Modified: trunk/blender/source/blender/blenkernel/BKE_particle.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_particle.h	2010-03-10 02:44:21 UTC (rev 27375)
+++ trunk/blender/source/blender/blenkernel/BKE_particle.h	2010-03-10 03:41:41 UTC (rev 27376)
@@ -169,6 +169,7 @@
 	float nor[3]; // normal at collision point
 	float vel[3]; // velocity of collision point
 	float co1[3], co2[3]; // ray start and end points
+	float ve1[3], ve2[3]; // particle velocities
 	float ray_len; // original length of co2-co1, needed for collision time evaluation
 	float t;	// time of previous collision, needed for substracting face velocity
 } ParticleCollision;

Modified: trunk/blender/source/blender/blenkernel/intern/particle_system.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle_system.c	2010-03-10 02:44:21 UTC (rev 27375)
+++ trunk/blender/source/blender/blenkernel/intern/particle_system.c	2010-03-10 03:41:41 UTC (rev 27376)
@@ -2720,6 +2720,12 @@
 
 	VECCOPY(col.co1, pa->prev_state.co);
 	VECCOPY(col.co2, pa->state.co);
+	
+	VECCOPY(col.ve1, pa->prev_state.vel);
+	VECCOPY(col.ve2, pa->state.vel);
+	mul_v3_fl(col.ve1, timestep * dfra);
+	mul_v3_fl(col.ve2, timestep * dfra);
+	
 	col.t = 0.0f;
 
 	/* override for boids */
@@ -2765,12 +2771,20 @@
 			int through = (BLI_frand() < pd->pdef_perm) ? 1 : 0;
 			float co[3]; /* point of collision */
 			float vec[3]; /* movement through collision */
-			float t = hit.dist/col.ray_len; /* time of collision between this iteration */
-			float dt = col.t + t * (1.0f - col.t); /* time of collision between frame change*/
+			float acc[3]; /* acceleration */
 
-			interp_v3_v3v3(co, col.co1, col.co2, t);
+			float x = hit.dist/col.ray_len; /* location of collision between this iteration */
+			float le = len_v3(col.ve1)/col.ray_len;
+			float ac = len_v3(col.ve2)/col.ray_len - le; /* (taking acceleration into account) */
+			float t = (-le + sqrt(le*le + 2*ac*x))/ac; /* time of collision between this iteration */
+			float dt = col.t + x * (1.0f - col.t); /* time of collision between frame change*/
+			float it = 1.0 - t;
+			
+			interp_v3_v3v3(co, col.co1, col.co2, x);
 			VECSUB(vec, col.co2, col.co1);
 
+			VECSUB(acc, col.ve2, col.ve1);
+			
 			mul_v3_fl(col.vel, 1.0f-col.t);
 
 			/* particle dies in collision */
@@ -2867,10 +2881,6 @@
 				/* combine components together again */
 				VECADD(vec, nor_vec, tan_vec);
 
-				/* calculate velocity from collision vector */
-				VECCOPY(vel, vec);
-				mul_v3_fl(vel, 1.0f/MAX2((timestep*dfra) * (1.0f - col.t), 0.00001));
-
 				/* make sure we don't hit the current face again */
 				VECADDFAC(co, co, col.nor, (through ? -0.0001f : 0.0001f));
 
@@ -2878,21 +2888,25 @@
 					BoidParticle *bpa = pa->boid;
 					if(bpa->data.mode == eBoidMode_OnLand || co[2] <= boid_z) {
 						co[2] = boid_z;
-						vel[2] = 0.0f;
+						vec[2] = 0.0f;
 					}
 				}
 
-				/* store state for reactors */
-				//VECCOPY(reaction_state.co, co);
-				//interp_v3_v3v3(reaction_state.vel, pa->prev_state.vel, pa->state.vel, dt);
-				//interp_qt_qtqt(reaction_state.rot, pa->prev_state.rot, pa->state.rot, dt);
+				/* set coordinates for next iteration */
+				
+				/* apply acceleration to final position, but make sure particle stays above surface */
+				madd_v3_v3v3fl(acc, vec, acc, it);
+				ac = dot_v3v3(acc, col.nor);
+				if((!through && ac < 0.0f) || (through && ac > 0.0f))
+					madd_v3_v3fl(acc, col.nor, -ac);
 
-				/* set coordinates for next iteration */
 				VECCOPY(col.co1, co);
-				VECADDFAC(col.co2, co, vec, 1.0f - t);
-				col.t = dt;
+				VECADDFAC(col.co2, co, acc, it);
 
-				if(len_v3(vec) < 0.001 && len_v3(pa->state.vel) < 0.001) {
+				VECCOPY(col.ve1, vec);
+				VECCOPY(col.ve2, acc);
+
+				if(len_v3(vec) < 0.001 && len_v3v3(pa->state.co, pa->prev_state.co) < 0.001) {
 					/* kill speed to stop slipping */
 					VECCOPY(pa->state.vel,zerovec);
 					VECCOPY(pa->state.co, co);
@@ -2902,10 +2916,14 @@
 				}
 				else {
 					VECCOPY(pa->state.co, col.co2);
+					mul_v3_v3fl(pa->state.vel, acc, 1.0f/MAX2((timestep*dfra) * (1.0f - col.t), 0.00001));
+					
 					/* Stickness to surface */
 					normalize_v3(nor_vec);
-					VECADDFAC(pa->state.vel, vel, nor_vec, -pd->pdef_stickness);
+					madd_v3_v3fl(pa->state.vel, nor_vec, -pd->pdef_stickness);
 				}
+
+				col.t = dt;
 			}
 			deflections++;
 





More information about the Bf-blender-cvs mailing list