#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 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& 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 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_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; }