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:
authorAlexander Gavrilov <angavrilov@gmail.com>2016-07-22 18:55:37 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2016-08-06 10:11:33 +0300
commit277b1d76ff73c3dfb2150ec06af622962c300618 (patch)
tree7902bae924e17e209569bd40d1202ac4efb82ec9 /source/blender/blenkernel/intern/particle_system.c
parentb98830902883401412c79638fe5e2b14219a07b1 (diff)
Fix T26658: particles stopped or bounced by 100% permeability colliders.
There were two issues here. One is that the fix done originally for this bug only checks for colliding with the same face as the single preceeding hit. If the particle hits an edge or vertex of the collider, it in fact hits two or more faces, so the loop ends up cycling between first two of them and reaches the max collision limit. The fix is to disable the collider for the sim step once a permeability roll succeeds, by adding it to a skip list. Skipping just one face causes some particles to bounce at odd angles in case of partial permeability. The second problem was that the collider bounced back a small percentage of particles, and the cause seemed to be that the code was set to flip the velocity if the particle was just past the collider but still within collision distance. Inverting both values causes a half permeable collider to stop particles, so it seems that this if branch shouldn't bounce at all. Test file: {F327322} Reviewers: lukastoenne, brecht Reviewed By: brecht Subscribers: brecht, #physics Maniphest Tasks: T26658 Differential Revision: https://developer.blender.org/D2120
Diffstat (limited to 'source/blender/blenkernel/intern/particle_system.c')
-rw-r--r--source/blender/blenkernel/intern/particle_system.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 8e3e2f5d6d0..0728fef2a32 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -2183,7 +2183,6 @@ static void basic_rotate(ParticleSettings *part, ParticleData *pa, float dfra, f
* http://en.wikipedia.org/wiki/Newton's_method
*
************************************************/
-#define COLLISION_MAX_COLLISIONS 10
#define COLLISION_MIN_RADIUS 0.001f
#define COLLISION_MIN_DISTANCE 0.0001f
#define COLLISION_ZERO 0.00001f
@@ -2570,10 +2569,6 @@ void BKE_psys_collision_neartest_cb(void *userdata, int index, const BVHTreeRay
pce.inside = 0;
pce.index = index;
- /* don't collide with same face again */
- if (col->hit == col->current && col->pce.index == index && col->pce.tot == 3)
- return;
-
collision = collision_sphere_to_tri(col, ray->radius, &pce, &t);
if (col->pce.inside == 0) {
collision += collision_sphere_to_edges(col, ray->radius, &pce, &t);
@@ -2609,8 +2604,17 @@ static int collision_detect(ParticleData *pa, ParticleCollision *col, BVHTreeRay
hit->dist = col->original_ray_length = 0.000001f;
for (coll = colliders->first; coll; coll=coll->next) {
- /* for boids: don't check with current ground object */
- if (coll->ob == col->skip)
+ /* for boids: don't check with current ground object; also skip if permeated */
+ bool skip = false;
+
+ for (int i = 0; i < col->skip_count; i++) {
+ if (coll->ob == col->skip[i]) {
+ skip = true;
+ break;
+ }
+ }
+
+ if (skip)
continue;
/* particles should not collide with emitter at birth */
@@ -2746,7 +2750,7 @@ static int collision_response(ParticleData *pa, ParticleCollision *col, BVHTreeR
if (through==0 && ((vc_dot>0.0f && v0_dot>0.0f && vc_dot>v0_dot) || (vc_dot<0.0f && v0_dot<0.0f && vc_dot<v0_dot)))
mul_v3_v3fl(v0_nor, pce->nor, vc_dot);
else if (v0_dot > 0.f)
- mul_v3_v3fl(v0_nor, pce->nor, vc_dot + (through ? -1.0f : 1.0f) * v0_dot);
+ mul_v3_v3fl(v0_nor, pce->nor, vc_dot + v0_dot);
else
mul_v3_v3fl(v0_nor, pce->nor, vc_dot + (through ? 1.0f : -1.0f) * v0_dot);
@@ -2801,8 +2805,10 @@ static int collision_response(ParticleData *pa, ParticleCollision *col, BVHTreeR
col->f = f;
}
- col->prev = col->hit;
- col->prev_index = hit->index;
+ /* if permeability random roll succeeded, disable collider for this sim step */
+ if (through) {
+ col->skip[col->skip_count++] = col->hit;
+ }
return 1;
}
@@ -2863,16 +2869,16 @@ static void collision_check(ParticleSimulationData *sim, int p, float dfra, floa
if (part->phystype == PART_PHYS_BOIDS && part->boids->options & BOID_ALLOW_LAND) {
col.boid = 1;
col.boid_z = pa->state.co[2];
- col.skip = pa->boid->ground;
+ col.skip[col.skip_count++] = pa->boid->ground;
}
/* 10 iterations to catch multiple collisions */
- while (collision_count < COLLISION_MAX_COLLISIONS) {
+ while (collision_count < PARTICLE_COLLISION_MAX_COLLISIONS) {
if (collision_detect(pa, &col, &hit, sim->colliders)) {
collision_count++;
- if (collision_count == COLLISION_MAX_COLLISIONS)
+ if (collision_count == PARTICLE_COLLISION_MAX_COLLISIONS)
collision_fail(pa, &col);
else if (collision_response(pa, &col, &hit, part->flag & PART_DIE_ON_COL, part->flag & PART_ROT_DYN)==0)
return;