|  |  |  | @ -23,7 +23,7 @@ vec3 hex_starts[] = { | 
		
	
		
			
				|  |  |  |  |   { HEX_X, 0,  HEX_Z/2}, | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | int32_t hex_starts_qr[][2] = { | 
		
	
		
			
				|  |  |  |  | HexCoord hex_starts_qr[] = { | 
		
	
		
			
				|  |  |  |  |   { 0, -1}, | 
		
	
		
			
				|  |  |  |  |   {-1,  0}, | 
		
	
		
			
				|  |  |  |  |   {-1,  1}, | 
		
	
	
		
			
				
					|  |  |  | @ -32,7 +32,7 @@ int32_t hex_starts_qr[][2] = { | 
		
	
		
			
				|  |  |  |  |   { 1, -1}, | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | int32_t hex_directions_qr[][2] = { | 
		
	
		
			
				|  |  |  |  | HexCoord hex_directions_qr[] = { | 
		
	
		
			
				|  |  |  |  |   {-1,  1}, | 
		
	
		
			
				|  |  |  |  |   { 0,  1}, | 
		
	
		
			
				|  |  |  |  |   { 1,  0}, | 
		
	
	
		
			
				
					|  |  |  | @ -1131,3 +1131,149 @@ VkResult update_hex_click( | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return VK_SUCCESS; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void hex_qr(uint32_t hex, HexCoord* world) { | 
		
	
		
			
				|  |  |  |  |   float radius = 0; | 
		
	
		
			
				|  |  |  |  |   float ring = 0; | 
		
	
		
			
				|  |  |  |  |   int side = 0; | 
		
	
		
			
				|  |  |  |  |   if(hex != 0) { | 
		
	
		
			
				|  |  |  |  |     radius = floor(0.5 + sqrt(12*hex-3)/6); | 
		
	
		
			
				|  |  |  |  |     ring = hex - (3*radius*radius - 3*radius + 1); | 
		
	
		
			
				|  |  |  |  |     side = floor(ring/radius); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   world->q = hex_starts_qr[side].q*radius + hex_directions_qr[side].q*(ring-(radius*side)); | 
		
	
		
			
				|  |  |  |  |   world->r = hex_starts_qr[side].r*radius + hex_directions_qr[side].r*(ring-(radius*side)); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void region_qr(HexCoord region, HexCoord* world) { | 
		
	
		
			
				|  |  |  |  |   world->q =  region.q * REGION_DIAMETER + region.r * (REGION_DIAMETER - 1)/2; | 
		
	
		
			
				|  |  |  |  |   world->r = -region.r * REGION_DIAMETER - region.q * (REGION_DIAMETER + 1)/2; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void hex_add(HexCoord from, HexCoord* to) { | 
		
	
		
			
				|  |  |  |  |   to->q += from.q; | 
		
	
		
			
				|  |  |  |  |   to->r += from.r; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | unsigned int hex_distance(HexCoord a, HexCoord b) { | 
		
	
		
			
				|  |  |  |  |   return (abs(a.q - b.q) + abs(a.r - b.r) + abs(a.q + a.r - b.q - b.r))/2; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | unsigned int region_radius_1(HexCoord hex, HexCoord region) { | 
		
	
		
			
				|  |  |  |  |   return region.q*REGION_DIAMETER + region.r*(REGION_SIZE-1) - hex.q; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | unsigned int region_radius_2(HexCoord hex, HexCoord region) { | 
		
	
		
			
				|  |  |  |  |   return -region.r*REGION_DIAMETER - region.q*REGION_SIZE - hex.r; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | unsigned int region_radius_3(HexCoord hex, HexCoord region) { | 
		
	
		
			
				|  |  |  |  |   return region.q*(REGION_SIZE-1) - region.r*REGION_SIZE - hex.q - hex.r; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void region_1(HexCoord hex, HexCoord* region) { | 
		
	
		
			
				|  |  |  |  |   region->q = ceil((hex.q*REGION_DIAMETER + hex.r*(REGION_SIZE-1))/(double)REGION_HEX_COUNT); | 
		
	
		
			
				|  |  |  |  |   region->r = floor((-hex.q*REGION_SIZE - hex.r*REGION_DIAMETER)/(double)REGION_HEX_COUNT); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void region_2(HexCoord hex, HexCoord* region) { | 
		
	
		
			
				|  |  |  |  |   region->q = ceil((hex.q*REGION_DIAMETER + hex.r*(REGION_SIZE - 1))/(double)REGION_HEX_COUNT); | 
		
	
		
			
				|  |  |  |  |   region->r = floor((-hex.q*REGION_SIZE - hex.r*REGION_DIAMETER + REGION_SIZE*REGION_SIZE - 2*REGION_SIZE + 1)/(double)REGION_HEX_COUNT); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void region_3(HexCoord hex, HexCoord* region) { | 
		
	
		
			
				|  |  |  |  |   region->q = ceil((hex.q*REGION_DIAMETER + hex.r*(REGION_SIZE-1) - REGION_SIZE*REGION_SIZE + 2*REGION_SIZE - 1)/(double)REGION_HEX_COUNT); | 
		
	
		
			
				|  |  |  |  |   region->r = ceil((-hex.q*REGION_SIZE - hex.r*REGION_DIAMETER)/(double)REGION_HEX_COUNT); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void region_4(HexCoord hex, HexCoord* region) { | 
		
	
		
			
				|  |  |  |  |   region->q = ceil((hex.q*REGION_DIAMETER + hex.r*(REGION_SIZE-1) - REGION_SIZE*REGION_SIZE + REGION_SIZE)/(double)REGION_HEX_COUNT); | 
		
	
		
			
				|  |  |  |  |   region->r = floor((-hex.q*REGION_SIZE - hex.r*REGION_DIAMETER)/(double)REGION_HEX_COUNT); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void region_5(HexCoord hex, HexCoord* region) { | 
		
	
		
			
				|  |  |  |  |   region->q = ceil((hex.r*(REGION_SIZE-1) + hex.q*REGION_DIAMETER - 2*REGION_SIZE*REGION_SIZE + 2*REGION_SIZE)/(double)REGION_HEX_COUNT); | 
		
	
		
			
				|  |  |  |  |   region->r = floor((-hex.q*REGION_SIZE - hex.r*REGION_DIAMETER + REGION_SIZE*REGION_SIZE - REGION_SIZE)/(double)REGION_HEX_COUNT); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void region_6(HexCoord hex, HexCoord* region) { | 
		
	
		
			
				|  |  |  |  |   region->q = floor((hex.q*REGION_DIAMETER + hex.r*(REGION_SIZE-1))/(double)REGION_HEX_COUNT); | 
		
	
		
			
				|  |  |  |  |   region->r = ceil((-hex.q*REGION_SIZE - hex.r*REGION_DIAMETER)/(double)REGION_HEX_COUNT); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void hex_index(HexCoord world, HexCoord* region, uint32_t* hex) { | 
		
	
		
			
				|  |  |  |  |   int R1, R2, R3; | 
		
	
		
			
				|  |  |  |  |   unsigned int side, radius; | 
		
	
		
			
				|  |  |  |  |   HexCoord side_start, region_center; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   region_1(world, region); | 
		
	
		
			
				|  |  |  |  |   R1 = region_radius_1(world, *region); | 
		
	
		
			
				|  |  |  |  |   R2 = region_radius_2(world, *region); | 
		
	
		
			
				|  |  |  |  |   R3 = region_radius_3(world, *region); | 
		
	
		
			
				|  |  |  |  |   radius = (R1 + R2 + R3)/2; | 
		
	
		
			
				|  |  |  |  |   if(R1 >= 0 && R2 > 0 && radius <= REGION_SIZE - 1) { | 
		
	
		
			
				|  |  |  |  |     side = 0; | 
		
	
		
			
				|  |  |  |  |     goto side_found; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   region_2(world, region); | 
		
	
		
			
				|  |  |  |  |   R1 = region_radius_1(world, *region); | 
		
	
		
			
				|  |  |  |  |   R2 = region_radius_2(world, *region); | 
		
	
		
			
				|  |  |  |  |   R3 = region_radius_3(world, *region); | 
		
	
		
			
				|  |  |  |  |   radius = (R1 - R2 + R3)/2; | 
		
	
		
			
				|  |  |  |  |   if(R2 <= 0 && R3 > 0 && radius <= REGION_SIZE - 1) { | 
		
	
		
			
				|  |  |  |  |     side = 1; | 
		
	
		
			
				|  |  |  |  |     goto side_found; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   region_3(world, region); | 
		
	
		
			
				|  |  |  |  |   R1 = region_radius_1(world, *region); | 
		
	
		
			
				|  |  |  |  |   R2 = region_radius_2(world, *region); | 
		
	
		
			
				|  |  |  |  |   R3 = region_radius_3(world, *region); | 
		
	
		
			
				|  |  |  |  |   radius = (R1 - R2 - R3)/2; | 
		
	
		
			
				|  |  |  |  |   if(R1 > 0 && R3 <= 0 && radius <= REGION_SIZE - 1) { | 
		
	
		
			
				|  |  |  |  |     side = 2; | 
		
	
		
			
				|  |  |  |  |     goto side_found; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   region_4(world, region); | 
		
	
		
			
				|  |  |  |  |   R1 = region_radius_1(world, *region); | 
		
	
		
			
				|  |  |  |  |   R2 = region_radius_2(world, *region); | 
		
	
		
			
				|  |  |  |  |   R3 = region_radius_3(world, *region); | 
		
	
		
			
				|  |  |  |  |   radius = (-R1 + R2 + R3)/2; | 
		
	
		
			
				|  |  |  |  |   if(R1 < 0 && R3 >= 0 && radius <= REGION_SIZE - 1) { | 
		
	
		
			
				|  |  |  |  |     side = 5; | 
		
	
		
			
				|  |  |  |  |     goto side_found; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   region_5(world, region); | 
		
	
		
			
				|  |  |  |  |   R1 = region_radius_1(world, *region); | 
		
	
		
			
				|  |  |  |  |   R2 = region_radius_2(world, *region); | 
		
	
		
			
				|  |  |  |  |   R3 = region_radius_3(world, *region); | 
		
	
		
			
				|  |  |  |  |   radius = (-R1 + R2 - R3)/2; | 
		
	
		
			
				|  |  |  |  |   if(R2 >= 0 && R3 < 0 && radius <= REGION_SIZE - 1) { | 
		
	
		
			
				|  |  |  |  |     side = 4; | 
		
	
		
			
				|  |  |  |  |     goto side_found; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   region_6(world, region); | 
		
	
		
			
				|  |  |  |  |   side = 3; | 
		
	
		
			
				|  |  |  |  |   R1 = region_radius_1(world, *region); | 
		
	
		
			
				|  |  |  |  |   R2 = region_radius_2(world, *region); | 
		
	
		
			
				|  |  |  |  |   R3 = region_radius_3(world, *region); | 
		
	
		
			
				|  |  |  |  |   radius = (-R1 - R2 -R3)/2; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | side_found: | 
		
	
		
			
				|  |  |  |  |   side_start.q = hex_starts_qr[side].q * radius; | 
		
	
		
			
				|  |  |  |  |   side_start.r = hex_starts_qr[side].r * radius; | 
		
	
		
			
				|  |  |  |  |   region_qr(*region, ®ion_center); | 
		
	
		
			
				|  |  |  |  |   hex_add(region_center, &side_start); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   unsigned int side_distance = hex_distance(world, side_start); | 
		
	
		
			
				|  |  |  |  |   if(radius == 0) { | 
		
	
		
			
				|  |  |  |  |     *hex = 0; | 
		
	
		
			
				|  |  |  |  |   } else { | 
		
	
		
			
				|  |  |  |  |     *hex = (3*radius*(radius-1) + 1) + radius*side + side_distance; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					|  |  |  | 
 |