Commit: cc20d9db37408e3a5ac760fbb609f5edead7d5f5
Author: mattoverby
Date:   Tue Aug 11 12:22:31 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rBcc20d9db37408e3a5ac760fbb609f5edead7d5f5

lerping obstacles for substeps and collisions

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

M       intern/softbody/admmpd_api.cpp

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

diff --git a/intern/softbody/admmpd_api.cpp b/intern/softbody/admmpd_api.cpp
index 73a92fe902f..06f0d1e693c 100644
--- a/intern/softbody/admmpd_api.cpp
+++ b/intern/softbody/admmpd_api.cpp
@@ -42,7 +42,14 @@
 
 #define ADMMPD_API_DEBUG
 
-
+// Collision obstacles are cached until
+// solve(...) is called. If we are substepping,
+// the obstacle is interpolated from start to end.
+struct CollisionObstacle
+{
+  Eigen::VectorXf x0, x1;
+  std::vector<unsigned int> F;
+};
 
 struct ADMMPDInternalData
 {
@@ -52,6 +59,8 @@ struct ADMMPDInternalData
   // Created in admmpd_update_solver
   std::shared_ptr<admmpd::Options> options;
   std::shared_ptr<admmpd::SolverData> data;
+  // Created in set_obstacles
+  CollisionObstacle obs;
 };
 
 
@@ -553,15 +562,26 @@ void admmpd_update_obstacles(
     unsigned int *in_faces,
     int nf)
 {
-    if (iface==NULL || in_verts_0==NULL || in_verts_1==NULL || in_faces==NULL)
-      return;
-    if (!iface->idata)
-      return;
-    if (!iface->idata->collision)
-      return;
+  if (iface==NULL || in_verts_0==NULL || in_verts_1==NULL || in_faces==NULL)
+    return;
+  if (!iface->idata) { return; }
+  if (!iface->idata->collision) { return; }
+  if (nf==0 || nv==0) { return; }
+
+  int nv3 = nv*3;
+  iface->idata->obs.x0.resize(nv3);
+  iface->idata->obs.x1.resize(nv3);
+  int nf3 = nf*3;
+  iface->idata->obs.F.resize(nf3);
+
+  for (int i=0; i<nv3; ++i)
+  {
+    iface->idata->obs.x0[i] = in_verts_0[i];
+    iface->idata->obs.x1[i] = in_verts_1[i];
+  }
+  for (int i=0; i<nf3; ++i)
+    iface->idata->obs.F[i] = in_faces[i];
 
-    iface->idata->collision->set_obstacles(
-      in_verts_0, in_verts_1, nv, in_faces, nf);
 }
 
 void admmpd_update_goals(
@@ -609,11 +629,47 @@ int admmpd_solve(ADMMPDInterfaceData *iface, Object *ob)
     iface->idata->options.get(),
     true);
 
+  // Changing the location of the obstacles requires a recompuation
+  // of the SDF. So we'll only do that if we need to:
+  // a) we are substepping (need to lerp)
+  // b) the obstacle is actually moving.
+  bool has_obstacles = 
+    iface->idata->collision &&
+    iface->idata->obs.x0.size() > 0 &&
+    iface->idata->obs.F.size() > 0 &&
+    iface->idata->obs.x0.size()==iface->idata->obs.x1.size();
+  bool lerp_obstacles =
+    has_obstacles &&
+    iface->idata->options->substeps>1 &&
+    (iface->idata->obs.x0-iface->idata->obs.x1).lpNorm<Eigen::Infinity>()>1e-6;
+
+  if (has_obstacles && !lerp_obstacles)
+  {
+    iface->idata->collision->set_obstacles(
+      iface->idata->obs.x0.data(),
+      iface->idata->obs.x1.data(),
+      iface->idata->obs.x0.size()/3,
+      iface->idata->obs.F.data(),
+      iface->idata->obs.F.size()/3);
+  }
+
   try
   {
+    Eigen::VectorXf obs_x1; // used if substeps > 1
     int substeps = std::max(1,iface->idata->options->substeps);
     for (int i=0; i<substeps; ++i)
     {
+      if (lerp_obstacles)
+      {
+          float t = float(i)/float(substeps-1);
+          obs_x1 = (1.f-t)*iface->idata->obs.x0 + t*iface->idata->obs.x1;
+          iface->idata->collision->set_obstacles(
+            iface->idata->obs.x0.data(),
+            obs_x1.data(),
+            iface->idata->obs.x0.size()/3,
+            iface->idata->obs.F.data(),
+            iface->idata->obs.F.size()/3);
+      }
       admmpd::Solver().solve(
         iface->idata->mesh.get(),
         iface->idata->options.get(),

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to