Extender MeshRaycaster so it can also provide hits on the clipping plane

This commit is contained in:
Lukas Matena 2022-02-07 14:34:21 +01:00
parent 7fef26527b
commit 016a7feb3d
2 changed files with 27 additions and 6 deletions

View File

@ -334,8 +334,11 @@ void MeshRaycaster::line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3
bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera, bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera,
Vec3f& position, Vec3f& normal, const ClippingPlane* clipping_plane, Vec3f& position, Vec3f& normal, const ClippingPlane* clipping_plane,
size_t* facet_idx) const size_t* facet_idx, bool* was_clipping_plane_hit) const
{ {
if (was_clipping_plane_hit)
*was_clipping_plane_hit = false;
Vec3d point; Vec3d point;
Vec3d direction; Vec3d direction;
line_from_mouse_pos(mouse_pos, trafo, camera, point, direction); line_from_mouse_pos(mouse_pos, trafo, camera, point, direction);
@ -356,9 +359,26 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d&
break; break;
} }
if (i==hits.size() || (hits.size()-i) % 2 != 0) { if (i==hits.size()) {
// All hits are either clipped, or there is an odd number of unclipped // All hits are clipped.
// hits - meaning the nearest must be from inside the mesh. return false;
}
if ((hits.size()-i) % 2 != 0) {
// There is an odd number of unclipped hits - meaning the nearest must be from inside the mesh.
// In that case, calculate intersection with the clipping place.
if (clipping_plane && was_clipping_plane_hit) {
direction = direction + point;
point = trafo * point; // transform to world coords
direction = trafo * direction - point;
Vec3d normal = -clipping_plane->get_normal().cast<double>();
double den = normal.dot(direction);
if (den != 0.) {
double t = (-clipping_plane->get_offset() - normal.dot(point))/den;
position = (point + t * direction).cast<float>();
*was_clipping_plane_hit = true;
}
}
return false; return false;
} }

View File

@ -154,10 +154,11 @@ public:
const Vec2d& mouse_pos, const Vec2d& mouse_pos,
const Transform3d& trafo, // how to get the mesh into world coords const Transform3d& trafo, // how to get the mesh into world coords
const Camera& camera, // current camera position const Camera& camera, // current camera position
Vec3f& position, // where to save the positibon of the hit (mesh coords) Vec3f& position, // where to save the positibon of the hit (mesh coords if mesh, world coords if clipping plane)
Vec3f& normal, // normal of the triangle that was hit Vec3f& normal, // normal of the triangle that was hit
const ClippingPlane* clipping_plane = nullptr, // clipping plane (if active) const ClippingPlane* clipping_plane = nullptr, // clipping plane (if active)
size_t* facet_idx = nullptr // index of the facet hit size_t* facet_idx = nullptr, // index of the facet hit
bool* was_clipping_plane_hit = nullptr // is the hit on the clipping place cross section?
) const; ) const;
// Given a vector of points in woorld coordinates, this returns vector // Given a vector of points in woorld coordinates, this returns vector