-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathp3a_box3.hpp
126 lines (120 loc) · 3.38 KB
/
p3a_box3.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#pragma once
#include "p3a_vector3.hpp"
#include "p3a_functions.hpp"
#include "p3a_constants.hpp"
namespace p3a {
template <class T>
class box3 {
vector3<T> m_lower;
vector3<T> m_upper;
public:
P3A_ALWAYS_INLINE box3() = default;
template <class U>
P3A_HOST_DEVICE P3A_ALWAYS_INLINE constexpr explicit
box3(box3<U> const& other)
:m_lower(other.lower())
,m_upper(other.upper())
{}
P3A_HOST_DEVICE P3A_ALWAYS_INLINE constexpr explicit
box3(vector3<T> const& upper_in)
:m_lower(vector3<T>::zero())
,m_upper(upper_in)
{}
P3A_HOST_DEVICE P3A_ALWAYS_INLINE constexpr
box3(vector3<T> const& lower_in, vector3<T> const& upper_in)
:m_lower(lower_in)
,m_upper(upper_in)
{}
P3A_HOST_DEVICE P3A_ALWAYS_INLINE constexpr
box3(T const& a, T const& b, T const& c)
:box3(vector3<T>(a, b, c))
{}
[[nodiscard]] P3A_HOST_DEVICE P3A_ALWAYS_INLINE constexpr
vector3<T> extents() const
{
return m_upper - m_lower;
}
[[nodiscard]] P3A_HOST_DEVICE P3A_ALWAYS_INLINE constexpr
auto volume() const
{
return extents().volume();
}
[[nodiscard]] P3A_HOST_DEVICE P3A_ALWAYS_INLINE constexpr
vector3<T> const& lower() const
{
return m_lower;
}
[[nodiscard]] P3A_HOST_DEVICE P3A_ALWAYS_INLINE constexpr
vector3<T> const& upper() const
{
return m_upper;
}
[[nodiscard]] P3A_HOST_DEVICE P3A_ALWAYS_INLINE constexpr
vector3<T>& lower()
{
return m_lower;
}
[[nodiscard]] P3A_HOST_DEVICE P3A_ALWAYS_INLINE constexpr
vector3<T>& upper()
{
return m_upper;
}
[[nodiscard]] P3A_HOST_DEVICE P3A_ALWAYS_INLINE constexpr
bool operator==(box3 const& other) const
{
return m_lower == other.m_lower &&
m_upper == other.m_upper;
}
[[nodiscard]] P3A_HOST_DEVICE P3A_ALWAYS_INLINE static constexpr
box3 empty()
{
return box3(
vector3<T>(
maximum_value<T>(),
maximum_value<T>(),
maximum_value<T>()),
vector3<T>(
minimum_value<T>(),
minimum_value<T>(),
minimum_value<T>()));
}
P3A_HOST_DEVICE P3A_ALWAYS_INLINE inline
void include_point(vector3<T> const& point)
{
m_lower.x() = min(m_lower.x(), point.x());
m_lower.y() = min(m_lower.y(), point.y());
m_lower.z() = min(m_lower.z(), point.z());
m_upper.x() = max(m_upper.x(), point.x());
m_upper.y() = max(m_upper.y(), point.y());
m_upper.z() = max(m_upper.z(), point.z());
}
};
template <class T>
[[nodiscard]] P3A_HOST_DEVICE P3A_ALWAYS_INLINE constexpr
box3<T> intersect(box3<T> const& a, box3<T> const& b)
{
auto const lower = vector3<T>(
max(a.lower().x(), b.lower().x()),
max(a.lower().y(), b.lower().y()),
max(a.lower().z(), b.lower().z()));
auto const upper = vector3<T>(
max(lower.x(), min(a.upper().x(), b.upper().x())),
max(lower.y(), min(a.upper().y(), b.upper().y())),
max(lower.z(), min(a.upper().z(), b.upper().z())));
return box3<T>(lower, upper);
}
template <class T>
[[nodiscard]] P3A_HOST_DEVICE P3A_ALWAYS_INLINE constexpr
box3<T> unite(box3<T> const& a, box3<T> const& b)
{
auto const lower = vector3<T>(
min(a.lower().x(), b.lower().x()),
min(a.lower().y(), b.lower().y()),
min(a.lower().z(), b.lower().z()));
auto const upper = vector3<T>(
max(a.upper().x(), b.upper().x()),
max(a.upper().y(), b.upper().y()),
max(a.upper().z(), b.upper().z()));
return box3<T>(lower, upper);
}
}