[Bf-blender-cvs] [c3ce36fdc42] particle-solver-dev: Simplified the moving triangle collision check algo

Sebastian Parborg noreply at git.blender.org
Fri Apr 3 15:17:21 CEST 2020


Commit: c3ce36fdc42f8a90f6d5affc2f5b5286998d98aa
Author: Sebastian Parborg
Date:   Fri Apr 3 15:16:18 2020 +0200
Branches: particle-solver-dev
https://developer.blender.org/rBc3ce36fdc42f8a90f6d5affc2f5b5286998d98aa

Simplified the moving triangle collision check algo

===================================================================

M	source/blender/simulations/bparticles/simulate.cpp

===================================================================

diff --git a/source/blender/simulations/bparticles/simulate.cpp b/source/blender/simulations/bparticles/simulate.cpp
index 5aaf4101cf8..741027824cf 100644
--- a/source/blender/simulations/bparticles/simulate.cpp
+++ b/source/blender/simulations/bparticles/simulate.cpp
@@ -30,39 +30,13 @@ using FN::CPPType;
 #define COLLISION_MIN_RADIUS 0.001f     // TODO check if this is needed
 #define COLLISION_MIN_DISTANCE 0.0001f  // TODO check if this is needed
 #define COLLISION_ZERO 0.00001f
-static float nr_signed_distance_to_plane(
-    float3 &p, std::array<float3, 3> &cur_tri_points, float3 &nor, float radius, int8_t &inv_nor)
+static float distance_to_tri(float3 &p, std::array<float3, 3> &cur_tri_points, float radius)
 {
-  float3 p0, e1, e2;
-  float d;
+  float3 closest_point;
+  closest_on_tri_to_point_v3(
+      closest_point, p, cur_tri_points[0], cur_tri_points[1], cur_tri_points[2]);
 
-  sub_v3_v3v3(e1, cur_tri_points[1], cur_tri_points[0]);
-  sub_v3_v3v3(e2, cur_tri_points[2], cur_tri_points[0]);
-  sub_v3_v3v3(p0, p, cur_tri_points[0]);
-
-  cross_v3_v3v3(nor, e1, e2);
-  normalize_v3(nor);
-
-  d = dot_v3v3(p0, nor);
-
-  if (inv_nor == -1) {
-    if (d < 0.f) {
-      inv_nor = 1;
-    }
-    else {
-      inv_nor = 0;
-    }
-  }
-
-  if (inv_nor == 1) {
-    negate_v3(nor);
-    d = -d;
-  }
-
-  // We are now in practise moving the math plane "up" along the normal by the particle radius.
-  // This means that we are now trying to find the time where the particle first touches the plane,
-  // not where it intersects.
-  return d - radius;
+  return float3::distance(closest_point, p) - radius;
 }
 
 static void collision_interpolate_element(std::array<std::pair<float3, float3>, 3> &tri_points,
@@ -85,15 +59,11 @@ static float collision_newton_rhapson(std::pair<float3, float3> &particle_points
   float t0, t1, dt_init, d0, d1, dd;
   float3 p;
 
-  // Used to keep track of if we should invert the plane normal.
-  int8_t invert_tri_normal = -1;
-
   dt_init = 0.001f;
   /* start from the beginning */
   t0 = 0.f;
   collision_interpolate_element(tri_points, cur_tri_points, t0);
-  d0 = nr_signed_distance_to_plane(
-      particle_points.first, cur_tri_points, coll_normal, radius, invert_tri_normal);
+  d0 = distance_to_tri(particle_points.first, cur_tri_points, radius);
   t1 = dt_init;
   d1 = 0.f;
 
@@ -102,13 +72,16 @@ static float collision_newton_rhapson(std::pair<float3, float3> &particle_points
     collision_interpolate_element(tri_points, cur_tri_points, t1);
     p = float3::interpolate(particle_points.first, particle_points.second, t1);
 
-    d1 = nr_signed_distance_to_plane(p, cur_tri_points, coll_normal, radius, invert_tri_normal);
+    d1 = distance_to_tri(p, cur_tri_points, radius);
 
     /* particle already inside face, so report collision */
-    if (iter == 0 && d0 < 0.f && d0 > -radius) {
+    if (iter == 0 && d0 <= COLLISION_ZERO) {
       p = particle_points.first;
-      // TODO need to check if inside triangle here too
-      // pce->inside = 1;
+      // Save barycentric weight for velocity calculation later
+      interp_weights_tri_v3(
+          hit_bary_weights, cur_tri_points[0], cur_tri_points[1], cur_tri_points[2], p);
+
+      normal_tri_v3(coll_normal, cur_tri_points[0], cur_tri_points[1], cur_tri_points[2]);
       return 0.f;
     }
 
@@ -120,8 +93,7 @@ static float collision_newton_rhapson(std::pair<float3, float3> &particle_points
       if (iter == 0) {
         t0 = 1.f;
         collision_interpolate_element(tri_points, cur_tri_points, t0);
-        d0 = nr_signed_distance_to_plane(
-            particle_points.second, cur_tri_points, coll_normal, radius, invert_tri_normal);
+        d0 = distance_to_tri(particle_points.second, cur_tri_points, radius);
         t1 = 1.0f - dt_init;
         d1 = 0.f;
         continue;
@@ -143,8 +115,7 @@ static float collision_newton_rhapson(std::pair<float3, float3> &particle_points
     if (iter == 0 && t1 < 0.f) {
       t0 = 1.f;
       collision_interpolate_element(tri_points, cur_tri_points, t0);
-      d0 = nr_signed_distance_to_plane(
-          particle_points.second, cur_tri_points, coll_normal, radius, invert_tri_normal);
+      d0 = distance_to_tri(particle_points.second, cur_tri_points, radius);
       t1 = 1.0f - dt_init;
       d1 = 0.f;
       continue;
@@ -155,27 +126,14 @@ static float collision_newton_rhapson(std::pair<float3, float3> &particle_points
 
     if (abs(d1) <= COLLISION_ZERO) {
       if (t1 >= -COLLISION_ZERO && t1 <= 1.f) {
-        /* Do we actually hit the triangle or did we only hit the math plane? */
-        float3 closest_point;
-        closest_on_tri_to_point_v3(
-            closest_point, p, cur_tri_points[0], cur_tri_points[1], cur_tri_points[2]);
-        if (float3::distance(closest_point, p) - radius <= 2.0f * COLLISION_ZERO) {
-          // We use "2.0f * COLLISION_ZERO" here because our applied radius offset to the math
-          // plane.
-          // This means that the distance from the actual plane can be: radius +/- COLLISION_ZERO.
-
-          // Save barycentric weight for velocity calculation later
-          interp_weights_tri_v3(hit_bary_weights,
-                                cur_tri_points[0],
-                                cur_tri_points[1],
-                                cur_tri_points[2],
-                                closest_point);
-          CLAMP(t1, 0.f, 1.f);
-          return t1;
-        }
-        else {
-          return -1.f;
-        }
+        // Save barycentric weight for velocity calculation later
+        interp_weights_tri_v3(
+            hit_bary_weights, cur_tri_points[0], cur_tri_points[1], cur_tri_points[2], p);
+
+        normal_tri_v3(coll_normal, cur_tri_points[0], cur_tri_points[1], cur_tri_points[2]);
+
+        CLAMP(t1, 0.f, 1.f);
+        return t1;
       }
       else {
         return -1.f;
@@ -268,7 +226,7 @@ BLI_NOINLINE static void raycast_callback(void *userdata,
     // We have a collision!
     hit->index = index;
     hit->dist = dist;
-    madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, hit->dist - ray->radius);
+    madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist);
     // zero_v3(hit->co);
     copy_v3_v3(hit->no, coll_normal);
 
@@ -389,8 +347,8 @@ BLI_NOINLINE static void simulate_particle_chunk(SimulationState &UNUSED(simulat
 
           if (!is_zero_v3(best_hit_vel)) {
             // XXX Put inside "is_zero" if statement for debugging
-            dead_state[pindex] = true;
-            velocities[pindex] += best_hit_vel;
+            // dead_state[pindex] = true;
+            velocities[pindex] = best_hit_vel;
           }
           // Calculate the remaining duration
           duration -= duration * (1.0f - best_hit.dist / max_move);



More information about the Bf-blender-cvs mailing list