diff --git a/src/entity.c b/src/entity.c index 1618e9fd..5a88eab3 100644 --- a/src/entity.c +++ b/src/entity.c @@ -17,7 +17,7 @@ READONLY struct entity _g_entity_nil = { .cached_global_xform = XFORM_IDENT_NOCAST, .cached_global_xform_dirty = false, .verlet_xform = XFORM_IDENT_NOCAST, - .density = 1, + .mass_unscaled = 1, .sprite_local_xform = XFORM_IDENT_NOCAST, .sprite_tint = COLOR_WHITE }; @@ -28,7 +28,7 @@ GLOBAL READONLY struct entity g_entity_default = { .cached_global_xform = XFORM_IDENT_NOCAST, .cached_global_xform_dirty = true, .verlet_xform = XFORM_IDENT_NOCAST, - .density = 1, + .mass_unscaled = 1, .sprite_local_xform = XFORM_IDENT_NOCAST, .sprite_tint = COLOR_WHITE }; diff --git a/src/entity.h b/src/entity.h index 36f27f19..6a98ee4f 100644 --- a/src/entity.h +++ b/src/entity.h @@ -101,7 +101,7 @@ struct entity { /* ENTITY_PROP_PHYSICAL */ - f32 density; + f32 mass_unscaled; /* Mass of entity in kg before any transformations */ f32 ground_friction; /* Xform of the entity from the previous frame (used to calculate velocity) */ diff --git a/src/game.c b/src/game.c index 6478c216..cddd3311 100644 --- a/src/game.c +++ b/src/game.c @@ -124,14 +124,14 @@ INTERNAL void spawn_test_entities(void) e->sprite_span_name = STR("idle.two_handed"); entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED); - e->control_move_force = 50; + e->control_move_force = 4500; e->control.focus = V2(0, -1); - e->ground_friction = 12; - e->density = 1.0; - - player_ent = e; entity_enable_prop(e, ENTITY_PROP_PHYSICAL); + e->mass_unscaled = 70; + e->ground_friction = 1000; + + player_ent = e; } /* Weapon */ @@ -156,6 +156,18 @@ INTERNAL void spawn_test_entities(void) player_ent->equipped = e->handle; } + /* Box */ + { + struct v2 pos = V2(1, -1); + struct v2 size = V2(1, 1); + f32 rot = 0; + struct entity *e = entity_alloc(root); + + e->sprite = sprite_tag_from_path(STR("res/graphics/box.ase")); + + entity_set_xform(e, XFORM_TRS(.t = pos, .s = size, .r = rot)); + } + /* Camera */ { struct entity *e = entity_alloc(root); @@ -512,7 +524,8 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) bullet->bullet_src = ent->handle; bullet->bullet_src_pos = rel_pos; bullet->bullet_src_dir = rel_dir; - bullet->bullet_impulse = 5; + bullet->bullet_impulse = 0.25; + bullet->mass_unscaled = 0.04; entity_enable_prop(bullet, ENTITY_PROP_BULLET); } @@ -581,8 +594,8 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) struct entity *ent = &store->entities[entity_index]; if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) { - f32 density = ent->density; - f32 mass = density; /* TODO: Real mass calculation */ + struct xform xf = entity_get_xform(ent); + f32 mass = ent->mass_unscaled * xform_get_determinant(xf); struct v2 acceleration = V2(0, 0); @@ -605,7 +618,6 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) } /* Verlet integration */ - struct xform xf = entity_get_xform(ent); struct v2 tick_velocity = v2_sub(xf.og, ent->verlet_xform.og); ent->verlet_xform = xf; xf.og = v2_add(xf.og, v2_add(tick_velocity, v2_mul(acceleration, dt))); diff --git a/src/math.h b/src/math.h index 9f60f78b..f304a792 100644 --- a/src/math.h +++ b/src/math.h @@ -907,6 +907,16 @@ INLINE struct v2 xform_invert_mul_v2(struct xform xf, struct v2 v) return res; } +INLINE struct quad xform_mul_quad(struct xform xf, struct quad quad) +{ + return (struct quad) { + xform_mul_v2(xf, quad.p1), + xform_mul_v2(xf, quad.p2), + xform_mul_v2(xf, quad.p3), + xform_mul_v2(xf, quad.p4) + }; +} + INLINE f32 xform_get_determinant(struct xform xf) { return v2_wedge(xf.bx, xf.by); @@ -1027,16 +1037,6 @@ INLINE struct quad quad_scale(struct quad q, f32 s) return q; } -INLINE struct quad quad_mul_xform(struct quad quad, struct xform m) -{ - return (struct quad) { - xform_mul_v2(m, quad.p1), - xform_mul_v2(m, quad.p2), - xform_mul_v2(m, quad.p3), - xform_mul_v2(m, quad.p4) - }; -} - INLINE struct quad quad_round(struct quad quad) { return (struct quad) { diff --git a/src/user.c b/src/user.c index 68a389c2..309a28b9 100644 --- a/src/user.c +++ b/src/user.c @@ -367,7 +367,7 @@ INTERNAL void debug_draw_xform(struct xform xf) y_ray = v2_mul(y_ray, ray_scale); struct quad quad = quad_from_rect(RECT(0, 0, 1, -1)); - quad = quad_mul_xform(quad_scale(quad, 0.075f), xf); + quad = xform_mul_quad(xf, quad_scale(quad, 0.075f)); draw_solid_arrow_ray(G.viewport_canvas, pos, x_ray, thickness, arrowhead_len, color_x); draw_solid_arrow_ray(G.viewport_canvas, pos, y_ray, thickness, arrowhead_len, color_y); @@ -842,7 +842,7 @@ INTERNAL void user_update(void) /* TODO: Fade in placeholder if texture isn't loaded */ if (sheet->loaded) { struct sprite_sheet_frame frame = sprite_sheet_get_frame(sheet, ent->animation_frame); - struct quad quad = quad_mul_xform(QUAD_UNIT_SQUARE_CENTERED, sprite_xform); + struct quad quad = xform_mul_quad(sprite_xform, QUAD_UNIT_SQUARE_CENTERED); struct draw_sprite_params params = DRAW_SPRITE_PARAMS(.sprite = sprite, .tint = ent->sprite_tint, .clip = frame.clip); draw_sprite_quad(G.world_canvas, params, quad); } @@ -924,8 +924,8 @@ INTERNAL void user_update(void) if (!slice.has_ray) { struct quad quad = quad_from_rect(slice.rect); - quad = quad_mul_xform(quad, sprite_xform); - quad = quad_mul_xform(quad, G.world_view); + quad = xform_mul_quad(sprite_xform, quad); + quad = xform_mul_quad(G.world_view, quad); draw_solid_quad_line(G.viewport_canvas, quad, 2, RGBA_32_F(1, 0, 0.5, 1)); } @@ -959,8 +959,8 @@ INTERNAL void user_update(void) struct xform quad_xf = xform_mul(xf, ent->camera_quad_xform); - struct quad quad = quad_mul_xform(QUAD_UNIT_SQUARE_CENTERED, quad_xf); - quad = quad_mul_xform(quad, G.world_view); + struct quad quad = xform_mul_quad(quad_xf, QUAD_UNIT_SQUARE_CENTERED); + quad = xform_mul_quad(G.world_view, quad); draw_solid_quad_line(G.viewport_canvas, quad, thickness, color); } @@ -979,7 +979,7 @@ INTERNAL void user_update(void) struct v2 size = V2(t->width, t->height); struct xform xf = XFORM_TRS(.t = crosshair_pos, .s = size); - struct quad quad = quad_mul_xform(QUAD_UNIT_SQUARE_CENTERED, xf); + struct quad quad = xform_mul_quad(xf, QUAD_UNIT_SQUARE_CENTERED); draw_sprite_quad(G.viewport_canvas, DRAW_SPRITE_PARAMS(.sprite = crosshair_tag, .tint = tint), quad); struct rect cursor_clip = RECT_FROM_V2(G.viewport_screen_offset, G.viewport_size);