Added function to convert hex world coordinate -> region hex coordinate + region hex index

main
noah metz 2024-11-22 19:36:14 -07:00
parent a9d702c5dc
commit 4e0cae59ca
4 changed files with 188 additions and 50 deletions

@ -16,11 +16,16 @@
#define max(a, b) ((a > b) ? a : b)
#define min(a, b) ((a < b) ? a : b)
typedef struct HexCoordStruct {
int32_t q;
int32_t r;
} HexCoord;
extern vec3 hex_vertices[];
extern vec3 hex_starts[];
extern vec3 hex_directions[];
extern int32_t hex_starts_qr[][2];
extern int32_t hex_directions_qr[][2];
extern HexCoord hex_starts_qr[];
extern HexCoord hex_directions_qr[];
extern int hex_indices[];
typedef struct GPUHexStruct {
@ -131,4 +136,12 @@ VkResult update_hex_click(
HexContext* hex,
RenderContext* gpu);
void hex_qr(uint32_t hex, HexCoord* world);
void region_qr(HexCoord region, HexCoord* world);
void hex_add(HexCoord from, HexCoord* to);
void hex_index(HexCoord world, HexCoord* region, uint32_t* hex);
#endif

@ -53,33 +53,7 @@ void main() {
} else {
position.y = region.hexes[hex_index].heights[indices[gl_VertexIndex]-1] + region.y;
}
color = int2color(region.hexes[hex_index].colors[indices[gl_VertexIndex]]);
/*
vec2 hex_qr = start_coords[side]*radius + direction_coords[side]*(ring-(radius*side));
vec2 world_qr = vec2(0, 0);
world_qr.x = hex_qr.x
+ region_qr.x*((region_size-1)*2 + 1.0)
+ region_qr.y*((region_size-1) + 0.0);
world_qr.y = hex_qr.y
- region_qr.x*((region_size-1) + 0.5)
- region_qr.y*((region_size-1)*2 + 1.0);
color = vec4(world_qr/100, 0, 1);
vec4 hex_pos = vec4(0, 0, 0, 1);
hex_pos.x = x*hex_qr.x;
hex_pos.z = -z*hex_qr.y - z*hex_qr.x/2;
vec4 world_pos = vec4(0, 0, 0, 1);
world_pos.x = hex_pos.x + region_pos.x;
world_pos.z = hex_pos.z + region_pos.z;
vec2 world_qr = vec2(0, 0);
world_qr.x = world_pos.x/x;
world_qr.y = -world_pos.z/z - world_pos.x/(2*x);
*/
color = int2color(region.hexes[hex_index].colors[indices[gl_VertexIndex]]);
gl_Position = pc.context.proj * pc.context.view * position;
}

@ -943,33 +943,22 @@ VkResult update_hex_info_ui(ClientContext* context) {
context->hex.data.clicked_hex);
VK_RESULT(update_ui_string(temp, 0x02, 0, 0, &context->ui, &context->render));
int32_t hex_index = context->hex.data.clicked_hex;
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);
}
// TODO: fix, these are wrong lmao
int32_t hex_q = hex_starts_qr[side][0]*radius + hex_directions_qr[side][0]*(ring-(radius*side));
int32_t hex_r = hex_starts_qr[side][1]*radius + hex_directions_qr[side][1]*(ring-(radius*side));
HexCoord hex_world;
hex_qr(context->hex.data.clicked_hex, &hex_world);
int32_t region_q = region->data.q*((REGION_SIZE-1)*2 + 1) + region->data.r*(REGION_SIZE-1);
int32_t region_r = region->data.q*((REGION_SIZE-1) + 0.5) + region->data.r*((REGION_SIZE-1)*2+1);
HexCoord region_coord = {region->data.q, region->data.r};
HexCoord region_world;
region_qr(region_coord, &region_world);
int32_t world_q = hex_q + region_q;
int32_t world_r = hex_r - region_r;
hex_add(region_world, &hex_world);
snprintf(
temp,
sizeof(temp),
"%d, %d, %d, %d",
world_q,
world_r,
hex_world.q,
hex_world.r,
region->data.y,
context->hex.data.clicked_vertex);
VK_RESULT(update_ui_string(temp, 0x02, 0, 1, &context->ui, &context->render));
@ -1205,6 +1194,22 @@ void editor_startup(ClientContext* context) {
color_ui(context);
}
void hex_vertex_neighbors(
uint32_t vertex, HexCoord region, uint32_t hex,
uint32_t n_vertex[2], HexCoord n_region[2], uint32_t n_hex[2]) {
HexCoord n1 = hex_directions_qr[(vertex+1) % 6];
HexCoord n2 = hex_directions_qr[(vertex+2) % 6];
HexCoord hex_world;
HexCoord region_world;
region_qr(region, &region_world);
hex_qr(hex, &hex_world);
hex_add(region_world, &hex_world);
hex_add(hex_world, &n1);
hex_add(hex_world, &n2);
}
int main() {
EditorData* data = malloc(sizeof(EditorData));
memset(data, 0, sizeof(EditorData));

@ -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, &region_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;
}
}