17#ifndef EBGEOMETRY_MESHRAYFORMS_HPP
18#define EBGEOMETRY_MESHRAYFORMS_HPP
40template <
class T,
size_t K,
size_t W>
108template <
class T,
size_t K>
291 insert(
const T a_t,
const bool a_entering)
noexcept
341 a_spans.add(RayDetail::openAt(a_t0), RayDetail::openAt(
horizon));
349 for (uint32_t i = 0; i <
m_count; i++) {
361template <
class T,
size_t K,
size_t W>
381 const auto bvh = a_shape.getRoot();
382 const auto groups = bvh.getPrimitives();
384 const auto leaf = [&groups, &a_ray, a_tMin](Nearest& a_state,
size_t a_offset,
size_t a_count)
noexcept {
385 for (
size_t i = a_offset; i < a_offset + a_count; i++) {
386 uint32_t face = UINT32_MAX;
389 const T t = groups[
static_cast<uint32_t
>(i)].rayCrossing(
390 a_ray.m_origin, a_ray.m_direction, a_tMin, a_state.m_t, face,
normal);
392 if (face != UINT32_MAX && t <= a_state.m_t) {
393 a_state = Nearest{t, face,
normal};
398 const auto bound = [](
const Nearest& a_state)
noexcept -> T {
return a_state.m_t; };
400 bvh.traverse(
BVH::RayQuery<T>(a_ray.m_origin, a_ray.m_direction, a_tMin), nearest, leaf, bound);
404 if (nearest.m_face != UINT32_MAX) {
406 hit.
m_t = nearest.m_t;
407 hit.
m_point = a_ray.at(nearest.m_t);
410 hit.
m_entering =
dot(a_ray.m_direction, nearest.m_normal) < T(0);
417template <
class T,
size_t K,
size_t W>
429 const auto bvh = a_shape.getRoot();
430 const auto groups = bvh.getPrimitives();
432 const auto leaf = [&groups, &a_ray, a_tMin, a_tMax](
bool& a_found,
size_t a_offset,
size_t a_count)
noexcept {
433 for (
size_t i = a_offset; i < a_offset + a_count && !a_found; i++) {
434 uint32_t face = UINT32_MAX;
438 groups[
static_cast<uint32_t
>(i)].rayCrossing(a_ray.m_origin, a_ray.m_direction, a_tMin, a_tMax, face,
normal);
440 a_found = face != UINT32_MAX && t <= a_tMax;
444 const auto bound = [a_tMax](
const bool& a_found)
noexcept -> T {
448 bvh.traverse(
BVH::RayQuery<T>(a_ray.m_origin, a_ray.m_direction, a_tMin), found, leaf, bound);
453template <
class T,
size_t K>
470 Nearest nearest{a_tMax, UINT32_MAX};
472 const auto bvh = a_shape.getRoot();
473 const auto mesh = a_shape.getMesh();
474 const auto faceIds = bvh.getPrimitives();
476 const auto leaf = [&faceIds, &mesh, &a_ray, a_tMin](Nearest& a_state,
size_t a_offset,
size_t a_count)
noexcept {
477 for (
size_t i = a_offset; i < a_offset + a_count; i++) {
478 const uint32_t face = faceIds[
static_cast<uint32_t
>(i)];
479 const T t = mesh.getFace(face).rayCrossing(a_ray.m_origin, a_ray.m_direction, a_tMin, a_state.m_t, mesh);
483 a_state = Nearest{t, face};
488 const auto bound = [](
const Nearest& a_state)
noexcept -> T {
return a_state.m_t; };
490 bvh.traverse(
BVH::RayQuery<T>(a_ray.m_origin, a_ray.m_direction, a_tMin), nearest, leaf, bound);
492 return nearest.m_face == UINT32_MAX
494 : RayDetail::faceHit(a_ray, nearest.m_t, nearest.m_face, mesh.getFace(nearest.m_face).getNormal());
497template <
class T,
size_t K>
509 const auto bvh = a_shape.getRoot();
510 const auto mesh = a_shape.getMesh();
511 const auto faceIds = bvh.getPrimitives();
513 const auto leaf = [&faceIds, &mesh, &a_ray, a_tMin, a_tMax](
bool& a_found,
size_t a_offset,
size_t a_count)
noexcept {
514 for (
size_t i = a_offset; i < a_offset + a_count && !a_found; i++) {
515 const auto& face = mesh.getFace(faceIds[
static_cast<uint32_t
>(i)]);
522 const auto bound = [a_tMax](
const bool& a_found)
noexcept -> T {
526 bvh.traverse(
BVH::RayQuery<T>(a_ray.m_origin, a_ray.m_direction, a_tMin), found, leaf, bound);
540 const auto mesh = a_shape.getMesh();
543 uint32_t face = UINT32_MAX;
545 for (uint32_t i = 0; i < mesh.numFaces(); i++) {
546 const T t = mesh.getFace(i).rayCrossing(a_ray.m_origin, a_ray.m_direction, a_tMin, nearest, mesh);
554 return face == UINT32_MAX ?
HitT<T>() : RayDetail::faceHit(a_ray, nearest, face, mesh.getFace(face).getNormal());
557template <
class T,
size_t K,
size_t W>
565 const bool a_firstOnly,
569 RayDetail::firstSpan(a_shape, a_ray, a_tMin, a_tMax, a_options, a_spans);
576 crossings.
m_tMax = a_tMax;
578 const auto bvh = a_shape.getRoot();
579 const auto groups = bvh.getPrimitives();
583 for (
size_t i = a_offset; i < a_offset + a_count; i++) {
584 const auto& group = groups[
static_cast<uint32_t
>(i)];
588 group.rayCrossings(a_ray.m_origin, a_ray.m_direction, a_tMin, a_state.horizon(), t);
590 for (
size_t lane = 0; lane < W; lane++) {
592 a_state.insert(t[lane],
dot(a_ray.m_direction, group.getNormal(lane)) < T(0));
600 bvh.traverse(
BVH::RayQuery<T>(a_ray.m_origin, a_ray.m_direction, a_tMin), crossings, leaf, bound);
602 crossings.
toSpans(a_tMin, crossings.
m_count == 0U && RayDetail::insideAt(a_shape, a_ray.at(a_tMin)), a_spans);
605template <
class T,
size_t K>
613 const bool a_firstOnly,
617 RayDetail::firstSpan(a_shape, a_ray, a_tMin, a_tMax, a_options, a_spans);
624 crossings.
m_tMax = a_tMax;
626 const auto bvh = a_shape.getRoot();
627 const auto mesh = a_shape.getMesh();
628 const auto faceIds = bvh.getPrimitives();
630 const auto leaf = [&faceIds, &mesh, &a_ray, a_tMin](
632 for (
size_t i = a_offset; i < a_offset + a_count; i++) {
633 const uint32_t face = faceIds[
static_cast<uint32_t
>(i)];
634 const auto& f = mesh.getFace(face);
635 const T t = f.rayCrossing(a_ray.m_origin, a_ray.m_direction, a_tMin, a_state.horizon(), mesh);
638 a_state.insert(t,
dot(a_ray.m_direction, f.getNormal()) < T(0));
645 bvh.traverse(
BVH::RayQuery<T>(a_ray.m_origin, a_ray.m_direction, a_tMin), crossings, leaf, bound);
647 crossings.
toSpans(a_tMin, crossings.
m_count == 0U && RayDetail::insideAt(a_shape, a_ray.at(a_tMin)), a_spans);
658 const bool a_firstOnly,
662 RayDetail::firstSpan(a_shape, a_ray, a_tMin, a_tMax, a_options, a_spans);
669 crossings.
m_tMax = a_tMax;
671 const auto mesh = a_shape.getMesh();
673 for (uint32_t i = 0; i < mesh.numFaces(); i++) {
674 const auto& f = mesh.getFace(i);
675 const T t = f.rayCrossing(a_ray.m_origin, a_ray.m_direction, a_tMin, crossings.
horizon(), mesh);
678 crossings.
insert(t,
dot(a_ray.m_direction, f.getNormal()) < T(0));
682 crossings.
toSpans(a_tMin, crossings.
m_count == 0U && RayDetail::insideAt(a_shape, a_ray.at(a_tMin)), a_spans);
#define EBGEOMETRY_HOST_DEVICE
Mark a function as callable from both host and device code (no-op on host compilers).
Definition EBGeometry_GPU.hpp:80
Declaration of signed distance functions for DCEL meshes.
Ray queries on any shape: where a ray, or the segment between two points, first crosses its surface (...
Signed distance function for a DCEL mesh. Does not use BVHs.
Definition EBGeometry_MeshDistanceFunctions.hpp:79
A FlatMeshSDF must be trivially copyable: that is what lets a rebasedView() be byte-copied into a dev...
Definition EBGeometry_MeshDistanceFunctions.hpp:249
Signed distance function for a pure triangle mesh using SoA-grouped primitives in a compact (lineariz...
Definition EBGeometry_MeshDistanceFunctions.hpp:514
Three-dimensional vector class with arithmetic operators.
Definition EBGeometry_Vec.hpp:258
static constexpr Vec3T< T > zeros() noexcept
Return a vector with x = y = z = 0.
Namespace containing all of EBGeometry's functionality.
Definition EBGeometry_Affine.hpp:26
HitStatus intersects(const S &a_shape, const RayT< T > &a_ray, typename RayT< T >::Scalar a_tMin, typename RayT< T >::Scalar a_tMax, const RayOptions< T > &a_options=RayOptions< T >()) noexcept
Whether a ray crosses a shape's surface in [a_tMin, a_tMax].
T dot(const Vec2T< T > &u, const Vec2T< T > &v) noexcept
Dot product of two 2D vectors.
Vec3T< T > normal(const F &a_function, const Vec3T< T > &a_point, const T &a_delta) noexcept
Outward unit normal of a function's level set, by central finite differences.
HitStatus
The outcome of a ray query.
Definition EBGeometry_Ray.hpp:84
@ Miss
The ray does not cross the surface in the interval.
@ Hit
The ray crosses the surface; HitT says where.
HitT< T > firstHit(const S &a_shape, const RayT< T > &a_ray, typename RayT< T >::Scalar a_tMin, typename RayT< T >::Scalar a_tMax, const RayOptions< T > &a_options=RayOptions< T >()) noexcept
The first crossing of a shape's surface along a ray, entering or leaving.
A ray tracked through a BVH: the key of a box is the distance along the ray at which it enters the bo...
Definition EBGeometry_BVHQuery.hpp:286
Where a ray first crosses a surface.
Definition EBGeometry_Ray.hpp:96
bool m_entering
Whether the ray enters the object there (it was outside just before), rather than leaving it.
Definition EBGeometry_Ray.hpp:129
bool m_exact
Whether the crossing is exact (found by a ray form), rather than found to within RayOptions::m_tolera...
Definition EBGeometry_Ray.hpp:135
T m_t
Distance along the ray: of the crossing for a hit, of the last point reached for an unresolved query,...
Definition EBGeometry_Ray.hpp:106
Vec3T< T > m_normal
The outward unit normal at the crossing: from the shape's ray form, or the normalized gradient of its...
Definition EBGeometry_Ray.hpp:124
uint32_t m_primitive
The finest element the shape can name at the crossing: the face of a mesh SDF, the deciding leaf of a...
Definition EBGeometry_Ray.hpp:118
HitStatus m_status
Whether the ray crosses the surface.
Definition EBGeometry_Ray.hpp:100
Vec3T< T > m_point
The point at m_t (for a hit or an unresolved query).
Definition EBGeometry_Ray.hpp:111
Numeric limits, with the meanings of the std::numeric_limits members of the same names.
Definition EBGeometry_Math.hpp:91
Pairs crossings, in order, into spans: a span from each crossing the ray enters at to the next it lea...
Definition EBGeometry_RaySpans.hpp:707
void take(const SpanEndT< T > &a_end, const bool a_entering, const T a_t0, RaySpansT< T > &a_spans) noexcept
Take the next crossing.
Definition EBGeometry_RaySpans.hpp:732
void finish(const T a_t, RaySpansT< T > &a_spans) noexcept
Close the open span, if any, at an Open end.
Definition EBGeometry_RaySpans.hpp:759
A crossing.
Definition EBGeometry_MeshRayForms.hpp:257
bool m_entering
Whether the ray enters there: it runs against the face's outward normal.
Definition EBGeometry_MeshRayForms.hpp:266
T m_t
Distance along the ray.
Definition EBGeometry_MeshRayForms.hpp:261
The nearest crossings of a mesh along a ray, in order, as a BVH walk finds them: at most Capacity,...
Definition EBGeometry_MeshRayForms.hpp:247
uint32_t m_count
How many are held.
Definition EBGeometry_MeshRayForms.hpp:277
Crossing m_crossings[Capacity]
The crossings, nearest first.
Definition EBGeometry_MeshRayForms.hpp:272
T horizon() const noexcept
How far the crossings are known: the end of the interval, or the farthest held once full.
Definition EBGeometry_MeshRayForms.hpp:320
void toSpans(const T a_t0, const bool a_inside, RaySpansT< T > &a_spans) const noexcept
The spans: the crossings paired by the side of the face the ray crosses from.
Definition EBGeometry_MeshRayForms.hpp:333
void insert(const T a_t, const bool a_entering) noexcept
Take a crossing.
Definition EBGeometry_MeshRayForms.hpp:291
static constexpr uint32_t Capacity
Most crossings held.
Definition EBGeometry_MeshRayForms.hpp:251
T m_tMax
End of the interval.
Definition EBGeometry_MeshRayForms.hpp:282
How a query marches, where a shape has no ray form.
Definition EBGeometry_Ray.hpp:155
Where a ray is inside an object over an interval [t0, t1]: its spans, in order, each from where it en...
Definition EBGeometry_Ray.hpp:248
A ray: the points origin + t * direction.
Definition EBGeometry_Ray.hpp:54
One end of a span: where a ray enters or leaves an object.
Definition EBGeometry_Ray.hpp:200