[Bf-blender-cvs] [0c6fc34eab5] soc-2020-soft-body: updating to use SDF all over
over0219
noreply at git.blender.org
Wed Jul 15 05:09:06 CEST 2020
Commit: 0c6fc34eab5dd002050d897f3bba22e60c777277
Author: over0219
Date: Tue Jul 14 12:17:06 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rB0c6fc34eab5dd002050d897f3bba22e60c777277
updating to use SDF all over
===================================================================
M extern/softbody/CMakeLists.txt
M extern/softbody/src/admmpd_bvh_traverse.cpp
M extern/softbody/src/admmpd_bvh_traverse.h
M extern/softbody/src/admmpd_collision.cpp
M extern/softbody/src/admmpd_collision.h
M extern/softbody/src/admmpd_embeddedmesh.cpp
M extern/softbody/src/admmpd_embeddedmesh.h
A extern/softbody/src/admmpd_geom.cpp
A extern/softbody/src/admmpd_geom.h
D extern/softbody/src/admmpd_math.cpp
D extern/softbody/src/admmpd_math.h
M extern/softbody/src/admmpd_pin.cpp
M extern/softbody/src/admmpd_pin.h
A extern/softbody/src/admmpd_sdf.cpp
A extern/softbody/src/admmpd_sdf.h
M extern/softbody/src/admmpd_solver.cpp
M extern/softbody/src/admmpd_tetmesh.cpp
M extern/softbody/src/admmpd_types.h
M intern/softbody/admmpd_api.cpp
===================================================================
diff --git a/extern/softbody/CMakeLists.txt b/extern/softbody/CMakeLists.txt
index 7f631400ce0..84b2de7fea7 100644
--- a/extern/softbody/CMakeLists.txt
+++ b/extern/softbody/CMakeLists.txt
@@ -28,6 +28,18 @@ set(INC_SYS
../../source/blender/makesdna # BLI_math_geom requires DNA
)
+set(SDFGEN_SRC
+ src/sdfgen/array1.h
+ src/sdfgen/array2.h
+ src/sdfgen/array3.h
+ src/sdfgen/hashgrid.h
+ src/sdfgen/hashtable.h
+ src/sdfgen/makelevelset3.cpp
+ src/sdfgen/makelevelset3.h
+ src/sdfgen/util.h
+ src/sdfgen/vec.h
+)
+
set(SRC
src/admmpd_bvh.h
src/admmpd_bvh.cpp
@@ -39,17 +51,20 @@ set(SRC
src/admmpd_embeddedmesh.cpp
src/admmpd_energy.h
src/admmpd_energy.cpp
+ src/admmpd_geom.h
+ src/admmpd_geom.cpp
src/admmpd_linsolve.h
src/admmpd_linsolve.cpp
- src/admmpd_math.h
- src/admmpd_math.cpp
src/admmpd_pin.h
src/admmpd_pin.cpp
+ src/admmpd_sdf.h
+ src/admmpd_sdf.cpp
src/admmpd_solver.h
src/admmpd_solver.cpp
src/admmpd_tetmesh.h
src/admmpd_tetmesh.cpp
src/admmpd_types.h
+ ${SDFGEN_SRC}
)
set(LIB
diff --git a/extern/softbody/src/admmpd_bvh_traverse.cpp b/extern/softbody/src/admmpd_bvh_traverse.cpp
index 0695aeef2b5..7def5340085 100644
--- a/extern/softbody/src/admmpd_bvh_traverse.cpp
+++ b/extern/softbody/src/admmpd_bvh_traverse.cpp
@@ -5,13 +5,86 @@
#define ADMMPD_BVH_H_ 1
#include "admmpd_bvh_traverse.h"
-#include "admmpd_math.h"
+#include "admmpd_geom.h"
#include "BLI_assert.h"
#include "BLI_math_geom.h"
namespace admmpd {
using namespace Eigen;
+template <typename T>
+RayClosestHit<T>::RayClosestHit(
+ const VecType &orig_,
+ const VecType &dir_,
+ const MatrixXType *prim_verts_,
+ const Eigen::MatrixXi *tri_inds_,
+ T eps_,
+ T t_min_,
+ T t_max_) :
+ o(orig_),
+ d(dir_),
+ prim_verts(prim_verts_),
+ tri_inds(tri_inds_),
+ eps(eps_),
+ t_min(t_min_)
+{
+ output.t_max = t_max_;
+ BLI_assert(prim_verts != NULL);
+ BLI_assert(tri_inds != NULL);
+ BLI_assert(prim_verts->cols()==3);
+ BLI_assert(tri_inds->cols()==3);
+}
+
+template <typename T>
+void RayClosestHit<T>::traverse(
+ const AABB &left_aabb, bool &go_left,
+ const AABB &right_aabb, bool &go_right,
+ bool &go_left_first)
+{
+ go_left = geom::ray_aabb<T>(o,d,left_aabb,t_min,output.t_max) ||
+ (eps > 0 ? left_aabb.exteriorDistance(o) < eps : false);
+ go_right = geom::ray_aabb<T>(o,d,right_aabb,t_min,output.t_max) ||
+ (eps > 0 ? right_aabb.exteriorDistance(o) < eps : false);
+}
+
+template <typename T>
+bool RayClosestHit<T>::stop_traversing(const AABB &aabb, int prim)
+{
+ BLI_assert(prim > 0);
+ BLI_assert(prim < tri_inds->rows());
+ if (!geom::ray_aabb<T>(o,d,aabb,t_min,output.t_max))
+ return true;
+ RowVector3i p = tri_inds->row(prim);
+ VecType v[3] = {
+ prim_verts->row(p[0]),
+ prim_verts->row(p[1]),
+ prim_verts->row(p[2])
+ };
+ T t_max = output.t_max;
+ VecType bary;
+ bool hit = geom::ray_triangle<T>(o,d,v[0],v[1],v[2],t_min,t_max,&bary);
+ if (hit)
+ {
+ output.prim = prim;
+ output.t_max = t_max;
+ output.barys = bary;
+ return false;
+ }
+ if (eps > 0)
+ {
+ VecType o_on_tri = geom::point_on_triangle<T>(o,v[0],v[1],v[2]);
+ T dist = (o-o_on_tri).norm();
+ if (dist < eps)
+ {
+ output.prim = prim;
+ output.t_max = dist;
+ output.barys = geom::point_triangle_barys<T>(o_on_tri,v[0],v[1],v[2]);
+ }
+ }
+ return false;
+}
+
+
template <typename T>
void PointInTetMeshTraverse<T>::traverse(
const AABB &left_aabb, bool &go_left,
@@ -43,7 +116,7 @@ bool PointInTetMeshTraverse<T>::stop_traversing(
prim_verts->row(t[3])
};
- bool hit = point_in_tet(
+ bool hit = geom::point_in_tet(
point.template cast<double>(),
v[0].template cast<double>(),
v[1].template cast<double>(),
@@ -285,6 +358,8 @@ bool TetIntersectsMeshTraverse<T>::stop_traversing(
} // end point in mesh stop traversing
// Compile template types
+template class admmpd::RayClosestHit<double>;
+template class admmpd::RayClosestHit<float>;
template class admmpd::PointInTetMeshTraverse<double>;
template class admmpd::PointInTetMeshTraverse<float>;
template class admmpd::PointInTriangleMeshTraverse<double>;
diff --git a/extern/softbody/src/admmpd_bvh_traverse.h b/extern/softbody/src/admmpd_bvh_traverse.h
index 774eb6a6b10..29eebd0163d 100644
--- a/extern/softbody/src/admmpd_bvh_traverse.h
+++ b/extern/softbody/src/admmpd_bvh_traverse.h
@@ -9,6 +9,7 @@
namespace admmpd {
+
// Traverse class for traversing the structures.
template <typename T, int DIM>
class Traverser
@@ -31,6 +32,51 @@ public:
virtual bool stop_traversing(const AABB &aabb, int prim) = 0;
};
+// Closest hit BVH traversal.
+template <typename T>
+class RayClosestHit : public Traverser<T,3>
+{
+protected:
+ using typename Traverser<T,3>::AABB;
+ typedef Eigen::Matrix<T,3,1> VecType;
+ typedef Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> MatrixXType;
+
+ VecType o, d;
+ const MatrixXType *prim_verts;
+ const Eigen::MatrixXi *tri_inds;
+ T eps;
+ T t_min;
+
+public:
+ struct Output {
+ int prim; // -1 if no intersections
+ T t_max;
+ VecType barys;
+ Output() :
+ prim(-1),
+ t_max(std::numeric_limits<T>::max()),
+ barys(VecType::Zero())
+ {}
+ } output;
+
+ RayClosestHit(
+ const VecType &orig_, // ray origin
+ const VecType &dir_, // normalized ray direction
+ const MatrixXType *prim_verts_,
+ const Eigen::MatrixXi *tri_inds_,
+ T eps_, // if dist(0,tri) < eps, is a hit. eps<=0 skips this test
+ T t_min_=0,
+ T t_max_=std::numeric_limits<T>::max());
+
+ void traverse(
+ const AABB &left_aabb, bool &go_left,
+ const AABB &right_aabb, bool &go_right,
+ bool &go_left_first);
+
+ // Searches for closest hit, so always returns false
+ bool stop_traversing(const AABB &aabb, int prim);
+};
+
// Point in tet mesh traversal
template <typename T>
class PointInTetMeshTraverse : public Traverser<T,3>
diff --git a/extern/softbody/src/admmpd_collision.cpp b/extern/softbody/src/admmpd_collision.cpp
index 4d2444e6a52..892a599264d 100644
--- a/extern/softbody/src/admmpd_collision.cpp
+++ b/extern/softbody/src/admmpd_collision.cpp
@@ -3,7 +3,7 @@
#include "admmpd_collision.h"
#include "admmpd_bvh_traverse.h"
-#include "admmpd_math.h"
+#include "admmpd_geom.h"
#include "BLI_assert.h"
#include "BLI_task.h"
@@ -51,6 +51,7 @@ void Collision::set_obstacles(
obsdata.aabbs.resize(nf);
}
+ Vector3d v_eta = Vector3d::Ones()*settings.collision_eps;
for (int i=0; i<nf; ++i)
{
obsdata.aabbs[i].setEmpty();
@@ -61,156 +62,93 @@ void Collision::set_obstacles(
obsdata.aabbs[i].extend(obsdata.V0.row(fj).transpose());
obsdata.aabbs[i].extend(obsdata.V1.row(fj).transpose());
}
+ obsdata.aabbs[i].extend(obsdata.aabbs[i].min()-v_eta);
+ obsdata.aabbs[i].extend(obsdata.aabbs[i].max()+v_eta);
}
obsdata.tree.init(obsdata.aabbs);
} // end add obstacle
-void Collision::detect_discrete_vf(
- const Eigen::Vector3d &pt,
- int pt_idx,
- bool pt_is_obs,
- const AABBTree<double,3> *mesh_tree,
- const Eigen::MatrixXd *mesh_x,
- const Eigen::MatrixXi *mesh_tris,
- bool mesh_is_obs,
- std::vector<VFCollisionPair> *pairs)
+std::pair<bool,VFCollisionPair>
+Collision::detect_point_against_mesh(
+ int pt_idx,
+ bool pt_is_obs,
+ const Eigen::Vector3d &pt_t0,
+ const Eigen::Vector3d &pt_t1,
+ bool mesh_is_obs,
+ const Eigen::MatrixXd *mesh_x,
+ const Eigen::MatrixXi *mesh_tris,
+ const AABBTree<double,3> *mesh_tree) const
{
+ std::pair<bool,VFCollisionPair> ret =
+ std::make_pair(false, VFCollisionPair());
+
// Any faces to detect against?
if (mesh_tris->rows()==0)
- return;
-
- // TODO
- // This won't work for overlapping obstacles.
- // We would instead need something like a signed distance field
- // or continuous collision detection.
-
- PointInTriangleMeshTraverse<double> pt_in_mesh(
- pt, mesh_x, mesh_tris);
- mesh_tree->traverse(pt_in_mesh);
- if (pt_in_mesh.output.num_hits() % 2 != 1)
- return;
-
- // If we are inside an obstacle, we
- // have to project to the nearest surface.
-
- // TODO
- // Consider replacing this with BLI codes:
- // BLI_bvhtree_find_nearest in BLI_kdopbvh.h
- // But since it doesn't have a point-in-mesh
- // detection, we may as use our own BVH/traverser
- // for now.
-
- NearestTriangleTraverse<double> find_nearest_tri(
- pt, mesh_x, mesh_tris);
- mesh_tree->traverse(find_nearest_tri);
- if (find_nearest_tri.output.prim < 0) // error
- return;
+ return ret;
- // Create collision pair
- pairs->emplace_back();
- VFCollisionPair &pair = pairs->back();
+/*
+ VFCollisionPair &pair = ret.second;
+ pair.p_idx = pt_idx;
+ pair.p_is_obs = false;
+ pair.q_idx = 0;
+ pair.q_is_obs = 1;
+ double max_z = mesh_x->col(2).maxCoeff();
+ pair.pt_on_q = Vector3d(pt_t1[0],pt_t1[1],max_z);
+*/
+ return ret;
+/*
+ // Use a ray that is pos at t0 to t1
+ // with t_max being the displacment. If not moving,
+ // set the "eps" variable used by traversal which
+ // does point-triangle distance, and considers it a hit
+ // if the distance is less than the eps.
+ Vector3d dx = (pt_t1-pt_t0);
+ double t_max = dx.norm();
+ double eps = -1; // used as point-triangle distance query
+ //if (t_max < settings.collision_eps)
+ if (false)
+ {
+ dx = Vector3d(0,0,1);
+ t_max = settings.collision_eps;
+ eps = settings.collision_eps;
+ }
+ dx.normalize();
+
+ // Traverse the BVH
+ RayClosestHit<double> ray_hit_mesh(
+ pt_t0, dx,
+ mesh_x, mesh_tris,
+ eps, 0, t_max);
+ mesh_tree->traverse(ray_hit_mesh);
+
+// if (pt_idx==0)
+// {
+// std::cout << "\n\nV0 (z): " << pt_t0[2] << std::endl;
+// std::cout << "dir: " << dx.transpose() << std::endl;
+// std::cout << ray_hit_mesh.output.prim << std::endl;
+// if(ray_hit_mesh.output.prim >= 0)
+// throw std::runtime_error("YAY HIT");
+// }
+
+ if (ray_hit_mesh.output.prim < 0)
+ return ret;
+
+ ret.first = true;
+ VFCollisionPair &pair = ret.second;
pair.p_idx = pt_idx;
pair.p_is_obs = pt_is_obs;
- pair.q_idx = find_nearest_tri.output.prim;
+ pair.q_idx = ray_hit_mesh.output.prim;
pair.q_is_obs = mesh_is_obs;
- pair.pt_on_q = find_nearest_tri.output.pt_on_tri;
-
- // Compute face normal
-// BLI_assert(pair.q_idx >= 0);
-// BLI_assert(pair.q_idx < mesh_tris->rows());
-// RowVector3i tri_inds = mesh_tris->row(pair.q_idx);
-/
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list