Browse Source

fixes for polygon/cone fill

master
cinnaboot 8 years ago
parent
commit
f8366d43e1
  1. 25
      src/hexgame.cpp
  2. 22
      src/hexlib.h
  3. 35
      src/renderer.h

25
src/hexgame.cpp

@ -1,13 +1,14 @@
// Some defaults for the game layout // Some defaults for the game layout
#define HEX_SIZE 20 #define HEX_SIZE 10
#define HEX_RADIUS 9 #define HEX_RADIUS 19
#define HEX_ORIENTATION layout_flat #define HEX_ORIENTATION layout_flat
#define FILL_COLOR 0x565656FF #define FILL_COLOR 0x565656FF
#define SELECTED_FILL_COLOR 0xF46000FF #define SELECTED_FILL_COLOR 0xF46000FF
#define DEBUG_DRAW true #define DEBUG_DRAW true
#define VIEWPORT_WIDTH 1280 #define VIEWPORT_WIDTH 1280
#define VIEWPORT_HEIGHT 720 #define VIEWPORT_HEIGHT 720
#define CONE_ANGLE 30
#include <string> #include <string>
@ -31,6 +32,7 @@ using std::vector;
game_state* g_game_state; game_state* g_game_state;
render_state* g_render_state; render_state* g_render_state;
vector<Point> g_polygon_select_vertices = {Point(), Point(), Point(), Point()};
void void
createHexes(vector<hex_info> *hxi_array, const Layout &layout, uint32 color) createHexes(vector<hex_info> *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); 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 angle = std::atan2(p2.y - p1.y, p2.x - p1.x);
real64 len = std::hypot(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 x1 = len * std::cos(angle);
real64 y1 = len * std::sin(angle); real64 y1 = len * std::sin(angle);
@ -193,14 +195,9 @@ updateHexConeFill(int32 x, int32 y)
real64 botX = x1 * std::cos(coneAngle) + y1 * std::sin(coneAngle) + p1.x; 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; 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 test_p;
Point vert2 = Point(botHex->XPos, botHex->YPos); Point vert2 = Point(botX, botY);
Point vert4 = Point(topHex->XPos, topHex->YPos); Point vert4 = Point(topX, topY);
std::vector<Point> vertices = {p1, vert2, p2, vert4}; std::vector<Point> vertices = {p1, vert2, p2, vert4};
for (hex_info &h : *g_game_state->hex_array) for (hex_info &h : *g_game_state->hex_array)
@ -219,7 +216,11 @@ updateHexConeFill(int32 x, int32 y)
h.current_color = h.stored_color; 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 SDL_Delay(16); // ~60hz
renderFrame(g_game_state->hex_array); renderFrame(g_game_state->hex_array);
if (g_render_state->is_debug_draw && g_game_state->draw_mode == CONE_FILL) 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, 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); g_game_state->start_hex, g_game_state->current_hex, g_game_state->is_selecting);
SDL_GL_SwapWindow(handles.window); SDL_GL_SwapWindow(handles.window);

22
src/hexlib.h

@ -301,25 +301,13 @@ crossingTest(vector<Point> vertices, Point p)
vert1 = vertices[i]; vert1 = vertices[i];
// check if edge can intersect the +X ray // check if edge can intersect the +X ray
if ((vert0.y >= p.y && vert1.y <= p.y) || // NOTE: upward/downward crossing excludes one vertex in the case that
(vert0.y <= p.y && vert1.y >= p.y)) // 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 m = (vert1.y - vert0.y) / (vert1.x - vert0.x);
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; x = (p.y - vert0.y) / m + vert0.x;
}
}
// if x is right of p.x it must intersect // if x is right of p.x it must intersect
if (x >= p.x) if (x >= p.x)
intersect_count++; intersect_count++;

35
src/renderer.h

@ -100,7 +100,7 @@ bool initRenderer(SDL_Handles &handles, v2i vpDims);
bool addTexture(SDL_Handles &handles, std::string path); bool addTexture(SDL_Handles &handles, std::string path);
bool createScene(std::vector<hex_info>* hexes); bool createScene(std::vector<hex_info>* hexes);
void renderFrame(const std::vector<hex_info> *hexes); void renderFrame(const std::vector<hex_info> *hexes);
void renderDebug(hex_info *start_hex, hex_info * current_hex); void renderDebug(std::vector<Point> &vertices);
void freeBuffers(); void freeBuffers();
// forward declarations // forward declarations
@ -518,37 +518,14 @@ renderFrame(std::vector<hex_info> *hexes)
} }
void void
renderDebug(hex_info *start_hex, hex_info *current_hex) renderDebug(std::vector<Point> &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 // TODO: indexed line drawing
real64 buf[4 * 3] = { real64 buf[4 * 3] = {
p1.x, p1.y, 0, vertices[0].x, vertices[0].y, 0,
botX, botY, 0, vertices[1].x, vertices[1].y, 0,
p2.x, p2.y, 0, vertices[2].x, vertices[2].y, 0,
topX, topY, 0, vertices[3].x, vertices[3].y, 0,
}; };
// copy vertexes to render group // copy vertexes to render group

Loading…
Cancel
Save