29 const std::string& r = walk.
reach;
31 body +=
" vec3 gmin = vec3(grid_min_x, grid_min_y, grid_min_z);\n";
32 body +=
" uvec3 dims = uvec3(dim_x, dim_y, dim_z);\n";
33 body +=
" ivec3 base = ivec3(floor((p - gmin) / cell_size));\n";
34 body +=
" base = clamp(base, ivec3(0), ivec3(dims) - ivec3(1));\n";
36 body +=
" for (int dz = -" + r +
"; dz <= " + r +
"; dz = dz + 1) {\n";
37 body +=
" for (int dy = -" + r +
"; dy <= " + r +
"; dy = dy + 1) {\n";
38 body +=
" for (int dx = -" + r +
"; dx <= " + r +
"; dx = dx + 1) {\n";
39 body +=
" ivec3 nc = base + ivec3(dx, dy, dz);\n";
40 body +=
" if (nc.x < 0 || nc.y < 0 || nc.z < 0 || "
41 "nc.x >= int(dim_x) || nc.y >= int(dim_y) || nc.z >= int(dim_z)) {\n";
42 body +=
" continue;\n";
44 body +=
" uint cell = uint(nc.x) + uint(nc.y) * dim_x + uint(nc.z) * dim_x * dim_y;\n";
45 body +=
" uint start = cell_start[cell];\n";
46 body +=
" uint count = cell_count[cell];\n";
47 body +=
" for (uint k = 0u; k < count; k = k + 1u) {\n";
48 body +=
" uint j = particle_index[start + k];\n";
49 body +=
" if (" + walk.
skip_self +
") { continue; }\n";
51 body +=
" if (cross_cluster == 0u && cluster_id[j] != my_cluster) "
54 body +=
" uint bj = j * stride_words;\n";
55 body +=
" vec3 pj = vec3(vertices[bj + position_offset], "
56 "vertices[bj + position_offset + 1u], vertices[bj + position_offset + 2u]);\n";
57 body +=
" if (length(pj - p) < " + walk.
radius +
") {\n";
59 for (std::size_t start = 0; start < walk.
on_hit.size();) {
60 const std::size_t nl = walk.
on_hit.find(
'\n', start);
61 const std::size_t end = nl == std::string::npos ? walk.
on_hit.size() : nl;
63 body += walk.
on_hit.substr(start, end - start);
65 if (nl == std::string::npos) {
void append_neighbour_walk(std::string &body, const NeighbourWalk &walk)
Append the spatial-hash neighbour-gather loop nest to a kernel body.
std::string radius
Distance cutoff, a GLSL expression.
std::string reach
Cell-block half-extent, a GLSL expression or int local name.
bool cluster_scoped
Emit the cross_cluster / cluster_id guard.
std::string on_hit
Statements run per in-range candidate; j, bj, pj, p in scope. One per line, no braces,...
std::string skip_self
Candidate skipped when this GLSL predicate holds.
Knobs for append_neighbour_walk.