Browse Source

first pass at polygon selection of hexes

master
cinnaboot 8 years ago
parent
commit
c9e7ca325d
  1. 2
      src/gooey.h
  2. 38
      src/hexgame.cpp
  3. 70
      src/hexlib.h
  4. 1
      src/renderer.h

2
src/gooey.h

@ -59,7 +59,7 @@ renderGooey(SDL_Handles &handles, HexDrawMode &mode, bool &is_debug,
window_flags |= ImGuiWindowFlags_NoCollapse;
ImGui::SetNextWindowPos(ImVec2(0,0));
ImGui::SetNextWindowSize(ImVec2(300, 550));
ImGui::SetNextWindowSize(ImVec2(300, 720));
ImGui::SetNextWindowBgAlpha(0.3f);
bool show_window;
ImGui::Begin("", &show_window, window_flags);

38
src/hexgame.cpp

@ -175,15 +175,40 @@ updateHexConeFill(int32 x, int32 y)
if (hxi && (hxi != g_game_state->current_hex) && g_game_state->start_hex)
{
g_game_state->current_hex = hxi;
vector<Hex> hexes = hex_conefill(g_game_state->start_hex->hex, hxi->hex);
// TODO: Remove debug code here and from gooey.h
Point p1(g_game_state->start_hex->XPos, g_game_state->start_hex->YPos);
Point p2(g_game_state->current_hex->XPos, g_game_state->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 = 30.f * 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;
hex_info* topHex = getSingleHex(topX, topY);
hex_info* botHex = getSingleHex(botX, botY);
if (topHex && botHex)
{
Point test_p;
Point vert2 = Point(botHex->XPos, botHex->YPos);
Point vert4 = Point(topHex->XPos, topHex->YPos);
std::vector<Point> vertices = {p1, vert2, p2, vert4};
for (hex_info &h : *g_game_state->hex_array)
{
// TODO: define a system of linear inequalities in hex-space to represent
// cones/arbitrary polygons
if (&h == g_game_state->start_hex)
continue;
test_p.x = h.XPos;
test_p.y = h.YPos;
if (hex_equal(h.hex, hxi->hex))
if (crossingTest(vertices, test_p))
{
h.selected = true;
h.current_color = g_render_state->selected_fill_color;
@ -196,6 +221,7 @@ updateHexConeFill(int32 x, int32 y)
}
}
}
}
void
handleMouseDown(SDL_MouseButtonEvent &e)
@ -385,7 +411,7 @@ int main(int argc, char* argv[])
g_game_state->is_selecting = false;
g_game_state->start_hex = 0x0;
g_game_state->current_hex = 0x0;
g_game_state->draw_mode = LINE;
g_game_state->draw_mode = CONE_FILL;
// init global render state
g_render_state = new render_state();

70
src/hexlib.h

@ -263,9 +263,77 @@ vector<Point> polygon_corners(Layout layout, Hex h)
// custom hex functions
bool hex_equal(Hex a, Hex b)
bool
hex_equal(Hex a, Hex b)
{
return (a.q == b.q && a.r == b.r && a.s == b.s);
}
vector<Hex>
hex_conefill(Hex a, Hex b)
{
vector<Hex> results = {};
return results;
}
// NOTE: implementation of this line crossing test
// https://graphics.stanford.edu/pub/Graphics/RTNews/html/rtnv5n3.html#art3
// NOTE: assumes use of convex polygons with vertices in CCW layout
bool
crossingTest(vector<Point> vertices, Point p)
{
int numVertices = vertices.size(), intersect_count = 0;
Point vert0, vert1;
double m, x;
if (numVertices < 3)
return false;
vert0 = vertices[0];
for (int i = 1; i < numVertices + 1; i++)
{
// use first vertex for the last edge
if (i == numVertices)
vert1 = vertices[0];
else
vert1 = vertices[i];
// check if edge can intersect the +X ray
if ((vert0.y >= p.y && vert1.y <= p.y) ||
(vert0.y <= p.y && vert1.y >= p.y))
{
// TODO: these checks for undefined is pretty hacky
double dx = vert1.x - vert0.x;
// solve for point on edge where y = p.y
if (dx == 0) // don't divide by zero
x = (vert0.x == 0) ? 1 : vert0.x;
else
{
double dm = vert1.x - vert0.x;
if (dm == 0) // don't divide by 0
x = (vert0.x == 0) ? 1 : vert0.x;
else
{
m = (vert1.y - vert0.y) / (dm);
x = (p.y - vert0.y) / m + vert0.x;
}
}
// if x is right of p.x it must intersect
if (x >= p.x)
intersect_count++;
// 2 intersections of convex polygon means we started outside
if (intersect_count > 1)
return false;
}
// start with previous vertex on next loop
vert0 = vert1;
}
return (intersect_count == 1);
}
#endif // HEXLIB_H

1
src/renderer.h

@ -97,6 +97,7 @@ gl_render_group g_debug_render_group;
// Interface
bool initRenderer(SDL_Handles &handles, v2i vpDims);
bool addTexture(SDL_Handles &handles, std::string path);
bool createScene(std::vector<hex_info>* hexes);
void renderFrame(const std::vector<hex_info> *hexes);
void renderDebug(hex_info *start_hex, hex_info * current_hex);

Loading…
Cancel
Save