[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