cmd_kind. fix aabb draw

This commit is contained in:
jacob 2025-03-01 09:39:00 -06:00
parent d16fdcd260
commit 0b92a1e8a4
8 changed files with 156 additions and 91 deletions

View File

@ -23,10 +23,10 @@
#define RESOURCES_EMBEDDED (!DEVELOPER) #define RESOURCES_EMBEDDED (!DEVELOPER)
#define RESOURCE_RELOADING (DEVELOPER && !RESOURCES_EMBEDDED) #define RESOURCE_RELOADING (DEVELOPER && !RESOURCES_EMBEDDED)
#define DEFAULT_CAMERA_WIDTH (7.0) #define DEFAULT_CAMERA_WIDTH (15.0)
#define DEFAULT_CAMERA_HEIGHT (DEFAULT_CAMERA_WIDTH / (16.0 / 9.0)) #define DEFAULT_CAMERA_HEIGHT (DEFAULT_CAMERA_WIDTH / (16.0 / 9.0))
#define IMAGE_PIXELS_PER_UNIT 256.0 #define IMAGE_PIXELS_PER_UNIT 128.0
/* How many ticks back in time should the user blend between? /* How many ticks back in time should the user blend between?
* <Delay> = <USER_INTERP_RATIO> * <Tick interval> * <Delay> = <USER_INTERP_RATIO> * <Tick interval>

View File

@ -1154,9 +1154,9 @@ INLINE struct quad quad_from_aabb(struct aabb aabb)
{ {
struct quad res; struct quad res;
res.p0 = V2(aabb.p0.x, aabb.p0.y); /* Top left */ res.p0 = V2(aabb.p0.x, aabb.p0.y); /* Top left */
res.p0 = V2(aabb.p1.x, aabb.p0.y); /* Top right */ res.p1 = V2(aabb.p1.x, aabb.p0.y); /* Top right */
res.p0 = V2(aabb.p1.x, aabb.p1.y); /* Bottom right */ res.p2 = V2(aabb.p1.x, aabb.p1.y); /* Bottom right */
res.p0 = V2(aabb.p0.x, aabb.p1.y); /* Bottom left */ res.p3 = V2(aabb.p0.x, aabb.p1.y); /* Bottom left */
return res; return res;
} }
@ -1197,9 +1197,9 @@ INLINE struct quad quad_round(struct quad quad)
{ {
struct quad res; struct quad res;
res.p0 = v2_round(quad.p0); res.p0 = v2_round(quad.p0);
res.p0 = v2_round(quad.p1); res.p1 = v2_round(quad.p1);
res.p0 = v2_round(quad.p2); res.p2 = v2_round(quad.p2);
res.p0 = v2_round(quad.p3); res.p3 = v2_round(quad.p3);
return res; return res;
} }
@ -1207,9 +1207,9 @@ INLINE struct quad quad_floor(struct quad quad)
{ {
struct quad res; struct quad res;
res.p0 = v2_floor(quad.p0); res.p0 = v2_floor(quad.p0);
res.p0 = v2_floor(quad.p1); res.p1 = v2_floor(quad.p1);
res.p0 = v2_floor(quad.p2); res.p2 = v2_floor(quad.p2);
res.p0 = v2_floor(quad.p3); res.p3 = v2_floor(quad.p3);
return res; return res;
} }

View File

@ -590,7 +590,6 @@ struct sim_snapshot *sim_snapshot_alloc_from_lerp(struct sim_client *client, str
} }
} }
return ss; return ss;
} }

View File

@ -150,6 +150,13 @@ struct sim_control {
u32 flags; u32 flags;
}; };
enum sim_cmd_kind {
SIM_CMD_KIND_INVALID,
SIM_CMD_KIND_CONTROL,
SIM_CMD_KIND_CHAT
};
struct sim_ent_bin; struct sim_ent_bin;
struct sim_snapshot { struct sim_snapshot {

View File

@ -149,7 +149,7 @@ void sim_ent_release_all_with_prop(struct sim_snapshot *ss, enum sim_ent_prop pr
* child entities will be released along with parent anyway) */ * child entities will be released along with parent anyway) */
for (u64 i = 0; i < ents_to_release_count; ++i) { for (u64 i = 0; i < ents_to_release_count; ++i) {
struct sim_ent *ent = ents_to_release[i]; struct sim_ent *ent = ents_to_release[i];
if (ent->valid && !ent->is_root && !sim_ent_has_prop(ent, SIM_ENT_PROP_CMD_CONTROL) && !sim_ent_has_prop(ent, SIM_ENT_PROP_PLAYER)) { if (ent->valid && !ent->is_root && !sim_ent_has_prop(ent, SIM_ENT_PROP_CMD) && !sim_ent_has_prop(ent, SIM_ENT_PROP_PLAYER)) {
sim_ent_release(ent); sim_ent_release(ent);
} }
} }

View File

@ -22,7 +22,7 @@ enum sim_ent_prop {
SIM_ENT_PROP_PLAYER, SIM_ENT_PROP_PLAYER,
SIM_ENT_PROP_PLAYER_IS_MASTER, SIM_ENT_PROP_PLAYER_IS_MASTER,
SIM_ENT_PROP_CMD_CONTROL, SIM_ENT_PROP_CMD,
SIM_ENT_PROP_PHYSICAL_DYNAMIC, SIM_ENT_PROP_PHYSICAL_DYNAMIC,
SIM_ENT_PROP_PHYSICAL_KINEMATIC, SIM_ENT_PROP_PHYSICAL_KINEMATIC,
@ -125,13 +125,27 @@ struct sim_ent {
/* ====================================================================== */ /* ====================================================================== */
/* Cmd */ /* Cmd */
/* SIM_ENT_PROP_CMD_CONTROL */ /* SIM_ENT_PROP_CMD */
enum sim_cmd_kind cmd_kind;
struct sim_ent_id cmd_player;
/* FIXME: Lerp */ /* FIXME: Lerp */
struct sim_ent_id cmd_player; /* Control cmd */
struct sim_control cmd_control; struct sim_control cmd_control;
struct sim_ent_id cmd_hovered_ent; struct sim_ent_id cmd_control_hovered_ent;
/* Chat cmd */
//struct string cmd_chat_msg;
/* ====================================================================== */
/* Chat */
/* SIM_ENT_PROP_CHAT */
struct sim_ent_id chat_player;
//struct string chat_msg;
/* ====================================================================== */ /* ====================================================================== */
/* Client */ /* Client */

View File

@ -129,13 +129,13 @@ INTERNAL void spawn_test_entities(struct sim_step_ctx *ctx, struct v2 offset)
#endif #endif
} }
INTERNAL struct sim_ent *spawn_test_player(struct sim_step_ctx *ctx) INTERNAL struct sim_ent *spawn_test_employee(struct sim_step_ctx *ctx)
{ {
struct sim_snapshot *world = ctx->world; struct sim_snapshot *world = ctx->world;
struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID); struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID);
/* Player */ /* Player */
struct sim_ent *player_ent = sim_ent_nil(); struct sim_ent *employee = sim_ent_nil();
//if (!ctx->extra_spawn) { //if (!ctx->extra_spawn) {
{ {
@ -165,7 +165,7 @@ INTERNAL struct sim_ent *spawn_test_player(struct sim_step_ctx *ctx)
e->local_collider.points[0] = V2(0, 0); e->local_collider.points[0] = V2(0, 0);
e->local_collider.count = 1; e->local_collider.count = 1;
e->local_collider.radius = 0.15f; e->local_collider.radius = 0.30f;
struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size); struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
//xf.bx.y = -1.f; //xf.bx.y = -1.f;
@ -178,20 +178,20 @@ INTERNAL struct sim_ent *spawn_test_player(struct sim_step_ctx *ctx)
e->friction = 0; e->friction = 0;
//e->control_force = 500; //e->control_force = 500;
e->control_force = 500; e->control_force = 1200;
e->control_force_max_speed = 4; e->control_force_max_speed = 8;
//e->control_torque = 5000; //e->control_torque = 5000;
e->control_torque = F32_INFINITY; e->control_torque = F32_INFINITY;
sim_ent_enable_prop(e, SIM_ENT_PROP_PHYSICAL_DYNAMIC); sim_ent_enable_prop(e, SIM_ENT_PROP_PHYSICAL_DYNAMIC);
player_ent = e; employee = e;
} }
/* Player weapon */ /* Player weapon */
if (player_ent->valid) { if (employee->valid) {
struct sim_ent *e = sim_ent_alloc_sync_src(player_ent); struct sim_ent *e = sim_ent_alloc_sync_src(employee);
e->sprite = sprite_tag_from_path(LIT("res/graphics/gun.ase")); e->sprite = sprite_tag_from_path(LIT("res/graphics/gun.ase"));
sim_ent_enable_prop(e, SIM_ENT_PROP_ATTACHED); sim_ent_enable_prop(e, SIM_ENT_PROP_ATTACHED);
@ -202,24 +202,24 @@ INTERNAL struct sim_ent *spawn_test_player(struct sim_step_ctx *ctx)
e->trigger_delay = 1.0f / 10.0f; e->trigger_delay = 1.0f / 10.0f;
//e->trigger_delay = 1.0f / 100.0f; //e->trigger_delay = 1.0f / 100.0f;
player_ent->equipped = e->id; employee->equipped = e->id;
} }
return player_ent; return employee;
} }
INTERNAL struct sim_ent *spawn_test_player_camera(struct sim_snapshot *world, struct sim_ent *player_ent) INTERNAL struct sim_ent *spawn_test_camera(struct sim_snapshot *world, struct sim_ent *follow)
{ {
struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID); struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID);
struct sim_ent *camera_ent = sim_ent_nil(); struct sim_ent *camera_ent = sim_ent_nil();
if (player_ent->valid) { if (follow->valid) {
camera_ent = sim_ent_alloc_sync_src(root); camera_ent = sim_ent_alloc_sync_src(root);
sim_ent_set_xform(camera_ent, XFORM_IDENT); sim_ent_set_xform(camera_ent, XFORM_IDENT);
sim_ent_enable_prop(camera_ent, SIM_ENT_PROP_CAMERA); sim_ent_enable_prop(camera_ent, SIM_ENT_PROP_CAMERA);
sim_ent_enable_prop(camera_ent, SIM_ENT_PROP_CAMERA_ACTIVE); sim_ent_enable_prop(camera_ent, SIM_ENT_PROP_CAMERA_ACTIVE);
camera_ent->camera_follow = player_ent->id; camera_ent->camera_follow = follow->id;
f32 width = (f32)DEFAULT_CAMERA_WIDTH; f32 width = (f32)DEFAULT_CAMERA_WIDTH;
f32 height = (f32)DEFAULT_CAMERA_HEIGHT; f32 height = (f32)DEFAULT_CAMERA_HEIGHT;
@ -419,7 +419,7 @@ void sim_step(struct sim_step_ctx *ctx)
/* Mark incoming cmds with correct client */ /* Mark incoming cmds with correct client */
for (u64 i = 0; i < world->num_ents_reserved; ++i) { for (u64 i = 0; i < world->num_ents_reserved; ++i) {
struct sim_ent *ent = &world->ents[i]; struct sim_ent *ent = &world->ents[i];
if (ent->valid && sim_ent_has_prop(ent, SIM_ENT_PROP_CMD_CONTROL) && sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_DST)) { if (ent->valid && sim_ent_has_prop(ent, SIM_ENT_PROP_CMD) && sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_DST)) {
ent->cmd_player = ent->owner; ent->cmd_player = ent->owner;
} }
} }
@ -428,7 +428,7 @@ void sim_step(struct sim_step_ctx *ctx)
if (!is_master) { if (!is_master) {
for (u64 i = 0; i < world->num_ents_reserved; ++i) { for (u64 i = 0; i < world->num_ents_reserved; ++i) {
struct sim_ent *ent = &world->ents[i]; struct sim_ent *ent = &world->ents[i];
if (sim_ent_is_valid_and_active(ent) && sim_ent_has_prop(ent, SIM_ENT_PROP_CMD_CONTROL)) { if (sim_ent_is_valid_and_active(ent) && sim_ent_has_prop(ent, SIM_ENT_PROP_CMD)) {
if (!sim_ent_id_is_nil(ent->cmd_player) && sim_ent_id_eq(ent->cmd_player, world->local_player)) { if (!sim_ent_id_is_nil(ent->cmd_player) && sim_ent_id_eq(ent->cmd_player, world->local_player)) {
sim_ent_enable_prop(ent, SIM_ENT_PROP_SYNC_SRC); sim_ent_enable_prop(ent, SIM_ENT_PROP_SYNC_SRC);
} }
@ -485,64 +485,99 @@ void sim_step(struct sim_step_ctx *ctx)
struct sim_ent *cmd_ent = &world->ents[ent_index]; struct sim_ent *cmd_ent = &world->ents[ent_index];
if (!is_master && !sim_ent_should_simulate(cmd_ent)) continue; if (!is_master && !sim_ent_should_simulate(cmd_ent)) continue;
if (sim_ent_has_prop(cmd_ent, SIM_ENT_PROP_CMD_CONTROL)) { if (sim_ent_has_prop(cmd_ent, SIM_ENT_PROP_CMD)) {
struct sim_ent *player = sim_ent_from_id(world, cmd_ent->cmd_player); struct sim_ent *player = sim_ent_from_id(world, cmd_ent->cmd_player);
if (sim_ent_should_simulate(player)) { if (sim_ent_should_simulate(player)) {
b32 persist_cmd = false;
if (!is_master && !sim_ent_id_eq(player->id, world->local_player)) { if (!is_master && !sim_ent_id_eq(player->id, world->local_player)) {
/* We are not the master and the command is not our own, skip processing */ /* We are not the master and the command is not our own, skip processing */
continue; continue;
} }
/* Process control cmd for client */ enum sim_cmd_kind kind = cmd_ent->cmd_kind;
struct sim_control old_control = player->player_control; switch (kind) {
struct sim_control *control = &player->player_control; case SIM_CMD_KIND_CONTROL:
*control = cmd_ent->cmd_control;
{
player->player_dbg_drag_start = false;
player->player_dbg_drag_stop = false;
if (v2_len_sq(control->move) > 1) {
/* Cap movement vector magnitude at 1 */
control->move = v2_norm(control->move);
}
/* Determine cursor pos from focus */
{ {
struct sim_ent_id player_control_ent_id = player->player_control_ent; /* Player's will send control cmds a lot, so keep it around to prevent re-creating it each time */
struct sim_ent *player_control_ent = sim_ent_from_id(world, player_control_ent_id); persist_cmd = true;
if (player_control_ent->valid || sim_ent_id_is_nil(player_control_ent_id)) {
/* Only update cursor pos if focus ent is valid (or nil) */
player->player_cursor_pos = v2_add(sim_ent_get_xform(player_control_ent).og, player->player_control.focus);
}
}
player->player_hovered_ent = cmd_ent->cmd_hovered_ent; /* Process control cmd for client */
struct sim_control old_control = player->player_control;
struct sim_control *control = &player->player_control;
*control = cmd_ent->cmd_control;
{
player->player_dbg_drag_start = false;
player->player_dbg_drag_stop = false;
u32 flags = control->flags; if (v2_len_sq(control->move) > 1) {
if (flags & SIM_CONTROL_FLAG_DRAG) { /* Cap movement vector magnitude at 1 */
if (!(old_control.flags & SIM_CONTROL_FLAG_DRAG)) { control->move = v2_norm(control->move);
player->player_dbg_drag_start = true; }
}
} else { /* Determine cursor pos from focus */
if (old_control.flags & SIM_CONTROL_FLAG_DRAG) { {
player->player_dbg_drag_stop = true; struct sim_ent_id player_control_ent_id = player->player_control_ent;
} struct sim_ent *player_control_ent = sim_ent_from_id(world, player_control_ent_id);
} if (player_control_ent->valid || sim_ent_id_is_nil(player_control_ent_id)) {
if (flags & SIM_CONTROL_FLAG_CLEAR_ALL) { /* Only update cursor pos if focus ent is valid (or nil) */
if (is_master && !(old_control.flags & SIM_CONTROL_FLAG_CLEAR_ALL)) { player->player_cursor_pos = v2_add(sim_ent_get_xform(player_control_ent).og, player->player_control.focus);
test_clear_level(ctx); }
} }
}
if (flags & SIM_CONTROL_FLAG_SPAWN_TEST) { player->player_hovered_ent = cmd_ent->cmd_control_hovered_ent;
if (!(old_control.flags & SIM_CONTROL_FLAG_SPAWN_TEST)) {
logf_info("Spawning (test)"); u32 flags = control->flags;
u32 count = 1; if (flags & SIM_CONTROL_FLAG_DRAG) {
f32 spread = 1; if (!(old_control.flags & SIM_CONTROL_FLAG_DRAG)) {
for (u32 j = 0; j < count; ++j) { player->player_dbg_drag_start = true;
spawn_test_entities(ctx, V2(0, (((f32)j / (f32)count) - 0.5) * spread)); }
} else {
if (old_control.flags & SIM_CONTROL_FLAG_DRAG) {
player->player_dbg_drag_stop = true;
}
}
if (flags & SIM_CONTROL_FLAG_CLEAR_ALL) {
if (is_master && !(old_control.flags & SIM_CONTROL_FLAG_CLEAR_ALL)) {
test_clear_level(ctx);
}
}
if (flags & SIM_CONTROL_FLAG_SPAWN_TEST) {
if (!(old_control.flags & SIM_CONTROL_FLAG_SPAWN_TEST)) {
logf_info("Spawning (test)");
u32 count = 1;
f32 spread = 1;
for (u32 j = 0; j < count; ++j) {
spawn_test_entities(ctx, V2(0, (((f32)j / (f32)count) - 0.5) * spread));
}
}
} }
} }
} } break;
#if 0
case SIM_CMD_KIND_CHAT:
{
struct sim_data_key msg_key = cmd_ent->cmd_chat_msg;
struct string msg = sim_data_from_key(sim_data_store, msg_key);
if (msg.len > 0) {
struct sim_ent *chat_ent = sim_ent_alloc_sync_src(root);
sim_ent_enable_prop(chat_ent, SIM_ENT_PROP_CHAT);
chat_ent->chat_player = player->id;
chat_ent->chat_msg = msg_key;
}
} break;
#endif
default:
{
/* Invalid cmd kind */
ASSERT(false);
} break;
}
/* Release cmd */
if (!persist_cmd) {
sim_ent_enable_prop(cmd_ent, SIM_ENT_PROP_RELEASE);
} }
} }
} }
@ -560,7 +595,7 @@ void sim_step(struct sim_step_ctx *ctx)
/* FIXME: Ents never released when client disconnects */ /* FIXME: Ents never released when client disconnects */
struct sim_ent *control_ent = sim_ent_from_id(world, ent->player_control_ent); struct sim_ent *control_ent = sim_ent_from_id(world, ent->player_control_ent);
if (!control_ent->valid) { if (!control_ent->valid) {
control_ent = spawn_test_player(ctx); control_ent = spawn_test_employee(ctx);
control_ent->predictor = ent->id; control_ent->predictor = ent->id;
sim_ent_enable_prop(control_ent, SIM_ENT_PROP_CONTROLLED); sim_ent_enable_prop(control_ent, SIM_ENT_PROP_CONTROLLED);
ent->player_control_ent = control_ent->id; ent->player_control_ent = control_ent->id;
@ -568,7 +603,7 @@ void sim_step(struct sim_step_ctx *ctx)
} }
struct sim_ent *camera_ent = sim_ent_from_id(world, ent->player_camera_ent); struct sim_ent *camera_ent = sim_ent_from_id(world, ent->player_camera_ent);
if (!camera_ent->valid) { if (!camera_ent->valid) {
camera_ent = spawn_test_player_camera(world, control_ent); camera_ent = spawn_test_camera(world, control_ent);
camera_ent->predictor = ent->id; camera_ent->predictor = ent->id;
ent->player_camera_ent = camera_ent->id; ent->player_camera_ent = camera_ent->id;
} }
@ -991,7 +1026,7 @@ void sim_step(struct sim_step_ctx *ctx)
* Create motor joints from ground friction (gravity) * Create motor joints from ground friction (gravity)
* ========================== */ * ========================== */
#if 0 #if 1
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
struct sim_ent *ent = &world->ents[ent_index]; struct sim_ent *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_should_simulate(ent)) continue;

View File

@ -1851,19 +1851,29 @@ INTERNAL void generate_user_input_cmds(struct sim_client *user_input_client, u64
struct sim_snapshot *user_input_ss = sim_snapshot_alloc(user_input_client, prev_user_input_ss, tick); struct sim_snapshot *user_input_ss = sim_snapshot_alloc(user_input_client, prev_user_input_ss, tick);
struct sim_ent *user_input_root = sim_ent_from_id(user_input_ss, SIM_ENT_ROOT_ID); struct sim_ent *user_input_root = sim_ent_from_id(user_input_ss, SIM_ENT_ROOT_ID);
/* Find / create local control cmd ent */ /* Find / create local control cmd ent */
struct sim_ent *control_cmd_ent = sim_ent_find_first_match_one(user_input_ss, SIM_ENT_PROP_CMD_CONTROL); struct sim_ent *control_cmd = sim_ent_find_first_match_one(user_input_ss, SIM_ENT_PROP_CMD);
if (!control_cmd_ent->valid) { if (!control_cmd->valid) {
control_cmd_ent = sim_ent_alloc_sync_src(user_input_root); control_cmd = sim_ent_alloc_sync_src(user_input_root);
control_cmd_ent->predictor = user_input_ss->local_player; control_cmd->cmd_kind = SIM_CMD_KIND_CONTROL;
sim_ent_enable_prop(control_cmd_ent, SIM_ENT_PROP_CMD_CONTROL); control_cmd->predictor = user_input_client->player_id;
control_cmd_ent->predictor = user_input_client->player_id; sim_ent_enable_prop(control_cmd, SIM_ENT_PROP_CMD);
sim_ent_activate(control_cmd_ent, user_input_ss->tick); sim_ent_activate(control_cmd, user_input_ss->tick);
} }
/* Update local control cmd ent */
{ {
struct sys_lock lock = sys_mutex_lock_e(&G.user_sim_cmd_mutex); struct sys_lock lock = sys_mutex_lock_e(&G.user_sim_cmd_mutex);
control_cmd_ent->cmd_control = G.user_sim_cmd_control; /* Update control cmd */
control_cmd_ent->cmd_hovered_ent = G.user_hovered_ent; {
control_cmd->cmd_control = G.user_sim_cmd_control;
control_cmd->cmd_control_hovered_ent = G.user_hovered_ent;
}
#if 0
/* Create chat cmd */
if (G.user_sim_cmd_chat.len > 0) {
struct sim_ent *chat_cmd = sim_ent_alloc_sync_src(user_input_root);
chat_cmd->cmd_kind = SIM_CMD_KIND_CHAT;
//chat_cmd->chat_msg = ZI
}
#endif
++G.user_sim_cmd_gen; ++G.user_sim_cmd_gen;
sys_mutex_unlock(&lock); sys_mutex_unlock(&lock);
} }