You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
4.8 KiB
217 lines
4.8 KiB
|
|
#include "aixlog.hpp" |
|
|
|
#include "hexgrid.h" |
|
|
|
|
|
// forward declarations |
|
bool createHexagonGrid(hexgrid hg); |
|
|
|
// interface |
|
|
|
bool |
|
hgCreateHexes(hexgrid& hg) |
|
{ |
|
if (hg.gridT == HEXAGON) { |
|
if (!createHexagonGrid(hg)) |
|
return false; |
|
} else { |
|
LOG(ERROR) << "Unhandled grid type\n"; |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
hex_info* |
|
hgGetSingleHex(hexgrid& hg, real32 x, real32 y) |
|
{ |
|
Point p(x, y); |
|
Hex h = hex_round(pixel_to_hex(hg.hexlib_layout, p)); |
|
|
|
for (hex_info &hxi : *hg.hex_array) { |
|
if (hex_equal(h, hxi.hex)) |
|
return &hxi; |
|
} |
|
|
|
return nullptr; |
|
} |
|
|
|
void |
|
hgResetHexes(hexgrid& hg) |
|
{ |
|
hg.start_hex = hg.current_hex = 0; |
|
|
|
for (hex_info &hxi : *hg.hex_array) { |
|
hxi.selected = false; |
|
hxi.current_color = hxi.stored_color; |
|
} |
|
} |
|
|
|
void |
|
hgUpdateHexFill(hexgrid& hg, int32 x, int32 y) |
|
{ |
|
hex_info *hxi = hgGetSingleHex(hg, x, y); |
|
if (hxi && (hxi != hg.current_hex) && hg.start_hex) |
|
{ |
|
hg.current_hex = hxi; |
|
int l = hex_distance(hg.start_hex->hex, hg.current_hex->hex); |
|
|
|
for (hex_info &h : *hg.hex_array) |
|
{ |
|
if (hex_distance(hg.start_hex->hex, h.hex) <= l) |
|
{ |
|
h.selected = true; |
|
h.current_color = hg.selected_fill_color; |
|
} |
|
else |
|
{ |
|
h.selected = false; |
|
h.current_color = h.stored_color; |
|
} |
|
} |
|
} |
|
} |
|
|
|
void |
|
hgUpdateHexLineDraw(hexgrid& hg, int32 x, int32 y) |
|
{ |
|
hex_info *hxi = hgGetSingleHex(hg, x, y); |
|
if (hxi && (hxi != hg.current_hex) && hg.start_hex) |
|
{ |
|
hg.current_hex = hxi; |
|
vector<Hex> hexLine = hex_linedraw(hg.start_hex->hex, hxi->hex); |
|
|
|
for (hex_info &h1 : *hg.hex_array) |
|
{ |
|
for (uint i = 0; i < hexLine.size(); i++) |
|
{ |
|
Hex h2 = hexLine[i]; |
|
if (hex_equal(h1.hex, h2)) |
|
{ |
|
h1.selected = true; |
|
h1.current_color = hg.selected_fill_color; |
|
break; |
|
} |
|
else if (i == hexLine.size() - 1) |
|
{ |
|
h1.selected = false; |
|
h1.current_color = h1.stored_color; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
void |
|
hgUpdateHexConeFill(hexgrid& hg, int32 x, int32 y, float cone_angle, std::vector<Point>& debug_vertices) |
|
{ |
|
hex_info *hxi = hgGetSingleHex(hg, x, y); |
|
if (hxi && (hxi != hg.current_hex) && hg.start_hex) |
|
{ |
|
hg.current_hex = hxi; |
|
|
|
// TODO: Remove debug code here and from gooey.h |
|
Point p1(hg.start_hex->XPos, hg.start_hex->YPos); |
|
Point p2(hg.current_hex->XPos, hg.current_hex->YPos); |
|
real64 angle = std::atan2(p2.y - p1.y, p2.x - p1.x); |
|
real64 len = std::hypot(p2.y - p1.y, p2.x - p1.x); |
|
real64 coneAngle = cone_angle * M_PI / 180; // M_PI is non-standard and may not be portable |
|
|
|
real64 x1 = len * std::cos(angle); |
|
real64 y1 = len * std::sin(angle); |
|
// top of cone |
|
real64 topX = x1 * std::cos(coneAngle) - y1 * std::sin(coneAngle) + p1.x; |
|
real64 topY = x1 * std::sin(coneAngle) + y1 * std::cos(coneAngle) + p1.y; |
|
// bottom of cone |
|
real64 botX = x1 * std::cos(coneAngle) + y1 * std::sin(coneAngle) + p1.x; |
|
real64 botY = x1 * std::sin(-1 * coneAngle) + y1 * std::cos(coneAngle) + p1.y; |
|
|
|
Point test_p; |
|
Point vert2 = Point(botX, botY); |
|
Point vert4 = Point(topX, topY); |
|
std::vector<Point> vertices = {p1, vert2, p2, vert4}; |
|
|
|
for (hex_info &h : *hg.hex_array) |
|
{ |
|
test_p.x = h.XPos; |
|
test_p.y = h.YPos; |
|
|
|
if (crossingTest(vertices, test_p)) |
|
{ |
|
h.selected = true; |
|
h.current_color = hg.selected_fill_color; |
|
} |
|
else |
|
{ |
|
h.selected = false; |
|
h.current_color = h.stored_color; |
|
} |
|
} |
|
|
|
debug_vertices[0] = p1; |
|
debug_vertices[1] = vert2; |
|
debug_vertices[2] = p2; |
|
debug_vertices[3] = vert4; |
|
} |
|
} |
|
|
|
void |
|
hgUpdateColorBuffer(gl_buffer& color_buf, std::vector<hex_info>* hex_array) |
|
{ |
|
uint buf_idx = 0; |
|
uint buf_len_per_hex = 54; // NOTE: 6 triangles * 3 vertices * 3 floats |
|
GLfloat color[3]; |
|
|
|
for (uint i = 0; i < hex_array->size(); i++) { |
|
buf_idx = i * buf_len_per_hex; |
|
hex_info hxi = (*hex_array)[i]; |
|
|
|
// TODO: check performance of this since we call multiple times per frame |
|
// maybe can cache glfloat triplets somewhere |
|
utilConvertColor(color, hxi.current_color); |
|
|
|
for (uint j = 0; j < buf_len_per_hex; j += 3) { |
|
color_buf.buffer[buf_idx + j] = color[0]; |
|
color_buf.buffer[buf_idx + j + 1] = color[1]; |
|
color_buf.buffer[buf_idx + j + 2] = color[2]; |
|
} |
|
} |
|
} |
|
|
|
// internal |
|
|
|
bool |
|
createHexagonGrid(hexgrid hg) |
|
{ |
|
if (hg.hex_array == nullptr) { |
|
LOG(ERROR) << "hg.hex_array is not initialized\n"; |
|
return false; |
|
} |
|
|
|
int hr = hg.hex_radius; |
|
int nhr = hg.hex_radius * -1; |
|
|
|
for (int q = nhr; q <= hr; q++) |
|
{ |
|
int r1 = std::max(nhr, -q - hr); |
|
int r2 = std::min(hr, -q + hr); |
|
|
|
for (int r = r1; r <= r2; r++) |
|
{ |
|
hex_info hxi; |
|
hxi.hexID = (int32) hg.hex_array->size(); |
|
hxi.hex.q = q; hxi.hex.r = r; hxi.hex.s = -q-r; |
|
Point p = hex_to_pixel(hg.hexlib_layout, hxi.hex); |
|
hxi.XPos = p.x; |
|
hxi.YPos = p.y; |
|
hxi.current_color = hg.fill_color; |
|
hxi.stored_color = hg.fill_color; |
|
hxi.vertices = polygon_corners(hg.hexlib_layout, hxi.hex); |
|
hxi.vertices.shrink_to_fit(); |
|
hg.hex_array->push_back(hxi); |
|
} |
|
} |
|
|
|
return true; |
|
}
|
|
|