Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanne Karhu <jhkarh@gmail.com>2010-03-10 06:41:41 +0300
committerJanne Karhu <jhkarh@gmail.com>2010-03-10 06:41:41 +0300
commit54b4266bef2f6cb0f0060b325a5b1462404ac93a (patch)
tree7a27a589c031115394dcf795282d11147e3ffac9 /source/blender
parentd440f0392a45f968dc010657aadb05c16b216dc5 (diff)
Fix for [#21411] Particles jitter when resting on a collision object
* Particle now take particle acceleration during collisions into account.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_particle.h1
-rw-r--r--source/blender/blenkernel/intern/particle_system.c54
2 files changed, 37 insertions, 18 deletions
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 45166ebf022..fcef00ae9b3 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -169,6 +169,7 @@ typedef struct ParticleCollision
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;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 491ecd6011b..38808131f92 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -2720,6 +2720,12 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
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 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
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*/
-
- interp_v3_v3v3(co, col.co1, col.co2, t);
+ float acc[3]; /* acceleration */
+
+ 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 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
/* 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 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
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);
+
VECCOPY(col.co1, co);
- VECADDFAC(col.co2, co, vec, 1.0f - t);
- col.t = dt;
+ VECADDFAC(col.co2, co, acc, it);
+
+ VECCOPY(col.ve1, vec);
+ VECCOPY(col.ve2, acc);
- if(len_v3(vec) < 0.001 && len_v3(pa->state.vel) < 0.001) {
+ 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 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
}
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++;