#version 450
layout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;
const uint HASH_SIZE = 65521;
const uint MAX_PER_CELL = 16;
struct InstanceData {
mat4 model;
vec4 color;
vec4 mat_props;
vec4 velocity;
vec4 angular_velocity;
vec4 physic_props;
};
layout(set = 0, binding = 0) readonly buffer ReadBuf { InstanceData data[]; } read_buf;
layout(set = 0, binding = 2) buffer GridCounts { uint data[]; } grid_counts;
layout(set = 0, binding = 3) buffer GridObjects { uint data[]; } grid_objects;
layout(push_constant) uniform PushConstants {
float dt;
uint total_objects;
uint offset;
uint count;
uint num_big_objects;
uint _pad[3];
vec4 global_gravity; // w = CELL_SIZE
} pc;
uint hashCell(ivec3 c) {
uvec3 u = uvec3(c);
return (u.x * 2654435761u ^ u.y * 2246822519u ^ u.z * 3266489917u) % HASH_SIZE;
}
void main() {
uint i = gl_GlobalInvocationID.x;
if (i >= pc.total_objects) return;
vec3 pos = read_buf.data[i].model[3].xyz;
float cell_size = pc.global_gravity.w;
ivec3 cell = ivec3(floor(pos / cell_size));
uint h = hashCell(cell);
uint idx = atomicAdd(grid_counts.data[h], 1);
if (idx < MAX_PER_CELL) {
grid_objects.data[h * MAX_PER_CELL + idx] = i;
}
}