store and calculate mass from unscaled mass instead of density

This commit is contained in:
jacob 2024-08-21 17:17:05 -05:00
parent c461956fb0
commit c4dd372041
5 changed files with 41 additions and 29 deletions

View File

@ -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
};

View File

@ -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) */

View File

@ -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)));

View File

@ -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) {

View File

@ -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);