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

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