[Bf-blender-cvs] [724859afb5c] soc-2020-soft-body: collision working a little better now

over0219 noreply at git.blender.org
Wed Jul 15 05:09:07 CEST 2020


Commit: 724859afb5cea489d315f18e394d2be7e0adec81
Author: over0219
Date:   Tue Jul 14 22:04:52 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rB724859afb5cea489d315f18e394d2be7e0adec81

collision working a little better now

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

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
M	extern/softbody/src/admmpd_geom.cpp
M	extern/softbody/src/admmpd_sdf.cpp
M	extern/softbody/src/admmpd_sdf.h
M	extern/softbody/src/admmpd_types.h

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

diff --git a/extern/softbody/src/admmpd_bvh_traverse.cpp b/extern/softbody/src/admmpd_bvh_traverse.cpp
index 7def5340085..8fd4b1118f6 100644
--- a/extern/softbody/src/admmpd_bvh_traverse.cpp
+++ b/extern/softbody/src/admmpd_bvh_traverse.cpp
@@ -139,6 +139,8 @@ PointInTriangleMeshTraverse<T>::PointInTriangleMeshTraverse(
 	prim_verts(prim_verts_),
 	prim_inds(prim_inds_)
 {
+	//dir = VecType::Random();
+
 	BLI_assert(prim_verts->rows()>=0);
 	BLI_assert(prim_inds->rows()>=0);
 	BLI_assert(prim_inds->cols()==3);
@@ -148,6 +150,7 @@ PointInTriangleMeshTraverse<T>::PointInTriangleMeshTraverse(
 		o[i] = (float)point[i];
 		d[i] = (float)dir[i];
 	}
+	isect_ray_tri_watertight_v3_precalc(&isect_precalc, d);
 }
 
 template <typename T>
@@ -156,31 +159,23 @@ void PointInTriangleMeshTraverse<T>::traverse(
 	const AABB &right_aabb, bool &go_right,
 	bool &go_left_first )
 {
-	float tmin = 0;
-	float tmax = std::numeric_limits<float>::max();
-	float l_bb_min[3] = { (float)left_aabb.min()[0], (float)left_aabb.min()[1], (float)left_aabb.min()[2] };
-	float l_bb_max[3] = { (float)left_aabb.max()[0], (float)left_aabb.max()[1], (float)left_aabb.max()[2] };
-	go_left = isect_ray_aabb_v3_simple(o,d,l_bb_min,l_bb_max,&tmin,&tmax);
-	tmin = 0;
-	tmax = std::numeric_limits<float>::max();
-	float r_bb_min[3] = { (float)right_aabb.min()[0], (float)right_aabb.min()[1], (float)right_aabb.min()[2] };
-	float r_bb_max[3] = { (float)right_aabb.max()[0], (float)right_aabb.max()[1], (float)right_aabb.max()[2] };
-	go_right = isect_ray_aabb_v3_simple(o,d,r_bb_min,r_bb_max,&tmin,&tmax);
+	const T t_min = 0;
+	const T t_max = std::numeric_limits<T>::max();
+	go_left = geom::ray_aabb<T>(point,dir,left_aabb,t_min,t_max);
+	go_right = geom::ray_aabb<T>(point,dir,right_aabb,t_min,t_max);
+	go_left_first = go_left;
 } // end point in mesh traverse
 
 template <typename T>
 bool PointInTriangleMeshTraverse<T>::stop_traversing(
 		const AABB &aabb, int prim )
 {
+	const T t_min = 0;
+	T t_max = std::numeric_limits<T>::max();
+
 	// Check if the tet box doesn't intersect the triangle box
-	{
-		float tmin = 0;
-		float tmax = std::numeric_limits<float>::max();
-		float bb_min[3] = { (float)aabb.min()[0], (float)aabb.min()[1], (float)aabb.min()[2] };
-		float bb_max[3] = { (float)aabb.max()[0], (float)aabb.max()[1], (float)aabb.max()[2] };
-		if (!isect_ray_aabb_v3_simple(o,d,bb_min,bb_max,&tmin,&tmax))
-			return false;
-	}
+	if (!geom::ray_aabb<T>(point,dir,aabb,t_min,t_max))
+		return false;
 
 	// Get the vertices of the face in float arrays
 	// to interface with Blender kernels.
@@ -201,8 +196,7 @@ bool PointInTriangleMeshTraverse<T>::stop_traversing(
 	// then record if it was a ray-hit.
 	float lambda = 0;
 	float uv[2] = {0,0};
-	bool hit = isect_ray_tri_watertight_v3_simple(
-		o, d, q0, q1, q2, &lambda, uv);
+	bool hit = isect_ray_tri_watertight_v3(o, &isect_precalc, q0, q1, q2, &lambda, uv);
 
 	if (hit)
 		output.hits.emplace_back(std::make_pair(prim,lambda));
@@ -235,26 +229,18 @@ bool NearestTriangleTraverse<T>::stop_traversing(const AABB &aabb, int prim)
 	if (b_dist > output.dist)
 		return false;
 
-	float p[3] = { (float)point[0], (float)point[1], (float)point[2] };
-	float r[3] = { p[0], p[1], p[2] };
 	RowVector3i tri = prim_inds->row(prim);
-	float t1[3], t2[3], t3[3];
-	for (int i=0; i<3; ++i)
-	{
-		t1[i] = (float)prim_verts->operator()(tri[0],i);
-		t2[i] = (float)prim_verts->operator()(tri[1],i);
-		t3[i] = (float)prim_verts->operator()(tri[2],i);
-	}
-
-	// I was hoping there would be kernels that are a bit faster
-	// to get point-triangle distance, but I guess this does what I need.
-	closest_on_tri_to_point_v3(r, p, t1, t2, t3);
-	VecType pt_on_tri((T)r[0], (T)r[1], (T)r[2]);
-	double d2 = (point-pt_on_tri).norm();
-	if (d2 < output.dist)
+	VecType v[3] = {
+		prim_verts->row(tri[0]),
+		prim_verts->row(tri[1]),
+		prim_verts->row(tri[2])
+	};
+	VecType pt_on_tri = geom::point_on_triangle<T>(point,v[0],v[1],v[2]);
+	double dist = (point-pt_on_tri).norm();
+	if (dist < output.dist)
 	{
 		output.prim = prim;
-		output.dist = d2;
+		output.dist = dist;
 		output.pt_on_tri = pt_on_tri;		
 	}
 
diff --git a/extern/softbody/src/admmpd_bvh_traverse.h b/extern/softbody/src/admmpd_bvh_traverse.h
index 29eebd0163d..ecbb85f3277 100644
--- a/extern/softbody/src/admmpd_bvh_traverse.h
+++ b/extern/softbody/src/admmpd_bvh_traverse.h
@@ -6,6 +6,7 @@
 
 #include <Eigen/Geometry>
 #include <vector>
+#include <BLI_math_geom.h>
 
 namespace admmpd {
 
@@ -129,10 +130,11 @@ protected:
 	const MatrixXType *prim_verts; // triangle mesh verts
 	const Eigen::MatrixXi *prim_inds; // triangle mesh inds
 	float o[3], d[3]; // pt and dir casted to float for Blender kernels
+	struct IsectRayPrecalc isect_precalc;
 
 public:
 	struct Output {
-		std::vector< std::pair<int,double> > hits; // [prim,t]
+		std::vector< std::pair<int,T> > hits; // [prim,t]
 		int num_hits() const { return hits.size(); }
 	} output;
 
diff --git a/extern/softbody/src/admmpd_collision.cpp b/extern/softbody/src/admmpd_collision.cpp
index 892a599264d..5e14bc3a756 100644
--- a/extern/softbody/src/admmpd_collision.cpp
+++ b/extern/softbody/src/admmpd_collision.cpp
@@ -20,7 +20,7 @@ VFCollisionPair::VFCollisionPair() :
     p_is_obs(0), // 0 or 1
     q_idx(-1), // face
     q_is_obs(0), // 0 or 1
-	pt_on_q(0,0,0)
+	q_bary(0,0,0)
 	{}
 
 void Collision::set_obstacles(
@@ -30,125 +30,86 @@ void Collision::set_obstacles(
 	const unsigned int *faces,
 	int nf)
 {
-	if (obsdata.V0.rows() != nv)
-		obsdata.V0.resize(nv,3);
-
-	if (obsdata.V1.rows() != nv)
-		obsdata.V1.resize(nv,3);
+	if (nv==0 || nf==0)
+	{
+//		obsdata.mesh = admmpd::EmbeddedMesh();
+		return;
+	}
 
+	if (obsdata.V.rows() != nv)
+		obsdata.V.resize(nv,3);
 	for (int i=0; i<nv; ++i)
 	{
 		for (int j=0; j<3; ++j)
-		{
-			obsdata.V0(i,j) = v0[i*3+j];
-			obsdata.V1(i,j) = v1[i*3+j];
-		}
+			obsdata.V(i,j) = v1[i*3+j];
 	}
 
+	if ((int)obsdata.leaves.size() != nf)
+		obsdata.leaves.resize(nf);
 	if (obsdata.F.rows() != nf)
-	{
 		obsdata.F.resize(nf,3);
-		obsdata.aabbs.resize(nf);
-	}
-
-	Vector3d v_eta = Vector3d::Ones()*settings.collision_eps;
 	for (int i=0; i<nf; ++i)
 	{
-		obsdata.aabbs[i].setEmpty();
+		obsdata.leaves[i].setEmpty();
 		for (int j=0; j<3; ++j)
 		{
-			int fj = faces[i*3+j];
-			obsdata.F(i,j) = fj;
-			obsdata.aabbs[i].extend(obsdata.V0.row(fj).transpose());
-			obsdata.aabbs[i].extend(obsdata.V1.row(fj).transpose());
+			obsdata.F(i,j) = faces[i*3+j];
+			Vector3d vi = obsdata.V.row(obsdata.F(i,j)).transpose();
+			obsdata.leaves[i].extend(vi);
 		}
-		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);
+	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>
-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
+Collision::detect_against_obs(
+        const Eigen::Vector3d &pt,
+        const ObstacleData *obs) const
 {
 	std::pair<bool,VFCollisionPair> ret = 
 		std::make_pair(false, VFCollisionPair());
 
-	// Any faces to detect against?
-	if (mesh_tris->rows()==0)
-		return ret;	
+	if (!obs->has_obs())
+		return ret;
 
-/*
-	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)
+	PointInTriangleMeshTraverse<double> pt_in_mesh(pt,&obs->V,&obs->F);
+	obs->tree.traverse(pt_in_mesh);
+	if (pt_in_mesh.output.num_hits()%2==0)
 		return ret;
 
+	NearestTriangleTraverse<double> nearest_tri(pt,&obs->V,&obs->F);
+	obs->tree.traverse(nearest_tri);
+
 	ret.first = true;
-	VFCollisionPair &pair = ret.second;
-	pair.p_idx = pt_idx;
-	pair.p_is_obs = pt_is_obs;
-	pair.q_idx = ray_hit_mesh.output.prim;
-	pair.q_is_obs = mesh_is_obs;
-	RowVector3i tris = mesh_tris->row(pair.q_idx);
-	pair.pt_on_q =
-		mesh_x->row(tris[0])*ray_hit_mesh.output.barys[0] +
-		mesh_x->row(tris[1])*ray_hit_mesh.output.barys[1] +
-		mesh_x->row(tris[2])*ray_hit_mesh.output.barys[2];
+	ret.second.q_idx = nearest_tri.ou

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list