Move Vectormath main
C++20 game and graphics mathematics
Loading...
Searching...
No Matches
PreparedRay3.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cmath>
4#include <cstddef>
5#include <limits>
6#include <type_traits>
7
9
10namespace mv::math
11{
12 // Reciprocal direction/sign preparation follows Williams et al., "An
13 // Efficient and Robust Ray-Box Intersection Algorithm" (JGT 2005).
14 template <typename T>
15 requires std::is_floating_point_v<T>
17 {
18 public:
19 explicit PreparedRay3(const Ray3<T>& ray) noexcept :
20 Ray_(ray),
21 ReciprocalDirection_(Reciprocal(ray.Direction().Vector().X()),
22 Reciprocal(ray.Direction().Vector().Y()),
23 Reciprocal(ray.Direction().Vector().Z())),
24 ParallelMask_(BuildParallelMask(ray.Direction().Vector()))
25 {
26 }
27
29 {
30 return Ray_;
31 }
32
34 {
35 return ReciprocalDirection_;
36 }
37
38 [[nodiscard]] bool IsParallel(std::size_t axis) const noexcept
39 {
40 return (ParallelMask_ & (1U << axis)) != 0U;
41 }
42
43 private:
44 [[nodiscard]] static T Reciprocal(T value) noexcept
45 {
46 return value == T(0)
47 ? std::copysign(std::numeric_limits<T>::infinity(),
48 value)
49 : T(1) / value;
50 }
51
52 [[nodiscard]] static unsigned int BuildParallelMask(
53 const Vec3<T>& direction) noexcept
54 {
55 return (IsEffectivelyParallel(direction.X()) ? 1U : 0U) |
56 (IsEffectivelyParallel(direction.Y()) ? 2U : 0U) |
57 (IsEffectivelyParallel(direction.Z()) ? 4U : 0U);
58 }
59
60 [[nodiscard]] static bool IsEffectivelyParallel(T value) noexcept
61 {
62 return value == T(0) || !std::isfinite(T(1) / value);
63 }
64
65 Ray3<T> Ray_;
66 Vec3<T> ReciprocalDirection_;
67 unsigned int ParallelMask_;
68 };
69
72} // namespace mv::math
73
74static_assert(std::is_trivially_copyable_v<mv::math::PreparedRay3f>);
75static_assert(std::is_standard_layout_v<mv::math::PreparedRay3f>);
76static_assert(std::is_trivially_copyable_v<mv::math::PreparedRay3d>);
77static_assert(std::is_standard_layout_v<mv::math::PreparedRay3d>);
PreparedRay3(const Ray3< T > &ray) noexcept
bool IsParallel(std::size_t axis) const noexcept
const Ray3< T > & Ray() const noexcept
const Vec3< T > & ReciprocalDirection() const noexcept