[Bf-blender-cvs] [0087149790a] soc-2020-soft-body: moved collision detection back to inner loop

over0219 noreply at git.blender.org
Thu Jul 16 01:43:31 CEST 2020


Commit: 0087149790a220173776449ce2bc152b747af3fc
Author: over0219
Date:   Wed Jul 15 18:43:25 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rB0087149790a220173776449ce2bc152b747af3fc

moved collision detection back to inner loop

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

M	extern/softbody/src/admmpd_bvh.cpp
M	extern/softbody/src/admmpd_bvh.h
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_linsolve.cpp
M	extern/softbody/src/admmpd_solver.cpp
M	extern/softbody/src/admmpd_solver.h
M	extern/softbody/src/admmpd_types.h

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

diff --git a/extern/softbody/src/admmpd_bvh.cpp b/extern/softbody/src/admmpd_bvh.cpp
index 6ea7a676d27..afa16874062 100644
--- a/extern/softbody/src/admmpd_bvh.cpp
+++ b/extern/softbody/src/admmpd_bvh.cpp
@@ -12,35 +12,35 @@ namespace admmpd {
 template <typename T, int DIM>
 void AABBTree<T,DIM>::clear()
 {
-    root = std::make_shared<Node>();
+    m_root = std::make_shared<Node>();
 }
 
 template <typename T, int DIM>
 void AABBTree<T,DIM>::init(const std::vector<AABB> &leaves)
 {
-    root = std::make_shared<Node>();
+    m_root = std::make_shared<Node>();
     int np = leaves.size();
     if (np==0)
         return;
     std::vector<int> queue(np);
     std::iota(queue.begin(), queue.end(), 0);
-    create_children(root.get(), queue, leaves);
+    create_children(m_root.get(), queue, leaves);
 }
 
 template <typename T, int DIM>
 void AABBTree<T,DIM>::update(const std::vector<AABB> &leaves)
 {
-    if (!root || (int)leaves.size()==0)
+    if (!m_root || (int)leaves.size()==0)
         return;
-    update_children(root.get(), leaves);
+    update_children(m_root.get(), leaves);
 }
 
 template <typename T, int DIM>
 bool AABBTree<T,DIM>::traverse(Traverser<T,DIM> &traverser) const
 {
-    if (!root)
+    if (!m_root)
         return false;
-    return traverse_children(root.get(), traverser);
+    return traverse_children(m_root.get(), traverser);
 }
 
 // If we are traversing with function pointers, we'll just
@@ -71,12 +71,12 @@ bool AABBTree<T,DIM>::traverse(
     std::function<void(const AABB&, bool&, const AABB&, bool&, bool&)> t,
     std::function<bool(const AABB&, int)> s) const
 {
-    if (!root)
+    if (!m_root)
         return false;
     TraverserFromFunctionPtrs<T,DIM> traverser;
     traverser.t = t;
     traverser.s = s;
-    return traverse_children(root.get(), traverser);
+    return traverse_children(m_root.get(), traverser);
 }
 
 template <typename T, int DIM>
@@ -264,7 +264,7 @@ typename Octree<T,DIM>::Node* Octree<T,DIM>::create_children(
     const std::vector<AABB> &boxes)
 {
     BLI_assert((int)queue.size()>0);
-    BLI_assert((int)prim_boxes.size()>0);
+    BLI_assert((int)boxes.size()>0);
     BLI_assert(F != nullptr);
     BLI_assert(V != nullptr);
     BLI_assert(F->cols()==3);
diff --git a/extern/softbody/src/admmpd_bvh.h b/extern/softbody/src/admmpd_bvh.h
index 20b810ac7be..88ff5393dc4 100644
--- a/extern/softbody/src/admmpd_bvh.h
+++ b/extern/softbody/src/admmpd_bvh.h
@@ -58,9 +58,13 @@ public:
 		}
 	};
 
+	// Return ptr to the root node
+	// Becomes invalidated after init()
+	std::shared_ptr<Node> root() { return m_root; }
+
 protected:
 
-	std::shared_ptr<Node> root;
+	std::shared_ptr<Node> m_root;
 
 	void create_children(
 		Node *node,
diff --git a/extern/softbody/src/admmpd_bvh_traverse.cpp b/extern/softbody/src/admmpd_bvh_traverse.cpp
index 9ec4c281368..fc0a8370ae8 100644
--- a/extern/softbody/src/admmpd_bvh_traverse.cpp
+++ b/extern/softbody/src/admmpd_bvh_traverse.cpp
@@ -45,6 +45,7 @@ void RayClosestHit<T>::traverse(
 		(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);
+	(void)(go_left_first);
 }
 
 template <typename T>
@@ -109,6 +110,15 @@ bool PointInTetMeshTraverse<T>::stop_traversing(
 		return false;
 
 	RowVector4i t = prim_inds->row(prim);
+	int n_skip = skip_inds.size();
+	for (int i=0; i<n_skip; ++i)
+	{
+		if (skip_inds[i]==t[0]) return false;
+		if (skip_inds[i]==t[1]) return false;
+		if (skip_inds[i]==t[2]) return false;
+		if (skip_inds[i]==t[3]) return false;
+	}
+
 	VecType v[4] = {
 		prim_verts->row(t[0]),
 		prim_verts->row(t[1]),
@@ -229,6 +239,15 @@ bool NearestTriangleTraverse<T>::stop_traversing(const AABB &aabb, int prim)
 		return false;
 
 	RowVector3i tri = prim_inds->row(prim);
+
+	int n_skip = skip_inds.size();
+	for (int i=0; i<n_skip; ++i)
+	{
+		if (skip_inds[i]==tri[0]) return false;
+		if (skip_inds[i]==tri[1]) return false;
+		if (skip_inds[i]==tri[2]) return false;
+	}
+
 	VecType v[3] = {
 		prim_verts->row(tri[0]),
 		prim_verts->row(tri[1]),
diff --git a/extern/softbody/src/admmpd_bvh_traverse.h b/extern/softbody/src/admmpd_bvh_traverse.h
index dce83d07a20..c6cc93c0037 100644
--- a/extern/softbody/src/admmpd_bvh_traverse.h
+++ b/extern/softbody/src/admmpd_bvh_traverse.h
@@ -6,7 +6,7 @@
 
 #include <Eigen/Geometry>
 #include <vector>
-#include <BLI_math_geom.h>
+#include "BLI_math_geom.h"
 
 namespace admmpd {
 
@@ -90,6 +90,7 @@ protected:
 	VecType point;
 	const MatrixXType *prim_verts;
 	const Eigen::MatrixXi *prim_inds;
+	std::vector<int> skip_inds;
 
 public:
 	struct Output {
@@ -100,10 +101,12 @@ public:
 	PointInTetMeshTraverse(
 		const VecType &point_,
 		const MatrixXType *prim_verts_,
-		const Eigen::MatrixXi *prim_inds_) :
+		const Eigen::MatrixXi *prim_inds_,
+		const std::vector<int> &skip_inds_=std::vector<int>()) :
 		point(point_),
 		prim_verts(prim_verts_),
-		prim_inds(prim_inds_)
+		prim_inds(prim_inds_),
+		skip_inds(skip_inds_)
 		{}
 
 	void traverse(
@@ -165,6 +168,7 @@ protected:
 	VecType point;
 	const MatrixXType *prim_verts; // triangle mesh verts
 	const Eigen::MatrixXi *prim_inds; // triangle mesh inds
+	std::vector<int> skip_inds;
 
 public:
 	struct Output {
@@ -181,10 +185,12 @@ public:
 	NearestTriangleTraverse(
 		const VecType &point_,
 		const MatrixXType *prim_verts_,
-		const Eigen::MatrixXi *prim_inds_) :
+		const Eigen::MatrixXi *prim_inds_,
+		const std::vector<int> &skip_inds_=std::vector<int>()) :
 		point(point_),
 		prim_verts(prim_verts_),
-		prim_inds(prim_inds_)
+		prim_inds(prim_inds_),
+		skip_inds(skip_inds_)
 		{}
 
 	void traverse(
diff --git a/extern/softbody/src/admmpd_collision.cpp b/extern/softbody/src/admmpd_collision.cpp
index a05b27287cc..69e300e598e 100644
--- a/extern/softbody/src/admmpd_collision.cpp
+++ b/extern/softbody/src/admmpd_collision.cpp
@@ -30,6 +30,7 @@ void Collision::set_obstacles(
 	const unsigned int *faces,
 	int nf)
 {
+	(void)(v0);
 	if (nv==0 || nf==0)
 	{
 //		obsdata.mesh = admmpd::EmbeddedMesh();
@@ -60,29 +61,7 @@ void Collision::set_obstacles(
 	}
 
 	obsdata.tree.init(obsdata.leaves);
-/*
-  	if (!obsdata.mesh.generate(V,F,true,2))
-		return;
-
-	int nt = obsdata.mesh.lat_tets.rows();
-	if ((int)obsdata.tet_leaves.size() != nt)
-		obsdata.tet_leaves.resize(nt);
 
-	for (int i=0; i<nt; ++i)
-	{
-		AlignedBox<double,3> &box = obsdata.tet_leaves[i];
-		box.setEmpty();
-		RowVector4i t = obsdata.mesh.lat_tets.row(i);
-		box.extend(obsdata.mesh.lat_rest_x.row(t[0]).transpose());
-		box.extend(obsdata.mesh.lat_rest_x.row(t[1]).transpose());
-		box.extend(obsdata.mesh.lat_rest_x.row(t[2]).transpose());
-		box.extend(obsdata.mesh.lat_rest_x.row(t[3]).transpose());
-//		box.extend(box.min()-Vector3d::Ones()*settings.collision_eps);
-//		box.extend(box.max()+Vector3d::Ones()*settings.collision_eps);
-	}
-
-	obsdata.tet_tree.init(obsdata.tet_leaves);
-*/
 } // end add obstacle
 
 std::pair<bool,VFCollisionPair>
@@ -119,13 +98,13 @@ int EmbeddedMeshCollision::detect(
 		return 0;
 
 	// Do we even need to process collisions?
-	if (!this->settings.test_floor &&
-		!this->settings.self_collision &&
-		!obsdata.has_obs())
+	if (!this->settings.floor_collision &&
+		(!this->settings.obs_collision || !obsdata.has_obs()) &&
+		!this->settings.self_collision)
 		return 0;
 
-	// Updates the BVH of deforming mesh
-	update_bvh(x0,x1);
+	if (!tet_tree.root())
+		throw std::runtime_error("EmbeddedMeshCollision::Detect: No tree");
 
 	// We store the results of the collisions in a per-vertex buffer.
 	// This is a workaround so we can create them in threads.
@@ -136,7 +115,7 @@ int EmbeddedMeshCollision::detect(
 	//
 	// Thread data for detection
 	//
-	typedef struct DetectThreadData {
+	typedef struct {
 		const Collision::Settings *settings;
 		const Collision *collision;
 		const TetMeshData *tetmesh;
@@ -162,18 +141,10 @@ int EmbeddedMeshCollision::detect(
 
 		std::vector<VFCollisionPair> &vi_pairs = td->per_vertex_pairs->at(vi);
 		vi_pairs.clear();
-
-		int tet_idx = td->embmesh->emb_vtx_to_tet[vi];
-		RowVector4i tet = td->embmesh->lat_tets.row(tet_idx);
-		Vector4d bary = td->embmesh->emb_barys.row(vi);
-		Vector3d pt_t1 = 
-			bary[0] * td->x1->row(tet[0]) +
-			bary[1] * td->x1->row(tet[1]) +
-			bary[2] * td->x1->row(tet[2]) +
-			bary[3] * td->x1->row(tet[3]);
+		Vector3d pt_t1 = td->embmesh->get_mapped_vertex(td->x1,vi);
 
 		// Special case, check if we are below the floor
-		if (td->settings->test_floor)
+		if (td->settings->floor_collision)
 		{
 			if (pt_t1[2] < td->settings->floor_z)
 			{
@@ -188,14 +159,28 @@ int EmbeddedMeshCollision::detect(
 			}
 		}
 
-		std::pair<bool,VFCollisionPair> pt_hit_obs =
-			td->collision->detect_against_obs(pt_t1,td->obsdata);
+		// Detect against obstacles
+		if (td->settings->obs_collision)
+		{
+			std::pair<bool,VFCollisionPair> pt_hit_obs =
+				td->collision->detect_against_obs(pt_t1,td->obsdata);
+			if (pt_hit_obs.first)
+			{
+				pt_hit_obs.second.p_idx = vi;
+				pt_hit_obs.second.p_is_obs = false;
+				vi_pairs.emplace_back(pt_hit_obs.second);
+			}
+		}
 
-		if (pt_hit_obs.first)
+		// Detect against self
+		if (td->settings->self_collision)
 		{
-			pt_hit_obs.second.p_idx = vi;
-			pt_hit_obs.second.p_is_obs = false;
-			vi_pairs.emplace_back(pt_hit_obs.second);
+			std::pair<bool,VFCollisionPair> pt_hit_self =
+				td->collision->detect_against_self(vi, pt_t1, td->x1);
+			if (pt_hit_self.first)
+			{
+				vi_pairs.emplace_back(pt_hit_self.second);
+			}
 		}
 
 	}; // end detect for a single embedded vertex
@@ -226,13 +211,138 @@ int EmbeddedMeshCollision::detect(
 	return vf_pairs.size();
 } // end detect
 
+void EmbeddedMeshCollision::init_bvh(
+	const Eigen::MatrixXd *x0,
+	const Eigen::MatrixXd *x1)
+{
+
+	(void)(x0);
+	int nt = mesh->lat_tets.rows();
+	if (nt==0)
+		throw std::runtime_error("EmbeddedMeshCollision::init_bvh: No tets");
+
+	if ((int)tet_boxes.size() != nt)
+		tet_boxes.resize(nt);
+
+	// Update leaf boxes
+	for (int i=0; i<nt; ++i)
+	{
+		RowVector4i tet = mesh->lat_tets.row(i);
+		tet_boxes[i].setEmpty();
+		tet_boxes[i].extend(x1->row(tet[0]).transpose());
+		te

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list