147 lines
4.5 KiB
Plaintext
147 lines
4.5 KiB
Plaintext
struct Agent
|
|
{
|
|
float x;
|
|
float y;
|
|
float direction;
|
|
};
|
|
|
|
static struct Agent *agents;
|
|
static float *ground;
|
|
static float *working_ground;
|
|
static int2 ground_dimensions;
|
|
|
|
constant float sense_distance = 3.0f;
|
|
constant float move_distance = 3.0f;
|
|
constant float diffusion_rate = 0.05f;
|
|
constant float cone_of_vision = 2.0f*M_PI_F/4.0f;
|
|
constant float vision_sensing_steps = 8.0f;
|
|
constant float color_r = 0.0f;
|
|
constant float color_g = 255.0f;
|
|
constant float color_b = 255.0f;
|
|
|
|
uint hash(uint input)
|
|
{
|
|
input ^= 2747636419u;
|
|
input *= 2654435769u;
|
|
input ^= input >> 16;
|
|
input *= 2654435769u;
|
|
input ^= input >> 16;
|
|
input *= 2654435769u;
|
|
return input;
|
|
}
|
|
|
|
void kernel initialize_globals(global struct Agent *new_agents, global float *new_ground, global float *new_working_ground, global int* new_ground_dimensions)
|
|
{
|
|
agents = new_agents;
|
|
ground = new_ground;
|
|
working_ground = new_working_ground;
|
|
ground_dimensions[0] = new_ground_dimensions[0];
|
|
ground_dimensions[1] = new_ground_dimensions[1];
|
|
}
|
|
|
|
void kernel update_ground()
|
|
{
|
|
int current_index = get_global_id(0);
|
|
int cx = current_index % ground_dimensions[0];
|
|
int cy = current_index / ground_dimensions[0];
|
|
|
|
float sum = 0.0f;
|
|
|
|
for (int i = cx-1; i <= cx+1; i++)
|
|
{
|
|
if (i < 0 || i >= ground_dimensions[0])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for(int j = cy-1; j <= cy+1; j++)
|
|
{
|
|
if (j < 0 || j >= ground_dimensions[1])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
sum += ground[i+j*ground_dimensions[0]];
|
|
}
|
|
}
|
|
|
|
working_ground[current_index] = sum/9.0f-diffusion_rate;
|
|
|
|
if (working_ground[current_index] < 0)
|
|
{
|
|
working_ground[current_index] = 0.0f;
|
|
}
|
|
}
|
|
|
|
void kernel iterate_ground()
|
|
{
|
|
ground[get_global_id(0)] = working_ground[get_global_id(0)];
|
|
}
|
|
|
|
void kernel move_agents()
|
|
{
|
|
int current_index = get_global_id(0);
|
|
|
|
uint psuedorandom_int = hash(agents[current_index].x+agents[current_index].y*ground_dimensions[0]);
|
|
|
|
if (psuedorandom_int % 100 < 12)
|
|
{
|
|
psuedorandom_int = hash(psuedorandom_int);
|
|
agents[current_index].direction += (float)(psuedorandom_int%1000)*cone_of_vision/1000.0f-cone_of_vision/2.0f;
|
|
}
|
|
else
|
|
{
|
|
float directional_change = cone_of_vision/2.0f;
|
|
float mx = agents[current_index].x + sense_distance*cos(agents[current_index].direction+directional_change);
|
|
float my = agents[current_index].y + sense_distance*sin(agents[current_index].direction+directional_change);
|
|
float max_sense = ground[(int)mx+(int)my*ground_dimensions[0]];
|
|
|
|
for(int i = 1; i <= 8; i++)
|
|
{
|
|
mx = agents[current_index].x + sense_distance*cos(agents[current_index].direction+cone_of_vision/2.0f-(float)i*cone_of_vision/vision_sensing_steps);
|
|
my = agents[current_index].y + sense_distance*sin(agents[current_index].direction+cone_of_vision/2.0f-(float)i*cone_of_vision/vision_sensing_steps);
|
|
|
|
if (ground[(int)mx+(int)my*ground_dimensions[0]] > max_sense)
|
|
{
|
|
directional_change = cone_of_vision/2.0f-(float)i*cone_of_vision/vision_sensing_steps;
|
|
max_sense = ground[(int)mx+(int)my*ground_dimensions[0]];
|
|
}
|
|
}
|
|
|
|
agents[current_index].direction += directional_change;
|
|
}
|
|
|
|
float nx = agents[current_index].x + move_distance*cos(agents[current_index].direction);
|
|
float ny = agents[current_index].y + move_distance*sin(agents[current_index].direction);
|
|
|
|
if(nx < 0.0f || nx >= ground_dimensions[0] || ny < 0.0f || ny >= ground_dimensions[1])
|
|
{
|
|
nx = (nx<0.0f)?0.0f:((nx>=ground_dimensions[0])?(ground_dimensions[0]-1.0f):nx);
|
|
ny = (ny<0.0f)?0.0f:((ny>=ground_dimensions[1])?(ground_dimensions[1]-1.0f):ny);
|
|
psuedorandom_int = hash(psuedorandom_int);
|
|
agents[current_index].direction = (float)(psuedorandom_int%1000)*2.0f*M_PI_F/1000.0f;
|
|
}
|
|
|
|
agents[current_index].x = nx;
|
|
agents[current_index].y = ny;
|
|
}
|
|
|
|
void kernel emit_agent_pheromones()
|
|
{
|
|
int current_index = get_global_id(0);
|
|
int x = agents[current_index].x;
|
|
int y = agents[current_index].y;
|
|
int ground_index = x+y*ground_dimensions[0];
|
|
|
|
ground[ground_index] = 1.0f;
|
|
}
|
|
|
|
void kernel fill_draw_data(global uchar* draw_data)
|
|
{
|
|
int index = get_global_id(0);
|
|
|
|
draw_data[4*index] = (uchar)(color_b*ground[index]);
|
|
draw_data[4*index+1] = (uchar)(color_g*ground[index]);
|
|
draw_data[4*index+2] = (uchar)(color_r*ground[index]);
|
|
draw_data[4*index+3] = 255;
|
|
} |