summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-12-09 15:32:12 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-12-09 15:32:12 -0500
commit9ca2a24de737b18d681a016557e4a037751e32bf (patch)
tree04b06760c4d699b3be0b3ed9efb23cf2e3efdb11
parent13e81cdeb7994ebf062729d7e8407d22e401d459 (diff)
set rotate speed in editor
-rw-r--r--Makefile6
-rw-r--r--main.cpp10
-rw-r--r--math.cpp10
-rw-r--r--sim.cpp161
-rw-r--r--sim.hpp3
5 files changed, 156 insertions, 34 deletions
diff --git a/Makefile b/Makefile
index 79eac2d..2ded1b2 100644
--- a/Makefile
+++ b/Makefile
@@ -5,8 +5,8 @@ obj/debug: physics obj/sim.so obj
touch obj/debug
physics: main.cpp gui.hpp sim.cpp time.cpp
$(CXX) main.cpp -o $@ $(DEBUG_CFLAGS)
-obj/sim.so: *.[ch]* obj
- $(CXX) sim.cpp -fPIC -shared -o $@ $(DEBUG_CFLAGS)
- touch obj/sim.so_changed
+# obj/sim.so: *.[ch]* obj
+# $(CXX) sim.cpp -fPIC -shared -o $@ $(DEBUG_CFLAGS)
+# touch obj/sim.so_changed
obj:
mkdir -p obj
diff --git a/main.cpp b/main.cpp
index 25c037d..52d547a 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,8 +1,12 @@
+#if DEBUG
+#define AUTO_RELOAD_CODE 0
+#endif
+
#ifdef _WIN32
#include <windows.h>
#endif
#include "gui.hpp"
-#if DEBUG
+#if AUTO_RELOAD_CODE
typedef void (*SimFrameFn)(Frame *);
#include "time.cpp"
#else
@@ -195,7 +199,7 @@ int main(void) {
#endif
Frame frame = {};
Input *input = &frame.input;
-#if DEBUG
+#if AUTO_RELOAD_CODE
struct timespec dynlib_last_modified = {};
SimFrameFn sim_frame = NULL;
#if __unix__
@@ -304,7 +308,7 @@ int main(void) {
frame.close = input->closed;
- #if DEBUG
+ #if AUTO_RELOAD_CODE
#if __unix__
#define DYNLIB_EXT "so"
#else
diff --git a/math.cpp b/math.cpp
index fcaa162..060eb0d 100644
--- a/math.cpp
+++ b/math.cpp
@@ -66,6 +66,12 @@ static float maxf(float a, float b) {
return a > b ? a : b;
}
+static float sgnf(float x) {
+ if (x < 0) return -1;
+ if (x > 0) return +1;
+ return 0;
+}
+
static float smoothstepf(float x) {
if (x <= 0) return 0;
if (x >= 1) return 1;
@@ -209,6 +215,10 @@ static v3 V3(float x, float y, float z) {
return v;
}
+static v3 v3_from_v2(v2 v) {
+ return V3(v.x, v.y, 0);
+}
+
#if MATH_GL
static void v3_gl_vertex(v3 v) {
glVertex3f(v.x, v.y, v.z);
diff --git a/sim.cpp b/sim.cpp
index 4ea76c7..395951c 100644
--- a/sim.cpp
+++ b/sim.cpp
@@ -171,11 +171,13 @@ static void platforms_render(State *state, Platform *platforms, u32 nplatforms)
GL *gl = &state->gl;
ShaderPlatform *shader = &state->shader_platform;
float platform_render_thickness = state->platform_thickness;
+ m4 transform = state->transform;
shader_start_using(gl, &shader->base);
gl->Uniform1f(shader->uniform_thickness, platform_render_thickness);
gl->UniformMatrix4fv(shader->uniform_transform, 1, GL_FALSE, state->transform.e);
+
glBegin(GL_QUADS);
glColor3f(1,0,1);
@@ -203,6 +205,43 @@ static void platforms_render(State *state, Platform *platforms, u32 nplatforms)
}
glEnd();
shader_stop_using(gl);
+
+ if (state->building) {
+ // show arrows for platforms
+ for (Platform *platform = platforms, *end = platform + nplatforms; platform != end; ++platform) {
+ gl_rgbacolor(platform->color);
+ if (platform->rotates) {
+ float speed = platform->rotate_speed;
+ float angle = speed * 0.5f;
+ if (angle) {
+ float theta1 = HALF_PIf;
+ float theta2 = theta1 + angle;
+ float dtheta = 0.03f * sgnf(angle);
+ float radius = platform->size;
+ glBegin(GL_LINE_STRIP);
+ for (float theta = theta1; angle > 0 ? (theta < theta2) : (theta > theta2); theta += dtheta) {
+ v3 point = v3_from_v2(v2_add(platform->center, v2_polar(radius, theta)));
+ point = m4_mul_v3(transform, point);
+ v3_gl_vertex(point);
+ }
+ glEnd();
+
+ v3 p1 = v3_from_v2(v2_add(platform->center, v2_polar(radius-0.2f, theta2-0.1f * sgnf(angle))));
+ v3 p2 = v3_from_v2(v2_add(platform->center, v2_polar(radius, theta2)));
+ v3 p3 = v3_from_v2(v2_add(platform->center, v2_polar(radius+0.2f, theta2-0.1f * sgnf(angle))));
+
+ p1 = m4_mul_v3(transform, p1);
+ p2 = m4_mul_v3(transform, p2);
+ p3 = m4_mul_v3(transform, p3);
+ glBegin(GL_LINE_STRIP);
+ v3_gl_vertex(p1);
+ v3_gl_vertex(p2);
+ v3_gl_vertex(p3);
+ glEnd();
+ }
+ }
+ }
+ }
}
// render the ball
@@ -367,9 +406,10 @@ static void simulate_time(State *state, float dt) {
state->time_residue = dt;
}
-static void platform_delete(State *state, u32 index) {
+static void platform_delete(State *state, Platform *platform) {
Platform *platforms = state->platforms;
u32 nplatforms = state->nplatforms;
+ u32 index = (u32)(platform - platforms);
state->world->DestroyBody(platforms[index].body);
@@ -386,6 +426,46 @@ static void platform_delete(State *state, u32 index) {
}
+static void correct_mouse_button(State *state, u8 *button) {
+ if (*button == MOUSE_LEFT) {
+ if (state->shift) {
+ // shift+left mouse = right mouse
+ *button = MOUSE_RIGHT;
+ } else if (state->ctrl) {
+ // ctrl+left mouse = middle mouse
+ *button = MOUSE_MIDDLE;
+ }
+ }
+}
+
+static void ball_reset(State *state) {
+ Ball *ball = &state->ball;
+ b2World *world = state->world;
+ if (ball->body)
+ world->DestroyBody(ball->body);
+
+
+ ball->radius = 0.3f;
+ ball->pos = V2(0, 10.0f);
+
+ // create ball
+ b2BodyDef ball_def;
+ ball_def.type = b2_dynamicBody;
+ ball_def.position.Set(ball->pos.x, ball->pos.y);
+ b2Body *ball_body = ball->body = world->CreateBody(&ball_def);
+
+ b2CircleShape ball_shape;
+ ball_shape.m_radius = ball->radius;
+
+ b2FixtureDef ball_fixture;
+ ball_fixture.shape = &ball_shape;
+ ball_fixture.density = 1.0f;
+ ball_fixture.friction = 0.3f;
+ ball_fixture.restitution = 0.3f; // bounciness
+
+ ball_body->CreateFixture(&ball_fixture);
+}
+
#ifdef __cplusplus
extern "C"
#endif
@@ -405,6 +485,17 @@ void sim_frame(Frame *frame) {
GL *gl = &state->gl;
maybe_unused u8 *keys_pressed = input->keys_pressed;
maybe_unused bool *keys_down = input->keys_down;
+ state->ctrl = input->keys_down[KEY_LCTRL] || input->keys_down[KEY_RCTRL];
+ state->shift = input->keys_down[KEY_LSHIFT] || input->keys_down[KEY_RSHIFT];
+
+ for (u32 i = 0; i < input->nmouse_presses; ++i) {
+ MousePress *p = &input->mouse_presses[i];
+ correct_mouse_button(state, &p->button);
+ }
+ for (u32 i = 0; i < input->nmouse_releases; ++i) {
+ MouseRelease *r = &input->mouse_releases[i];
+ correct_mouse_button(state, &r->button);
+ }
state->win_width = (float)width;
state->win_height = (float)height;
@@ -474,9 +565,6 @@ void sim_frame(Frame *frame) {
text_font_load(state, &state->font, "assets/font.ttf", 36.0f);
- ball->radius = 0.3f;
- ball->pos = V2(0, 10.0f);
-
b2Vec2 gravity(0, -9.81f);
b2World *world = state->world = new b2World(gravity);
@@ -497,22 +585,7 @@ void sim_frame(Frame *frame) {
left_wall_shape.SetAsBox(0.5f, 1000);
left_wall_body->CreateFixture(&left_wall_shape, 0);
- // create ball
- b2BodyDef ball_def;
- ball_def.type = b2_dynamicBody;
- ball_def.position.Set(ball->pos.x, ball->pos.y);
- b2Body *ball_body = ball->body = world->CreateBody(&ball_def);
-
- b2CircleShape ball_shape;
- ball_shape.m_radius = ball->radius;
-
- b2FixtureDef ball_fixture;
- ball_fixture.shape = &ball_shape;
- ball_fixture.density = 1.0f;
- ball_fixture.friction = 0.3f;
- ball_fixture.restitution = 0.3f; // bounciness
-
- ball_body->CreateFixture(&ball_fixture);
+ ball_reset(state);
{ // initialize platforms
Platform *p = &state->platforms[0];
@@ -571,6 +644,12 @@ void sim_frame(Frame *frame) {
float dt = state->dt;
if (dt > 100) dt = 100; // prevent floating-point problems for very large dt's
simulate_time(state, dt);
+ if (keys_pressed[KEY_SPACE]) {
+ state->building = true;
+ state->simulating = false;
+ keys_pressed[KEY_SPACE] = 0;
+ ball_reset(state);
+ }
}
if (state->building) {
@@ -591,14 +670,36 @@ void sim_frame(Frame *frame) {
if (keys_down[KEY_DOWN])
platform_building->size -= size_change_amount;
+ if (platform_building->rotates) {
+ // change rotation speed
+ float rotate_change_amount = 2.0f * dt;
+ if (keys_down[KEY_Q])
+ platform_building->rotate_speed += rotate_change_amount;
+ if (keys_down[KEY_E])
+ platform_building->rotate_speed -= rotate_change_amount;
+ }
+
+ platform_building->rotate_speed = clampf(platform_building->rotate_speed, -3, +3);
platform_building->size = clampf(platform_building->size, 0.3f, 10.0f);
platform_building->angle = fmodf(platform_building->angle, TAUf);
+ if (keys_pressed[KEY_R]) {
+ // toggle rotating platform
+ platform_building->rotates = !platform_building->rotates;
+ if (platform_building->rotate_speed == 0) {
+ platform_building->rotate_speed = 1;
+ }
+ }
+
for (u32 i = 0; i < input->nmouse_presses; ++i) {
- if (input->mouse_presses[i].button == MOUSE_LEFT) {
+ MousePress *press = &input->mouse_presses[i];
+ u8 button = press->button;
+
+ if (button == MOUSE_LEFT) {
if (mouse_platform) {
- // click to delete platform
- platform_delete(state, (u32)(mouse_platform - state->platforms));
+ *platform_building = *mouse_platform;
+ platform_delete(state, mouse_platform);
+ platform_building->color = (platform_building->color & 0xFFFFFF00) | 0x7F;
} else {
// left-click to build platform
if (state->nplatforms < MAX_PLATFORMS) {
@@ -608,6 +709,11 @@ void sim_frame(Frame *frame) {
platform_make_body(state, p);
}
}
+ } else if (button == MOUSE_RIGHT) {
+ if (mouse_platform) {
+ // right-click to delete platform
+ platform_delete(state, mouse_platform);
+ }
}
}
@@ -620,15 +726,16 @@ void sim_frame(Frame *frame) {
u32 prev_mouse_platform_color = mouse_platform ? mouse_platform->color : 0;
if (state->building) {
- // turn platform under mouse red (if user clicks, it will be deleted)
- if (mouse_platform) mouse_platform->color = 0xFF0000FF;
+ // turn platform under mouse blue
+ if (mouse_platform) mouse_platform->color = 0x007FFFFF;
}
platforms_render(state, state->platforms, state->nplatforms);
if (state->building) {
- if (mouse_platform)
+ if (mouse_platform) {
mouse_platform->color = prev_mouse_platform_color;
- else
+ } else {
platforms_render(state, &state->platform_building, 1);
+ }
}
ball_render(state);
diff --git a/sim.hpp b/sim.hpp
index 7cfbe59..2a83412 100644
--- a/sim.hpp
+++ b/sim.hpp
@@ -132,13 +132,13 @@ typedef struct {
float angle;
bool moves; // does this platform move?
+ bool rotates; // does this platform rotate?
// if it's a moving platform
float move_speed;
v2 move_p1;
v2 move_p2;
-
float rotate_speed;
u32 color;
@@ -163,6 +163,7 @@ typedef struct {
float win_width, win_height; // width,height of window in pixels
v2 mouse_pos; // mouse position in Box2D (not GL) coordinates
+ bool shift, ctrl; // is either shift/ctrl key down?
float dt; // time in seconds since last frame