forked from bartvdbraak/blender
Fix for [#21411] Particles jitter when resting on a collision object
* Particle now take particle acceleration during collisions into account.
This commit is contained in:
parent
d440f0392a
commit
54b4266bef
@ -169,6 +169,7 @@ typedef struct ParticleCollision
|
|||||||
float nor[3]; // normal at collision point
|
float nor[3]; // normal at collision point
|
||||||
float vel[3]; // velocity of collision point
|
float vel[3]; // velocity of collision point
|
||||||
float co1[3], co2[3]; // ray start and end points
|
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 ray_len; // original length of co2-co1, needed for collision time evaluation
|
||||||
float t; // time of previous collision, needed for substracting face velocity
|
float t; // time of previous collision, needed for substracting face velocity
|
||||||
} ParticleCollision;
|
} ParticleCollision;
|
||||||
|
@ -2720,6 +2720,12 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
|
|||||||
|
|
||||||
VECCOPY(col.co1, pa->prev_state.co);
|
VECCOPY(col.co1, pa->prev_state.co);
|
||||||
VECCOPY(col.co2, pa->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;
|
col.t = 0.0f;
|
||||||
|
|
||||||
/* override for boids */
|
/* 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;
|
int through = (BLI_frand() < pd->pdef_perm) ? 1 : 0;
|
||||||
float co[3]; /* point of collision */
|
float co[3]; /* point of collision */
|
||||||
float vec[3]; /* movement through collision */
|
float vec[3]; /* movement through collision */
|
||||||
float t = hit.dist/col.ray_len; /* time of collision between this iteration */
|
float acc[3]; /* acceleration */
|
||||||
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 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(vec, col.co2, col.co1);
|
||||||
|
|
||||||
|
VECSUB(acc, col.ve2, col.ve1);
|
||||||
|
|
||||||
mul_v3_fl(col.vel, 1.0f-col.t);
|
mul_v3_fl(col.vel, 1.0f-col.t);
|
||||||
|
|
||||||
/* particle dies in collision */
|
/* particle dies in collision */
|
||||||
@ -2867,10 +2881,6 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
|
|||||||
/* combine components together again */
|
/* combine components together again */
|
||||||
VECADD(vec, nor_vec, tan_vec);
|
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 */
|
/* make sure we don't hit the current face again */
|
||||||
VECADDFAC(co, co, col.nor, (through ? -0.0001f : 0.0001f));
|
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;
|
BoidParticle *bpa = pa->boid;
|
||||||
if(bpa->data.mode == eBoidMode_OnLand || co[2] <= boid_z) {
|
if(bpa->data.mode == eBoidMode_OnLand || co[2] <= boid_z) {
|
||||||
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 */
|
/* set coordinates for next iteration */
|
||||||
VECCOPY(col.co1, co);
|
|
||||||
VECADDFAC(col.co2, co, vec, 1.0f - t);
|
/* apply acceleration to final position, but make sure particle stays above surface */
|
||||||
col.t = dt;
|
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);
|
||||||
|
|
||||||
if(len_v3(vec) < 0.001 && len_v3(pa->state.vel) < 0.001) {
|
VECCOPY(col.co1, co);
|
||||||
|
VECADDFAC(col.co2, co, acc, it);
|
||||||
|
|
||||||
|
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 */
|
/* kill speed to stop slipping */
|
||||||
VECCOPY(pa->state.vel,zerovec);
|
VECCOPY(pa->state.vel,zerovec);
|
||||||
VECCOPY(pa->state.co, co);
|
VECCOPY(pa->state.co, co);
|
||||||
@ -2902,10 +2916,14 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VECCOPY(pa->state.co, col.co2);
|
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 */
|
/* Stickness to surface */
|
||||||
normalize_v3(nor_vec);
|
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++;
|
deflections++;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user