VTK-m  2.0
BVHTraverser.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_rendering_raytracing_BVH_Traverser_h
11 #define vtk_m_rendering_raytracing_BVH_Traverser_h
12 
16 
19 
20 namespace vtkm
21 {
22 namespace rendering
23 {
24 namespace raytracing
25 {
26 #define END_FLAG -1000000000
27 
28 template <typename BVHPortalType, typename Precision>
29 VTKM_EXEC inline bool IntersectAABB(const BVHPortalType& bvh,
30  const vtkm::Int32& currentNode,
31  const vtkm::Vec<Precision, 3>& originDir,
32  const vtkm::Vec<Precision, 3>& invDir,
33  const Precision& closestDistance,
34  bool& hitLeftChild,
35  bool& hitRightChild,
36  const Precision& minDistance) //Find hit after this distance
37 {
38  vtkm::Vec4f_32 first4 = bvh.Get(currentNode);
39  vtkm::Vec4f_32 second4 = bvh.Get(currentNode + 1);
40  vtkm::Vec4f_32 third4 = bvh.Get(currentNode + 2);
41 
42  Precision xmin0 = first4[0] * invDir[0] - originDir[0];
43  Precision ymin0 = first4[1] * invDir[1] - originDir[1];
44  Precision zmin0 = first4[2] * invDir[2] - originDir[2];
45  Precision xmax0 = first4[3] * invDir[0] - originDir[0];
46  Precision ymax0 = second4[0] * invDir[1] - originDir[1];
47  Precision zmax0 = second4[1] * invDir[2] - originDir[2];
48 
49  Precision min0 = vtkm::Max(
50  vtkm::Max(vtkm::Max(vtkm::Min(ymin0, ymax0), vtkm::Min(xmin0, xmax0)), vtkm::Min(zmin0, zmax0)),
51  minDistance);
52  Precision max0 = vtkm::Min(
53  vtkm::Min(vtkm::Min(vtkm::Max(ymin0, ymax0), vtkm::Max(xmin0, xmax0)), vtkm::Max(zmin0, zmax0)),
54  closestDistance);
55  hitLeftChild = (max0 >= min0);
56 
57  Precision xmin1 = second4[2] * invDir[0] - originDir[0];
58  Precision ymin1 = second4[3] * invDir[1] - originDir[1];
59  Precision zmin1 = third4[0] * invDir[2] - originDir[2];
60  Precision xmax1 = third4[1] * invDir[0] - originDir[0];
61  Precision ymax1 = third4[2] * invDir[1] - originDir[1];
62  Precision zmax1 = third4[3] * invDir[2] - originDir[2];
63 
64  Precision min1 = vtkm::Max(
65  vtkm::Max(vtkm::Max(vtkm::Min(ymin1, ymax1), vtkm::Min(xmin1, xmax1)), vtkm::Min(zmin1, zmax1)),
66  minDistance);
67  Precision max1 = vtkm::Min(
68  vtkm::Min(vtkm::Min(vtkm::Max(ymin1, ymax1), vtkm::Max(xmin1, xmax1)), vtkm::Max(zmin1, zmax1)),
69  closestDistance);
70  hitRightChild = (max1 >= min1);
71  return (min0 > min1);
72 }
73 
75 {
76 public:
78  {
79  private:
80  VTKM_EXEC
81  inline vtkm::Float32 rcp(vtkm::Float32 f) const { return 1.0f / f; }
82  VTKM_EXEC
84  {
85  return rcp((vtkm::Abs(f) < 1e-8f) ? 1e-8f : f);
86  }
87  VTKM_EXEC
88  inline vtkm::Float64 rcp(vtkm::Float64 f) const { return 1.0 / f; }
89  VTKM_EXEC
91  {
92  return rcp((vtkm::Abs(f) < 1e-8f) ? 1e-8f : f);
93  }
94 
95  public:
96  VTKM_CONT
98  using ControlSignature = void(FieldIn,
99  FieldIn,
100  FieldOut,
101  FieldIn,
102  FieldIn,
103  FieldOut,
104  FieldOut,
105  FieldOut,
106  WholeArrayIn,
107  ExecObject leafIntersector,
108  WholeArrayIn,
109  WholeArrayIn);
110  using ExecutionSignature = void(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12);
111 
112 
113  template <typename PointPortalType,
114  typename Precision,
115  typename LeafType,
116  typename InnerNodePortalType,
117  typename LeafPortalType>
119  const vtkm::Vec<Precision, 3>& origin,
120  Precision& distance,
121  const Precision& minDistance,
122  const Precision& maxDistance,
123  Precision& minU,
124  Precision& minV,
125  vtkm::Id& hitIndex,
126  const PointPortalType& points,
127  LeafType& leafIntersector,
128  const InnerNodePortalType& flatBVH,
129  const LeafPortalType& leafs) const
130  {
131  Precision closestDistance = maxDistance;
132  distance = maxDistance;
133  hitIndex = -1;
134 
136  invDir[0] = rcp_safe(dir[0]);
137  invDir[1] = rcp_safe(dir[1]);
138  invDir[2] = rcp_safe(dir[2]);
139  vtkm::Int32 currentNode;
140 
141  vtkm::Int32 todo[64];
142  vtkm::Int32 stackptr = 0;
143  vtkm::Int32 barrier = (vtkm::Int32)END_FLAG;
144  currentNode = 0;
145 
146  todo[stackptr] = barrier;
147 
148  vtkm::Vec<Precision, 3> originDir = origin * invDir;
149 
150  while (currentNode != END_FLAG)
151  {
152  if (currentNode > -1)
153  {
154 
155 
156  bool hitLeftChild, hitRightChild;
157  bool rightCloser = IntersectAABB(flatBVH,
158  currentNode,
159  originDir,
160  invDir,
161  closestDistance,
162  hitLeftChild,
163  hitRightChild,
164  minDistance);
165 
166  if (!hitLeftChild && !hitRightChild)
167  {
168  currentNode = todo[stackptr];
169  stackptr--;
170  }
171  else
172  {
173  vtkm::Vec4f_32 children = flatBVH.Get(currentNode + 3); //Children.Get(currentNode);
174  vtkm::Int32 leftChild;
175  memcpy(&leftChild, &children[0], 4);
176  vtkm::Int32 rightChild;
177  memcpy(&rightChild, &children[1], 4);
178  currentNode = (hitLeftChild) ? leftChild : rightChild;
179  if (hitLeftChild && hitRightChild)
180  {
181  if (rightCloser)
182  {
183  currentNode = rightChild;
184  stackptr++;
185  todo[stackptr] = leftChild;
186  }
187  else
188  {
189  stackptr++;
190  todo[stackptr] = rightChild;
191  }
192  }
193  }
194  } // if inner node
195 
196  if (currentNode < 0 && currentNode != barrier) //check register usage
197  {
198  currentNode = -currentNode - 1; //swap the neg address
199  leafIntersector.IntersectLeaf(currentNode,
200  origin,
201  dir,
202  points,
203  hitIndex,
204  closestDistance,
205  minU,
206  minV,
207  leafs,
208  minDistance);
209  currentNode = todo[stackptr];
210  stackptr--;
211  } // if leaf node
212 
213  } //while
214 
215  if (hitIndex != -1)
216  distance = closestDistance;
217  } // ()
218  };
219 
220 
221  template <typename Precision, typename LeafIntersectorType>
223  LinearBVH& bvh,
224  LeafIntersectorType& leafIntersector,
225  vtkm::cont::CoordinateSystem& coordsHandle)
226  {
228  intersectDispatch.Invoke(rays.Dir,
229  rays.Origin,
230  rays.Distance,
231  rays.MinDistance,
232  rays.MaxDistance,
233  rays.U,
234  rays.V,
235  rays.HitIdx,
236  coordsHandle,
237  leafIntersector,
238  bvh.FlatBVH,
239  bvh.Leafs);
240  }
241 }; // BVHTraverser
242 #undef END_FLAG
243 }
244 }
245 } //namespace vtkm::rendering::raytracing
246 #endif //vtk_m_rendering_raytracing_BVHTraverser_h
vtkm::rendering::raytracing::LinearBVH::Leafs
LeafNodesHandle Leafs
Definition: BoundingVolumeHierarchy.h:44
vtkm::rendering::raytracing::BVHTraverser::Intersector::rcp
VTKM_EXEC vtkm::Float64 rcp(vtkm::Float64 f) const
Definition: BVHTraverser.h:88
END_FLAG
#define END_FLAG
Definition: BVHTraverser.h:26
VTKM_EXEC
#define VTKM_EXEC
Definition: ExportMacros.h:51
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
WorkletMapField.h
vtkm::rendering::raytracing::Ray::U
vtkm::cont::ArrayHandle< Precision > U
Definition: Ray.h:81
vtkm::rendering::raytracing::BVHTraverser::Intersector
Definition: BVHTraverser.h:77
vtkm::rendering::raytracing::BVHTraverser::Intersector::operator()
VTKM_EXEC void operator()(const vtkm::Vec< Precision, 3 > &dir, const vtkm::Vec< Precision, 3 > &origin, Precision &distance, const Precision &minDistance, const Precision &maxDistance, Precision &minU, Precision &minV, vtkm::Id &hitIndex, const PointPortalType &points, LeafType &leafIntersector, const InnerNodePortalType &flatBVH, const LeafPortalType &leafs) const
Definition: BVHTraverser.h:118
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::rendering::raytracing::Ray::V
vtkm::cont::ArrayHandle< Precision > V
Definition: Ray.h:82
DispatcherMapField.h
vtkm::rendering::raytracing::BVHTraverser::Intersector::ExecutionSignature
void(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) ExecutionSignature
Definition: BVHTraverser.h:110
vtkm::rendering::raytracing::BVHTraverser
Definition: BVHTraverser.h:74
vtkm::cont::CoordinateSystem
Definition: CoordinateSystem.h:25
vtkm::rendering::raytracing::Ray::MinDistance
vtkm::cont::ArrayHandle< Precision > MinDistance
Definition: Ray.h:93
vtkm::rendering::raytracing::Ray
Definition: Ray.h:37
vtkm::rendering::raytracing::BVHTraverser::IntersectRays
VTKM_CONT void IntersectRays(Ray< Precision > &rays, LinearBVH &bvh, LeafIntersectorType &leafIntersector, vtkm::cont::CoordinateSystem &coordsHandle)
Definition: BVHTraverser.h:222
vtkm::worklet::DispatcherMapField
Dispatcher for worklets that inherit from WorkletMapField.
Definition: DispatcherMapField.h:25
vtkm::rendering::raytracing::BVHTraverser::Intersector::rcp_safe
VTKM_EXEC vtkm::Float32 rcp_safe(vtkm::Float32 f) const
Definition: BVHTraverser.h:83
vtkm::rendering::raytracing::IntersectAABB
VTKM_EXEC bool IntersectAABB(const BVHPortalType &bvh, const vtkm::Int32 &currentNode, const vtkm::Vec< Precision, 3 > &originDir, const vtkm::Vec< Precision, 3 > &invDir, const Precision &closestDistance, bool &hitLeftChild, bool &hitRightChild, const Precision &minDistance)
Definition: BVHTraverser.h:29
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::rendering::raytracing::Ray::HitIdx
vtkm::cont::ArrayHandle< vtkm::Id > HitIdx
Definition: Ray.h:90
vtkm::rendering::raytracing::LinearBVH::FlatBVH
InnerNodesHandle FlatBVH
Definition: BoundingVolumeHierarchy.h:43
vtkm::rendering::raytracing::Ray::Distance
vtkm::cont::ArrayHandle< Precision > Distance
Definition: Ray.h:88
vtkm::rendering::raytracing::Ray::Dir
vtkm::cont::ArrayHandleCompositeVector< vtkm::cont::ArrayHandle< Precision >, vtkm::cont::ArrayHandle< Precision >, vtkm::cont::ArrayHandle< Precision > > Dir
Definition: Ray.h:66
vtkm::rendering::raytracing::BVHTraverser::Intersector::Intersector
VTKM_CONT Intersector()
Definition: BVHTraverser.h:97
vtkm::Vec
A short fixed-length array.
Definition: Types.h:767
vtkm::rendering::raytracing::BVHTraverser::Intersector::rcp
VTKM_EXEC vtkm::Float32 rcp(vtkm::Float32 f) const
Definition: BVHTraverser.h:81
vtkm::Float32
float Float32
Definition: Types.h:154
vtkm::Int32
int32_t Int32
Definition: Types.h:160
vtkm::Float64
double Float64
Definition: Types.h:155
RayTracingTypeDefs.h
vtkm::rendering::raytracing::Ray::Origin
vtkm::cont::ArrayHandleCompositeVector< vtkm::cont::ArrayHandle< Precision >, vtkm::cont::ArrayHandle< Precision >, vtkm::cont::ArrayHandle< Precision > > Origin
Definition: Ray.h:60
vtkm::rendering::raytracing::BVHTraverser::Intersector::rcp_safe
VTKM_EXEC vtkm::Float64 rcp_safe(vtkm::Float64 f) const
Definition: BVHTraverser.h:90
vtkm::rendering::raytracing::Ray::MaxDistance
vtkm::cont::ArrayHandle< Precision > MaxDistance
Definition: Ray.h:94
vtkm::rendering::raytracing::BVHTraverser::Intersector::ControlSignature
void(FieldIn, FieldIn, FieldOut, FieldIn, FieldIn, FieldOut, FieldOut, FieldOut, WholeArrayIn, ExecObject leafIntersector, WholeArrayIn, WholeArrayIn) ControlSignature
Definition: BVHTraverser.h:109
Ray.h
vtkm::worklet::WorkletMapField
Base class for worklets that do a simple mapping of field arrays.
Definition: WorkletMapField.h:38
vtkm::rendering::raytracing::LinearBVH
Definition: BoundingVolumeHierarchy.h:37
BoundingVolumeHierarchy.h