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. @@

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

Reply via email to