Browse Source

fixes for polygon/cone fill

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

51
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 <string>
@ -31,6 +32,7 @@ using std::vector;
game_state* g_game_state;
render_state* g_render_state;
vector<Point> g_polygon_select_vertices = {Point(), Point(), Point(), Point()};
void
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);
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<Point> 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<Point> 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);

26
src/hexlib.h

@ -299,27 +299,15 @@ crossingTest(vector<Point> 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++;

35
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<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();
// forward declarations
@ -518,37 +518,14 @@ renderFrame(std::vector<hex_info> *hexes)
}
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
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

Loading…
Cancel
Save