Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
TWideBvhNode.ipp
Go to the documentation of this file.
1#pragma once
2
4
5namespace ph::math
6{
7
8template<std::size_t N, typename Index>
9inline TWideBvhNode<N, Index>
10::TWideBvhNode()
11 : m_aabbMins{}
12 , m_aabbMaxs{}
13 , m_offsets(make_array<Index, N>(static_cast<Index>(-1)))
14 , m_childrenData{}
15{
16 const auto emptyAABB = AABB3D::makeEmpty();
17 for(std::size_t di = 0; di < 3; ++di)
18 {
19 for(std::size_t ni = 0; ni < N; ++ni)
20 {
21 m_aabbMins[di][ni] = emptyAABB.getMinVertex()[di];
22 m_aabbMaxs[di][ni] = emptyAABB.getMaxVertex()[di];
23 }
24 }
25}
26
27template<std::size_t N, typename Index>
28inline auto TWideBvhNode<N, Index>
29::getAABB(const std::size_t childIdx) const
30-> AABB3D
31{
32 PH_ASSERT_LT(childIdx, N);
33
34 return AABB3D(
35 Vector3R(m_aabbMins[0][childIdx], m_aabbMins[1][childIdx], m_aabbMins[2][childIdx]),
36 Vector3R(m_aabbMaxs[0][childIdx], m_aabbMaxs[1][childIdx], m_aabbMaxs[2][childIdx]));
37}
38
39template<std::size_t N, typename Index>
40inline auto TWideBvhNode<N, Index>
41::getMinVerticesOnAxis(const std::size_t axis) const
43{
44 PH_ASSERT_IN_RANGE_INCLUSIVE(axis, 0, 2);
45
46 return m_aabbMins[axis];
47}
48
49template<std::size_t N, typename Index>
50inline auto TWideBvhNode<N, Index>
51::getMaxVerticesOnAxis(const std::size_t axis) const
53{
54 PH_ASSERT_IN_RANGE_INCLUSIVE(axis, 0, 2);
55
56 return m_aabbMaxs[axis];
57}
58
59template<std::size_t N, typename Index>
60inline bool TWideBvhNode<N, Index>
61::isLeaf(const std::size_t childIdx) const
62{
63 PH_ASSERT_LT(childIdx, m_childrenData.size());
64
65 return m_childrenData[childIdx].isLeaf;
66}
67
68template<std::size_t N, typename Index>
69inline bool TWideBvhNode<N, Index>
70::isInternal(const std::size_t childIdx) const
71{
72 return !isLeaf(childIdx);
73}
74
75template<std::size_t N, typename Index>
76inline auto TWideBvhNode<N, Index>
77::getChildOffset(const std::size_t childIdx) const
78-> std::size_t
79{
80 PH_ASSERT(isInternal(childIdx));
81
82 return static_cast<std::size_t>(m_offsets[childIdx]);
83}
84
85template<std::size_t N, typename Index>
86inline auto TWideBvhNode<N, Index>
87::getSplitAxis(const std::size_t childIdx) const
88-> std::size_t
89{
90 return static_cast<std::size_t>(m_childrenData[childIdx].splitAxis);
91}
92
93template<std::size_t N, typename Index>
94inline auto TWideBvhNode<N, Index>
95::getItemOffset(const std::size_t childIdx) const
96-> std::size_t
97{
98 PH_ASSERT(isLeaf(childIdx));
99
100 return static_cast<std::size_t>(m_offsets[childIdx]);
101}
102
103template<std::size_t N, typename Index>
104inline auto TWideBvhNode<N, Index>
105::numItems(const std::size_t childIdx) const
106-> std::size_t
107{
108 PH_ASSERT(isLeaf(childIdx));
109
110 return static_cast<std::size_t>(m_childrenData[childIdx].numItems);
111}
112
113template<std::size_t N, typename Index>
114inline auto TWideBvhNode<N, Index>
116 const std::size_t childIdx,
117 const AABB3D& childAABB,
118 const std::size_t childOffset,
119 const std::size_t splitAxis)
120-> TWideBvhNode&
121{
122 PH_ASSERT_LT(childIdx, N);
123 PH_ASSERT_IN_RANGE_INCLUSIVE(splitAxis, 0, 2);
124
125 for(std::size_t di = 0; di < 3; ++di)
126 {
127 m_aabbMins[di][childIdx] = childAABB.getMinVertex()[di];
128 m_aabbMaxs[di][childIdx] = childAABB.getMaxVertex()[di];
129 }
130
131 m_offsets[childIdx] = lossless_cast<Index>(childOffset);
132 m_childrenData[childIdx] = {
133 .isLeaf = false,
134 .splitAxis = static_cast<uint8>(splitAxis),
135 .numItems = 0};
136
137 return *this;
138}
139
140template<std::size_t N, typename Index>
141inline auto TWideBvhNode<N, Index>
143 const std::size_t childIdx,
144 const AABB3D& childAABB,
145 const std::size_t itemOffset,
146 const std::size_t splitAxis,
147 const std::size_t numItems)
148-> TWideBvhNode&
149{
150 PH_ASSERT_LT(childIdx, N);
151 PH_ASSERT_IN_RANGE_INCLUSIVE(splitAxis, 0, 2);
152 PH_ASSERT_LE(numItems, MAX_NODE_ITEMS);
153
154 for(std::size_t di = 0; di < 3; ++di)
155 {
156 m_aabbMins[di][childIdx] = childAABB.getMinVertex()[di];
157 m_aabbMaxs[di][childIdx] = childAABB.getMaxVertex()[di];
158 }
159
160 m_offsets[childIdx] = lossless_cast<Index>(itemOffset);
161 m_childrenData[childIdx] = {
162 .isLeaf = true,
163 .splitAxis = static_cast<uint8>(splitAxis),
164 .numItems = static_cast<uint8>(numItems)};
165
166 return *this;
167}
168
169template<std::size_t N, typename Index>
170inline auto TWideBvhNode<N, Index>
172 const std::size_t childIdx,
173 const std::size_t splitAxis)
174-> TWideBvhNode&
175{
176 return setLeaf(
177 childIdx,
179 static_cast<Index>(-1),
180 splitAxis,
181 0);
182}
183
184}// end namespace ph::math
static TAABB3D makeEmpty()
Definition TAABB3D.ipp:15
Definition TWideBvhNode.h:26
Math functions and utilities.
Definition TransformInfo.h:10
TAABB3D< real > AABB3D
Definition TAABB3D.h:21
TVector3< real > Vector3R
Definition math_fwd.h:52
std::span< const T, EXTENT > TSpanView
Same as TSpan, except that the objects are const-qualified. Note that for pointer types,...
Definition TSpan.h:19