Introducing signed_distance into the collision detection.
Everything is broken O.o
This commit is contained in:
parent
4f83703232
commit
6c0b65208f
3 changed files with 41 additions and 16 deletions
|
@ -578,7 +578,7 @@ inline double ray_mesh_intersect(const Vec3d& s,
|
||||||
// samples: how many rays will be shot
|
// samples: how many rays will be shot
|
||||||
// safety distance: This will be added to the radiuses to have a safety distance
|
// safety distance: This will be added to the radiuses to have a safety distance
|
||||||
// from the mesh.
|
// from the mesh.
|
||||||
double pinhead_mesh_intersect(const Vec3d& s_original,
|
double pinhead_mesh_intersect(const Vec3d& s,
|
||||||
const Vec3d& dir,
|
const Vec3d& dir,
|
||||||
double r_pin,
|
double r_pin,
|
||||||
double r_back,
|
double r_back,
|
||||||
|
@ -597,8 +597,6 @@ double pinhead_mesh_intersect(const Vec3d& s_original,
|
||||||
|
|
||||||
// Move away slightly from the touching point to avoid raycasting on the
|
// Move away slightly from the touching point to avoid raycasting on the
|
||||||
// inner surface of the mesh.
|
// inner surface of the mesh.
|
||||||
Vec3d s = s_original + r_pin * dir;
|
|
||||||
|
|
||||||
Vec3d v = dir; // Our direction (axis)
|
Vec3d v = dir; // Our direction (axis)
|
||||||
Vec3d c = s + width * dir;
|
Vec3d c = s + width * dir;
|
||||||
|
|
||||||
|
@ -634,15 +632,20 @@ double pinhead_mesh_intersect(const Vec3d& s_original,
|
||||||
s(Y) + rpscos * a(Y) + rpssin * b(Y),
|
s(Y) + rpscos * a(Y) + rpssin * b(Y),
|
||||||
s(Z) + rpscos * a(Z) + rpssin * b(Z));
|
s(Z) + rpscos * a(Z) + rpssin * b(Z));
|
||||||
|
|
||||||
|
// Point ps is not on mesh but can be inside or outside as well. This
|
||||||
|
// would cause many problems with ray-casting. So we query the closest
|
||||||
|
// point on the mesh to this.
|
||||||
|
auto result = m.signed_distance(ps);
|
||||||
|
|
||||||
// This is the point on the circle on the back sphere
|
// This is the point on the circle on the back sphere
|
||||||
Vec3d p(c(X) + rpbcos * a(X) + rpbsin * b(X),
|
Vec3d p(c(X) + rpbcos * a(X) + rpbsin * b(X),
|
||||||
c(Y) + rpbcos * a(Y) + rpbsin * b(Y),
|
c(Y) + rpbcos * a(Y) + rpbsin * b(Y),
|
||||||
c(Z) + rpbcos * a(Z) + rpbsin * b(Z));
|
c(Z) + rpbcos * a(Z) + rpbsin * b(Z));
|
||||||
|
|
||||||
if(m.inside(ps) && m.inside(p)) {
|
if(!m.inside(p)) {
|
||||||
Vec3d n = (p - ps).normalized();
|
Vec3d n = (p - result.point_on_mesh() + 0.01 * dir).normalized();
|
||||||
phi = m.query_ray_hit(ps, n);
|
phi = m.query_ray_hit(result.point_on_mesh(), n);
|
||||||
} else phi = std::numeric_limits<double>::infinity();
|
} else phi = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mit = std::min_element(phis.begin(), phis.end());
|
auto mit = std::min_element(phis.begin(), phis.end());
|
||||||
|
@ -650,7 +653,7 @@ double pinhead_mesh_intersect(const Vec3d& s_original,
|
||||||
return *mit;
|
return *mit;
|
||||||
}
|
}
|
||||||
|
|
||||||
double bridge_mesh_intersect(const Vec3d& s_original,
|
double bridge_mesh_intersect(const Vec3d& s,
|
||||||
const Vec3d& dir,
|
const Vec3d& dir,
|
||||||
double r,
|
double r,
|
||||||
const EigenMesh3D& m,
|
const EigenMesh3D& m,
|
||||||
|
@ -658,7 +661,7 @@ double bridge_mesh_intersect(const Vec3d& s_original,
|
||||||
double safety_distance = 0.05)
|
double safety_distance = 0.05)
|
||||||
{
|
{
|
||||||
// helper vector calculations
|
// helper vector calculations
|
||||||
Vec3d s = s_original + r*dir; Vec3d a(0, 1, 0), b;
|
Vec3d a(0, 1, 0), b;
|
||||||
|
|
||||||
a(Z) = -(dir(X)*a(X) + dir(Y)*a(Y)) / dir(Z);
|
a(Z) = -(dir(X)*a(X) + dir(Y)*a(Y)) / dir(Z);
|
||||||
b = a.cross(dir);
|
b = a.cross(dir);
|
||||||
|
@ -680,8 +683,9 @@ double bridge_mesh_intersect(const Vec3d& s_original,
|
||||||
s(Y) + rcos * a(Y) + rsin * b(Y),
|
s(Y) + rcos * a(Y) + rsin * b(Y),
|
||||||
s(Z) + rcos * a(Z) + rsin * b(Z));
|
s(Z) + rcos * a(Z) + rsin * b(Z));
|
||||||
|
|
||||||
if(m.inside(p)) phi = m.query_ray_hit(p, dir);
|
auto result = m.signed_distance(p);
|
||||||
else phi = std::numeric_limits<double>::infinity();
|
|
||||||
|
phi = m.query_ray_hit(result.point_on_mesh() + 0.05*dir, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mit = std::min_element(phis.begin(), phis.end());
|
auto mit = std::min_element(phis.begin(), phis.end());
|
||||||
|
@ -1190,6 +1194,8 @@ bool SLASupportTree::generate(const PointSet &points,
|
||||||
std::sin(azimuth) * std::sin(polar),
|
std::sin(azimuth) * std::sin(polar),
|
||||||
std::cos(polar));
|
std::cos(polar));
|
||||||
|
|
||||||
|
nn.normalize();
|
||||||
|
|
||||||
// save the head (pinpoint) position
|
// save the head (pinpoint) position
|
||||||
Vec3d hp = filt_pts.row(i);
|
Vec3d hp = filt_pts.row(i);
|
||||||
|
|
||||||
|
|
|
@ -130,9 +130,26 @@ public:
|
||||||
// Casting a ray on the mesh, returns the distance where the hit occures.
|
// Casting a ray on the mesh, returns the distance where the hit occures.
|
||||||
double query_ray_hit(const Vec3d &s, const Vec3d &dir) const;
|
double query_ray_hit(const Vec3d &s, const Vec3d &dir) const;
|
||||||
|
|
||||||
|
class si_result {
|
||||||
|
double m_value;
|
||||||
|
int m_fidx;
|
||||||
|
Vec3d m_p;
|
||||||
|
si_result(double val, int i, const Vec3d& c):
|
||||||
|
m_value(val), m_fidx(i), m_p(c) {}
|
||||||
|
friend class EigenMesh3D;
|
||||||
|
public:
|
||||||
|
|
||||||
|
si_result() = delete;
|
||||||
|
|
||||||
|
double value() const { return m_value; }
|
||||||
|
operator double() const { return m_value; }
|
||||||
|
const Vec3d& point_on_mesh() const { return m_p; }
|
||||||
|
int F_idx() const { return m_fidx; }
|
||||||
|
};
|
||||||
|
|
||||||
// The signed distance from a point to the mesh. Outputs the distance,
|
// The signed distance from a point to the mesh. Outputs the distance,
|
||||||
// the index of the triangle and the closest point in mesh coordinate space.
|
// the index of the triangle and the closest point in mesh coordinate space.
|
||||||
std::tuple<double, unsigned, Vec3d> signed_distance(const Vec3d& p) const;
|
si_result signed_distance(const Vec3d& p) const;
|
||||||
|
|
||||||
bool inside(const Vec3d& p) const;
|
bool inside(const Vec3d& p) const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -166,10 +166,12 @@ double EigenMesh3D::query_ray_hit(const Vec3d &s, const Vec3d &dir) const
|
||||||
return double(hit.t);
|
return double(hit.t);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<double, unsigned, Vec3d>
|
EigenMesh3D::si_result EigenMesh3D::signed_distance(const Vec3d &p) const {
|
||||||
EigenMesh3D::signed_distance(const Vec3d &/*p*/) const {
|
double sign = 0; double sqdst = 0; int i = 0; Vec3d c;
|
||||||
// TODO: implement
|
igl::signed_distance_winding_number(*m_aabb, m_V, m_F, m_aabb->windtree,
|
||||||
return std::make_tuple(0.0, 0, Vec3d());
|
p, sign, sqdst, i, c);
|
||||||
|
|
||||||
|
return si_result(sign * std::sqrt(sqdst), i, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EigenMesh3D::inside(const Vec3d &p) const {
|
bool EigenMesh3D::inside(const Vec3d &p) const {
|
||||||
|
|
Loading…
Reference in a new issue