summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-12-09 12:21:01 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-12-09 12:21:01 -0500
commit461f1810d6434f1d7438c2332594a844316cc963 (patch)
tree8e9d04d860f00cf413c57fb8baef091b88e06238
parentc84af0bd3367d448bd9ef8a21942a61e574cb057 (diff)
started platform building
-rw-r--r--gui.hpp15
-rw-r--r--main.cpp5
-rw-r--r--math.cpp39
-rw-r--r--sim.cpp80
-rw-r--r--sim.hpp15
5 files changed, 130 insertions, 24 deletions
diff --git a/gui.hpp b/gui.hpp
index 39adb54..f40c361 100644
--- a/gui.hpp
+++ b/gui.hpp
@@ -33,11 +33,26 @@ enum {
};
typedef u16 Key;
+#define MOUSE_LEFT 0
+#define MOUSE_MIDDLE 1
+#define MOUSE_RIGHT 2
+
+typedef struct {
+ u8 button;
+ i32 x, y;
+} MousePress;
+typedef MousePress MouseRelease;
+
typedef struct {
bool closed; // was the window closed?
u8 keys_pressed[NKEYS]; // [i] = how many times was key #i pressed this frame?
u8 keys_released[NKEYS]; // [i] = how many times was key #i released this frame?
bool keys_down[NKEYS]; // [i] = is key #i down?
+ u16 nmouse_presses;
+#define MAX_MOUSE_PRESSES_PER_FRAME 256
+ MousePress mouse_presses[MAX_MOUSE_PRESSES_PER_FRAME];
+
+ i32 mouse_x, mouse_y; // (+y = down)
bool shift, ctrl;
} Input;
diff --git a/main.cpp b/main.cpp
index ad5daaf..7fe4994 100644
--- a/main.cpp
+++ b/main.cpp
@@ -388,6 +388,11 @@ int main(void) {
SDL_GetWindowSize(window, &w, &h);
frame.width = w;
frame.height = h;
+
+ int x = 0, y = 0;
+ SDL_GetMouseState(&x, &y);
+ input->mouse_x = x;
+ input->mouse_y = y;
}
{
diff --git a/math.cpp b/math.cpp
index 25c5917..fcaa162 100644
--- a/math.cpp
+++ b/math.cpp
@@ -267,6 +267,10 @@ static v3 v3_normalize(v3 v) {
return v3_scale(v, mul);
}
+static v2 v3_xy(v3 v) {
+ return V2(v.x, v.y);
+}
+
// a point on a unit sphere
static v3 v3_on_sphere(float yaw, float pitch) {
return V3(cosf(yaw) * cosf(pitch), sinf(pitch), sinf(yaw) * cosf(pitch));
@@ -495,6 +499,41 @@ static m4 m4_mul(m4 a, m4 b) {
return prod;
}
+static m4 m4_inv(m4 mat) {
+ m4 ret;
+ float *inv = ret.e;
+ float *m = mat.e;
+
+ inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] + m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10];
+ inv[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] - m[8] * m[7] * m[14] - m[12] * m[6] * m[11] + m[12] * m[7] * m[10];
+ inv[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] + m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9];
+ inv[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] - m[8] * m[6] * m[13] - m[12] * m[5] * m[10] + m[12] * m[6] * m[9];
+ inv[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] - m[9] * m[3] * m[14] - m[13] * m[2] * m[11] + m[13] * m[3] * m[10];
+ inv[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] + m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10];
+ inv[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] - m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9];
+ inv[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] + m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9];
+ inv[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] + m[5] * m[3] * m[14] + m[13] * m[2] * m[7] - m[13] * m[3] * m[6];
+ inv[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] - m[4] * m[3] * m[14] - m[12] * m[2] * m[7] + m[12] * m[3] * m[6];
+ inv[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] + m[4] * m[3] * m[13] + m[12] * m[1] * m[7] - m[12] * m[3] * m[5];
+ inv[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] - m[4] * m[2] * m[13] - m[12] * m[1] * m[6] + m[12] * m[2] * m[5];
+ inv[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] - m[5] * m[3] * m[10] - m[9] * m[2] * m[7] + m[9] * m[3] * m[6];
+ inv[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] + m[4] * m[3] * m[10] + m[8] * m[2] * m[7] - m[8] * m[3] * m[6];
+ inv[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] - m[4] * m[3] * m[9] - m[8] * m[1] * m[7] + m[8] * m[3] * m[5];
+ inv[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] + m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - m[8] * m[2] * m[5];
+
+ float det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
+
+ if (det == 0) {
+ memset(inv, 0, sizeof *inv);
+ } else {
+ det = 1 / det;
+
+ for (int i = 0; i < 16; i++)
+ inv[i] *= det;
+ }
+
+ return ret;
+}
typedef struct {
int x, y;
} v2i;
diff --git a/sim.cpp b/sim.cpp
index 49cdeef..70a2830 100644
--- a/sim.cpp
+++ b/sim.cpp
@@ -187,6 +187,8 @@ static void platforms_render(State *state, Platform *platforms, u32 nplatforms)
v2 endpoint1 = v2_add(center, platform_r);
v2 endpoint2 = v2_sub(center, platform_r);
+ gl_rgbacolor(platform->color);
+
#if 1
gl->VertexAttrib2f(shader->vertex_p1, endpoint1.x, endpoint1.y);
gl->VertexAttrib2f(shader->vertex_p2, endpoint2.x, endpoint2.y);
@@ -346,8 +348,8 @@ void sim_frame(Frame *frame) {
maybe_unused u8 *keys_pressed = input->keys_pressed;
maybe_unused bool *keys_down = input->keys_down;
- state->win_width = width;
- state->win_height = height;
+ state->win_width = (float)width;
+ state->win_height = (float)height;
state->dt = (float)frame->dt;
@@ -459,25 +461,23 @@ void sim_frame(Frame *frame) {
p->center = V2(-1.0f, 5.0f);
p->angle = 0;
p->size = 1.0f;
- //p->rotate_speed = -1.0f;
- platform_make_body(state, p);
- ++p;
- p->moves = true;
- p->move_p1 = V2(2.0f, 0.5f);
- p->move_p2 = V2(-2.0f, 1.5f);
- p->move_speed = 1.0f;
- p->angle = 0.05f;
- p->size = 6.0f;
+ p->color = 0xFF00FFFF;
platform_make_body(state, p);
state->nplatforms = (u32)(p - state->platforms + 1);
- }
+ Platform *b = &state->platform_building;
+ b->size = 3.0f;
+ b->color = 0xFF00FF7F;
+ }
+
+ state->building = true;
+
state->initialized = true;
#if DEBUG
state->magic_number = MAGIC_NUMBER;
#endif
}
- if (input->keys_pressed[KEY_ESCAPE]) {
+ if (keys_pressed[KEY_ESCAPE]) {
frame->close = true;
return;
}
@@ -486,25 +486,61 @@ void sim_frame(Frame *frame) {
shaders_reload_if_necessary(state);
#endif
- maybe_unused b2World *world = state->world;
+ {
+ float half_height = 10.0f;
+ float half_width = half_height * state->win_width / state->win_height;
+ float ball_x = ball->pos.x, ball_y = ball->pos.y;
+ // center view around ball
+ state->transform = m4_ortho(ball_x - half_width, ball_x + half_width, ball_y - half_height, ball_y + half_height, -1, +1);
+ state->inv_transform = m4_inv(state->transform);
+ }
+
+ { // calculate mouse position in Box2D coordinates
+ v3 mouse_gl_coords = V3(
+ (float)input->mouse_x / state->win_width * 2 - 1,
+ (1 - (float)input->mouse_y / state->win_height) * 2 - 1,
+ 0
+ );
+
+ state->mouse_pos = v3_xy(m4_mul_v3(state->inv_transform, mouse_gl_coords));
+ }
+
Font *font = &state->font;
- // simulate physics
- {
+ if (state->simulating) {
+ // simulate physics
float dt = state->dt;
if (dt > 100) dt = 100; // prevent floating-point problems for very large dt's
simulate_time(state, dt);
}
- {
- float half_height = 10.0f;
- float half_width = half_height * (float)state->win_width / (float)state->win_height;
- float ball_x = ball->pos.x, ball_y = ball->pos.y;
- // center view around ball
- state->transform = m4_ortho(ball_x - half_width, ball_x + half_width, ball_y - half_height, ball_y + half_height, -1, +1);
+ if (state->building) {
+ Platform *platform_building = &state->platform_building;
+ platform_building->center = state->mouse_pos;
+ float dt = state->dt;
+ float rotate_amount = 2.0f * dt;
+ float size_change_amount = 4.0f * dt;
+ // rotate platform using left/right
+ if (keys_down[KEY_LEFT])
+ platform_building->angle += rotate_amount;
+ if (keys_down[KEY_RIGHT])
+ platform_building->angle -= rotate_amount;
+
+ // change size of platform using up/down
+ if (keys_down[KEY_UP])
+ platform_building->size += size_change_amount;
+ if (keys_down[KEY_DOWN])
+ platform_building->size -= size_change_amount;
+
+ platform_building->size = clampf(platform_building->size, 0.3f, 10.0f);
+ platform_building->angle = fmodf(platform_building->angle, TAUf);
}
+
platforms_render(state, state->platforms, state->nplatforms);
+ if (state->building) {
+ platforms_render(state, &state->platform_building, 1);
+ }
ball_render(state);
{
diff --git a/sim.hpp b/sim.hpp
index 0f4dbd7..dcc32fb 100644
--- a/sim.hpp
+++ b/sim.hpp
@@ -138,7 +138,10 @@ typedef struct {
v2 move_p1;
v2 move_p2;
+
float rotate_speed;
+
+ u32 color;
} Platform;
typedef struct {
@@ -150,7 +153,9 @@ typedef struct {
typedef struct {
bool initialized;
- i32 win_width, win_height; // width,height of window
+ float win_width, win_height; // width,height of window in pixels
+
+ v2 mouse_pos; // mouse position in Box2D (not GL) coordinates
float dt; // time in seconds since last frame
@@ -159,12 +164,16 @@ typedef struct {
// will be some left over, if the frame time is not a multiple of the fixed time step)
float time_residue;
m4 transform; // the transform for converting our coordinates to GL coordinates
+ m4 inv_transform; // inverse of transform (for converting GL coordinates to our coordinates)
GL gl; // gl functions
ShaderPlatform shader_platform;
ShaderBall shader_ball;
- b2World *world;
+ bool building; // is the user building a setup?
+ bool simulating; // are we simulating the world's physics?
+
+ b2World *world; // Box2D world
Ball ball;
float bottom_y; // y-position of "floor" (if y goes below here, it's over)
@@ -172,6 +181,8 @@ typedef struct {
Font font;
+ Platform platform_building; // the platform the user is currently placing
+
float platform_thickness;
u32 nplatforms;
Platform platforms[1000];