diff options
-rw-r--r-- | gui.hpp | 15 | ||||
-rw-r--r-- | main.cpp | 5 | ||||
-rw-r--r-- | math.cpp | 39 | ||||
-rw-r--r-- | sim.cpp | 80 | ||||
-rw-r--r-- | sim.hpp | 15 |
5 files changed, 130 insertions, 24 deletions
@@ -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; @@ -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; } { @@ -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; @@ -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); { @@ -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]; |