tile testing

This commit is contained in:
jacob 2025-05-21 13:10:58 -05:00
parent 7c9a07ff94
commit 3a8a66850d
13 changed files with 153 additions and 22 deletions

BIN
res/graphics/box.ase (Stored with Git LFS)

Binary file not shown.

BIN
res/graphics/gun.ase (Stored with Git LFS)

Binary file not shown.

BIN
res/graphics/tile.ase (Stored with Git LFS) Normal file

Binary file not shown.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,