From f8366d43e172d4410a24149cb6faf7251c103895 Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Thu, 14 Jun 2018 12:38:59 -0400 Subject: [PATCH] fixes for polygon/cone fill --- src/hexgame.cpp | 51 +++++++++++++++++++++++++------------------------ src/hexlib.h | 26 +++++++------------------ src/renderer.h | 35 ++++++--------------------------- 3 files changed, 39 insertions(+), 73 deletions(-) diff --git a/src/hexgame.cpp b/src/hexgame.cpp index 0243de0..2123ea0 100644 --- a/src/hexgame.cpp +++ b/src/hexgame.cpp @@ -1,13 +1,14 @@ // Some defaults for the game layout -#define HEX_SIZE 20 -#define HEX_RADIUS 9 +#define HEX_SIZE 10 +#define HEX_RADIUS 19 #define HEX_ORIENTATION layout_flat #define FILL_COLOR 0x565656FF #define SELECTED_FILL_COLOR 0xF46000FF #define DEBUG_DRAW true #define VIEWPORT_WIDTH 1280 #define VIEWPORT_HEIGHT 720 +#define CONE_ANGLE 30 #include @@ -31,6 +32,7 @@ using std::vector; game_state* g_game_state; render_state* g_render_state; +vector g_polygon_select_vertices = {Point(), Point(), Point(), Point()}; void createHexes(vector *hxi_array, const Layout &layout, uint32 color) @@ -182,7 +184,7 @@ updateHexConeFill(int32 x, int32 y) 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 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); @@ -193,33 +195,32 @@ updateHexConeFill(int32 x, int32 y) 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); + Point test_p; + Point vert2 = Point(botX, botY); + Point vert4 = Point(topX, topY); + std::vector vertices = {p1, vert2, p2, vert4}; - if (topHex && botHex) + for (hex_info &h : *g_game_state->hex_array) { - Point test_p; - Point vert2 = Point(botHex->XPos, botHex->YPos); - Point vert4 = Point(topHex->XPos, topHex->YPos); - std::vector vertices = {p1, vert2, p2, vert4}; + test_p.x = h.XPos; + test_p.y = h.YPos; - for (hex_info &h : *g_game_state->hex_array) + if (crossingTest(vertices, test_p)) { - test_p.x = h.XPos; - test_p.y = h.YPos; - - if (crossingTest(vertices, test_p)) - { - h.selected = true; - h.current_color = g_render_state->selected_fill_color; - } - else - { - h.selected = false; - h.current_color = h.stored_color; - } + h.selected = true; + h.current_color = g_render_state->selected_fill_color; + } + else + { + h.selected = false; + h.current_color = h.stored_color; } } + + g_polygon_select_vertices[0].x = p1.x; g_polygon_select_vertices[0].y = p1.y; + g_polygon_select_vertices[1].x = vert2.x; g_polygon_select_vertices[1].y = vert2.y; + g_polygon_select_vertices[2].x = p2.x; g_polygon_select_vertices[2].y = p2.y; + g_polygon_select_vertices[3].x = vert4.x; g_polygon_select_vertices[3].y = vert4.y; } } @@ -475,7 +476,7 @@ int main(int argc, char* argv[]) SDL_Delay(16); // ~60hz renderFrame(g_game_state->hex_array); if (g_render_state->is_debug_draw && g_game_state->draw_mode == CONE_FILL) - renderDebug(g_game_state->start_hex, g_game_state->current_hex); + renderDebug(g_polygon_select_vertices); renderGooey(handles, g_game_state->draw_mode, g_render_state->is_debug_draw, g_game_state->start_hex, g_game_state->current_hex, g_game_state->is_selecting); SDL_GL_SwapWindow(handles.window); diff --git a/src/hexlib.h b/src/hexlib.h index 30d0beb..21d2b7a 100644 --- a/src/hexlib.h +++ b/src/hexlib.h @@ -299,27 +299,15 @@ crossingTest(vector vertices, Point p) 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)) + // NOTE: upward/downward crossing excludes one vertex in the case that + // the ray intersects a vertex + if ((vert0.y > p.y && vert1.y <= p.y) || // downward crossing + (vert0.y <= p.y && vert1.y > p.y)) // upward crossing { - // 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; - } - } + m = (vert1.y - vert0.y) / (vert1.x - vert0.x); + x = (p.y - vert0.y) / m + vert0.x; // if x is right of p.x it must intersect if (x >= p.x) intersect_count++; diff --git a/src/renderer.h b/src/renderer.h index ed36d07..d3c81f4 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -100,7 +100,7 @@ bool initRenderer(SDL_Handles &handles, v2i vpDims); bool addTexture(SDL_Handles &handles, std::string path); bool createScene(std::vector* hexes); void renderFrame(const std::vector *hexes); -void renderDebug(hex_info *start_hex, hex_info * current_hex); +void renderDebug(std::vector &vertices); void freeBuffers(); // forward declarations @@ -518,37 +518,14 @@ renderFrame(std::vector *hexes) } void -renderDebug(hex_info *start_hex, hex_info *current_hex) +renderDebug(std::vector &vertices) { - if (!start_hex || !current_hex) - return; - - // fill vertex buffer - Point p1(start_hex->XPos, start_hex->YPos); - Point p2(current_hex->XPos, 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 - - // TODO: add matrix math library for rotation transform? - // |x| | cos(a + b) -sin(a + b) 0 | - // |y| * | sin(a + b) cos(a + b) 0 | - // |0| | 0 0 1 | - // - 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; // TODO: indexed line drawing real64 buf[4 * 3] = { - p1.x, p1.y, 0, - botX, botY, 0, - p2.x, p2.y, 0, - topX, topY, 0, + vertices[0].x, vertices[0].y, 0, + vertices[1].x, vertices[1].y, 0, + vertices[2].x, vertices[2].y, 0, + vertices[3].x, vertices[3].y, 0, }; // copy vertexes to render group