prediction progress
This commit is contained in:
parent
4d419da97b
commit
f0834c203f
@ -488,7 +488,6 @@ struct string32 {
|
||||
};
|
||||
|
||||
#define UID(hi, lo) (struct uid) { .v = U128((hi), (lo)) }
|
||||
#define UID0 (struct uid) { 0 }
|
||||
struct uid {
|
||||
union {
|
||||
u128 v;
|
||||
@ -499,6 +498,7 @@ struct uid {
|
||||
};
|
||||
};
|
||||
INLINE b32 uid_eq(struct uid a, struct uid b) { return u128_eq(a.v, b.v); }
|
||||
INLINE b32 uid_is_zero(struct uid uid) { return u128_eq(uid.v, U128(0, 0)); }
|
||||
|
||||
struct image_rgba {
|
||||
u32 width;
|
||||
|
||||
@ -332,6 +332,8 @@ struct sim_snapshot *sim_snapshot_alloc(struct sim_client *client, struct sim_sn
|
||||
root->handle = SIM_ENT_ROOT_HANDLE;
|
||||
root->valid = true;
|
||||
root->is_root = true;
|
||||
root->mass_unscaled = F32_INFINITY;
|
||||
root->inertia_unscaled = F32_INFINITY;
|
||||
++ss->num_ents_allocated;
|
||||
++ss->num_ents_reserved;
|
||||
} else {
|
||||
|
||||
@ -99,7 +99,7 @@ void sim_ent_release_raw(struct sim_ent *ent)
|
||||
}
|
||||
|
||||
/* Release uid */
|
||||
sim_ent_set_uid(ent, UID0);
|
||||
sim_ent_set_uid(ent, UID(0, 0));
|
||||
|
||||
/* Release */
|
||||
++ent->handle.gen;
|
||||
@ -174,7 +174,7 @@ void sim_ent_set_uid(struct sim_ent *ent, struct uid uid)
|
||||
struct uid old_uid = ent->uid;
|
||||
|
||||
/* Release old from lookup */
|
||||
if (!uid_eq(old_uid, UID0)) {
|
||||
if (!uid_is_zero(old_uid)) {
|
||||
u64 hash = hash_from_uid(old_uid);
|
||||
struct sim_ent_bucket *bucket = &buckets[hash % num_uid_buckets];
|
||||
struct sim_ent *prev = sim_ent_nil();
|
||||
@ -203,7 +203,7 @@ void sim_ent_set_uid(struct sim_ent *ent, struct uid uid)
|
||||
}
|
||||
|
||||
/* Insert new uid into lookup */
|
||||
if (!uid_eq(uid, UID0)) {
|
||||
if (!uid_is_zero(uid)) {
|
||||
u64 hash = hash_from_uid(uid);
|
||||
struct sim_ent_bucket *bucket = &buckets[hash % num_uid_buckets];
|
||||
struct sim_ent *last = sim_ent_from_handle(ss, bucket->last);
|
||||
@ -223,7 +223,7 @@ struct sim_ent *sim_ent_from_uid(struct sim_snapshot *ss, struct uid uid)
|
||||
{
|
||||
struct sim_ent *res = sim_ent_nil();
|
||||
u64 num_buckets = ss->num_uid_buckets;
|
||||
if (num_buckets > 0 && !uid_eq(uid, UID0)) {
|
||||
if (num_buckets > 0 && !uid_is_zero(uid)) {
|
||||
u64 hash = hash_from_uid(uid);
|
||||
struct sim_ent_bucket *bucket = &ss->uid_buckets[hash % num_buckets];
|
||||
for (struct sim_ent *e = sim_ent_from_handle(ss, bucket->first); e->valid; e = sim_ent_from_handle(ss, e->next_in_uid_bucket)) {
|
||||
|
||||
@ -387,6 +387,11 @@ INLINE b32 sim_ent_is_valid_and_active(struct sim_ent *ent)
|
||||
return ent->valid && sim_ent_has_prop(ent, SIM_ENT_PROP_ACTIVE);
|
||||
}
|
||||
|
||||
INLINE b32 sim_ent_should_simulate(struct sim_ent *ent)
|
||||
{
|
||||
return !sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_DST);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Ent functions
|
||||
* ========================== */
|
||||
|
||||
@ -358,7 +358,6 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
sim_ent_release_all_with_prop(world, SIM_ENT_PROP_RELEASE);
|
||||
sim_accel_reset(world, ctx->accel);
|
||||
|
||||
if (ctx->is_master) {
|
||||
/* ========================== *
|
||||
* Activate entities
|
||||
* ========================== */
|
||||
@ -366,6 +365,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||
struct sim_ent *ent = &world->ents[ent_index];
|
||||
if (!ent->valid) continue;
|
||||
if (!sim_ent_should_simulate(ent)) continue;
|
||||
|
||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_ACTIVE)) {
|
||||
u64 atick = ent->activation_tick;
|
||||
@ -375,20 +375,6 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Spawn test entities
|
||||
* ========================== */
|
||||
|
||||
/* TODO: remove this (testing) */
|
||||
/* Initialize entities */
|
||||
{
|
||||
static b32 run = 0;
|
||||
if (!run) {
|
||||
run = 1;
|
||||
spawn_test_entities(world, V2(0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Reset triggered entities
|
||||
* ========================== */
|
||||
@ -396,6 +382,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||
struct sim_ent *ent = &world->ents[ent_index];
|
||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||
if (!sim_ent_should_simulate(ent)) continue;
|
||||
|
||||
if (sim_ent_has_prop(ent, SIM_ENT_PROP_TRIGGER_NEXT_TICK)) {
|
||||
sim_ent_disable_prop(ent, SIM_ENT_PROP_TRIGGER_NEXT_TICK);
|
||||
@ -416,6 +403,11 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
if (sim_ent_has_prop(cmd_ent, SIM_ENT_PROP_CMD_CONTROL)) {
|
||||
struct sim_ent *client_ent = sim_ent_from_handle(world, cmd_ent->cmd_client);
|
||||
if (sim_ent_is_valid_and_active(client_ent)) {
|
||||
if (!ctx->is_master && !uid_eq(client_ent->uid, world->local_client_ent_uid)) {
|
||||
/* We are not the master and the command is not our own, skip processing */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Process control cmd for client */
|
||||
struct sim_control old_control = client_ent->client_control;
|
||||
struct sim_control *control = &client_ent->client_control;
|
||||
@ -476,6 +468,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
* Create client player ents
|
||||
* ========================== */
|
||||
|
||||
if (ctx->is_master) {
|
||||
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
|
||||
struct sim_ent *ent = &world->ents[i];
|
||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||
@ -495,6 +488,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Update entity control from client control
|
||||
@ -503,6 +497,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||
struct sim_ent *ent = &world->ents[ent_index];
|
||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||
if (!sim_ent_should_simulate(ent)) continue;
|
||||
|
||||
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) {
|
||||
struct sim_ent *client_ent = sim_ent_from_handle(world, ent->controlling_client);
|
||||
@ -525,6 +520,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||
struct sim_ent *ent = &world->ents[ent_index];
|
||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||
if (!sim_ent_should_simulate(ent)) continue;
|
||||
if (sprite_tag_is_nil(ent->sprite)) continue;
|
||||
|
||||
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
|
||||
@ -625,6 +621,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||
struct sim_ent *ent = &world->ents[ent_index];
|
||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||
if (!sim_ent_should_simulate(ent)) continue;
|
||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_ATTACHED)) continue;
|
||||
|
||||
struct sim_ent *parent = sim_ent_from_handle(world, ent->parent);
|
||||
@ -701,6 +698,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||
struct sim_ent *ent = &world->ents[ent_index];
|
||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||
if (!sim_ent_should_simulate(ent)) continue;
|
||||
|
||||
if (sim_ent_has_prop(ent, SIM_ENT_PROP_TRIGGERING_EQUIPPED)) {
|
||||
struct sim_ent *eq = sim_ent_from_handle(world, ent->equipped);
|
||||
@ -717,6 +715,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||
struct sim_ent *ent = &world->ents[ent_index];
|
||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||
if (!sim_ent_should_simulate(ent)) continue;
|
||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_TRIGGERED_THIS_TICK)) continue;
|
||||
if ((world->sim_time_ns - ent->last_triggered_ns < NS_FROM_SECONDS(ent->trigger_delay)) && ent->last_triggered_ns != 0) continue;
|
||||
|
||||
@ -781,11 +780,12 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||
struct sim_ent *ent = &world->ents[ent_index];
|
||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||
if (!sim_ent_should_simulate(ent)) continue;
|
||||
|
||||
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) {
|
||||
struct sim_ent *joint_ent = sim_ent_from_handle(world, ent->move_joint);
|
||||
if (!sim_ent_is_valid_and_active(joint_ent)) {
|
||||
joint_ent = sim_ent_alloc_sync_src(root);
|
||||
joint_ent = sim_ent_alloc_local(root);
|
||||
joint_ent->mass_unscaled = F32_INFINITY;
|
||||
joint_ent->inertia_unscaled = F32_INFINITY;
|
||||
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_MOTOR_JOINT);
|
||||
@ -814,6 +814,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||
struct sim_ent *ent = &world->ents[ent_index];
|
||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||
//if (!sim_ent_should_simulate(ent)) continue;
|
||||
|
||||
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) {
|
||||
struct xform xf = sim_ent_get_xform(ent);
|
||||
@ -822,7 +823,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
/* Retrieve / create aim joint */
|
||||
struct sim_ent *joint_ent = sim_ent_from_handle(world, ent->aim_joint);
|
||||
if (!sim_ent_is_valid_and_active(joint_ent)) {
|
||||
joint_ent = sim_ent_alloc_sync_src(root);
|
||||
joint_ent = sim_ent_alloc_local(root);
|
||||
joint_ent->mass_unscaled = F32_INFINITY;
|
||||
joint_ent->inertia_unscaled = F32_INFINITY;
|
||||
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_PHYSICAL_KINEMATIC); /* Since we'll be setting velocity manually */
|
||||
@ -907,6 +908,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||
struct sim_ent *ent = &world->ents[ent_index];
|
||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||
if (!sim_ent_should_simulate(ent)) continue;
|
||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_DYNAMIC)) continue;
|
||||
|
||||
struct sim_ent *joint_ent = sim_ent_from_handle(world, ent->ground_friction_joint);
|
||||
@ -919,7 +921,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
def.max_torque = ent->angular_ground_friction;
|
||||
if (joint_ent->motor_joint_data.max_force != def.max_force || joint_ent->motor_joint_data.max_torque != def.max_torque) {
|
||||
if (!sim_ent_is_valid_and_active(joint_ent)) {
|
||||
joint_ent = sim_ent_alloc_sync_src(root);
|
||||
joint_ent = sim_ent_alloc_local(root);
|
||||
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_MOTOR_JOINT);
|
||||
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_ACTIVE);
|
||||
joint_ent->motor_joint_data = phys_motor_joint_from_def(def);
|
||||
@ -935,6 +937,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
|
||||
struct sim_ent *client_ent = &world->ents[i];
|
||||
if (!sim_ent_is_valid_and_active(client_ent)) continue;
|
||||
if (!sim_ent_should_simulate(client_ent)) continue;
|
||||
if (!sim_ent_has_prop(client_ent, SIM_ENT_PROP_CLIENT)) continue;
|
||||
|
||||
struct v2 cursor = client_ent->client_cursor_pos;
|
||||
@ -944,42 +947,16 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
struct sim_ent *joint_ent = sim_ent_from_handle(world, client_ent->client_dbg_drag_joint_ent);
|
||||
struct sim_ent *target_ent = sim_ent_from_handle(world, joint_ent->mouse_joint_data.target);
|
||||
|
||||
if (start_dragging) {
|
||||
#if 0
|
||||
struct xform mouse_xf = xform_from_pos(cursor);
|
||||
struct collider_shape mouse_shape = ZI;
|
||||
mouse_shape.points[0] = V2(0, 0);
|
||||
mouse_shape.count = 1;
|
||||
|
||||
for (u64 sim_ent_index = 0; sim_ent_index < world->num_ents_reserved; ++sim_ent_index) {
|
||||
struct sim_ent *ent = &world->ents[sim_ent_index];
|
||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_DYNAMIC)) continue;
|
||||
|
||||
struct collider_shape ent_collider = ent->local_collider;
|
||||
if (ent_collider.count > 0) {
|
||||
struct xform ent_xf = sim_ent_get_xform(ent);
|
||||
/* TODO: Can just use boolean GJK */
|
||||
struct collider_collision_points_result res = collider_collision_points(&ent_collider, &mouse_shape, ent_xf, mouse_xf);
|
||||
if (res.num_points > 0) {
|
||||
target_ent = ent;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
target_ent = sim_ent_from_handle(world, client_ent->client_hovered_ent);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (stop_dragging) {
|
||||
target_ent = sim_ent_nil();
|
||||
} else if (start_dragging) {
|
||||
target_ent = sim_ent_from_handle(world, client_ent->client_hovered_ent);
|
||||
}
|
||||
|
||||
if (sim_ent_is_valid_and_active(target_ent)) {
|
||||
if (!sim_ent_is_valid_and_active(joint_ent)) {
|
||||
/* FIXME: Joint ent may never release */
|
||||
joint_ent = sim_ent_alloc_sync_src(root);
|
||||
joint_ent = sim_ent_alloc_local(root);
|
||||
joint_ent->mass_unscaled = F32_INFINITY;
|
||||
joint_ent->inertia_unscaled = F32_INFINITY;
|
||||
client_ent->client_dbg_drag_joint_ent = joint_ent->handle;
|
||||
@ -1008,7 +985,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
* Physics step
|
||||
* ========================== */
|
||||
|
||||
{
|
||||
if (ctx->is_master) {
|
||||
struct phys_step_ctx phys = ZI;
|
||||
phys.sim_step_ctx = ctx;
|
||||
phys.pre_solve_callback = on_collision;
|
||||
@ -1022,6 +999,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||
struct sim_ent *ent = &world->ents[ent_index];
|
||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||
if (!sim_ent_should_simulate(ent)) continue;
|
||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_TRACER)) continue;
|
||||
|
||||
struct v2 end = sim_ent_get_xform(ent).og;
|
||||
@ -1046,6 +1024,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||
struct sim_ent *ent = &world->ents[ent_index];
|
||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||
if (!sim_ent_should_simulate(ent)) continue;
|
||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_BULLET)) continue;
|
||||
|
||||
if (ent->activation_tick == world->tick) {
|
||||
@ -1101,6 +1080,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||
struct sim_ent *ent = &world->ents[ent_index];
|
||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||
if (!sim_ent_should_simulate(ent)) continue;
|
||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_CAMERA)) continue;
|
||||
|
||||
struct xform xf = sim_ent_get_xform(ent);
|
||||
@ -1157,6 +1137,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||
struct sim_ent *ent = &world->ents[ent_index];
|
||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||
if (!sim_ent_should_simulate(ent)) continue;
|
||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_QUAKE)) continue;
|
||||
|
||||
ent->quake_intensity = max_f32(0, ent->quake_intensity - (ent->quake_fade * sim_dt));
|
||||
@ -1183,7 +1164,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
|
||||
i32 parent_layer = parent->final_layer;
|
||||
for (struct sim_ent *child = sim_ent_from_handle(world, parent->first); child->valid; child = sim_ent_from_handle(world, child->next)) {
|
||||
if (sim_ent_is_valid_and_active(child)) {
|
||||
if (sim_ent_is_valid_and_active(child) && sim_ent_should_simulate(child)) {
|
||||
child->final_layer = parent_layer + child->layer;
|
||||
*arena_push(temp.arena, struct sim_ent *) = child;
|
||||
++stack_count;
|
||||
@ -1193,7 +1174,6 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
|
||||
arena_temp_end(temp);
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Release entities at end of frame
|
||||
|
||||
Loading…
Reference in New Issue
Block a user