diff --git a/res/graphics/box.ase b/res/graphics/box.ase index 44dfa89f..6a85b495 100644 --- a/res/graphics/box.ase +++ b/res/graphics/box.ase @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4511b3d43b961486e8a9464be00675c5d488f9b4168f1e97ef679859c4128937 -size 3471 +oid sha256:034e70b0879d645f4253eb2505393d44e36b12081d46238475a29b19c04f0018 +size 4532 diff --git a/res/graphics/gun.ase b/res/graphics/gun.ase index 538f7004..b5132af1 100644 --- a/res/graphics/gun.ase +++ b/res/graphics/gun.ase @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1d152c89738c4c61ed3e7bad4e4d51e107bd5752e0b61ef44fd03ca4606eec23 -size 743 +oid sha256:b2b935778f7355ff04b16fa755b06784271b24f5b9ef8afa43c0a968ca93ac91 +size 684 diff --git a/res/graphics/tile.ase b/res/graphics/tile.ase new file mode 100644 index 00000000..41422f8b --- /dev/null +++ b/res/graphics/tile.ase @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e21a8acdf81686d7beadc8bec5544e8fdaa55830789713a69c049750b2ceff01 +size 672 diff --git a/src/common.h b/src/common.h index 02a678d1..b7cfe6f9 100644 --- a/src/common.h +++ b/src/common.h @@ -288,7 +288,7 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t); #define RGBA_F(r, g, b, a) RGBA(_RGB_U8_FROM_F((r)), _RGB_U8_FROM_F((g)), _RGB_U8_FROM_F((b)), _RGB_U8_FROM_F((a))) #define RGB_F(r, g, b) RGBA_F((r), (g), (b), 1.f) -#define ALPHA_F(color, a) ((color) & 0xFFFFFF00) | _RGB_U8_FROM_F((a)) +#define ALPHA_F(color, a) ((color) & 0x00FFFFFF) | (_RGB_U8_FROM_F((a)) << 24) /* Palette color defines */ #define COLOR_WHITE RGB(0xE6, 0xE8, 0xE6) diff --git a/src/config.h b/src/config.h index b7ac6444..e3bee223 100644 --- a/src/config.h +++ b/src/config.h @@ -39,8 +39,8 @@ #define SPACE_CELL_BINS_SQRT (64) #define SPACE_CELL_SIZE (1) -#define SIM_TILES_PER_UNIT_SQRT (2) -#define SIM_TILES_PER_CHUNK_SQRT (1) +#define SIM_TILES_PER_UNIT_SQRT (4) +#define SIM_TILES_PER_CHUNK_SQRT (16) #define SIM_TICKS_PER_SECOND 50 //#define SIM_TIMESCALE 1 diff --git a/src/math.h b/src/math.h index d0b44b2f..2f3be9a2 100644 --- a/src/math.h +++ b/src/math.h @@ -1076,6 +1076,14 @@ INLINE struct v2 xform_mul_v2(struct xform xf, struct v2 v) return res; } +INLINE struct xform xform_basis(struct xform xf) +{ + struct xform res = ZI; + res.bx = xf.bx; + res.by = xf.by; + return res; +} + INLINE struct v2 xform_basis_invert_mul_v2(struct xform xf, struct v2 v) { struct xform inv = xform_invert(xf); diff --git a/src/phys.c b/src/phys.c index 7bdbbef2..8c2d9fee 100644 --- a/src/phys.c +++ b/src/phys.c @@ -6,6 +6,9 @@ #include "space.h" #include "uid.h" +#define CONTACT_SPRING_HZ 25 +#define CONTACT_SPRING_DAMP 10 + /* ========================== * * Contact * ========================== */ @@ -460,9 +463,7 @@ void phys_solve_contacts(struct phys_step_ctx *ctx, f32 dt, b32 apply_bias) velocity_bias = separation / dt; } else if (apply_bias) { /* Soft constraint */ - const f32 spring_hz = 25; - const f32 spring_damp = 10; - struct math_spring_result softness = math_spring(spring_hz, spring_damp, dt); + struct math_spring_result softness = math_spring(CONTACT_SPRING_HZ, CONTACT_SPRING_DAMP, dt); f32 pushout_velocity = constraint->pushout_velocity; mass_scale = softness.mass_scale; impulse_scale = softness.impulse_scale; diff --git a/src/sim.h b/src/sim.h index d6909caa..b259acab 100644 --- a/src/sim.h +++ b/src/sim.h @@ -8,6 +8,7 @@ #define SIM_LAYER_BULLETS (-200) #define SIM_LAYER_TRACERS (-100) #define SIM_LAYER_SHOULDERS (0) +#define SIM_LAYER_WALLS (100) /* Relative layers */ #define SIM_LAYER_RELATIVE_DEFAULT (0) @@ -143,9 +144,10 @@ enum sim_control_flag { SIM_CONTROL_FLAG_CLEAR_ALL = 1 << 4, SIM_CONTROL_FLAG_SPAWN1_TEST = 1 << 5, SIM_CONTROL_FLAG_SPAWN2_TEST = 1 << 6, - SIM_CONTROL_FLAG_TILE_TEST = 1 << 7, - SIM_CONTROL_FLAG_EXPLODE_TEST = 1 << 8, - SIM_CONTROL_FLAG_TELEPORT_TEST = 1 << 9, + SIM_CONTROL_FLAG_SPAWN3_TEST = 1 << 7, + SIM_CONTROL_FLAG_TILE_TEST = 1 << 8, + SIM_CONTROL_FLAG_EXPLODE_TEST = 1 << 9, + SIM_CONTROL_FLAG_TELEPORT_TEST = 1 << 10, }; struct sim_control { diff --git a/src/sim_ent.c b/src/sim_ent.c index cbdae81c..fb8ea438 100644 --- a/src/sim_ent.c +++ b/src/sim_ent.c @@ -499,6 +499,20 @@ void sim_ent_set_local_xform(struct sim_ent *ent, struct xform xf) * Ent movement * ========================== */ +void sim_ent_set_linear_velocity(struct sim_ent *ent, struct v2 velocity) +{ + if (sim_ent_has_prop(ent, SEPROP_KINEMATIC) || sim_ent_has_prop(ent, SEPROP_DYNAMIC)) { + ent->linear_velocity = v2_clamp_len(velocity, SIM_MAX_LINEAR_VELOCITY); + } +} + +void sim_ent_set_angular_velocity(struct sim_ent *ent, f32 velocity) +{ + if (sim_ent_has_prop(ent, SEPROP_KINEMATIC) || sim_ent_has_prop(ent, SEPROP_DYNAMIC)) { + ent->angular_velocity = clamp_f32(velocity, -SIM_MAX_ANGULAR_VELOCITY, SIM_MAX_ANGULAR_VELOCITY); + } +} + void sim_ent_apply_linear_impulse(struct sim_ent *ent, struct v2 impulse, struct v2 point) { if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) { diff --git a/src/sim_ent.h b/src/sim_ent.h index 27993cbd..4668925a 100644 --- a/src/sim_ent.h +++ b/src/sim_ent.h @@ -522,8 +522,8 @@ void sim_ent_set_xform(struct sim_ent *ent, struct xform xf); void sim_ent_set_local_xform(struct sim_ent *ent, struct xform xf); /* Movement */ -INLINE void sim_ent_set_linear_velocity(struct sim_ent *ent, struct v2 velocity) { ent->linear_velocity = v2_clamp_len(velocity, SIM_MAX_LINEAR_VELOCITY); } -INLINE void sim_ent_set_angular_velocity(struct sim_ent *ent, f32 velocity) { ent->angular_velocity = clamp_f32(velocity, -SIM_MAX_ANGULAR_VELOCITY, SIM_MAX_ANGULAR_VELOCITY); } +void sim_ent_set_linear_velocity(struct sim_ent *ent, struct v2 velocity); +void sim_ent_set_angular_velocity(struct sim_ent *ent, f32 velocity); void sim_ent_apply_linear_impulse(struct sim_ent *ent, struct v2 impulse, struct v2 world_point); void sim_ent_apply_linear_impulse_to_center(struct sim_ent *ent, struct v2 impulse); void sim_ent_apply_force_to_center(struct sim_ent *ent, struct v2 force); diff --git a/src/sim_step.c b/src/sim_step.c index 985990f6..f1abd9c6 100644 --- a/src/sim_step.c +++ b/src/sim_step.c @@ -51,6 +51,22 @@ void sim_accel_reset(struct sim_snapshot *ss, struct sim_accel *accel) /* TODO: Remove this */ +INTERNAL struct sim_ent *spawn_test_smg(struct sim_ent *parent) +{ + struct sim_ent *e = sim_ent_alloc_sync_src(parent); + e->sprite = sprite_tag_from_path(LIT("res/graphics/gun.ase")); + + sim_ent_enable_prop(e, SEPROP_ATTACHED); + e->attach_slice = LIT("attach.wep"); + e->layer = SIM_LAYER_RELATIVE_WEAPON; + + sim_ent_enable_prop(e, SEPROP_WEAPON_SMG); + e->primary_fire_delay = 1.0f / 10.0f; + e->secondary_fire_delay = 1.0f / 10.0f; + + return e; +} + INTERNAL struct sim_ent *spawn_test_launcher(struct sim_ent *parent) { struct sim_ent *e = sim_ent_alloc_sync_src(parent); @@ -161,6 +177,7 @@ INTERNAL struct sim_ent *spawn_test_employee(struct sim_ent *parent) /* Player weapon */ if (employee->valid) { + (UNUSED)spawn_test_smg; (UNUSED)spawn_test_launcher; (UNUSED)spawn_test_chucker; @@ -231,22 +248,25 @@ INTERNAL void spawn_test_entities2(struct sim_ent *parent, struct v2 pos) { (UNUSED)pos; - /* Big box */ + /* Small Box */ #if 1 { //struct sim_ent *e = sim_ent_alloc_local(parent); struct sim_ent *e = sim_ent_alloc_sync_src(parent); f32 r = 0; - struct v2 size = V2(0.5, 0.25); + struct v2 size = V2(1, 0.5); struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size); sim_ent_set_xform(e, xf); e->sprite = sprite_tag_from_path(LIT("res/graphics/box.ase")); - e->sprite_collider_slice = LIT("shape"); e->layer = SIM_LAYER_SHOULDERS; + e->sprite_tint = ALPHA_F(COLOR_BLUE, 0.75); + sim_ent_enable_prop(e, SEPROP_SOLID); + struct quad collider_quad = quad_from_rect(RECT(-0.5, -0.5, 1, 1)); + e->local_collider = collider_from_quad(collider_quad); sim_ent_enable_prop(e, SEPROP_DYNAMIC); e->mass_unscaled = 100; @@ -282,6 +302,66 @@ INTERNAL void spawn_test_entities2(struct sim_ent *parent, struct v2 pos) #endif } +INTERNAL void spawn_test_entities3(struct sim_ent *parent, struct v2 pos) +{ + (UNUSED)pos; + + /* Heavy box */ + { + //struct sim_ent *e = sim_ent_alloc_local(parent); + struct sim_ent *e = sim_ent_alloc_sync_src(parent); + + f32 r = 0; + struct v2 size = V2(1, 1); + struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size); + sim_ent_set_xform(e, xf); + + e->sprite = sprite_tag_from_path(LIT("res/graphics/box.ase")); + e->layer = SIM_LAYER_SHOULDERS; + + e->sprite_tint = COLOR_RED; + + sim_ent_enable_prop(e, SEPROP_SOLID); + struct quad collider_quad = quad_from_rect(RECT(-0.5, -0.5, 1, 1)); + e->local_collider = collider_from_quad(collider_quad); + } +} + +INTERNAL void spawn_test_tile(struct sim_ent *parent, struct v2 cursor_pos) +{ + struct sim_ent *e = sim_ent_alloc_sync_src(parent); + + i32 sign_x = (cursor_pos.x >= 0) - (cursor_pos.x < 0); + i32 sign_y = (cursor_pos.y >= 0) - (cursor_pos.y < 0); + struct v2i32 tile_index = V2I32(cursor_pos.x * SIM_TILES_PER_UNIT_SQRT, cursor_pos.y * SIM_TILES_PER_UNIT_SQRT); + cursor_pos.x -= sign_x < 0; + cursor_pos.y -= sign_y < 0; + + struct v2 tile_size = V2(1.f / SIM_TILES_PER_UNIT_SQRT, 1.f / SIM_TILES_PER_UNIT_SQRT); + + struct v2 pos = V2((f32)tile_index.x / SIM_TILES_PER_UNIT_SQRT, (f32)tile_index.y / SIM_TILES_PER_UNIT_SQRT); + pos = v2_add(pos, v2_mul(V2(tile_size.x * sign_x, tile_size.y * sign_y), 0.5)); + + struct xform xf = XFORM_TRS(.t = pos); + sim_ent_set_xform(e, xf); + + e->layer = SIM_LAYER_WALLS; + e->sprite = sprite_tag_from_path(LIT("res/graphics/tile.ase")); + e->sprite_tint = COLOR_RED; + + { + struct sprite_scope *scope = sprite_scope_begin(); + struct sprite_sheet *sheet = sprite_sheet_from_tag_await(scope, e->sprite); + e->sprite_local_xform = XFORM_TRS(.s = v2_div(sheet->frame_size, IMAGE_PIXELS_PER_UNIT)); + sprite_scope_end(scope); + } + + sim_ent_enable_prop(e, SEPROP_SOLID); + struct quad collider_quad = quad_from_rect(RECT(-tile_size.x / 2, -tile_size.y / 2, tile_size.y, tile_size.y)); + e->local_collider = collider_from_quad(collider_quad); + +} + INTERNAL void test_clear_level(struct sim_step_ctx *ctx) { struct sim_snapshot *world = ctx->world; @@ -634,6 +714,16 @@ void sim_step(struct sim_step_ctx *ctx) spawn_test_entities2(root, pos); } } + if (flags & SIM_CONTROL_FLAG_SPAWN3_TEST) { + logf_info("Spawn1 (test)"); + u32 count = 1; + f32 spread = 0; + for (u32 j = 0; j < count; ++j) { + struct v2 pos = player->player_cursor_pos; + pos.y += (((f32)j / (f32)count) - 0.5) * spread; + spawn_test_entities3(root, pos); + } + } if (flags & SIM_CONTROL_FLAG_EXPLODE_TEST) { logf_info("Explosion (test)"); spawn_test_explosion(root, player->player_cursor_pos, 100, 2); @@ -669,6 +759,8 @@ void sim_step(struct sim_step_ctx *ctx) new_data.text[tile_index] = SIM_TILE_KIND_TEST; sim_ent_set_tile_chunk_data(chunk_ent, new_data); } +#else + spawn_test_tile(root, player->player_cursor_pos); #endif } } @@ -792,6 +884,7 @@ void sim_step(struct sim_step_ctx *ctx) ent->animation_frame = frame_index; } +#if 0 /* Update sprite local xform */ { struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, LIT("pivot"), ent->animation_frame); @@ -806,6 +899,7 @@ void sim_step(struct sim_step_ctx *ctx) xf = xform_translated(xf, v2_neg(slice.center)); ent->sprite_local_xform = xf; } +#endif /* Update collider from sprite */ if (ent->sprite_collider_slice.len > 0) { @@ -1050,9 +1144,9 @@ void sim_step(struct sim_step_ctx *ctx) def.e0 = ent->id; def.e1 = target->id; def.xf = xf0_to_xf1; - def.linear_spring_hz = 5; + def.linear_spring_hz = 10; def.linear_spring_damp = 0.3; - def.angular_spring_hz = 5; + def.angular_spring_hz = 10; def.angular_spring_damp = 0.3; joint_ent->weld_joint_data = phys_weld_joint_from_def(def); ent->chucker_joint = joint_ent->id; @@ -1082,6 +1176,7 @@ void sim_step(struct sim_step_ctx *ctx) joint_ent->mass_unscaled = F32_INFINITY; joint_ent->inertia_unscaled = F32_INFINITY; sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE); + sim_ent_enable_prop(joint_ent, SEPROP_KINEMATIC); ent->move_joint = joint_ent->id; sim_ent_enable_prop(joint_ent, SEPROP_MOTOR_JOINT); diff --git a/src/user.c b/src/user.c index 30a8a04d..2265123e 100644 --- a/src/user.c +++ b/src/user.c @@ -144,7 +144,7 @@ GLOBAL READONLY enum user_bind_kind g_binds[SYS_BTN_COUNT] = { /* Testing */ - [SYS_BTN_M4] = USER_BIND_KIND_TILE_TEST, + [SYS_BTN_Z] = USER_BIND_KIND_TILE_TEST, [SYS_BTN_M5] = USER_BIND_KIND_DEBUG_DRAG, [SYS_BTN_M4] = USER_BIND_KIND_DEBUG_DELETE, @@ -153,6 +153,7 @@ GLOBAL READONLY enum user_bind_kind g_binds[SYS_BTN_COUNT] = { [SYS_BTN_C] = USER_BIND_KIND_DEBUG_CLEAR, [SYS_BTN_1] = USER_BIND_KIND_DEBUG_SPAWN1, [SYS_BTN_2] = USER_BIND_KIND_DEBUG_SPAWN2, + [SYS_BTN_3] = USER_BIND_KIND_DEBUG_SPAWN3, [SYS_BTN_N] = USER_BIND_KIND_DEBUG_STEP, [SYS_BTN_Q] = USER_BIND_KIND_DEBUG_FOLLOW, [SYS_BTN_F1] = USER_BIND_KIND_DEBUG_PAUSE, @@ -1036,6 +1037,8 @@ INTERNAL void user_update(void) struct xform parent_xf = sim_ent_get_xform(parent); b32 skip_debug_draw = !G.debug_camera && ent == local_camera; + skip_debug_draw = skip_debug_draw || sim_ent_has_prop(ent, SEPROP_MOTOR_JOINT); + b32 skip_debug_draw_transform = sim_ent_has_prop(ent, SEPROP_CAMERA); skip_debug_draw_transform = true; @@ -1103,7 +1106,7 @@ INTERNAL void user_update(void) if (G.debug_draw && !skip_debug_draw) { struct temp_arena temp = arena_temp_begin(scratch.arena); - if (sim_ent_has_prop(ent, SEPROP_DYNAMIC) || sim_ent_has_prop(ent, SEPROP_KINEMATIC)) { + if (sim_ent_has_prop(ent, SEPROP_KINEMATIC) || sim_ent_has_prop(ent, SEPROP_DYNAMIC)) { debug_draw_movement(ent); } @@ -1627,6 +1630,7 @@ INTERNAL void user_update(void) struct bind_state clear_state = G.bind_states[USER_BIND_KIND_DEBUG_CLEAR]; struct bind_state spawn1_state = G.bind_states[USER_BIND_KIND_DEBUG_SPAWN1]; struct bind_state spawn2_state = G.bind_states[USER_BIND_KIND_DEBUG_SPAWN2]; + struct bind_state spawn3_state = G.bind_states[USER_BIND_KIND_DEBUG_SPAWN3]; struct bind_state pause_state = G.bind_states[USER_BIND_KIND_DEBUG_PAUSE]; struct bind_state step_state = G.bind_states[USER_BIND_KIND_DEBUG_STEP]; struct bind_state tile_state = G.bind_states[USER_BIND_KIND_TILE_TEST]; @@ -1654,6 +1658,9 @@ INTERNAL void user_update(void) if (spawn2_state.num_presses_and_repeats) { control.flags |= SIM_CONTROL_FLAG_SPAWN2_TEST; } + if (spawn3_state.num_presses_and_repeats) { + control.flags |= SIM_CONTROL_FLAG_SPAWN3_TEST; + } if (tile_state.num_presses_and_repeats) { control.flags |= SIM_CONTROL_FLAG_TILE_TEST; } diff --git a/src/user.h b/src/user.h index eeabb1ee..959ef7e7 100644 --- a/src/user.h +++ b/src/user.h @@ -31,6 +31,7 @@ enum user_bind_kind { USER_BIND_KIND_DEBUG_CLEAR, USER_BIND_KIND_DEBUG_SPAWN1, USER_BIND_KIND_DEBUG_SPAWN2, + USER_BIND_KIND_DEBUG_SPAWN3, USER_BIND_KIND_DEBUG_FOLLOW, USER_BIND_KIND_DEBUG_DRAW, USER_BIND_KIND_DEBUG_CAMERA,