Lagrange
Loading...
Searching...
No Matches
RayCaster.h
1/*
2 * Copyright 2017 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <lagrange/SurfaceMesh.h>
15#include <lagrange/raycasting/api.h>
16#include <lagrange/scene/SimpleScene.h>
17#include <lagrange/utils/BitField.h>
18#include <lagrange/utils/function_ref.h>
19#include <lagrange/utils/value_ptr.h>
20
21#include <Eigen/Core>
22
23#include <cstdint>
24#include <functional>
25#include <limits>
26#include <memory>
27#include <optional>
28#include <variant>
29
30namespace lagrange::raycasting {
31
32namespace internal {
34} // namespace internal
35
36
40struct HitBase
41{
44
47
50
54 Eigen::Vector2f barycentric_coord = Eigen::Vector2f::Zero();
55
57 Eigen::Vector3f position = Eigen::Vector3f::Zero();
58};
59
63struct ClosestPointHit : public HitBase
64{
66 float distance = std::numeric_limits<float>::infinity();
67};
68
72struct RayHit : public HitBase
73{
75 float ray_depth = 0;
76
78 Eigen::Vector3f normal = Eigen::Vector3f::Zero();
79};
80
86template <size_t N>
88{
90 uint32_t valid_mask = 0;
91
93 Eigen::Vector<uint32_t, N> mesh_indices =
94 Eigen::Vector<uint32_t, N>::Constant(invalid<uint32_t>());
95
97 Eigen::Vector<uint32_t, N> instance_indices =
98 Eigen::Vector<uint32_t, N>::Constant(invalid<uint32_t>());
99
101 Eigen::Vector<uint32_t, N> facet_indices =
102 Eigen::Vector<uint32_t, N>::Constant(invalid<uint32_t>());
103
107 Eigen::Matrix<float, 2, N> barycentric_coords = Eigen::Matrix<float, 2, N>::Zero();
108
110 Eigen::Matrix<float, 3, N> positions = Eigen::Matrix<float, 3, N>::Zero();
111
112 bool is_valid(size_t i) const { return (valid_mask & (1u << i)) != 0; }
113};
114
120template <size_t N>
121struct ClosestPointHitN : public HitBaseN<N>
122{
124 Eigen::Vector<float, N> distances =
125 Eigen::Vector<float, N>::Constant(std::numeric_limits<float>::infinity());
126};
127
133template <size_t N>
134struct RayHitN : public HitBaseN<N>
135{
137 Eigen::Vector<float, N> ray_depths = Eigen::Vector<float, N>::Zero();
138
140 Eigen::Matrix<float, 3, N> normals = Eigen::Matrix<float, 3, N>::Zero();
141};
142
145enum class SceneFlags {
147 None = 0,
148
150 Dynamic = 1 << 0,
151
153 Compact = 1 << 1,
154
157 Robust = 1 << 2,
158
160 Filter = 1 << 3,
161};
162
167enum class BuildQuality {
169 Low = 0,
170
173
175 High = 2,
176};
177
196{
197public:
199 using Pointf = Eigen::Vector3f;
200
202 using Directionf = Eigen::Vector3f;
203
205 template <typename Scalar>
206 using Affine = Eigen::Transform<Scalar, 3, Eigen::Affine>;
207
209 using Hit = RayHit;
210
213 using Point4f = Eigen::Matrix<float, 4, 3, Eigen::RowMajor>;
214 using Direction4f = Eigen::Matrix<float, 4, 3, Eigen::RowMajor>;
215 using Float4 = Eigen::Vector<float, 4>;
216 using Mask4 = Eigen::Vector<bool, 4>;
217 using RayHit4 = RayHitN<4>;
218 using ClosestPointHit4 = ClosestPointHitN<4>;
220
223 using Point8f = Eigen::Matrix<float, 8, 3, Eigen::RowMajor>;
224 using Direction8f = Eigen::Matrix<float, 8, 3, Eigen::RowMajor>;
225 using Float8 = Eigen::Vector<float, 8>;
226 using Mask8 = Eigen::Vector<bool, 8>;
227 using RayHit8 = RayHitN<8>;
228 using ClosestPointHit8 = ClosestPointHitN<8>;
230
233 using Point16f = Eigen::Matrix<float, 16, 3, Eigen::RowMajor>;
234 using Direction16f = Eigen::Matrix<float, 16, 3, Eigen::RowMajor>;
235 using Float16 = Eigen::Vector<float, 16>;
236 using Mask16 = Eigen::Vector<bool, 16>;
237 using RayHit16 = RayHitN<16>;
238 using ClosestPointHit16 = ClosestPointHitN<16>;
240
241public:
244
251 explicit RayCaster(
253 BuildQuality build_quality = BuildQuality::Medium);
254
257
259 RayCaster(RayCaster&& other) noexcept;
260
262 RayCaster& operator=(RayCaster&& other) noexcept;
263
265 RayCaster(const RayCaster&) = delete;
266
268 RayCaster& operator=(const RayCaster&) = delete;
269
271
274
295 template <typename Scalar, typename Index>
296 uint32_t add_mesh(
298 const std::optional<Affine<Scalar>>& transform = Affine<Scalar>::Identity());
299
314 uint32_t add_instance(uint32_t mesh_index, const Eigen::Affine3f& transform);
315
326 template <typename Scalar, typename Index>
328
334 void commit_updates();
335
337
340
351 template <typename Scalar, typename Index>
352 void update_mesh(uint32_t mesh_index, const SurfaceMesh<Scalar, Index>& mesh);
353
369 template <typename Scalar, typename Index>
370 void update_vertices(uint32_t mesh_index, const SurfaceMesh<Scalar, Index>& mesh);
371
381 template <typename Scalar>
382 void update_vertices(uint32_t mesh_index, span<const Scalar> vertices);
383
393 Eigen::Affine3f get_transform(uint32_t mesh_index, uint32_t instance_index) const;
394
403 void update_transform(
404 uint32_t mesh_index,
405 uint32_t instance_index,
406 const Eigen::Affine3f& transform);
407
416 bool get_visibility(uint32_t mesh_index, uint32_t instance_index);
417
425 void update_visibility(uint32_t mesh_index, uint32_t instance_index, bool visible);
426
428
431
439 auto get_intersection_filter(uint32_t mesh_index) const
440 -> std::function<bool(uint32_t instance_index, uint32_t facet_index)>;
441
450 uint32_t mesh_index,
451 std::function<bool(uint32_t instance_index, uint32_t facet_index)>&& filter);
452
460 auto get_occlusion_filter(uint32_t mesh_index) const
461 -> std::function<bool(uint32_t instance_index, uint32_t facet_index)>;
462
471 uint32_t mesh_index,
472 std::function<bool(uint32_t instance_index, uint32_t facet_index)>&& filter);
473
475
478
486 std::optional<ClosestPointHit> closest_point(const Pointf& query_point) const;
487
500 ClosestPointHit4 closest_point4(
501 const Point4f& query_points,
502 const std::variant<Mask4, size_t>& active) const;
503
516 ClosestPointHit8 closest_point8(
517 const Point8f& query_points,
518 const std::variant<Mask8, size_t>& active) const;
519
532 ClosestPointHit16 closest_point16(
533 const Point16f& query_points,
534 const std::variant<Mask16, size_t>& active) const;
535
537
540
551 std::optional<ClosestPointHit> closest_vertex(const Pointf& query_point) const;
552
565 ClosestPointHit4 closest_vertex4(
566 const Point4f& query_points,
567 const std::variant<Mask4, size_t>& active) const;
568
581 ClosestPointHit8 closest_vertex8(
582 const Point8f& query_points,
583 const std::variant<Mask8, size_t>& active) const;
584
597 ClosestPointHit16 closest_vertex16(
598 const Point16f& query_points,
599 const std::variant<Mask16, size_t>& active) const;
600
602
603
606
617 std::optional<RayHit> cast(
618 const Pointf& origin,
619 const Directionf& direction,
620 float tmin = 0,
621 float tmax = std::numeric_limits<float>::infinity()) const;
622
633 bool occluded(
634 const Pointf& origin,
635 const Directionf& direction,
636 float tmin = 0,
637 float tmax = std::numeric_limits<float>::infinity()) const;
638
640
643
657 RayHit4 cast4(
658 const Point4f& origins,
659 const Direction4f& directions,
660 const std::variant<Mask4, size_t>& active = size_t(4),
661 const Float4& tmin = Float4::Zero(),
662 const Float4& tmax = Float4::Constant(std::numeric_limits<float>::infinity())) const;
663
677 uint32_t occluded4(
678 const Point4f& origins,
679 const Direction4f& directions,
680 const std::variant<Mask4, size_t>& active = size_t(4),
681 const Float4& tmin = Float4::Zero(),
682 const Float4& tmax = Float4::Constant(std::numeric_limits<float>::infinity())) const;
683
685
688
702 RayHit8 cast8(
703 const Point8f& origins,
704 const Direction8f& directions,
705 const std::variant<Mask8, size_t>& active = size_t(8),
706 const Float8& tmin = Float8::Zero(),
707 const Float8& tmax = Float8::Constant(std::numeric_limits<float>::infinity())) const;
708
722 uint32_t occluded8(
723 const Point8f& origins,
724 const Direction8f& directions,
725 const std::variant<Mask8, size_t>& active = size_t(8),
726 const Float8& tmin = Float8::Zero(),
727 const Float8& tmax = Float8::Constant(std::numeric_limits<float>::infinity())) const;
728
730
733
747 RayHit16 cast16(
748 const Point16f& origins,
749 const Direction16f& directions,
750 const std::variant<Mask16, size_t>& active = size_t(16),
751 const Float16& tmin = Float16::Zero(),
752 const Float16& tmax = Float16::Constant(std::numeric_limits<float>::infinity())) const;
753
767 uint32_t occluded16(
768 const Point16f& origins,
769 const Direction16f& directions,
770 const std::variant<Mask16, size_t>& active = size_t(16),
771 const Float16& tmin = Float16::Zero(),
772 const Float16& tmax = Float16::Constant(std::numeric_limits<float>::infinity())) const;
773
775
776private:
778 friend struct internal::RayCasterOBBAccess;
779
784 struct OrientedBox
785 {
786 Eigen::Vector3f center = Eigen::Vector3f::Zero();
787 Eigen::Matrix3f axes = Eigen::Matrix3f::Identity();
788 Eigen::Vector3f half_extents = Eigen::Vector3f::Zero();
789 };
790
791 void overlap_obb_internal(
792 const OrientedBox& obb,
793 function_ref<bool(uint32_t mesh_index, uint32_t instance_index, uint32_t facet_index)>
794 callback) const;
795
802 void overlap_obb16_internal(
804 std::variant<Mask16, size_t> active,
806 bool(uint32_t lane, uint32_t mesh_index, uint32_t instance_index, uint32_t facet_index)>
807 callback) const;
808
809 struct Impl;
810 value_ptr<Impl> m_impl;
812};
813
814} // namespace lagrange::raycasting
Bit field utility class.
Definition BitField.h:33
A general purpose polygonal mesh class.
Definition SurfaceMesh.h:73
A lightweight non-owning reference to a callable.
Definition function_ref.h:47
uint32_t occluded4(const Point4f &origins, const Direction4f &directions, const std::variant< Mask4, size_t > &active=size_t(4), const Float4 &tmin=Float4::Zero(), const Float4 &tmax=Float4::Constant(std::numeric_limits< float >::infinity())) const
Test a packet of up to 4 rays for occlusion.
Definition RayCaster.cpp:1592
std::optional< RayHit > cast(const Pointf &origin, const Directionf &direction, float tmin=0, float tmax=std::numeric_limits< float >::infinity()) const
Cast a single ray and find the closest intersection.
Definition RayCaster.cpp:1235
bool occluded(const Pointf &origin, const Directionf &direction, float tmin=0, float tmax=std::numeric_limits< float >::infinity()) const
Test whether a single ray hits anything in the scene (occlusion query).
Definition RayCaster.cpp:1300
void update_vertices(uint32_t mesh_index, const SurfaceMesh< Scalar, Index > &mesh)
Notify the raycaster that vertices of a mesh have been modified externally.
Definition RayCaster.cpp:899
void add_scene(scene::SimpleScene< Scalar, Index, 3 > simple_scene)
Add all meshes and instances from a SimpleScene.
Definition RayCaster.cpp:855
ClosestPointHit8 closest_vertex8(const Point8f &query_points, const std::variant< Mask8, size_t > &active) const
Find the closest vertex on the scene for a packet of up to 8 query points.
Definition RayCaster.cpp:1216
RayCaster(const RayCaster &)=delete
Non-copyable.
ClosestPointHit16 closest_point16(const Point16f &query_points, const std::variant< Mask16, size_t > &active) const
Find the closest point on the scene for a packet of up to 16 query points.
Definition RayCaster.cpp:1197
Eigen::Vector3f Pointf
3D point type.
Definition RayCaster.h:199
RayCaster & operator=(const RayCaster &)=delete
Non-copyable.
uint32_t add_mesh(SurfaceMesh< Scalar, Index > mesh, const std::optional< Affine< Scalar > > &transform=Affine< Scalar >::Identity())
Add a single mesh to the scene.
Definition RayCaster.cpp:827
uint32_t occluded16(const Point16f &origins, const Direction16f &directions, const std::variant< Mask16, size_t > &active=size_t(16), const Float16 &tmin=Float16::Zero(), const Float16 &tmax=Float16::Constant(std::numeric_limits< float >::infinity())) const
Test a packet of up to 16 rays for occlusion.
Definition RayCaster.cpp:1640
ClosestPointHit8 closest_point8(const Point8f &query_points, const std::variant< Mask8, size_t > &active) const
Find the closest point on the scene for a packet of up to 8 query points.
Definition RayCaster.cpp:1190
uint32_t occluded8(const Point8f &origins, const Direction8f &directions, const std::variant< Mask8, size_t > &active=size_t(8), const Float8 &tmin=Float8::Zero(), const Float8 &tmax=Float8::Constant(std::numeric_limits< float >::infinity())) const
Test a packet of up to 8 rays for occlusion.
Definition RayCaster.cpp:1616
auto get_intersection_filter(uint32_t mesh_index) const -> std::function< bool(uint32_t instance_index, uint32_t facet_index)>
Get the intersection filter function currently bound to a given mesh.
Definition RayCaster.cpp:1014
RayHit4 cast4(const Point4f &origins, const Direction4f &directions, const std::variant< Mask4, size_t > &active=size_t(4), const Float4 &tmin=Float4::Zero(), const Float4 &tmax=Float4::Constant(std::numeric_limits< float >::infinity())) const
Cast a packet of up to 4 rays and find the closest intersections.
Definition RayCaster.cpp:1582
Eigen::Transform< Scalar, 3, Eigen::Affine > Affine
4x4 affine transform type (column-major).
Definition RayCaster.h:206
RayHit16 cast16(const Point16f &origins, const Direction16f &directions, const std::variant< Mask16, size_t > &active=size_t(16), const Float16 &tmin=Float16::Zero(), const Float16 &tmax=Float16::Constant(std::numeric_limits< float >::infinity())) const
Cast a packet of up to 16 rays and find the closest intersections.
Definition RayCaster.cpp:1630
std::optional< ClosestPointHit > closest_vertex(const Pointf &query_point) const
Find the closest vertex on the scene to a query point.
Definition RayCaster.cpp:1204
std::optional< ClosestPointHit > closest_point(const Pointf &query_point) const
Find the closest point on the scene to a query point.
Definition RayCaster.cpp:1178
RayHit Hit
Hit result type.
Definition RayCaster.h:209
ClosestPointHit4 closest_vertex4(const Point4f &query_points, const std::variant< Mask4, size_t > &active) const
Find the closest vertex on the scene for a packet of up to 4 query points.
Definition RayCaster.cpp:1209
RayCaster & operator=(RayCaster &&other) noexcept
Move assignment.
void update_transform(uint32_t mesh_index, uint32_t instance_index, const Eigen::Affine3f &transform)
Update the affine transform of a given mesh instance.
Definition RayCaster.cpp:946
RayHit8 cast8(const Point8f &origins, const Direction8f &directions, const std::variant< Mask8, size_t > &active=size_t(8), const Float8 &tmin=Float8::Zero(), const Float8 &tmax=Float8::Constant(std::numeric_limits< float >::infinity())) const
Cast a packet of up to 8 rays and find the closest intersections.
Definition RayCaster.cpp:1606
RayCaster(RayCaster &&other) noexcept
Move constructor.
RayCaster(BitField< SceneFlags > scene_flags=SceneFlags::Robust, BuildQuality build_quality=BuildQuality::Medium)
Construct a RayCaster with the given Embree scene configuration.
Definition RayCaster.cpp:809
Eigen::Affine3f get_transform(uint32_t mesh_index, uint32_t instance_index) const
Get the affine transform of a given mesh instance.
Definition RayCaster.cpp:935
void set_occlusion_filter(uint32_t mesh_index, std::function< bool(uint32_t instance_index, uint32_t facet_index)> &&filter)
Set an occlusion filter that is called for every hit on (every instance of) a mesh during an occlusio...
Definition RayCaster.cpp:1046
void commit_updates()
Notify the raycaster that all pending updates have been made and the BVH can be rebuilt.
Definition RayCaster.cpp:864
auto get_occlusion_filter(uint32_t mesh_index) const -> std::function< bool(uint32_t instance_index, uint32_t facet_index)>
Get the occlusion filter function currently bound to a given mesh.
Definition RayCaster.cpp:1037
uint32_t add_instance(uint32_t mesh_index, const Eigen::Affine3f &transform)
Add a single instance of an existing source mesh to the scene with a given affine transform.
Definition RayCaster.cpp:842
ClosestPointHit4 closest_point4(const Point4f &query_points, const std::variant< Mask4, size_t > &active) const
Find the closest point on the scene for a packet of up to 4 query points.
Definition RayCaster.cpp:1183
bool get_visibility(uint32_t mesh_index, uint32_t instance_index)
Get the visibility flag of a given mesh instance.
Definition RayCaster.cpp:974
void update_mesh(uint32_t mesh_index, const SurfaceMesh< Scalar, Index > &mesh)
Replace a mesh in the scene.
Definition RayCaster.cpp:874
Eigen::Vector3f Directionf
3D direction type.
Definition RayCaster.h:202
ClosestPointHit16 closest_vertex16(const Point16f &query_points, const std::variant< Mask16, size_t > &active) const
Find the closest vertex on the scene for a packet of up to 16 query points.
Definition RayCaster.cpp:1223
void update_visibility(uint32_t mesh_index, uint32_t instance_index, bool visible)
Update the visibility of a given mesh instance.
Definition RayCaster.cpp:985
void set_intersection_filter(uint32_t mesh_index, std::function< bool(uint32_t instance_index, uint32_t facet_index)> &&filter)
Set an intersection filter that is called for every hit on (every instance of) a mesh during an inter...
Definition RayCaster.cpp:1023
Simple scene container for instanced meshes.
Definition SimpleScene.h:62
Smart pointer with value semantics.
Definition value_ptr.h:134
::nonstd::span< T, Extent > span
A bounds-safe view for sequences of objects.
Definition span.h:27
constexpr T invalid()
You can use invalid<T>() to get a value that can represent "invalid" values, such as invalid indices ...
Definition invalid.h:40
Raycasting operations.
Definition compute_local_feature_size.h:20
SceneFlags
Flags for configuring the ray caster and the underlying Embree scene.
Definition RayCaster.h:145
@ None
No special behavior.
Definition RayCaster.h:147
@ Dynamic
Indicates that the scene will be updated frequently.
Definition RayCaster.h:150
@ Compact
Use a more compact BVH layout that may be faster to build but slower to traverse.
Definition RayCaster.h:153
@ Robust
Use a more robust BVH traversal algorithm that is slower but less likely to miss hits due to numerica...
Definition RayCaster.h:157
@ Filter
Enable user-defined intersection and occlusion filters.
Definition RayCaster.h:160
BuildQuality
Quality levels for BVH construction.
Definition RayCaster.h:167
@ Low
Fastest build time, lowest BVH quality.
Definition RayCaster.h:169
@ High
Slowest build time, highest BVH quality.
Definition RayCaster.h:175
@ Medium
Moderate build time and BVH quality.
Definition RayCaster.h:172
Result of a single closest point query.
Definition RayCaster.h:64
float distance
Distance from the query point to the closest point on the surface.
Definition RayCaster.h:66
Result of a multi-point closest point query.
Definition RayCaster.h:122
Eigen::Vector< float, N > distances
Definition RayCaster.h:124
Shared base struct for ray and closest point hits.
Definition RayCaster.h:41
Eigen::Vector2f barycentric_coord
Barycentric coordinates of the hit point within the hit facet.
Definition RayCaster.h:54
uint32_t facet_index
Index of the facet that was hit.
Definition RayCaster.h:49
Eigen::Vector3f position
World-space position of the hit point.
Definition RayCaster.h:57
uint32_t mesh_index
Index of the mesh that was hit.
Definition RayCaster.h:43
uint32_t instance_index
Index of the instance that was hit (relative to the source mesh).
Definition RayCaster.h:46
Shared base struct for multi-ray and multi-point hits.
Definition RayCaster.h:88
Eigen::Vector< uint32_t, N > mesh_indices
Index of the mesh that was hit.
Definition RayCaster.h:93
uint32_t valid_mask
Bitmask indicating which rays in the packet hit something (1 bit per ray).
Definition RayCaster.h:90
Eigen::Matrix< float, 3, N > positions
World-space position of the hit point.
Definition RayCaster.h:110
Eigen::Vector< uint32_t, N > instance_indices
Index of the instance that was hit (relative to the source mesh).
Definition RayCaster.h:97
Eigen::Matrix< float, 2, N > barycentric_coords
Barycentric coordinates of the hit points within the hit facets.
Definition RayCaster.h:107
Eigen::Vector< uint32_t, N > facet_indices
Index of the facet that was hit.
Definition RayCaster.h:101
Result of a single-ray intersection query.
Definition RayCaster.h:73
Eigen::Vector3f normal
Unnormalized geometric normal at the hit point.
Definition RayCaster.h:78
float ray_depth
Parametric distance along the ray (t value).
Definition RayCaster.h:75
Result of a multi-ray intersection query.
Definition RayCaster.h:135
Eigen::Matrix< float, 3, N > normals
Definition RayCaster.h:140
Eigen::Vector< float, N > ray_depths
Definition RayCaster.h:137
Friend accessor to RayCaster's OBB overlap queries.
Definition RayCasterOBBAccess.h:25