|  |  | @ -18,6 +18,7 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <stdlib.h> |  |  |  | #include <stdlib.h> | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #define max(a, b) ((a > b) ? a : b) |  |  |  | #define max(a, b) ((a > b) ? a : b) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #define min(a, b) ((a < b) ? a : b) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | typedef struct ClientContextStruct { |  |  |  | typedef struct ClientContextStruct { | 
			
		
	
		
		
			
				
					
					|  |  |  |   GLFWwindow* window; |  |  |  |   GLFWwindow* window; | 
			
		
	
	
		
		
			
				
					|  |  | @ -55,7 +56,157 @@ void* network_thread(void* data) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   return NULL; |  |  |  |   return NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | vec3 zero = {0, 0, 0}; |  |  |  | // cos(I*PI/3)/2, sin(I*PI/3)/2
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 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 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   1. For each triangle in the hexagon, check for intersection | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   2. If intersections, return the closest along the ray | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   GPUHexRegion* region = &context->regions[region_index]->data; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   GPUHex* hex = ®ion->hexes[hex_index]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   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 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] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                        + 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; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | vec3 up = {0, 1, 0}; |  |  |  | vec3 up = {0, 1, 0}; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | VkResult main_thread(ClientContext* context) { |  |  |  | VkResult main_thread(ClientContext* context) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -103,20 +254,18 @@ VkResult main_thread(ClientContext* context) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   add_transfer(&context->hex->data.current_map, context->hex->context, offsetof(GPUHexContext, current_map), sizeof(uint32_t), context->render->current_frame, context->render); |  |  |  |   add_transfer(&context->hex->data.current_map, context->hex->context, offsetof(GPUHexContext, current_map), sizeof(uint32_t), context->render->current_frame, context->render); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   uint32_t region = 0; |  |  |  |   uint32_t region = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |   for(int32_t y = -2; y < 2; y++) { |  |  |  |   for(int32_t q = -5; q < 5; q++) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     for(int32_t q = -5; q < 5; q++) { |  |  |  |     for(int32_t r = -5; r < 5; r++) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       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(set_hex_region(q, r, y, 0x01, ®ions[region], context->hex, context->render)); |  |  |  |       for(uint32_t i = 0; i < REGION_HEX_COUNT; i++) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         for(uint32_t i = 0; i < REGION_HEX_COUNT; i++) { |  |  |  |         for(uint32_t h = 0; h < 6; h++) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |           for(uint32_t h = 0; h < 6; h++) { |  |  |  |           regions[region]->data.hexes[i].color[h] = colors[(q+r+50) % (sizeof(colors)/sizeof(uint32_t))]; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             regions[region]->data.hexes[i].color[h] = colors[(q+r+50) % (sizeof(colors)/sizeof(uint32_t))]; |  |  |  |           regions[region]->data.hexes[i].height[h] = (float)i/REGION_HEX_COUNT;  | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             regions[region]->data.hexes[i].height[h] = (float)i/REGION_HEX_COUNT;  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |           } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |           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)); |  |  |  |         regions[region]->data.hexes[i].color[6] = colors[(q+r+50) % (sizeof(colors)/sizeof(uint32_t))]; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         region++; |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       VK_RESULT(add_transfer(®ions[region]->data.hexes, regions[region]->region, offsetof(GPUHexRegion, hexes), sizeof(GPUHex)*REGION_HEX_COUNT, 0, context->render)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       region++; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -127,7 +276,6 @@ VkResult main_thread(ClientContext* context) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   int frame = 0; |  |  |  |   int frame = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |   double last_frame_time = 0; |  |  |  |   double last_frame_time = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |   double test = glfwGetTime(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   while(glfwWindowShouldClose(context->window) == 0) { |  |  |  |   while(glfwWindowShouldClose(context->window) == 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     double frame_time = glfwGetTime(); |  |  |  |     double frame_time = glfwGetTime(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     double delta_time = (frame_time - last_frame_time); |  |  |  |     double delta_time = (frame_time - last_frame_time); | 
			
		
	
	
		
		
			
				
					|  |  | @ -140,19 +288,7 @@ VkResult main_thread(ClientContext* context) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     context->zoom = 0; |  |  |  |     context->zoom = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |     context->cur_spin[0] = 0; |  |  |  |     context->cur_spin[0] = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |     context->cur_spin[1] = 0; |  |  |  |     context->cur_spin[1] = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     glfwPollEvents(); |  |  |  |     glfwPollEvents(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     if((frame_time - test) > 0.05) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       test = frame_time; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       context->hex->data.clicked_region  = 210; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       context->hex->data.hovered_region  = 210; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       context->hex->data.hovered_hex     = context->hex->data.clicked_hex; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       context->hex->data.clicked_hex    += 1; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       if(context->hex->data.clicked_hex >= REGION_HEX_COUNT) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         context->hex->data.clicked_hex = 0; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       add_transfer(&context->hex->data.clicked_region, context->hex->context, offsetof(GPUHexContext, clicked_region), 2*sizeof(uint32_t) + 2*sizeof(int32_t), context->render->current_frame, context->render); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if((context->key_spin[0] != 0 || context->key_spin[1] != 0 || |  |  |  |     if((context->key_spin[0] != 0 || context->key_spin[1] != 0 || | 
			
		
	
		
		
			
				
					
					|  |  |  |        context->zoom != 0 || |  |  |  |        context->zoom != 0 || | 
			
		
	
	
		
		
			
				
					|  |  | @ -292,16 +428,21 @@ bool contains(double* point, GPUContainer* container, GPUDrawable* rect) { | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void cursor_to_world_ray(ClientContext* context, double cursor[2], vec4 start, vec4 end) { |  |  |  | void cursor_to_world_ray(ClientContext* context, double cursor[2], vec4 start, vec4 end) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   double cursor_scaled[2] = { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     2*(cursor[0]*context->render->window_scale[0]/context->render->swapchain_extent.width - 0.5), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     2*(cursor[1]*context->render->window_scale[1]/context->render->swapchain_extent.height - 0.5), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   }; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   vec4 transformed_start = { |  |  |  |   vec4 transformed_start = { | 
			
		
	
		
		
			
				
					
					|  |  |  |     cursor[0]*context->render->window_scale[0]*2/context->render->swapchain_extent.width - 1, |  |  |  |     cursor_scaled[0], | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     cursor[1]*context->render->window_scale[1]*2/context->render->swapchain_extent.height - 1, |  |  |  |     cursor_scaled[1], | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     0, |  |  |  |     PERSPECTIVE_NEARZ, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     1.0 |  |  |  |     1.0, | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   }; |  |  |  |   }; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   vec4 transformed_end = { |  |  |  |   vec4 transformed_end = { | 
			
		
	
		
		
			
				
					
					|  |  |  |     PERSPECTIVE_FARZ*(cursor[0]*context->render->window_scale[0]*2/context->render->swapchain_extent.width - 1), |  |  |  |     PERSPECTIVE_FARZ*cursor_scaled[0], | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     PERSPECTIVE_FARZ*(cursor[1]*context->render->window_scale[1]*2/context->render->swapchain_extent.height - 1), |  |  |  |     PERSPECTIVE_FARZ*cursor_scaled[1], | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     PERSPECTIVE_FARZ, |  |  |  |     PERSPECTIVE_FARZ, | 
			
		
	
		
		
			
				
					
					|  |  |  |     PERSPECTIVE_FARZ, |  |  |  |     PERSPECTIVE_FARZ, | 
			
		
	
		
		
			
				
					
					|  |  |  |   }; |  |  |  |   }; | 
			
		
	
	
		
		
			
				
					|  |  | @ -333,7 +474,25 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) | 
			
		
	
		
		
			
				
					
					|  |  |  |       cursor_to_world_ray(context, cursor, context->hex->data.click_start, context->hex->data.click_end); |  |  |  |       cursor_to_world_ray(context, cursor, context->hex->data.click_start, context->hex->data.click_end); | 
			
		
	
		
		
			
				
					
					|  |  |  |       add_transfer(&context->hex->data.click_start, context->hex->context, offsetof(GPUHexContext, click_start), sizeof(vec4)*2, context->render->current_frame, context->render); |  |  |  |       add_transfer(&context->hex->data.click_start, context->hex->context, offsetof(GPUHexContext, click_start), sizeof(vec4)*2, context->render->current_frame, context->render); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |       for(int32_t c = context->ui->max_containers - 1; c >= 0; c--) { |  |  |  |       // Hex intersections
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       float distance; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       for(uint32_t r = 0; r < MAX_LOADED_REGIONS; r++) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(context->hex->regions[r] == NULL) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } else if(context->hex->regions[r]->data.map != context->hex->data.current_map) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         for(uint32_t h = 0; h < REGION_HEX_COUNT; h++) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           if(ray_hex_intersect(&distance, context->hex->data.click_start, context->hex->data.click_end, r, h, context->hex)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             context->hex->data.clicked_region = r; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             context->hex->data.clicked_hex = h; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             add_transfer(&context->hex->data.clicked_region, context->hex->context, offsetof(GPUHexContext, clicked_region), sizeof(uint32_t)*2, context->render->current_frame, context->render); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       // UI intersections
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       for(uint32_t c = 0; c < context->ui->max_containers; c++) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(context->ui->containers[c].id == 0x00000000) { |  |  |  |         if(context->ui->containers[c].id == 0x00000000) { | 
			
		
	
		
		
			
				
					
					|  |  |  |           continue; |  |  |  |           continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
	
		
		
			
				
					|  |  | @ -375,6 +534,7 @@ void cursor_pos_callback(GLFWwindow* window, double xpos, double ypos) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   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_transfer(&context->hex->data.hover_start, context->hex->context, offsetof(GPUHexContext, hover_start), sizeof(vec4)*2, context->render->current_frame, context->render); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | int main() { |  |  |  | int main() { | 
			
		
	
	
		
		
			
				
					|  |  | @ -395,6 +555,10 @@ int main() { | 
			
		
	
		
		
			
				
					
					|  |  |  |     return VK_ERROR_OUT_OF_HOST_MEMORY; |  |  |  |     return VK_ERROR_OUT_OF_HOST_MEMORY; | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   memset(context.render, 0, sizeof(RenderContext)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   memset(context.ui, 0, sizeof(UIContext)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   memset(context.hex, 0, sizeof(HexContext)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   glfwSetWindowUserPointer(context.window, &context); |  |  |  |   glfwSetWindowUserPointer(context.window, &context); | 
			
		
	
		
		
			
				
					
					|  |  |  |   glfwSetKeyCallback(context.window, key_callback); |  |  |  |   glfwSetKeyCallback(context.window, key_callback); | 
			
		
	
		
		
			
				
					
					|  |  |  |   glfwSetMouseButtonCallback(context.window, mouse_button_callback); |  |  |  |   glfwSetMouseButtonCallback(context.window, mouse_button_callback); | 
			
		
	
	
		
		
			
				
					|  |  | @ -404,7 +568,8 @@ int main() { | 
			
		
	
		
		
			
				
					
					|  |  |  |   int error; |  |  |  |   int error; | 
			
		
	
		
		
			
				
					
					|  |  |  |   VkResult result; |  |  |  |   VkResult result; | 
			
		
	
		
		
			
				
					
					|  |  |  |   VK_RESULT(init_vulkan(context.window, context.render)); |  |  |  |   VK_RESULT(init_vulkan(context.window, context.render)); | 
			
		
	
		
		
			
				
					
					|  |  |  |    |  |  |  | 
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   | 
			
		
	
		
		
			
				
					
					|  |  |  |   // TODO: make # of fonts/textures/containers scaling, recreate GPU buffers as necessary
 |  |  |  |   // TODO: make # of fonts/textures/containers scaling, recreate GPU buffers as necessary
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   VK_RESULT(create_ui_context(10, 10, 10, context.render, context.ui)); |  |  |  |   VK_RESULT(create_ui_context(10, 10, 10, context.render, context.ui)); | 
			
		
	
		
		
			
				
					
					|  |  |  |   VK_RESULT(create_hex_context(context.render, context.hex)); |  |  |  |   VK_RESULT(create_hex_context(context.render, context.hex)); | 
			
		
	
	
		
		
			
				
					|  |  | 
 |