|
|
@ -56,76 +56,14 @@ void* network_thread(void* data) {
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// cos(I*PI/3)/2, sin(I*PI/3)/2
|
|
|
|
bool ray_hex_intersect(float* distance, vec3 start, vec3 dir, vec3 region_offset, uint32_t hex_index, HexRegion* region) {
|
|
|
|
vec3 hex_vertices[] = {
|
|
|
|
|
|
|
|
{ 1.0/2, 0, 0},
|
|
|
|
|
|
|
|
{ 1.0/4, 0, SQRT3/4},
|
|
|
|
|
|
|
|
{-1.0/4, 0, SQRT3/4},
|
|
|
|
|
|
|
|
{-1.0/2, 0, 0},
|
|
|
|
|
|
|
|
{-1.0/4, 0, -SQRT3/4},
|
|
|
|
|
|
|
|
{ 1.0/4, 0, -SQRT3/4},
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vec3 hex_starts[] = {
|
|
|
|
|
|
|
|
{ 0, 0, HEX_Z},
|
|
|
|
|
|
|
|
{-HEX_X, 0, HEX_Z/2},
|
|
|
|
|
|
|
|
{-HEX_X, 0, -HEX_Z/2},
|
|
|
|
|
|
|
|
{ 0, 0, -HEX_Z},
|
|
|
|
|
|
|
|
{ HEX_X, 0, -HEX_Z/2},
|
|
|
|
|
|
|
|
{ HEX_X, 0, HEX_Z/2},
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vec3 hex_directions[] = {
|
|
|
|
|
|
|
|
{-HEX_X, 0, -HEX_Z/2},
|
|
|
|
|
|
|
|
{ 0, 0, -HEX_Z},
|
|
|
|
|
|
|
|
{ HEX_X, 0, -HEX_Z/2},
|
|
|
|
|
|
|
|
{ HEX_X, 0, HEX_Z/2},
|
|
|
|
|
|
|
|
{ 0, 0, HEX_Z},
|
|
|
|
|
|
|
|
{-HEX_X, 0, HEX_Z/2},
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int hex_indices[] = {
|
|
|
|
|
|
|
|
0, 2, 1,
|
|
|
|
|
|
|
|
0, 3, 2,
|
|
|
|
|
|
|
|
0, 4, 3,
|
|
|
|
|
|
|
|
0, 5, 4,
|
|
|
|
|
|
|
|
0, 6, 5,
|
|
|
|
|
|
|
|
0, 1, 6,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool ray_hex_intersect(float* distance, vec4 ray_start, vec4 ray_end, uint32_t region_index, uint32_t hex_index, HexContext* context) {
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
Ray-hexagon intersection
|
|
|
|
Ray-hexagon intersection
|
|
|
|
1. For each triangle in the hexagon, check for intersection
|
|
|
|
1. For each triangle in the hexagon, check for intersection
|
|
|
|
2. If intersections, return the closest along the ray
|
|
|
|
2. If intersections, return the closest along the ray
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
GPUHexRegion* region = &context->regions[region_index]->data;
|
|
|
|
|
|
|
|
GPUHex* hex = ®ion->hexes[hex_index];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vec3 start;
|
|
|
|
GPUHex* hex = ®ion->data.hexes[hex_index];
|
|
|
|
start[0] = ray_start[0]/ray_start[3];
|
|
|
|
|
|
|
|
start[1] = ray_start[1]/ray_start[3];
|
|
|
|
|
|
|
|
start[2] = ray_start[2]/ray_start[3];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vec3 end;
|
|
|
|
|
|
|
|
end[0] = ray_end[0]/ray_end[3];
|
|
|
|
|
|
|
|
end[1] = ray_end[1]/ray_end[3];
|
|
|
|
|
|
|
|
end[2] = ray_end[2]/ray_end[3];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vec3 dir;
|
|
|
|
|
|
|
|
dir[0] = end[0] - start[0];
|
|
|
|
|
|
|
|
dir[1] = end[1] - start[1];
|
|
|
|
|
|
|
|
dir[2] = end[2] - start[2];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float dir_len = glm_vec3_norm(dir);
|
|
|
|
|
|
|
|
glm_vec3_divs(dir, dir_len, dir);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vec3 region_offset = {
|
|
|
|
|
|
|
|
((float)region->q + (float)region->r/2)*REGION_WIDTH - region->r*HEX_X/2,
|
|
|
|
|
|
|
|
0,
|
|
|
|
|
|
|
|
0.75*region->r*REGION_HEIGHT + 0.25*region->r*HEX_Z + 0.5*region->q*HEX_Z,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float center_height = (hex->height[0]
|
|
|
|
float center_height = (hex->height[0]
|
|
|
|
+ hex->height[1]
|
|
|
|
+ hex->height[1]
|
|
|
@ -207,6 +145,74 @@ bool ray_hex_intersect(float* distance, vec4 ray_start, vec4 ray_end, uint32_t r
|
|
|
|
return intersect;
|
|
|
|
return intersect;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool ray_region_intersect(float* distance, uint32_t* hid, vec3 start, vec3 dir, HexRegion* region) {
|
|
|
|
|
|
|
|
bool intersect = false;
|
|
|
|
|
|
|
|
float temp_distance;
|
|
|
|
|
|
|
|
*distance = INFINITY;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vec3 region_offset = {
|
|
|
|
|
|
|
|
((float)region->data.q + (float)region->data.r/2)*REGION_WIDTH - region->data.r*HEX_X/2,
|
|
|
|
|
|
|
|
0,
|
|
|
|
|
|
|
|
0.75*region->data.r*REGION_HEIGHT + 0.25*region->data.r*HEX_Z + 0.5*region->data.q*HEX_Z,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(uint32_t temp_hid = 0; temp_hid < REGION_HEX_COUNT; temp_hid++) {
|
|
|
|
|
|
|
|
if(ray_hex_intersect(&temp_distance, start, dir, region_offset, temp_hid, region)) {
|
|
|
|
|
|
|
|
if(temp_distance < *distance) {
|
|
|
|
|
|
|
|
intersect = true;
|
|
|
|
|
|
|
|
*hid = temp_hid;
|
|
|
|
|
|
|
|
*distance = temp_distance;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return intersect;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool ray_world_intersect(float* distance, uint32_t* rid, uint32_t* hid, vec4 ray_start, vec4 ray_end, HexContext* context) {
|
|
|
|
|
|
|
|
vec3 start;
|
|
|
|
|
|
|
|
start[0] = ray_start[0]/ray_start[3];
|
|
|
|
|
|
|
|
start[1] = ray_start[1]/ray_start[3];
|
|
|
|
|
|
|
|
start[2] = ray_start[2]/ray_start[3];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vec3 end;
|
|
|
|
|
|
|
|
end[0] = ray_end[0]/ray_end[3];
|
|
|
|
|
|
|
|
end[1] = ray_end[1]/ray_end[3];
|
|
|
|
|
|
|
|
end[2] = ray_end[2]/ray_end[3];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vec3 dir;
|
|
|
|
|
|
|
|
dir[0] = end[0] - start[0];
|
|
|
|
|
|
|
|
dir[1] = end[1] - start[1];
|
|
|
|
|
|
|
|
dir[2] = end[2] - start[2];
|
|
|
|
|
|
|
|
float mdir = glm_vec3_norm(dir);
|
|
|
|
|
|
|
|
glm_vec3_divs(dir, mdir, dir);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool intersect = false;
|
|
|
|
|
|
|
|
float temp_distance;
|
|
|
|
|
|
|
|
uint32_t temp_hid;
|
|
|
|
|
|
|
|
*distance = INFINITY;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(uint32_t temp_rid = 0; temp_rid < MAX_LOADED_REGIONS; temp_rid++) {
|
|
|
|
|
|
|
|
HexRegion* region = context->regions[temp_rid];
|
|
|
|
|
|
|
|
if(region == NULL) {
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
} else if(region->data.map != context->data.current_map) {
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(ray_region_intersect(&temp_distance, &temp_hid, start, dir, region)) {
|
|
|
|
|
|
|
|
if(temp_distance < *distance) {
|
|
|
|
|
|
|
|
intersect = true;
|
|
|
|
|
|
|
|
*hid = temp_hid;
|
|
|
|
|
|
|
|
*rid = temp_rid;
|
|
|
|
|
|
|
|
*distance = temp_distance;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return intersect;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vec3 up = {0, 1, 0};
|
|
|
|
vec3 up = {0, 1, 0};
|
|
|
|
|
|
|
|
|
|
|
|
VkResult main_thread(ClientContext* context) {
|
|
|
|
VkResult main_thread(ClientContext* context) {
|
|
|
@ -251,7 +257,7 @@ VkResult main_thread(ClientContext* context) {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
context->hex->data.current_map = 0x01;
|
|
|
|
context->hex->data.current_map = 0x01;
|
|
|
|
add_transfer(&context->hex->data.current_map, context->hex->context, offsetof(GPUHexContext, current_map), sizeof(uint32_t), context->render->current_frame, context->render);
|
|
|
|
add_transfers(&context->hex->data.current_map, context->hex->context, offsetof(GPUHexContext, current_map), sizeof(uint32_t), context->render);
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t region = 0;
|
|
|
|
uint32_t region = 0;
|
|
|
|
for(int32_t q = -5; q < 5; q++) {
|
|
|
|
for(int32_t q = -5; q < 5; q++) {
|
|
|
@ -264,7 +270,7 @@ VkResult main_thread(ClientContext* context) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
regions[region]->data.hexes[i].color[6] = colors[(q+r+50) % (sizeof(colors)/sizeof(uint32_t))];
|
|
|
|
regions[region]->data.hexes[i].color[6] = colors[(q+r+50) % (sizeof(colors)/sizeof(uint32_t))];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VK_RESULT(add_transfer(®ions[region]->data.hexes, regions[region]->region, offsetof(GPUHexRegion, hexes), sizeof(GPUHex)*REGION_HEX_COUNT, 0, context->render));
|
|
|
|
VK_RESULT(add_transfer(®ions[region]->data.hexes, regions[region]->region, offsetof(GPUHexRegion, hexes), sizeof(GPUHex)*REGION_HEX_COUNT, context->render->current_frame, context->render));
|
|
|
|
region++;
|
|
|
|
region++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -302,12 +308,11 @@ VkResult main_thread(ClientContext* context) {
|
|
|
|
PERSPECTIVE_NEARZ,
|
|
|
|
PERSPECTIVE_NEARZ,
|
|
|
|
PERSPECTIVE_FARZ,
|
|
|
|
PERSPECTIVE_FARZ,
|
|
|
|
context->hex->data.proj);
|
|
|
|
context->hex->data.proj);
|
|
|
|
VK_RESULT(add_transfer(
|
|
|
|
VK_RESULT(add_transfers(
|
|
|
|
&context->hex->data.proj,
|
|
|
|
&context->hex->data.proj,
|
|
|
|
context->hex->context,
|
|
|
|
context->hex->context,
|
|
|
|
offsetof(GPUHexContext, proj),
|
|
|
|
offsetof(GPUHexContext, proj),
|
|
|
|
sizeof(mat4),
|
|
|
|
sizeof(mat4),
|
|
|
|
context->render->current_frame,
|
|
|
|
|
|
|
|
context->render));
|
|
|
|
context->render));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -343,7 +348,7 @@ VkResult main_thread(ClientContext* context) {
|
|
|
|
glm_mat4_mul(context->hex->data.proj, context->hex->data.view, regular);
|
|
|
|
glm_mat4_mul(context->hex->data.proj, context->hex->data.view, regular);
|
|
|
|
glm_mat4_inv(regular, context->inverse);
|
|
|
|
glm_mat4_inv(regular, context->inverse);
|
|
|
|
|
|
|
|
|
|
|
|
add_transfer(&context->hex->data, context->hex->context, 0, 2*sizeof(mat4), context->render->current_frame, context->render);
|
|
|
|
add_transfers(&context->hex->data, context->hex->context, 0, 2*sizeof(mat4), context->render);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(context->clicked_hex[0] != 0 || context->clicked_hex[1] != 0) {
|
|
|
|
if(context->clicked_hex[0] != 0 || context->clicked_hex[1] != 0) {
|
|
|
@ -471,25 +476,33 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case GLFW_MOUSE_BUTTON_LEFT:
|
|
|
|
case GLFW_MOUSE_BUTTON_LEFT:
|
|
|
|
if(action == GLFW_PRESS) {
|
|
|
|
if(action == GLFW_PRESS) {
|
|
|
|
cursor_to_world_ray(context, cursor, context->hex->data.click_start, context->hex->data.click_end);
|
|
|
|
cursor_to_world_ray(
|
|
|
|
add_transfer(&context->hex->data.click_start, context->hex->context, offsetof(GPUHexContext, click_start), sizeof(vec4)*2, context->render->current_frame, context->render);
|
|
|
|
context,
|
|
|
|
|
|
|
|
cursor,
|
|
|
|
|
|
|
|
context->hex->data.click_start, context->hex->data.click_end);
|
|
|
|
|
|
|
|
add_transfers(
|
|
|
|
|
|
|
|
&context->hex->data.click_start,
|
|
|
|
|
|
|
|
context->hex->context,
|
|
|
|
|
|
|
|
offsetof(GPUHexContext, click_start),
|
|
|
|
|
|
|
|
sizeof(vec4)*2,
|
|
|
|
|
|
|
|
context->render);
|
|
|
|
|
|
|
|
|
|
|
|
// Hex intersections
|
|
|
|
// Hex intersections
|
|
|
|
float distance;
|
|
|
|
float distance;
|
|
|
|
for(uint32_t r = 0; r < MAX_LOADED_REGIONS; r++) {
|
|
|
|
if(ray_world_intersect(
|
|
|
|
if(context->hex->regions[r] == NULL) {
|
|
|
|
&distance,
|
|
|
|
continue;
|
|
|
|
&context->hex->data.clicked_region,
|
|
|
|
} else if(context->hex->regions[r]->data.map != context->hex->data.current_map) {
|
|
|
|
&context->hex->data.clicked_hex,
|
|
|
|
continue;
|
|
|
|
context->hex->data.click_start,
|
|
|
|
}
|
|
|
|
context->hex->data.click_end,
|
|
|
|
for(uint32_t h = 0; h < REGION_HEX_COUNT; h++) {
|
|
|
|
context->hex)) {
|
|
|
|
if(ray_hex_intersect(&distance, context->hex->data.click_start, context->hex->data.click_end, r, h, context->hex)) {
|
|
|
|
add_transfers(
|
|
|
|
context->hex->data.clicked_region = r;
|
|
|
|
&context->hex->data.clicked_region,
|
|
|
|
context->hex->data.clicked_hex = h;
|
|
|
|
context->hex->context,
|
|
|
|
add_transfer(&context->hex->data.clicked_region, context->hex->context, offsetof(GPUHexContext, clicked_region), sizeof(uint32_t)*2, context->render->current_frame, context->render);
|
|
|
|
offsetof(GPUHexContext, clicked_region),
|
|
|
|
}
|
|
|
|
sizeof(uint32_t)*2,
|
|
|
|
}
|
|
|
|
context->render);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// UI intersections
|
|
|
|
// UI intersections
|
|
|
|
for(uint32_t c = 0; c < context->ui->max_containers; c++) {
|
|
|
|
for(uint32_t c = 0; c < context->ui->max_containers; c++) {
|
|
|
@ -533,23 +546,28 @@ void cursor_pos_callback(GLFWwindow* window, double xpos, double ypos) {
|
|
|
|
context->cursor[0] = xpos;
|
|
|
|
context->cursor[0] = xpos;
|
|
|
|
context->cursor[1] = ypos;
|
|
|
|
context->cursor[1] = ypos;
|
|
|
|
cursor_to_world_ray(context, context->cursor, context->hex->data.hover_start, context->hex->data.hover_end);
|
|
|
|
cursor_to_world_ray(context, context->cursor, context->hex->data.hover_start, context->hex->data.hover_end);
|
|
|
|
add_transfer(&context->hex->data.hover_start, context->hex->context, offsetof(GPUHexContext, hover_start), sizeof(vec4)*2, context->render->current_frame, context->render);
|
|
|
|
add_transfers(
|
|
|
|
|
|
|
|
&context->hex->data.hover_start,
|
|
|
|
|
|
|
|
context->hex->context,
|
|
|
|
|
|
|
|
offsetof(GPUHexContext, hover_start),
|
|
|
|
|
|
|
|
sizeof(vec4)*2,
|
|
|
|
|
|
|
|
context->render);
|
|
|
|
|
|
|
|
|
|
|
|
// Hex intersections
|
|
|
|
// Hex intersections
|
|
|
|
float distance;
|
|
|
|
float distance;
|
|
|
|
for(uint32_t r = 0; r < MAX_LOADED_REGIONS; r++) {
|
|
|
|
if(ray_world_intersect(
|
|
|
|
if(context->hex->regions[r] == NULL) {
|
|
|
|
&distance,
|
|
|
|
continue;
|
|
|
|
&context->hex->data.hovered_region,
|
|
|
|
} else if(context->hex->regions[r]->data.map != context->hex->data.current_map) {
|
|
|
|
&context->hex->data.hovered_hex,
|
|
|
|
continue;
|
|
|
|
context->hex->data.hover_start,
|
|
|
|
}
|
|
|
|
context->hex->data.hover_end,
|
|
|
|
for(uint32_t h = 0; h < REGION_HEX_COUNT; h++) {
|
|
|
|
context->hex)) {
|
|
|
|
if(ray_hex_intersect(&distance, context->hex->data.hover_start, context->hex->data.hover_end, r, h, context->hex)) {
|
|
|
|
add_transfers(
|
|
|
|
context->hex->data.hovered_region = r;
|
|
|
|
&context->hex->data.hovered_region,
|
|
|
|
context->hex->data.hovered_hex = h;
|
|
|
|
context->hex->context,
|
|
|
|
add_transfer(&context->hex->data.hovered_region, context->hex->context, offsetof(GPUHexContext, hovered_region), sizeof(uint32_t)*2, context->render->current_frame, context->render);
|
|
|
|
offsetof(GPUHexContext, hovered_region),
|
|
|
|
}
|
|
|
|
sizeof(uint32_t)*2,
|
|
|
|
}
|
|
|
|
context->render);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|