32 Kokkos::View<const ShapeDesc*, CpMem> shapes,
bool px,
34 float globalScale = 1.0f) {
36 const long total = (long)rx * ry * rz;
37 const F3 origin = dmin;
38 const F3 vox{(dmax.
x - dmin.
x) / rx, (dmax.
y - dmin.
y) / ry, (dmax.
z - dmin.
z) / rz};
40 Kokkos::View<float*, CpMem> grid(
"sdf_grid", total);
41 Kokkos::View<int*, CpMem> state(
"sdf_state", total);
42 Kokkos::deep_copy(grid, 100.0f);
43 Kokkos::deep_copy(state, 0);
47 "peclet::dem::sdf::splat", Kokkos::RangePolicy<CpExec>(space, 0, numReal),
48 KOKKOS_LAMBDA(
int i) {
49 const F3 pw =
loadF3(pos, i);
50 const F4 q =
loadF4(quat, i);
55 const float sc = scale(i) * globalScale;
56 const ShapeDesc shp = shapes(shapeId(i));
59 const float r = shp.params.x, h = shp.params.y;
60 rbound = Kokkos::sqrt(r * r + (h * 0.5f) * (h * 0.5f));
61 }
else if (shp.type ==
SPHERE)
62 rbound = shp.params.x;
64 rbound = shp.params.x;
68 int minx = (int)Kokkos::floor((pw.x - rbound - origin.x) / vox.x),
69 maxx = (
int)Kokkos::ceil((pw.x + rbound - origin.x) / vox.x);
70 int miny = (int)Kokkos::floor((pw.y - rbound - origin.y) / vox.y),
71 maxy = (
int)Kokkos::ceil((pw.y + rbound - origin.y) / vox.y);
72 int minz = (int)Kokkos::floor((pw.z - rbound - origin.z) / vox.z),
73 maxz = (
int)Kokkos::ceil((pw.z + rbound - origin.z) / vox.z);
75 minx = minx < 0 ? 0 : minx;
76 maxx = maxx > rx - 1 ? rx - 1 : maxx;
79 miny = miny < 0 ? 0 : miny;
80 maxy = maxy > ry - 1 ? ry - 1 : maxy;
83 minz = minz < 0 ? 0 : minz;
84 maxz = maxz > rz - 1 ? rz - 1 : maxz;
87 for (
int z = minz; z <= maxz; ++z)
88 for (
int y = miny; y <= maxy; ++y)
89 for (
int x = minx; x <= maxx; ++x) {
90 const F3 vp{origin.x + (x + 0.5f) * vox.x, origin.y + (y + 0.5f) * vox.y,
91 origin.z + (z + 0.5f) * vox.z};
92 const F3 prel =
sub3(vp, pw);
97 else if (shp.type ==
SPHERE)
103 const float dist = distc * sc;
104 const int wx = (x % rx + rx) % rx, wy = (y % ry + ry) % ry, wz = (z % rz + rz) % rz;
105 if (!px && (x < 0 || x >= rx))
107 if (!py && (y < 0 || y >= ry))
109 if (!pz && (z < 0 || z >= rz))
111 const long vi = (long)wz * rx * ry + (
long)wy * rx + wx;
112 Kokkos::atomic_min(&grid(vi), dist);
120 Kokkos::View<float*, CpMem> grid2(
"sdf_grid2", total);
121 const int iters = Kokkos::max(Kokkos::max(rx, ry), rz) * 4;
122 const float h = vox.x;
123 Kokkos::View<float*, CpMem> in = grid, out = grid2;
124 for (
int it = 0; it < iters; ++it) {
125 Kokkos::View<float*, CpMem> din = in, dout = out;
126 Kokkos::View<int*, CpMem> st = state;
127 Kokkos::parallel_for(
128 "peclet::dem::sdf::eikonal", Kokkos::RangePolicy<CpExec>(space, 0, total),
129 KOKKOS_LAMBDA(
long idx) {
131 dout(idx) = din(idx);
134 const long sy = rx, sz = (long)rx * ry;
135 const int z = (int)(idx / sz);
136 const long rem = idx % sz;
137 const int y = (int)(rem / sy), x = (int)(rem % sy);
138 float xm = 100.0f, xp = 100.0f, ym = 100.0f, yp = 100.0f, zm = 100.0f, zp = 100.0f;
142 xm = din(idx - 1 + rx);
146 xp = din(idx + 1 - rx);
150 ym = din((
long)z * sz + (
long)(ry - 1) * sy + x);
154 yp = din((
long)z * sz + x);
158 zm = din((
long)(rz - 1) * sz + (
long)y * sy + x);
162 zp = din((
long)y * sy + x);
163 float a = Kokkos::fmin(xm, xp), b = Kokkos::fmin(ym, yp), c = Kokkos::fmin(zm, zp);
179 float u = 100.0f, u1 = a + h;
183 const float d2 = 2.0f * h * h - (a - b) * (a - b);
184 float u2 = (d2 < 0.0f) ? 100.0f : (a + b + Kokkos::sqrt(d2)) * 0.5f;
188 const float s = a + b + c, qd = s * s - 3.0f * (a * a + b * b + c * c - h * h);
189 u = (qd < 0.0f) ? 100.0f : (s + Kokkos::sqrt(qd)) / 3.0f;
200 std::vector<float> h_grid(total);
201 auto hv = Kokkos::create_mirror_view(in);
202 Kokkos::deep_copy(hv, in);
203 for (
long i = 0; i < total; ++i)
std::vector< float > generateSdfKokkos(int rx, int ry, int rz, F3 dmin, F3 dmax, int numReal, PosView pos, QuatView quat, ScalarF scale, ScalarI shapeId, Kokkos::View< const ShapeDesc *, CpMem > shapes, bool px, bool py, bool pz, GridView sdfGrid=GridView{}, float globalScale=1.0f)
globalScale multiplies every per-particle scale, exactly as the narrow-phase does (narrowphase....