|  |  |  | @ -25,7 +25,6 @@ typedef struct ClientContextStruct { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   uint32_t clicked_container; | 
		
	
		
			
				|  |  |  |  |   uint32_t clicked_element; | 
		
	
		
			
				|  |  |  |  |   int32_t  clicked_hex[2]; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   double  cursor[2]; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -42,8 +41,6 @@ typedef struct ClientContextStruct { | 
		
	
		
			
				|  |  |  |  |   float   key_spin_speed; | 
		
	
		
			
				|  |  |  |  |   float   cur_spin_speed; | 
		
	
		
			
				|  |  |  |  |   float   zoom_speed; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   mat4 inverse; | 
		
	
		
			
				|  |  |  |  | } ClientContext; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void* network_thread(void* data) { | 
		
	
	
		
			
				
					|  |  |  | @ -119,10 +116,6 @@ VkResult main_thread(ClientContext* context) { | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   //
 | 
		
	
		
			
				|  |  |  |  |   uint32_t* mapped_codes = context->ui->containers[0].layers[0].codes_buffer; | 
		
	
		
			
				|  |  |  |  |   GPUString* mapped_string = context->ui->containers[0].layers[0].strings_buffer; | 
		
	
		
			
				|  |  |  |  |   char str[51]; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   int frame = 0; | 
		
	
		
			
				|  |  |  |  |   double last_frame_time = 0; | 
		
	
		
			
				|  |  |  |  |   while(glfwWindowShouldClose(context->window) == 0) { | 
		
	
	
		
			
				
					|  |  |  | @ -132,8 +125,6 @@ VkResult main_thread(ClientContext* context) { | 
		
	
		
			
				|  |  |  |  |     // Reset callback variables
 | 
		
	
		
			
				|  |  |  |  |     context->clicked_element   = 0x00000000; | 
		
	
		
			
				|  |  |  |  |     context->clicked_container = 0x00000000; | 
		
	
		
			
				|  |  |  |  |     context->clicked_hex[0] = 0; | 
		
	
		
			
				|  |  |  |  |     context->clicked_hex[1] = 0; | 
		
	
		
			
				|  |  |  |  |     context->zoom = 0; | 
		
	
		
			
				|  |  |  |  |     context->cur_spin[0] = 0; | 
		
	
		
			
				|  |  |  |  |     context->cur_spin[1] = 0; | 
		
	
	
		
			
				
					|  |  |  | @ -173,29 +164,9 @@ VkResult main_thread(ClientContext* context) { | 
		
	
		
			
				|  |  |  |  |             context->position, | 
		
	
		
			
				|  |  |  |  |             context->rotation, | 
		
	
		
			
				|  |  |  |  |             context->distance, | 
		
	
		
			
				|  |  |  |  |             context->inverse, | 
		
	
		
			
				|  |  |  |  |             context->render, | 
		
	
		
			
				|  |  |  |  |             context->hex)); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if(context->clicked_hex[0] != 0 || context->clicked_hex[1] != 0) { | 
		
	
		
			
				|  |  |  |  |       snprintf(str, 50, "Clicked: (%d,%d)", context->clicked_hex[0], context->clicked_hex[1]); | 
		
	
		
			
				|  |  |  |  |       map_string(str, mapped_codes, 0, 0, context->ui); | 
		
	
		
			
				|  |  |  |  |       VK_RESULT(add_transfers( | 
		
	
		
			
				|  |  |  |  |             context->ui->containers[0].layers[0].codes_buffer, | 
		
	
		
			
				|  |  |  |  |             context->ui->containers[0].layers[0].codes, | 
		
	
		
			
				|  |  |  |  |             0, | 
		
	
		
			
				|  |  |  |  |             strlen(str)*sizeof(uint32_t), | 
		
	
		
			
				|  |  |  |  |             context->render)); | 
		
	
		
			
				|  |  |  |  |       mapped_string->length = strlen(str); | 
		
	
		
			
				|  |  |  |  |       VK_RESULT(add_transfers( | 
		
	
		
			
				|  |  |  |  |             &context->ui->containers[0].layers[0].strings_buffer[0].length, | 
		
	
		
			
				|  |  |  |  |             context->ui->containers[0].layers[0].strings, | 
		
	
		
			
				|  |  |  |  |             offsetof(GPUString, length), | 
		
	
		
			
				|  |  |  |  |             sizeof(uint32_t), | 
		
	
		
			
				|  |  |  |  |             context->render)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     //
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     VkResult result = draw_frame(context->render, context->ui, context->hex, frame_time); | 
		
	
	
		
			
				
					|  |  |  | @ -259,30 +230,6 @@ bool contains(double* point, GPUContainer* container, GPUDrawable* rect) { | 
		
	
		
			
				|  |  |  |  |          (point[1] >= container->offset[1] && point[1] <= container->offset[1] + container->size[1]); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 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 = { | 
		
	
		
			
				|  |  |  |  |     cursor_scaled[0], | 
		
	
		
			
				|  |  |  |  |     cursor_scaled[1], | 
		
	
		
			
				|  |  |  |  |     PERSPECTIVE_NEARZ, | 
		
	
		
			
				|  |  |  |  |     1.0, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   vec4 transformed_end = { | 
		
	
		
			
				|  |  |  |  |     PERSPECTIVE_FARZ*cursor_scaled[0], | 
		
	
		
			
				|  |  |  |  |     PERSPECTIVE_FARZ*cursor_scaled[1], | 
		
	
		
			
				|  |  |  |  |     PERSPECTIVE_FARZ, | 
		
	
		
			
				|  |  |  |  |     PERSPECTIVE_FARZ, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   glm_mat4_mulv(context->inverse, transformed_start, start); | 
		
	
		
			
				|  |  |  |  |   glm_mat4_mulv(context->inverse, transformed_end, end); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) { | 
		
	
		
			
				|  |  |  |  |   ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -303,35 +250,8 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) | 
		
	
		
			
				|  |  |  |  |     break; | 
		
	
		
			
				|  |  |  |  |   case GLFW_MOUSE_BUTTON_LEFT: | 
		
	
		
			
				|  |  |  |  |     if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |       cursor_to_world_ray( | 
		
	
		
			
				|  |  |  |  |           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
 | 
		
	
		
			
				|  |  |  |  |       float distance; | 
		
	
		
			
				|  |  |  |  |       if(ray_world_intersect( | 
		
	
		
			
				|  |  |  |  |             &distance, | 
		
	
		
			
				|  |  |  |  |             &context->hex->data.clicked_region, | 
		
	
		
			
				|  |  |  |  |             &context->hex->data.clicked_hex, | 
		
	
		
			
				|  |  |  |  |             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, | 
		
	
		
			
				|  |  |  |  |             offsetof(GPUHexContext, clicked_region), | 
		
	
		
			
				|  |  |  |  |             sizeof(uint32_t)*2, | 
		
	
		
			
				|  |  |  |  |             context->render); | 
		
	
		
			
				|  |  |  |  |       }   | 
		
	
		
			
				|  |  |  |  |       // Hex intersection
 | 
		
	
		
			
				|  |  |  |  |       update_hex_click(cursor, context->hex, context->render); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       // UI intersections
 | 
		
	
		
			
				|  |  |  |  |       for(uint32_t c = 0; c < context->ui->max_containers; c++) { | 
		
	
	
		
			
				
					|  |  |  | @ -354,10 +274,6 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       // NOTE: this logic is the same as it would be for right-click(just with different outcomes), so dont repeat yourself
 | 
		
	
		
			
				|  |  |  |  |       // 1. Search through the UI context for the first element that the contains the mouse point
 | 
		
	
		
			
				|  |  |  |  |       // 2. If no UI element intersection, cast a ray through the world scene to find the "clicked entity" 
 | 
		
	
		
			
				|  |  |  |  |       // 3. Based on what was clicked, start the mouse click animation at the target area
 | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     break; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
	
		
			
				
					|  |  |  | @ -374,32 +290,13 @@ void cursor_pos_callback(GLFWwindow* window, double xpos, double ypos) { | 
		
	
		
			
				|  |  |  |  |   if(context->camera_mode == true) { | 
		
	
		
			
				|  |  |  |  |     context->cur_spin[0] = (xpos - context->cursor[0])/context->render->swapchain_extent.width*-100; | 
		
	
		
			
				|  |  |  |  |     context->cur_spin[1] = (ypos - context->cursor[1])/context->render->swapchain_extent.height*100; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   context->cursor[0] = xpos; | 
		
	
		
			
				|  |  |  |  |   context->cursor[1] = ypos; | 
		
	
		
			
				|  |  |  |  |   cursor_to_world_ray(context, context->cursor, context->hex->data.hover_start, context->hex->data.hover_end); | 
		
	
		
			
				|  |  |  |  |   add_transfers( | 
		
	
		
			
				|  |  |  |  |       &context->hex->data.hover_start, | 
		
	
		
			
				|  |  |  |  |       context->hex->context, | 
		
	
		
			
				|  |  |  |  |       offsetof(GPUHexContext, hover_start), | 
		
	
		
			
				|  |  |  |  |       sizeof(vec4)*2, | 
		
	
		
			
				|  |  |  |  |       context->render); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   // Hex intersections
 | 
		
	
		
			
				|  |  |  |  |   float distance; | 
		
	
		
			
				|  |  |  |  |   if(ray_world_intersect( | 
		
	
		
			
				|  |  |  |  |         &distance, | 
		
	
		
			
				|  |  |  |  |         &context->hex->data.hovered_region, | 
		
	
		
			
				|  |  |  |  |         &context->hex->data.hovered_hex, | 
		
	
		
			
				|  |  |  |  |         context->hex->data.hover_start, | 
		
	
		
			
				|  |  |  |  |         context->hex->data.hover_end, | 
		
	
		
			
				|  |  |  |  |         context->hex)) { | 
		
	
		
			
				|  |  |  |  |     add_transfers( | 
		
	
		
			
				|  |  |  |  |         &context->hex->data.hovered_region, | 
		
	
		
			
				|  |  |  |  |         context->hex->context, | 
		
	
		
			
				|  |  |  |  |         offsetof(GPUHexContext, hovered_region), | 
		
	
		
			
				|  |  |  |  |         sizeof(uint32_t)*2, | 
		
	
		
			
				|  |  |  |  |         context->render); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     context->cursor[0] = xpos; | 
		
	
		
			
				|  |  |  |  |     context->cursor[1] = ypos; | 
		
	
		
			
				|  |  |  |  |   } else { | 
		
	
		
			
				|  |  |  |  |     context->cursor[0] = xpos; | 
		
	
		
			
				|  |  |  |  |     context->cursor[1] = ypos; | 
		
	
		
			
				|  |  |  |  |     update_hex_hover(context->cursor, context->hex, context->render); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | 
 |