|
|
|
@ -17,9 +17,6 @@
|
|
|
|
|
#include <math.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
#define max(a, b) ((a > b) ? a : b)
|
|
|
|
|
#define min(a, b) ((a < b) ? a : b)
|
|
|
|
|
|
|
|
|
|
typedef struct ClientContextStruct {
|
|
|
|
|
GLFWwindow* window;
|
|
|
|
|
RenderContext* render;
|
|
|
|
@ -56,165 +53,6 @@ void* network_thread(void* data) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ray_hex_intersect(float* distance, vec3 start, vec3 dir, vec3 region_offset, uint32_t hex_index, HexRegion* region) {
|
|
|
|
|
/*
|
|
|
|
|
Ray-hexagon intersection
|
|
|
|
|
1. For each triangle in the hexagon, check for intersection
|
|
|
|
|
2. If intersections, return the closest along the ray
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
GPUHex* hex = ®ion->data.hexes[hex_index];
|
|
|
|
|
|
|
|
|
|
float center_height = (hex->height[0]
|
|
|
|
|
+ hex->height[1]
|
|
|
|
|
+ hex->height[2]
|
|
|
|
|
+ hex->height[3]
|
|
|
|
|
+ hex->height[4]
|
|
|
|
|
+ hex->height[5])/6;
|
|
|
|
|
|
|
|
|
|
vec3 vertices[7] = {
|
|
|
|
|
{0, 0, 0},
|
|
|
|
|
};
|
|
|
|
|
glm_vec3_add(vertices[0], region_offset, vertices[0]);
|
|
|
|
|
glm_vec3_add(hex_vertices[0], region_offset, vertices[1]);
|
|
|
|
|
glm_vec3_add(hex_vertices[1], region_offset, vertices[2]);
|
|
|
|
|
glm_vec3_add(hex_vertices[2], region_offset, vertices[3]);
|
|
|
|
|
glm_vec3_add(hex_vertices[3], region_offset, vertices[4]);
|
|
|
|
|
glm_vec3_add(hex_vertices[4], region_offset, vertices[5]);
|
|
|
|
|
glm_vec3_add(hex_vertices[5], region_offset, vertices[6]);
|
|
|
|
|
|
|
|
|
|
vertices[0][1] += center_height;
|
|
|
|
|
vertices[1][1] += hex->height[0];
|
|
|
|
|
vertices[2][1] += hex->height[1];
|
|
|
|
|
vertices[3][1] += hex->height[2];
|
|
|
|
|
vertices[4][1] += hex->height[3];
|
|
|
|
|
vertices[5][1] += hex->height[4];
|
|
|
|
|
vertices[6][1] += hex->height[5];
|
|
|
|
|
|
|
|
|
|
vec3 hex_offset = {0, 0, 0};
|
|
|
|
|
float radius = 0;
|
|
|
|
|
float ring = 0;
|
|
|
|
|
int side = 0;
|
|
|
|
|
if(hex_index != 0) {
|
|
|
|
|
radius = floor(0.5 + sqrt(12*hex_index-3)/6);
|
|
|
|
|
ring = hex_index - (3*radius*radius - 3*radius + 1);
|
|
|
|
|
side = floor(ring/radius);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glm_vec3_muladds(hex_starts[side], radius, hex_offset);
|
|
|
|
|
glm_vec3_muladds(hex_directions[side], ring-(radius*side), hex_offset);
|
|
|
|
|
for(uint32_t vertex = 0; vertex < 7; vertex++) {
|
|
|
|
|
glm_vec3_add(vertices[vertex], hex_offset, vertices[vertex]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*distance = INFINITY;
|
|
|
|
|
bool intersect = false;
|
|
|
|
|
|
|
|
|
|
for(uint32_t triangle = 0; triangle < 6; triangle++) {
|
|
|
|
|
vec3 vert[3];
|
|
|
|
|
for(int v_i = 0; v_i < 3; v_i++) {
|
|
|
|
|
vert[v_i][0] = vertices[hex_indices[triangle*3+v_i]][0];
|
|
|
|
|
vert[v_i][1] = vertices[hex_indices[triangle*3+v_i]][1];
|
|
|
|
|
vert[v_i][2] = vertices[hex_indices[triangle*3+v_i]][2];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vec3 v0v1;
|
|
|
|
|
glm_vec3_sub(vert[1], vert[0], v0v1);
|
|
|
|
|
vec3 v0v2;
|
|
|
|
|
glm_vec3_sub(vert[2], vert[0], v0v2);
|
|
|
|
|
vec3 pvec;
|
|
|
|
|
glm_vec3_cross(dir, v0v2, pvec);
|
|
|
|
|
float det = glm_vec3_dot(v0v1, pvec);
|
|
|
|
|
|
|
|
|
|
float det_inv = 1/det;
|
|
|
|
|
|
|
|
|
|
vec3 t;
|
|
|
|
|
glm_vec3_sub(start, vert[0], t);
|
|
|
|
|
float u = glm_vec3_dot(t, pvec) * det_inv;
|
|
|
|
|
if(u < 0 || u > 1) continue;
|
|
|
|
|
|
|
|
|
|
vec3 q;
|
|
|
|
|
glm_vec3_cross(t, v0v1, q);
|
|
|
|
|
float v = glm_vec3_dot(dir, q) * det_inv;
|
|
|
|
|
if(v < 0 || (u+v) > 1) continue;
|
|
|
|
|
|
|
|
|
|
intersect = true;
|
|
|
|
|
*distance = min(*distance, glm_vec3_dot(v0v2, q) * det_inv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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};
|
|
|
|
|
|
|
|
|
|
VkResult main_thread(ClientContext* context) {
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
@ -257,12 +95,17 @@ VkResult main_thread(ClientContext* context) {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
context->hex->data.current_map = 0x01;
|
|
|
|
|
add_transfers(&context->hex->data.current_map, context->hex->context, offsetof(GPUHexContext, current_map), sizeof(uint32_t), context->render);
|
|
|
|
|
VK_RESULT(add_transfers(
|
|
|
|
|
&context->hex->data.current_map,
|
|
|
|
|
context->hex->context,
|
|
|
|
|
offsetof(GPUHexContext, current_map),
|
|
|
|
|
sizeof(uint32_t),
|
|
|
|
|
context->render));
|
|
|
|
|
|
|
|
|
|
uint32_t region = 0;
|
|
|
|
|
for(int32_t q = -5; q < 5; q++) {
|
|
|
|
|
for(int32_t r = -5; r < 5; r++) {
|
|
|
|
|
VK_RESULT(set_hex_region(q, r, 0, 0x01, ®ions[region], context->hex, context->render));
|
|
|
|
|
VK_RESULT(allocate_hex_region(q, r, 0, 0x01, ®ions[region], context->hex, context->render));
|
|
|
|
|
for(uint32_t i = 0; i < REGION_HEX_COUNT; i++) {
|
|
|
|
|
for(uint32_t h = 0; h < 6; h++) {
|
|
|
|
|
regions[region]->data.hexes[i].color[h] = colors[(q+r+50) % (sizeof(colors)/sizeof(uint32_t))];
|
|
|
|
@ -270,7 +113,7 @@ VkResult main_thread(ClientContext* context) {
|
|
|
|
|
}
|
|
|
|
|
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, context->render->current_frame, context->render));
|
|
|
|
|
VK_RESULT(set_hex_region(regions[region], context->hex, context->render));
|
|
|
|
|
region++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -302,18 +145,7 @@ VkResult main_thread(ClientContext* context) {
|
|
|
|
|
context->render->framebuffer_recreated == true) && frame > 0) {
|
|
|
|
|
if(context->render->framebuffer_recreated == true) {
|
|
|
|
|
context->render->framebuffer_recreated = false;
|
|
|
|
|
glm_perspective(
|
|
|
|
|
PERSPECTIVE_FOVY,
|
|
|
|
|
(float)context->render->swapchain_extent.width/(float)context->render->swapchain_extent.height,
|
|
|
|
|
PERSPECTIVE_NEARZ,
|
|
|
|
|
PERSPECTIVE_FARZ,
|
|
|
|
|
context->hex->data.proj);
|
|
|
|
|
VK_RESULT(add_transfers(
|
|
|
|
|
&context->hex->data.proj,
|
|
|
|
|
context->hex->context,
|
|
|
|
|
offsetof(GPUHexContext, proj),
|
|
|
|
|
sizeof(mat4),
|
|
|
|
|
context->render));
|
|
|
|
|
VK_RESULT(update_hex_proj(context->render, context->hex));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
context->rotation[0] += (float)context->key_spin[0]*delta_time*context->key_spin_speed;
|
|
|
|
@ -337,18 +169,13 @@ VkResult main_thread(ClientContext* context) {
|
|
|
|
|
context->distance = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vec3 camera = {};
|
|
|
|
|
camera[0] = context->position[0] + context->distance*cos(context->rotation[1])*cos(context->rotation[0]);
|
|
|
|
|
camera[1] = context->position[1] + context->distance*sin(context->rotation[1]);
|
|
|
|
|
camera[2] = context->position[2] + context->distance*cos(context->rotation[1])*sin(context->rotation[0]);
|
|
|
|
|
|
|
|
|
|
glm_lookat(camera, context->position, up, context->hex->data.view);
|
|
|
|
|
|
|
|
|
|
mat4 regular;
|
|
|
|
|
glm_mat4_mul(context->hex->data.proj, context->hex->data.view, regular);
|
|
|
|
|
glm_mat4_inv(regular, context->inverse);
|
|
|
|
|
|
|
|
|
|
add_transfers(&context->hex->data, context->hex->context, 0, 2*sizeof(mat4), context->render);
|
|
|
|
|
VK_RESULT(update_hex_view(
|
|
|
|
|
context->position,
|
|
|
|
|
context->rotation,
|
|
|
|
|
context->distance,
|
|
|
|
|
context->inverse,
|
|
|
|
|
context->render,
|
|
|
|
|
context->hex));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(context->clicked_hex[0] != 0 || context->clicked_hex[1] != 0) {
|
|
|
|
@ -496,6 +323,8 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
|
|
|
|
context->hex->data.click_start,
|
|
|
|
|
context->hex->data.click_end,
|
|
|
|
|
context->hex)) {
|
|
|
|
|
context->clicked_hex[0] = context->hex->data.clicked_region;
|
|
|
|
|
context->clicked_hex[1] = context->hex->data.clicked_hex;
|
|
|
|
|
add_transfers(
|
|
|
|
|
&context->hex->data.clicked_region,
|
|
|
|
|
context->hex->context,
|
|
|
|
@ -515,7 +344,10 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
|
|
|
|
if(context->ui->containers[c].layers[l].drawables_buffer[d].id == 0x00000000) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if(contains(cursor, &context->ui->containers[c].data, &context->ui->containers[c].layers[l].drawables_buffer[d])) {
|
|
|
|
|
if(contains(
|
|
|
|
|
cursor,
|
|
|
|
|
&context->ui->containers[c].data,
|
|
|
|
|
&context->ui->containers[c].layers[l].drawables_buffer[d])) {
|
|
|
|
|
context->clicked_container = context->ui->containers[c].id;
|
|
|
|
|
context->clicked_element = context->ui->containers[c].layers[l].drawables_buffer[d].id;
|
|
|
|
|
}
|
|
|
|
|