CUDAPointHashGridSearcher3-Impl.hpp
Go to the documentation of this file.
1 // This code is based on Jet framework.
2 // Copyright (c) 2018 Doyub Kim
3 // CubbyFlow is voxel-based fluid simulation engine for computer games.
4 // Copyright (c) 2020 CubbyFlow Team
5 // Core Part: Chris Ohk, Junwoo Hwang, Jihong Sin, Seungwoo Yoo
6 // AI Part: Dongheon Cho, Minseo Kim
7 // We are making my contributions/submissions to this project solely in our
8 // personal capacity and are not conveying any rights to any intellectual
9 // property of any third parties.
10 
11 #ifndef CUBBYFLOW_CUDA_POINT_HASH_GRID_SEARCHER3_IMPL_HPP
12 #define CUBBYFLOW_CUDA_POINT_HASH_GRID_SEARCHER3_IMPL_HPP
13 
14 #ifdef CUBBYFLOW_USE_CUDA
15 
16 #include <Core/CUDA/CUDAUtils.hpp>
17 
18 #include <thrust/for_each.h>
19 #include <thrust/iterator/counting_iterator.h>
20 
21 namespace CubbyFlow
22 {
23 CUBBYFLOW_CUDA_HOST_DEVICE CUDAPointHashGridSearcher3::HashUtils::HashUtils(
24  float gridSpacing, uint3 resolution)
25  : m_gridSpacing{ gridSpacing }, m_resolution{ resolution }
26 {
27  // Do nothing
28 }
29 
30 inline CUBBYFLOW_CUDA_HOST_DEVICE void
31 CUDAPointHashGridSearcher3::HashUtils::GetNearbyKeys(float4 position,
32  uint32_t* nearbyKeys) const
33 {
34  int3 originIndex = GetBucketIndex(position), nearbyBucketIndices[8];
35 
36  for (int i = 0; i < 8; i++)
37  {
38  nearbyBucketIndices[i] = originIndex;
39  }
40 
41  if ((originIndex.x + 0.5f) * m_gridSpacing <= position.x)
42  {
43  nearbyBucketIndices[1].x += 1;
44  nearbyBucketIndices[3].x += 1;
45  nearbyBucketIndices[5].x += 1;
46  nearbyBucketIndices[7].x += 1;
47  }
48  else
49  {
50  nearbyBucketIndices[1].x -= 1;
51  nearbyBucketIndices[3].x -= 1;
52  nearbyBucketIndices[5].x -= 1;
53  nearbyBucketIndices[7].x -= 1;
54  }
55 
56  if ((originIndex.y + 0.5f) * m_gridSpacing <= position.y)
57  {
58  nearbyBucketIndices[2].y += 1;
59  nearbyBucketIndices[3].y += 1;
60  nearbyBucketIndices[6].y += 1;
61  nearbyBucketIndices[7].y += 1;
62  }
63  else
64  {
65  nearbyBucketIndices[2].y -= 1;
66  nearbyBucketIndices[3].y -= 1;
67  nearbyBucketIndices[6].y -= 1;
68  nearbyBucketIndices[7].y -= 1;
69  }
70 
71  if ((originIndex.z + 0.5f) * m_gridSpacing <= position.z)
72  {
73  nearbyBucketIndices[4].z += 1;
74  nearbyBucketIndices[5].z += 1;
75  nearbyBucketIndices[6].z += 1;
76  nearbyBucketIndices[7].z += 1;
77  }
78  else
79  {
80  nearbyBucketIndices[4].z -= 1;
81  nearbyBucketIndices[5].z -= 1;
82  nearbyBucketIndices[6].z -= 1;
83  nearbyBucketIndices[7].z -= 1;
84  }
85 
86  for (int i = 0; i < 8; i++)
87  {
88  nearbyKeys[i] = GetHashKeyFromBucketIndex(nearbyBucketIndices[i]);
89  }
90 }
91 
92 inline CUBBYFLOW_CUDA_HOST_DEVICE int3
93 CUDAPointHashGridSearcher3::HashUtils::GetBucketIndex(float4 position) const
94 {
95  int3 bucketIndex;
96 
97  bucketIndex.x = static_cast<int>(floorf(position.x / m_gridSpacing));
98  bucketIndex.y = static_cast<int>(floorf(position.y / m_gridSpacing));
99  bucketIndex.z = static_cast<int>(floorf(position.z / m_gridSpacing));
100 
101  return bucketIndex;
102 }
103 
104 inline CUBBYFLOW_CUDA_HOST_DEVICE uint32_t
105 CUDAPointHashGridSearcher3::HashUtils::GetHashKeyFromBucketIndex(
106  int3 bucketIndex) const
107 {
108  // Assumes m_resolution is power of two
109  bucketIndex.x = bucketIndex.x & (m_resolution.x - 1);
110  bucketIndex.y = bucketIndex.y & (m_resolution.y - 1);
111  bucketIndex.z = bucketIndex.z & (m_resolution.z - 1);
112  return bucketIndex.z * m_resolution.y * m_resolution.x +
113  bucketIndex.y * m_resolution.x + bucketIndex.x;
114 }
115 
116 inline CUBBYFLOW_CUDA_HOST_DEVICE uint32_t
117 CUDAPointHashGridSearcher3::HashUtils::GetHashKeyFromPosition(
118  float4 position) const
119 {
120  int3 bucketIndex = GetBucketIndex(position);
121  return GetHashKeyFromBucketIndex(bucketIndex);
122 }
123 
124 template <typename Callback>
125 inline CUBBYFLOW_CUDA_HOST_DEVICE CUDAPointHashGridSearcher3::
126  ForEachNearbyPointFunc<Callback>::ForEachNearbyPointFunc(
127  float r, float gridSpacing, uint3 resolution, const uint32_t* sit,
128  const uint32_t* eit, const uint32_t* si, const float4* p,
129  const float4* o, Callback cb)
130  : m_hashUtils(gridSpacing, resolution),
131  m_radius(r),
132  m_startIndexTable(sit),
133  m_endIndexTable(eit),
134  m_sortedIndices(si),
135  m_points(p),
136  m_origins(o),
137  m_callback(cb)
138 {
139  // Do nothing
140 }
141 
142 template <typename Callback>
143 template <typename Index>
144 inline CUBBYFLOW_CUDA_HOST_DEVICE void
145 CUDAPointHashGridSearcher3::ForEachNearbyPointFunc<Callback>::operator()(
146  Index idx)
147 {
148  const float4 origin = m_origins[idx];
149 
150  uint32_t nearbyKeys[8];
151  m_hashUtils.GetNearbyKeys(origin, nearbyKeys);
152 
153  const float queryRadiusSquared = m_radius * m_radius;
154 
155  for (int i = 0; i < 8; i++)
156  {
157  uint32_t nearbyKey = nearbyKeys[i];
158  uint32_t start = m_startIndexTable[nearbyKey];
159 
160  // Empty bucket -- continue to next bucket
161  if (start == 0xffffffff)
162  {
163  continue;
164  }
165 
166  uint32_t end = m_endIndexTable[nearbyKey];
167 
168  for (uint32_t jj = start; jj < end; ++jj)
169  {
170  uint32_t j = m_sortedIndices[jj];
171  float4 p = m_points[jj];
172  float4 direction = p - origin;
173 
174  float distanceSquared = LengthSquared(direction);
175  if (distanceSquared <= queryRadiusSquared)
176  {
177  if (distanceSquared > 0)
178  {
179  float distance = sqrtf(distanceSquared);
180  direction /= distance;
181  }
182 
183  m_callback(idx, origin, j, p);
184  }
185  }
186  }
187 }
188 
189 template <typename Callback>
190 void CUDAPointHashGridSearcher3::ForEachNearbyPoint(
191  const ConstCUDAArrayView1<float4>& origins, float radius,
192  Callback callback) const
193 {
194  thrust::for_each(
195  thrust::counting_iterator<size_t>(0),
196  thrust::counting_iterator<size_t>(0) + origins.Length(),
197  ForEachNearbyPointFunc<Callback>(
198  radius, m_gridSpacing, m_resolution, m_startIndexTable.data(),
199  m_endIndexTable.data(), m_sortedIndices.data(), m_points.data(),
200  origins.data(), callback));
201 }
202 } // namespace CubbyFlow
203 
204 #endif
205 
206 #endif
Iterator end()
Definition: ArrayBase-Impl.hpp:102
Definition: pybind11Utils.hpp:20
size_t Index(size_t i) const
Definition: ArrayBase-Impl.hpp:17