| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- #version 430 core
- struct particle_t {
- float pos_x;
- float pos_y;
- float dir_x;
- float dir_y;
- };
- struct cell_t {
- float pheromone;
- float result;
- int population;
- };
- uniform uint map_width;
- uniform uint map_height;
- uniform uint population;
- uniform float speed;
- uniform float steering;
- uniform float sensing_distance;
- uniform float sensing_angle;
- uniform float dt;
- layout(std430, binding = 1) coherent buffer particles_buffer
- {
- particle_t particles[];
- };
- layout(std430, binding = 2) coherent buffer map_buffer
- {
- cell_t map[];
- };
- vec2 rotate(vec2 v, float angle){
- float c = cos(angle);
- float s = sin(angle);
- return vec2(v.x * c - v.y * s, v.x * s + v.y * c);
- }
- vec2 ahead(vec2 at, vec2 dir, float d){
- return at + d * dir;
- }
- vec2 wrap_coord(vec2 v){
- return mod(v, vec2(map_width, map_height));
- }
- uint cell_id(vec2 v){
- ivec2 map_pos = ivec2(floor(v));
- return uint(map_pos.y * map_width + map_pos.x);
- }
- layout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;
- void main(){
- uint particle_id = uint(gl_GlobalInvocationID.x);
- if(particle_id >= population){
- return;
- }
- // Update particle position
- particle_t p = particles[particle_id];
- vec2 pos = vec2(p.pos_x, p.pos_y);
- vec2 dir = vec2(p.dir_x, p.dir_y);
- pos = wrap_coord(pos + dt * speed * dir);
- particles[particle_id].pos_x = pos.x;
- particles[particle_id].pos_y = pos.y;
-
- // Count particle
- uint p_cell_id = cell_id(pos);
- atomicAdd(map[p_cell_id].population, 1);
- // Sense and turn
- vec2 look_ahead = wrap_coord(ahead(pos, dir, sensing_distance));
- vec2 look_left = wrap_coord(ahead(pos, rotate(dir, sensing_angle), sensing_distance));
- vec2 look_right = wrap_coord(ahead(pos, rotate(dir, -sensing_angle), sensing_distance));
- float pheromone_ahead = map[cell_id(look_ahead)].pheromone;
- float pheromone_left = map[cell_id(look_left )].pheromone;
- float pheromone_right = map[cell_id(look_right)].pheromone;
- if(pheromone_left > pheromone_ahead && pheromone_left > pheromone_right){
- dir = rotate(dir, steering * dt);
- }else if(pheromone_right > pheromone_ahead && pheromone_right > pheromone_left){
- dir = rotate(dir, -steering * dt);
- }
- particles[particle_id].dir_x = dir.x;
- particles[particle_id].dir_y = dir.y;
- }
|