[Bf-blender-cvs] [ed69983ec26] particle-solver-dev: Added friction and fixed some issue that were discovered when doing so.

Sebastian Parborg noreply at git.blender.org
Mon Jun 22 13:31:08 CEST 2020


Commit: ed69983ec264a5ce4786fd770f7832b5346c5376
Author: Sebastian Parborg
Date:   Mon Jun 22 13:30:22 2020 +0200
Branches: particle-solver-dev
https://developer.blender.org/rBed69983ec264a5ce4786fd770f7832b5346c5376

Added friction and fixed some issue that were discovered when doing so.

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

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

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

diff --git a/source/blender/simulations/bparticles/simulate.cpp b/source/blender/simulations/bparticles/simulate.cpp
index 7175c2538ee..c4c47b89045 100644
--- a/source/blender/simulations/bparticles/simulate.cpp
+++ b/source/blender/simulations/bparticles/simulate.cpp
@@ -1,3 +1,4 @@
+#include "DNA_object_force_types.h"
 
 #include "BLI_timeit.h"
 #include "BLI_array_cxx.h"
@@ -246,10 +247,7 @@ BLI_NOINLINE static void raycast_callback(void *userdata,
     if (dist >= 0.0f && dist < hit->dist) {
       hit->index = index;
       hit->dist = dist;
-      // Subract COLLISION_MIN_DISTANCE from the distance to make sure that we do not collide with
-      // the exact same point if the particle does not have time to move away from the collision
-      // point.
-      madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist - COLLISION_MIN_DISTANCE);
+      madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist);
 
       normal_from_closest_point_to_tri(hit->no, hit->co, v0, v1, v2);
       // TODO clean up (unify this into a function and using it in the rapson code)
@@ -381,6 +379,7 @@ BLI_NOINLINE static void simulate_particle_chunk(SimulationState &UNUSED(simulat
 
   MutableArrayRef<float3> velocities = attributes.get<float3>("Velocity");
   MutableArrayRef<float3> positions = attributes.get<float3>("Position");
+  MutableArrayRef<float> sizes = attributes.get<float>("Size");
   MutableArrayRef<bool> dead_state = attributes.get<bool>("Dead");
 
   // system_info.collision_objects
@@ -388,10 +387,14 @@ BLI_NOINLINE static void simulate_particle_chunk(SimulationState &UNUSED(simulat
   // cloth_bvh_collision
 
   for (uint pindex : IndexRange(amount)) {
-    // if (pindex != 84 /* && pindex != 357 && pindex != 378*/) {
+    // if (pindex != 11) {
     //  continue;
     //}
 
+    // if (positions[pindex][2] > -1.0f) {
+    //  printf("pindex: %d\n", pindex);
+    //}
+
     float mass = 1.0f;
     float duration = remaining_durations[pindex];
     bool collided;
@@ -407,6 +410,7 @@ BLI_NOINLINE static void simulate_particle_chunk(SimulationState &UNUSED(simulat
       do {
         BVHTreeRayHit best_hit;
         float3 best_hit_vel;
+        PartDeflect *best_hit_settings;
         float max_move;
 
         float3 dir;
@@ -439,7 +443,7 @@ BLI_NOINLINE static void simulate_particle_chunk(SimulationState &UNUSED(simulat
           hit.dist = max_move;
 
           // TODO the particle radius seems a bit flaky with higher distances?
-          float particle_radius = 0.05f;
+          float particle_radius = sizes[pindex];
 
           float3 start = positions[pindex];
 
@@ -467,7 +471,11 @@ BLI_NOINLINE static void simulate_particle_chunk(SimulationState &UNUSED(simulat
             // We didn't hit anything
             continue;
           }
-          if (prev_collider == collmd && prev_hit_idx == hit.index) {
+          if (false && prev_collider == collmd && prev_hit_idx == hit.index) {
+            // TODO look into removing this check as it shouldn't be needed anymore. If the
+            // particle hits the same face twice in a row, it must be because it couldn't move
+            // enough and should be poked again by this face.
+
             // We collided with the same face twice in a row.
             // Skip collision handling here as the set velocity from the previous collision
             // handling should keep the particle from tunneling through the face.
@@ -476,6 +484,8 @@ BLI_NOINLINE static void simulate_particle_chunk(SimulationState &UNUSED(simulat
 
           best_hit = hit;
           best_hit_vel = rd.hit_vel;
+          best_hit_settings = col->ob->pd;
+
           prev_collider = collmd;
           prev_hit_idx = hit.index;
           collided = true;
@@ -491,38 +501,62 @@ BLI_NOINLINE static void simulate_particle_chunk(SimulationState &UNUSED(simulat
           velocities[pindex] += elapsed_time * forces[pindex] * mass;
 
           // dead_state[pindex] = true;
-          float dampening = 0.2f;
+          // TODO rename "dampening, in the old particle system dampening here was used to only
+          // reduce the speed in the normal direction. So a better name would be bouncyness or
+          // elastisity.
+          float dampening = best_hit_settings->pdef_damp;
+          float friction = best_hit_settings->pdef_frict;
 
           float3 normal = best_hit.no;
 
+          float dot_epsilon = 1e-5f;
+
           // printf("==== COLLIDED ====\n");
           // print_v3("best_hit", best_hit.co);
 
           // print_v3("hit normal", normal);
           // print_v3("hit velo", best_hit_vel);
           // print_v3("part velo", velocities[pindex]);
+          // print_v3("const vel pre", constraint_velo);
 
           // Modify constraint_velo so if it is along the collider normal if it is moving into
           // the collision plane.
-          if (dot_v3v3(constraint_velo, normal) < 0.0f) {
+          if (dot_v3v3(constraint_velo, normal) < -dot_epsilon) {
+            float len = constraint_velo.length();
+
             constraint_velo -= float3::project(constraint_velo, normal);
+
+            // Make sure that we are moving the same amount as before, otherwise this will cause
+            // the constraint to lose the desired final speed and the particle will possibly not
+            // move enough.
+            constraint_velo *= len / constraint_velo.length();
           }
 
-          if (dot_v3v3(best_hit_vel, normal) > 0.0f) {
+          if (dot_v3v3(best_hit_vel, normal) > dot_epsilon) {
             // The collider is moving towards the particle, we need to make sure that the particle
             // has enough velocity to not tunnel through.
-
-            constraint_velo = min_add(constraint_velo, best_hit_vel);
+            // The minimal distance we have to travel to still be outside is in the normal
+            // direction.
+            float3 min_move = float3::project(best_hit_vel, normal);
+            // print_v3("normal", normal);
+            // print_v3("min_move", min_move);
+            // min_move *= best_hit_vel.length() / min_move.length();
+
+            constraint_velo = min_add(constraint_velo, min_move);
           }
 
           float3 hit_velo_normal = float3::project(best_hit_vel, normal);
+          float3 hit_velo_tangent = best_hit_vel - hit_velo_normal;
 
           float3 part_velo_normal = float3::project(velocities[pindex], normal);
           float3 part_velo_tangent = velocities[pindex] - part_velo_normal;
 
-          float3 deflect_vel = part_velo_tangent - (part_velo_normal - hit_velo_normal);
+          interp_v3_v3v3(part_velo_tangent, part_velo_tangent, hit_velo_tangent, friction);
+
+          float3 deflect_vel = part_velo_tangent -
+                               (part_velo_normal - hit_velo_normal) * (1.0f - dampening);
 
-          if (dot_v3v3(best_hit_vel, velocities[pindex]) > 0.0f) {
+          if (dot_v3v3(hit_velo_normal, part_velo_normal) > dot_epsilon) {
             // The collider were traveling in the same direction as the particle.
             // We need to add the initial particle velocity back (in the normal direction) to get
             // the final velocity.
@@ -530,14 +564,15 @@ BLI_NOINLINE static void simulate_particle_chunk(SimulationState &UNUSED(simulat
             deflect_vel += part_velo_normal;
           }
 
-          deflect_vel *= (1.0f - dampening);
+          // deflect_vel *= (1.0f - dampening);
 
           // print_v3("normal", normal);
           // printf("normal dir %f\n", normal_dot);
           // print_v3("n_v", n_v);
-          // print_v3("vel hit", best_hit_vel);
+          // print_v3("best hit vel", best_hit_vel);
           // print_v3("hit_normal_velo", hit_normal_velo);
-          // print_v3("vel_pre", velocities[pindex]);
+          // print_v3("pos", positions[pindex]);
+          // print_v3("velo", velocities[pindex]);
           // print_v3("vel_local", local_velo);
           // print_v3("deflect_vel", deflect_vel);
           // print_v3("const vel", constraint_velo);
@@ -547,17 +582,18 @@ BLI_NOINLINE static void simulate_particle_chunk(SimulationState &UNUSED(simulat
 
           sub_v3_v3v3(temp, positions[pindex], best_hit.co);
 
-          if (temp.length() > velocities[pindex].length()) {
-            // We moved further than our velocity should have allowed us to.
-            print_v3("best_hit", best_hit.co);
-            printf("pindex: %d\n\n\n\n", pindex);
-          }
+          // if (temp.length() > velocities[pindex].length()) {
+          //  // We moved further than our velocity should have allowed us to.
+          //  print_v3("best_hit", best_hit.co);
+          //  printf("pindex: %d\n\n\n\n", pindex);
+          //}
 
           if (!is_zero_v3(constraint_velo)) {
-            if (coll_num == 9) {
+            if (coll_num == 99) {
               // If we are at the last collision check, just try to go into the constraint velocity
               // direction and hope for the best.
-              deflect_vel = constraint_velo;
+              deflect_vel = float3(0, 0, 1);
+              printf("Gahh\n");
             }
             else if (float3::project(deflect_vel, constraint_velo).length() <
                      constraint_velo.length()) {
@@ -576,7 +612,8 @@ BLI_NOINLINE static void simulate_particle_chunk(SimulationState &UNUSED(simulat
           // printf("pindex: %d collnum: %d\n\n", pindex, coll_num);
           coll_num++;
         }
-      } while (collided && coll_num < 10);
+      } while (collided && coll_num < 100);
+      // TODO perhaps expose the max iterations in the UI?
     }
     float3 move_vec = duration * velocities[pindex];
     positions[pindex] += move_vec;



More information about the Bf-blender-cvs mailing list