[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