|  |  |  | @ -41,6 +41,166 @@ int hex_indices[] = { | 
		
	
		
			
				|  |  |  |  |   0, 1, 6, | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | VkResult create_point_pipeline( | 
		
	
		
			
				|  |  |  |  |     RenderContext* gpu, | 
		
	
		
			
				|  |  |  |  |     GraphicsPipeline* pipeline) { | 
		
	
		
			
				|  |  |  |  |   VkResult result; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkShaderModule vert_shader = load_shader_file("shader/point.vert.spv", gpu->device); | 
		
	
		
			
				|  |  |  |  |   VkShaderModule frag_shader = load_shader_file("shader/point.frag.spv", gpu->device); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkPipelineShaderStageCreateInfo stages[] = { | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, | 
		
	
		
			
				|  |  |  |  |       .stage = VK_SHADER_STAGE_VERTEX_BIT, | 
		
	
		
			
				|  |  |  |  |       .pName = "main", | 
		
	
		
			
				|  |  |  |  |       .module = vert_shader, | 
		
	
		
			
				|  |  |  |  |     }, | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, | 
		
	
		
			
				|  |  |  |  |       .stage = VK_SHADER_STAGE_FRAGMENT_BIT, | 
		
	
		
			
				|  |  |  |  |       .pName = "main", | 
		
	
		
			
				|  |  |  |  |       .module = frag_shader, | 
		
	
		
			
				|  |  |  |  |     }, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkPushConstantRange push = { | 
		
	
		
			
				|  |  |  |  |     .size = sizeof(HexPushConstant), | 
		
	
		
			
				|  |  |  |  |     .offset = 0, | 
		
	
		
			
				|  |  |  |  |     .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkPipelineLayoutCreateInfo layout_info = { | 
		
	
		
			
				|  |  |  |  |     .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, | 
		
	
		
			
				|  |  |  |  |     .pPushConstantRanges = &push, | 
		
	
		
			
				|  |  |  |  |     .pushConstantRangeCount = 1, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(vkCreatePipelineLayout(gpu->device, &layout_info, NULL, &pipeline->layout)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkPipelineVertexInputStateCreateInfo vertex_info = { | 
		
	
		
			
				|  |  |  |  |     .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkPipelineInputAssemblyStateCreateInfo input_info = { | 
		
	
		
			
				|  |  |  |  |     .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, | 
		
	
		
			
				|  |  |  |  |     .topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, | 
		
	
		
			
				|  |  |  |  |     .primitiveRestartEnable = VK_FALSE, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkViewport viewport = { | 
		
	
		
			
				|  |  |  |  |     .x = 0.0f, | 
		
	
		
			
				|  |  |  |  |     .y = 0.0f, | 
		
	
		
			
				|  |  |  |  |     .width = (float)(100), | 
		
	
		
			
				|  |  |  |  |     .height = (float)(100), | 
		
	
		
			
				|  |  |  |  |     .minDepth = 0.0f, | 
		
	
		
			
				|  |  |  |  |     .maxDepth = 1.0f, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkRect2D scissor = { | 
		
	
		
			
				|  |  |  |  |     .offset = { | 
		
	
		
			
				|  |  |  |  |       .x = 0, | 
		
	
		
			
				|  |  |  |  |       .y = 0, | 
		
	
		
			
				|  |  |  |  |     }, | 
		
	
		
			
				|  |  |  |  |     .extent = { | 
		
	
		
			
				|  |  |  |  |       .width = 100, | 
		
	
		
			
				|  |  |  |  |       .height = 100, | 
		
	
		
			
				|  |  |  |  |     }, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkPipelineViewportStateCreateInfo viewport_info = { | 
		
	
		
			
				|  |  |  |  |     .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, | 
		
	
		
			
				|  |  |  |  |     .viewportCount = 1, | 
		
	
		
			
				|  |  |  |  |     .pViewports = &viewport, | 
		
	
		
			
				|  |  |  |  |     .scissorCount = 1, | 
		
	
		
			
				|  |  |  |  |     .pScissors = &scissor, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkPipelineRasterizationStateCreateInfo raster_info = { | 
		
	
		
			
				|  |  |  |  |     .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, | 
		
	
		
			
				|  |  |  |  |     .depthClampEnable = VK_FALSE, | 
		
	
		
			
				|  |  |  |  |     .rasterizerDiscardEnable = VK_FALSE, | 
		
	
		
			
				|  |  |  |  |     .polygonMode = VK_POLYGON_MODE_FILL, | 
		
	
		
			
				|  |  |  |  |     .lineWidth = 1.0f, | 
		
	
		
			
				|  |  |  |  |     .cullMode = VK_CULL_MODE_BACK_BIT, | 
		
	
		
			
				|  |  |  |  |     .frontFace = VK_FRONT_FACE_CLOCKWISE, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkPipelineColorBlendAttachmentState blend_attachments = { | 
		
	
		
			
				|  |  |  |  |     .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, | 
		
	
		
			
				|  |  |  |  |     .blendEnable = VK_TRUE, | 
		
	
		
			
				|  |  |  |  |     .srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA, | 
		
	
		
			
				|  |  |  |  |     .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, | 
		
	
		
			
				|  |  |  |  |     .colorBlendOp = VK_BLEND_OP_ADD, | 
		
	
		
			
				|  |  |  |  |     .srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO, | 
		
	
		
			
				|  |  |  |  |     .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO, | 
		
	
		
			
				|  |  |  |  |     .alphaBlendOp = VK_BLEND_OP_ADD, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkPipelineColorBlendStateCreateInfo blend_info = { | 
		
	
		
			
				|  |  |  |  |     .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, | 
		
	
		
			
				|  |  |  |  |     .logicOpEnable = VK_FALSE, | 
		
	
		
			
				|  |  |  |  |     .logicOp = VK_LOGIC_OP_COPY, | 
		
	
		
			
				|  |  |  |  |     .attachmentCount = 1, | 
		
	
		
			
				|  |  |  |  |     .pAttachments = &blend_attachments, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkDynamicState dynamic_states[] = { | 
		
	
		
			
				|  |  |  |  |     VK_DYNAMIC_STATE_VIEWPORT, | 
		
	
		
			
				|  |  |  |  |     VK_DYNAMIC_STATE_SCISSOR, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkPipelineDynamicStateCreateInfo dynamic_info = { | 
		
	
		
			
				|  |  |  |  |     .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, | 
		
	
		
			
				|  |  |  |  |     .dynamicStateCount = sizeof(dynamic_states)/sizeof(VkDynamicState), | 
		
	
		
			
				|  |  |  |  |     .pDynamicStates = dynamic_states, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkPipelineMultisampleStateCreateInfo multisample_info = { | 
		
	
		
			
				|  |  |  |  |     .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, | 
		
	
		
			
				|  |  |  |  |     .sampleShadingEnable = VK_FALSE, | 
		
	
		
			
				|  |  |  |  |     .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, | 
		
	
		
			
				|  |  |  |  |     .minSampleShading = 1.0f, | 
		
	
		
			
				|  |  |  |  |     .pSampleMask = 0, | 
		
	
		
			
				|  |  |  |  |     .alphaToCoverageEnable = VK_FALSE, | 
		
	
		
			
				|  |  |  |  | .alphaToOneEnable = VK_FALSE, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkPipelineDepthStencilStateCreateInfo depth_info = { | 
		
	
		
			
				|  |  |  |  |     .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, | 
		
	
		
			
				|  |  |  |  |     .depthTestEnable = VK_TRUE, | 
		
	
		
			
				|  |  |  |  |     .depthWriteEnable = VK_TRUE, | 
		
	
		
			
				|  |  |  |  |     .depthCompareOp = VK_COMPARE_OP_LESS, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkGraphicsPipelineCreateInfo graphics_pipeline_info = { | 
		
	
		
			
				|  |  |  |  |     .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, | 
		
	
		
			
				|  |  |  |  |     .layout = pipeline->layout, | 
		
	
		
			
				|  |  |  |  |     .stageCount = sizeof(stages)/sizeof(VkPipelineShaderStageCreateInfo), | 
		
	
		
			
				|  |  |  |  |     .pStages = stages, | 
		
	
		
			
				|  |  |  |  |     .pVertexInputState = &vertex_info, | 
		
	
		
			
				|  |  |  |  |     .pInputAssemblyState = &input_info, | 
		
	
		
			
				|  |  |  |  |     .pViewportState = &viewport_info, | 
		
	
		
			
				|  |  |  |  |     .pRasterizationState = &raster_info, | 
		
	
		
			
				|  |  |  |  |     .pColorBlendState = &blend_info, | 
		
	
		
			
				|  |  |  |  |     .pDynamicState = &dynamic_info, | 
		
	
		
			
				|  |  |  |  |     .pMultisampleState = &multisample_info, | 
		
	
		
			
				|  |  |  |  |     .pDepthStencilState = &depth_info, | 
		
	
		
			
				|  |  |  |  |     .renderPass = gpu->render_pass, | 
		
	
		
			
				|  |  |  |  |     .subpass = 0, | 
		
	
		
			
				|  |  |  |  |     .basePipelineHandle = VK_NULL_HANDLE, | 
		
	
		
			
				|  |  |  |  |     .basePipelineIndex = -1, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(vkCreateGraphicsPipelines( | 
		
	
		
			
				|  |  |  |  |         gpu->device, | 
		
	
		
			
				|  |  |  |  |         VK_NULL_HANDLE, | 
		
	
		
			
				|  |  |  |  |         1, &graphics_pipeline_info, | 
		
	
		
			
				|  |  |  |  |         NULL, | 
		
	
		
			
				|  |  |  |  |         &pipeline->pipeline)); | 
		
	
		
			
				|  |  |  |  |   return VK_SUCCESS; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | VkResult create_ray_pipeline( | 
		
	
		
			
				|  |  |  |  |     RenderContext* gpu, | 
		
	
		
			
				|  |  |  |  |     GraphicsPipeline* pipeline) { | 
		
	
	
		
			
				
					|  |  |  | @ -531,6 +691,7 @@ VkResult create_hex_context( | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(create_ray_pipeline(gpu, &context->ray_pipeline)); | 
		
	
		
			
				|  |  |  |  | #endif | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(create_hex_highlight_pipeline(gpu, &context->highlight_pipeline)); | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(create_point_pipeline(gpu, &context->point_pipeline)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   memset(&context->data, 0, sizeof(GPUHexContext)); | 
		
	
		
			
				|  |  |  |  |   glm_perspective( | 
		
	
	
		
			
				
					|  |  |  | @ -636,6 +797,7 @@ VkResult allocate_hex_region( | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | bool ray_hex_intersect( | 
		
	
		
			
				|  |  |  |  |     float* distance, | 
		
	
		
			
				|  |  |  |  |     uint32_t* vertex, | 
		
	
		
			
				|  |  |  |  |     vec3 start, | 
		
	
		
			
				|  |  |  |  |     vec3 dir, | 
		
	
		
			
				|  |  |  |  |     vec3 region_offset, | 
		
	
	
		
			
				
					|  |  |  | @ -685,39 +847,41 @@ bool ray_hex_intersect( | 
		
	
		
			
				|  |  |  |  |     glm_vec3_add(vertices[vertex], hex_offset, vertices[vertex]); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   *distance = INFINITY; | 
		
	
		
			
				|  |  |  |  |   bool intersect = false; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   vec3 t; | 
		
	
		
			
				|  |  |  |  |   glm_vec3_sub(start, vertices[0], t); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   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 vert[2]; | 
		
	
		
			
				|  |  |  |  |     for(int v_i = 0; v_i < 2; v_i++) { | 
		
	
		
			
				|  |  |  |  |       vert[v_i][0] = vertices[hex_indices[triangle*3+v_i + 1]][0]; | 
		
	
		
			
				|  |  |  |  |       vert[v_i][1] = vertices[hex_indices[triangle*3+v_i + 1]][1]; | 
		
	
		
			
				|  |  |  |  |       vert[v_i][2] = vertices[hex_indices[triangle*3+v_i + 1]][2]; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     vec3 v0v1; | 
		
	
		
			
				|  |  |  |  |     glm_vec3_sub(vert[1], vert[0], v0v1); | 
		
	
		
			
				|  |  |  |  |     glm_vec3_sub(vert[0], vertices[0], v0v1); | 
		
	
		
			
				|  |  |  |  |     vec3 v0v2; | 
		
	
		
			
				|  |  |  |  |     glm_vec3_sub(vert[2], vert[0], v0v2); | 
		
	
		
			
				|  |  |  |  |     glm_vec3_sub(vert[1], vertices[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; | 
		
	
		
			
				|  |  |  |  |     float u = glm_vec3_dot(t, pvec) / det; | 
		
	
		
			
				|  |  |  |  |     if(u < 0 || u > 1) continue; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     vec3 q; | 
		
	
		
			
				|  |  |  |  |     glm_vec3_cross(t, v0v1, q); | 
		
	
		
			
				|  |  |  |  |     float v = glm_vec3_dot(dir, q) * det_inv; | 
		
	
		
			
				|  |  |  |  |     float v = glm_vec3_dot(dir, q) / det; | 
		
	
		
			
				|  |  |  |  |     if(v < 0 || (u+v) > 1) continue; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     intersect = true; | 
		
	
		
			
				|  |  |  |  |     *distance = min(*distance, glm_vec3_dot(v0v2, q) * det_inv); | 
		
	
		
			
				|  |  |  |  |     float intersect_distance = glm_vec3_dot(v0v2, q) / det; | 
		
	
		
			
				|  |  |  |  |     if(intersect_distance < *distance) { | 
		
	
		
			
				|  |  |  |  |       *distance = intersect_distance; | 
		
	
		
			
				|  |  |  |  |       *vertex = (u > v) ? ((triangle+1) % 6)+1 : triangle+1; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return intersect; | 
		
	
	
		
			
				
					|  |  |  | @ -725,26 +889,27 @@ bool ray_hex_intersect( | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | bool ray_region_intersect( | 
		
	
		
			
				|  |  |  |  |     float* distance, | 
		
	
		
			
				|  |  |  |  |     uint32_t* vertex, | 
		
	
		
			
				|  |  |  |  |     uint32_t* hid, | 
		
	
		
			
				|  |  |  |  |     vec3 start, | 
		
	
		
			
				|  |  |  |  |     vec3 dir, | 
		
	
		
			
				|  |  |  |  |     HexRegion* region) { | 
		
	
		
			
				|  |  |  |  |   bool intersect = false; | 
		
	
		
			
				|  |  |  |  |   float temp_distance; | 
		
	
		
			
				|  |  |  |  |   *distance = INFINITY; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   float intersect_distance = INFINITY; | 
		
	
		
			
				|  |  |  |  |   uint32_t intersection_vertex = 0; | 
		
	
		
			
				|  |  |  |  |    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) { | 
		
	
		
			
				|  |  |  |  |   for(uint32_t intersect_hid = 0; intersect_hid < REGION_HEX_COUNT; intersect_hid++) { | 
		
	
		
			
				|  |  |  |  |     if(ray_hex_intersect(&intersect_distance, &intersection_vertex, start, dir, region_offset, intersect_hid, region)) { | 
		
	
		
			
				|  |  |  |  |       if(intersect_distance < *distance) { | 
		
	
		
			
				|  |  |  |  |         intersect = true; | 
		
	
		
			
				|  |  |  |  |         *hid = temp_hid; | 
		
	
		
			
				|  |  |  |  |         *distance = temp_distance; | 
		
	
		
			
				|  |  |  |  |         *hid = intersect_hid; | 
		
	
		
			
				|  |  |  |  |         *distance = intersect_distance; | 
		
	
		
			
				|  |  |  |  |         *vertex = intersection_vertex; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
	
		
			
				
					|  |  |  | @ -754,6 +919,7 @@ bool ray_region_intersect( | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | bool ray_world_intersect( | 
		
	
		
			
				|  |  |  |  |     float* distance, | 
		
	
		
			
				|  |  |  |  |     uint32_t* vertex, | 
		
	
		
			
				|  |  |  |  |     uint32_t* rid, | 
		
	
		
			
				|  |  |  |  |     uint32_t* hid, | 
		
	
		
			
				|  |  |  |  |     vec4 ray_start, | 
		
	
	
		
			
				
					|  |  |  | @ -777,24 +943,27 @@ bool ray_world_intersect( | 
		
	
		
			
				|  |  |  |  |   glm_vec3_divs(dir, mdir, dir); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   bool intersect = false; | 
		
	
		
			
				|  |  |  |  |   float temp_distance; | 
		
	
		
			
				|  |  |  |  |   uint32_t temp_hid; | 
		
	
		
			
				|  |  |  |  |   float intersect_distance = INFINITY; | 
		
	
		
			
				|  |  |  |  |   uint32_t intersection_vertex = 0; | 
		
	
		
			
				|  |  |  |  |   uint32_t intersect_hid; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   *distance = INFINITY; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   for(uint32_t temp_rid = 0; temp_rid < MAX_LOADED_REGIONS; temp_rid++) { | 
		
	
		
			
				|  |  |  |  |     HexRegion* region = context->regions[temp_rid]; | 
		
	
		
			
				|  |  |  |  |   for(uint32_t intersect_rid = 0; intersect_rid < MAX_LOADED_REGIONS; intersect_rid++) { | 
		
	
		
			
				|  |  |  |  |     HexRegion* region = context->regions[intersect_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) { | 
		
	
		
			
				|  |  |  |  |     if(ray_region_intersect(&intersect_distance, &intersection_vertex, &intersect_hid, start, dir, region)) { | 
		
	
		
			
				|  |  |  |  |       if(intersect_distance < *distance) { | 
		
	
		
			
				|  |  |  |  |         intersect = true; | 
		
	
		
			
				|  |  |  |  |         *hid = temp_hid; | 
		
	
		
			
				|  |  |  |  |         *rid = temp_rid; | 
		
	
		
			
				|  |  |  |  |         *distance = temp_distance; | 
		
	
		
			
				|  |  |  |  |         *hid = intersect_hid; | 
		
	
		
			
				|  |  |  |  |         *rid = intersect_rid; | 
		
	
		
			
				|  |  |  |  |         *vertex = intersection_vertex; | 
		
	
		
			
				|  |  |  |  |         *distance = intersect_distance; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
	
		
			
				
					|  |  |  | @ -884,6 +1053,7 @@ VkResult update_hex_hover( | 
		
	
		
			
				|  |  |  |  |   float distance; | 
		
	
		
			
				|  |  |  |  |   if(ray_world_intersect( | 
		
	
		
			
				|  |  |  |  |         &distance, | 
		
	
		
			
				|  |  |  |  |         &hex->data.hovered_vertex, | 
		
	
		
			
				|  |  |  |  |         &hex->data.hovered_region, | 
		
	
		
			
				|  |  |  |  |         &hex->data.hovered_hex, | 
		
	
		
			
				|  |  |  |  |         hex->data.hover_start, | 
		
	
	
		
			
				
					|  |  |  | @ -893,7 +1063,7 @@ VkResult update_hex_hover( | 
		
	
		
			
				|  |  |  |  |         &hex->data.hovered_region, | 
		
	
		
			
				|  |  |  |  |         hex->context, | 
		
	
		
			
				|  |  |  |  |         offsetof(GPUHexContext, hovered_region), | 
		
	
		
			
				|  |  |  |  |         sizeof(uint32_t)*2, | 
		
	
		
			
				|  |  |  |  |         sizeof(uint32_t)*3, | 
		
	
		
			
				|  |  |  |  |         gpu); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -923,6 +1093,7 @@ VkResult update_hex_click( | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   if(ray_world_intersect( | 
		
	
		
			
				|  |  |  |  |         &distance, | 
		
	
		
			
				|  |  |  |  |         &hex->data.clicked_vertex, | 
		
	
		
			
				|  |  |  |  |         &hex->data.clicked_region, | 
		
	
		
			
				|  |  |  |  |         &hex->data.clicked_hex, | 
		
	
		
			
				|  |  |  |  |         hex->data.click_start, | 
		
	
	
		
			
				
					|  |  |  | @ -932,7 +1103,7 @@ VkResult update_hex_click( | 
		
	
		
			
				|  |  |  |  |         &hex->data.clicked_region, | 
		
	
		
			
				|  |  |  |  |         hex->context, | 
		
	
		
			
				|  |  |  |  |         offsetof(GPUHexContext, clicked_region), | 
		
	
		
			
				|  |  |  |  |         sizeof(uint32_t)*2, | 
		
	
		
			
				|  |  |  |  |         sizeof(uint32_t)*3, | 
		
	
		
			
				|  |  |  |  |         gpu)); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | 
 |