Loading...
Searching...
No Matches
CUDAPointHashGridSearcher2-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_SEARCHER2_IMPL_HPP
12#define CUBBYFLOW_CUDA_POINT_HASH_GRID_SEARCHER2_IMPL_HPP
13
14#ifdef CUBBYFLOW_USE_CUDA
15
17
18#include <thrust/for_each.h>
19#include <thrust/iterator/counting_iterator.h>
20
21namespace CubbyFlow
22{
23CUBBYFLOW_CUDA_HOST_DEVICE CUDAPointHashGridSearcher2::HashUtils::HashUtils(
25 : m_gridSpacing{ gridSpacing }, m_resolution{ resolution }
26{
27 (void)m_dummy;
28}
29
30inline CUBBYFLOW_CUDA_HOST_DEVICE void
31CUDAPointHashGridSearcher2::HashUtils::GetNearbyKeys(float2 position,
32 uint32_t* nearbyKeys) const
33{
34 int2 originIndex = GetBucketIndex(position), nearbyBucketIndices[8];
35
36 for (int i = 0; i < 4; i++)
37 {
38 nearbyBucketIndices[i] = originIndex;
39 }
40
41 if ((originIndex.x + 0.5f) * m_gridSpacing <= position.x)
42 {
43 nearbyBucketIndices[2].x += 1;
44 nearbyBucketIndices[3].x += 1;
45 }
46 else
47 {
48 nearbyBucketIndices[2].x -= 1;
49 nearbyBucketIndices[3].x -= 1;
50 }
51
52 if ((originIndex.y + 0.5f) * m_gridSpacing <= position.y)
53 {
54 nearbyBucketIndices[1].y += 1;
55 nearbyBucketIndices[3].y += 1;
56 }
57 else
58 {
59 nearbyBucketIndices[1].y -= 1;
60 nearbyBucketIndices[3].y -= 1;
61 }
62
63 for (int i = 0; i < 4; i++)
64 {
65 nearbyKeys[i] = GetHashKeyFromBucketIndex(nearbyBucketIndices[i]);
66 }
67}
68
69inline CUBBYFLOW_CUDA_HOST_DEVICE int2
70CUDAPointHashGridSearcher2::HashUtils::GetBucketIndex(float2 position) const
71{
72 int2 bucketIndex;
73
74 bucketIndex.x = static_cast<int>(floorf(position.x / m_gridSpacing));
75 bucketIndex.y = static_cast<int>(floorf(position.y / m_gridSpacing));
76
77 return bucketIndex;
78}
79
80inline CUBBYFLOW_CUDA_HOST_DEVICE uint32_t
81CUDAPointHashGridSearcher2::HashUtils::GetHashKeyFromBucketIndex(
82 int2 bucketIndex) const
83{
84 // Assumes m_resolution is power of two
85 bucketIndex.x = bucketIndex.x & (m_resolution.x - 1);
86 bucketIndex.y = bucketIndex.y & (m_resolution.y - 1);
87 return bucketIndex.y * m_resolution.x + bucketIndex.x;
88}
89
90inline CUBBYFLOW_CUDA_HOST_DEVICE uint32_t
91CUDAPointHashGridSearcher2::HashUtils::GetHashKeyFromPosition(
92 float2 position) const
93{
94 int2 bucketIndex = GetBucketIndex(position);
95 return GetHashKeyFromBucketIndex(bucketIndex);
96}
97
98template <typename Callback>
99inline CUBBYFLOW_CUDA_HOST_DEVICE CUDAPointHashGridSearcher2::
100 ForEachNearbyPointFunc<Callback>::ForEachNearbyPointFunc(
101 float r, float gridSpacing, uint2 resolution, const uint32_t* sit,
102 const uint32_t* eit, const uint32_t* si, const float2* p,
103 const float2* o, Callback cb)
104 : m_hashUtils(gridSpacing, resolution),
105 m_radius(r),
106 m_startIndexTable(sit),
107 m_endIndexTable(eit),
108 m_sortedIndices(si),
109 m_points(p),
110 m_origins(o),
111 m_callback(cb)
112{
113 // Do nothing
114}
115
116template <typename Callback>
117template <typename Index>
118inline CUBBYFLOW_CUDA_HOST_DEVICE void
119CUDAPointHashGridSearcher2::ForEachNearbyPointFunc<Callback>::operator()(
120 Index idx)
121{
122 const float2 origin = m_origins[idx];
123
124 uint32_t nearbyKeys[4];
125 m_hashUtils.GetNearbyKeys(origin, nearbyKeys);
126
127 const float queryRadiusSquared = m_radius * m_radius;
128
129 for (int i = 0; i < 4; i++)
130 {
131 uint32_t nearbyKey = nearbyKeys[i];
132 uint32_t start = m_startIndexTable[nearbyKey];
133
134 // Empty bucket -- continue to next bucket
135 if (start == 0xffffffff)
136 {
137 continue;
138 }
139
140 uint32_t end = m_endIndexTable[nearbyKey];
141
142 for (uint32_t jj = start; jj < end; ++jj)
143 {
144 uint32_t j = m_sortedIndices[jj];
145 float2 p = m_points[jj];
146 float2 direction = p - origin;
147
148 float distanceSquared = LengthSquared(direction);
149 if (distanceSquared <= queryRadiusSquared)
150 {
151 if (distanceSquared > 0)
152 {
153 float distance = sqrtf(distanceSquared);
154 direction /= distance;
155 }
156
157 m_callback(idx, origin, j, p);
158 }
159 }
160 }
161}
162
163template <typename Callback>
164void CUDAPointHashGridSearcher2::ForEachNearbyPoint(
165 const ConstCUDAArrayView1<float2>& origins, float radius,
166 Callback callback) const
167{
168 thrust::for_each(
169 thrust::counting_iterator<size_t>(0),
170 thrust::counting_iterator<size_t>(0) + origins.Length(),
171 ForEachNearbyPointFunc<Callback>(
172 radius, m_gridSpacing, m_resolution, m_startIndexTable.data(),
173 m_endIndexTable.data(), m_sortedIndices.data(), m_points.data(),
174 origins.data(), callback));
175}
176} // namespace CubbyFlow
177
178#endif
179
180#endif
Definition pybind11Utils.hpp:21
Matrix< T, Rows, 1 > Vector
Definition Matrix.hpp:738