pp refactor progress

This commit is contained in:
jacob 2025-08-05 16:14:39 -05:00
parent bb300b9ef4
commit b25bd21b72
7 changed files with 751 additions and 744 deletions

View File

@ -97,7 +97,7 @@ void DrawDebugMovement(Entity *ent)
u32 color_vel = ColorOrange;
Xform xf = sim_ent_get_xform(ent);
Xform xf = XformFromEntity(ent);
Vec2 velocity = ent->linear_velocity;
Vec2 pos = MulXformV2(g->world_to_ui_xf, xf.og);
@ -122,8 +122,8 @@ String DebugStringFromEntity(Arena *arena, Entity *ent)
//result.len += StringFormat(arena, Lit("[%F]"), FmtUid(ent->id.uid)).len;
{
b32 transmitting = sim_ent_has_prop(ent, Prop_SyncSrc);
b32 receiving = sim_ent_has_prop(ent, Prop_SyncDst);
b32 transmitting = HasProp(ent, Prop_SyncSrc);
b32 receiving = HasProp(ent, Prop_SyncDst);
if (transmitting & receiving)
{
result.len += PushString(arena, Lit(" networked (sending & receiving)")).len;
@ -166,12 +166,12 @@ String DebugStringFromEntity(Arena *arena, Entity *ent)
result.len += PushString(arena, Lit("\n")).len;
}
if (!sim_ent_id_eq(ent->parent, SIM_ENT_ROOT_ID))
if (!EqEntityId(ent->parent, RootEntityId))
{
result.len += StringFormat(arena, Lit("parent: [%F]\n"), FmtUid(ent->parent.uid)).len;
}
if (!sim_ent_id_is_nil(ent->next) || !sim_ent_id_is_nil(ent->prev))
if (!IsNilEntityId(ent->next) || !IsNilEntityId(ent->prev))
{
result.len += StringFormat(arena, Lit("prev: [%F]\n"), FmtUid(ent->prev.uid)).len;
result.len += StringFormat(arena, Lit("next: [%F]\n"), FmtUid(ent->next.uid)).len;
@ -180,7 +180,7 @@ String DebugStringFromEntity(Arena *arena, Entity *ent)
result.len += PushString(arena, Lit("\n")).len;
/* Pos */
Xform xf = sim_ent_get_xform(ent);
Xform xf = XformFromEntity(ent);
Vec2 linear_velocity = ent->linear_velocity;
f32 angular_velocity = ent->angular_velocity;
result.len += StringFormat(arena, Lit("pos: (%F, %F)\n"), FmtFloat(xf.og.x), FmtFloat(xf.og.y)).len;
@ -191,10 +191,10 @@ String DebugStringFromEntity(Arena *arena, Entity *ent)
result.len += StringFormat(arena, Lit("collision dir: (%F, %F)\n"), FmtFloat(ent->collision_dir.x), FmtFloat(ent->collision_dir.y)).len;
/* Children */
if (!sim_ent_id_is_nil(ent->first) || !sim_ent_id_is_nil(ent->last))
if (!IsNilEntityId(ent->first) || !IsNilEntityId(ent->last))
{
Entity *child = sim_ent_from_id(ss, ent->first);
if (!sim_ent_id_eq(ent->first, ent->last) || !child->valid)
Entity *child = EntityFromId(ss, ent->first);
if (!EqEntityId(ent->first, ent->last) || !child->valid)
{
result.len += StringFormat(arena, Lit("first child: [%F]\n"), FmtUid(ent->first.uid)).len;
result.len += StringFormat(arena, Lit("last child: [%F]\n"), FmtUid(ent->last.uid)).len;
@ -205,7 +205,7 @@ String DebugStringFromEntity(Arena *arena, Entity *ent)
result.len += PushString(arena, Lit("CHILD\n")).len;
String child_text = DebugStringFromEntity(scratch.arena, child);
result.len += IndentString(arena, child_text, 4).len;
child = sim_ent_from_id(ss, child->next);
child = EntityFromId(ss, child->next);
}
}
@ -365,8 +365,8 @@ MergesortCompareFuncDef(EntitySortCmp, arg_a, arg_b, _)
if (result == 0)
{
/* Sort by light */
b32 a_cmp = sim_ent_has_prop(a, Prop_LightTest);
b32 b_cmp = sim_ent_has_prop(b, Prop_LightTest);
b32 a_cmp = HasProp(a, Prop_LightTest);
b32 b_cmp = HasProp(b, Prop_LightTest);
result = (a_cmp > b_cmp) - (a_cmp < b_cmp);
}
if (result == 0)
@ -616,13 +616,13 @@ void UpdateUser(P_Window *window)
//- Find local entities
Entity *local_player = sim_ent_from_id(g->ss_blended, g->ss_blended->local_player);
Entity *local_control = sim_ent_from_id(g->ss_blended, local_player->player_control_ent);
Entity *local_camera = sim_ent_from_id(g->ss_blended, local_player->player_camera_ent);
Entity *local_player = EntityFromId(g->ss_blended, g->ss_blended->local_player);
Entity *local_control = EntityFromId(g->ss_blended, local_player->player_control_ent);
Entity *local_camera = EntityFromId(g->ss_blended, local_player->player_camera_ent);
//- Find hovered entity
Entity *hovered_ent = sim_ent_nil();
Entity *hovered_ent = NilEntity();
{
Xform mouse_xf = XformFromPos(g->world_cursor);
CLD_Shape mouse_shape = ZI;
@ -632,17 +632,17 @@ void UpdateUser(P_Window *window)
for (u64 ent_index = 0; ent_index < g->ss_blended->num_ents_reserved; ++ent_index)
{
Entity *ent = &g->ss_blended->ents[ent_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
if (!IsValidAndActive(ent)) continue;
CLD_Shape ent_collider = ent->local_collider;
if (ent_collider.count > 0)
{
/* TODO: Can just use boolean GJK */
Xform ent_xf = sim_ent_get_xform(ent);
Xform ent_xf = XformFromEntity(ent);
CLD_CollisionData collision_result = CLD_CollisionDataFromShapes(&ent_collider, &mouse_shape, ent_xf, mouse_xf);
if (collision_result.num_points > 0)
{
hovered_ent = sim_ent_from_id(g->ss_blended, ent->top);
hovered_ent = EntityFromId(g->ss_blended, ent->top);
break;
}
}
@ -685,23 +685,23 @@ void UpdateUser(P_Window *window)
{
if (g->bind_states[BindKind_DebugFollow].num_presses > 0)
{
if (sim_ent_id_is_nil(g->debug_following))
if (IsNilEntityId(g->debug_following))
{
g->debug_following = hovered_ent->id;
}
else
{
g->debug_following = SIM_ENT_NIL_ID;
g->debug_following = NilEntityId;
}
}
if (!sim_ent_id_is_nil(g->debug_following))
if (!IsNilEntityId(g->debug_following))
{
Entity *follow_ent = sim_ent_from_id(g->ss_blended, g->debug_following);
Entity *follow_camera = sim_ent_nil();
Entity *follow_ent = EntityFromId(g->ss_blended, g->debug_following);
Entity *follow_camera = NilEntity();
for (u64 i = 0; i < g->ss_blended->num_ents_reserved; ++i)
{
Entity *ent = &g->ss_blended->ents[i];
Entity *ent_camera_follow = sim_ent_from_id(g->ss_blended, ent->camera_follow);
Entity *ent_camera_follow = EntityFromId(g->ss_blended, ent->camera_follow);
if (ent_camera_follow->valid && ent_camera_follow == follow_ent)
{
follow_camera = ent;
@ -714,7 +714,7 @@ void UpdateUser(P_Window *window)
}
else
{
g->debug_following = SIM_ENT_NIL_ID;
g->debug_following = NilEntityId;
}
}
}
@ -724,7 +724,7 @@ void UpdateUser(P_Window *window)
for (u64 ent_index = 0; ent_index < g->ss_blended->num_ents_reserved; ++ent_index)
{
Entity *ent = &g->ss_blended->ents[ent_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
if (!IsValidAndActive(ent)) continue;
/* How much time between camera shakes */
i64 frequency_ns = NsFromSeconds(0.01f);
@ -744,9 +744,9 @@ void UpdateUser(P_Window *window)
f32 blend = (f32)(g->ss_blended->sim_time_ns % frequency_ns) / (f32)frequency_ns;
Vec2 vec = LerpVec2(vec0, vec1, blend);
Xform xf = sim_ent_get_xform(ent);
Xform xf = XformFromEntity(ent);
xf.og = AddVec2(xf.og, MulVec2(vec, shake));
sim_ent_set_xform(ent, xf);
SetEntityXform(ent, xf);
}
}
@ -764,7 +764,7 @@ void UpdateUser(P_Window *window)
f32 aspect_ratio = (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT);
if (local_camera->valid)
{
Xform quad_xf = MulXform(sim_ent_get_xform(local_camera), local_camera->camera_quad_xform);
Xform quad_xf = MulXform(XformFromEntity(local_camera), local_camera->camera_quad_xform);
Vec2 camera_size = ScaleFromXform(quad_xf);
if (!IsVec2Zero(camera_size))
{
@ -833,7 +833,7 @@ void UpdateUser(P_Window *window)
}
else
{
Xform xf = sim_ent_get_xform(local_camera);
Xform xf = XformFromEntity(local_camera);
Vec2 world_center = xf.og;
f32 rot = RotationFromXform(xf);
@ -937,7 +937,7 @@ void UpdateUser(P_Window *window)
for (u64 ent_index = 0; ent_index < g->ss_blended->num_ents_reserved; ++ent_index)
{
Entity *chunk_ent = &g->ss_blended->ents[ent_index];
if (sim_ent_is_valid_and_active(chunk_ent) && sim_ent_has_prop(chunk_ent, Prop_TileChunk))
if (IsValidAndActive(chunk_ent) && HasProp(chunk_ent, Prop_TileChunk))
{
struct user_tile_cache_entry *entry = user_tile_cache_entry_from_chunk_pos(chunk_ent->tile_chunk_pos);
if (!entry->valid)
@ -1049,7 +1049,7 @@ void UpdateUser(P_Window *window)
for (u64 ent_index = 0; ent_index < g->ss_blended->num_ents_reserved; ++ent_index)
{
Entity *ent = &g->ss_blended->ents[ent_index];
if (sim_ent_is_valid_and_active(ent))
if (IsValidAndActive(ent))
{
*PushStructNoZero(scratch.arena, Entity *) = ent;
++sorted_count;
@ -1070,20 +1070,20 @@ void UpdateUser(P_Window *window)
for (u64 sorted_index = 0; sorted_index < sorted_count; ++sorted_index)
{
Entity *ent = sorted[sorted_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
if (!IsValidAndActive(ent)) continue;
//if (S_IsTagNil(ent->sprite)) continue;
S_Tag sprite = ent->sprite;
Entity *parent = sim_ent_from_id(g->ss_blended, ent->parent);
Entity *parent = EntityFromId(g->ss_blended, ent->parent);
Xform xf = sim_ent_get_xform(ent);
Xform parent_xf = sim_ent_get_xform(parent);
Xform xf = XformFromEntity(ent);
Xform parent_xf = XformFromEntity(parent);
b32 skip_debug_draw = !g->debug_camera && ent == local_camera;
skip_debug_draw = skip_debug_draw || sim_ent_has_prop(ent, Prop_MotorJoint);
skip_debug_draw = skip_debug_draw || HasProp(ent, Prop_MotorJoint);
b32 skip_debug_draw_transform = sim_ent_has_prop(ent, Prop_Camera);
b32 skip_debug_draw_transform = HasProp(ent, Prop_Camera);
skip_debug_draw_transform = 1;
Xform sprite_xform = MulXform(xf, ent->sprite_local_xform);
@ -1091,7 +1091,7 @@ void UpdateUser(P_Window *window)
/* Draw tracer */
/* TODO: Enable this */
#if 0
if (sim_ent_has_prop(ent, Prop_Tracer))
if (HasProp(ent, Prop_Tracer))
{
Vec2 velocity = ent->tracer_start_velocity;
@ -1143,7 +1143,7 @@ void UpdateUser(P_Window *window)
/* TODO: Fade in placeholder if texture isn't loaded */
if (sheet->loaded && texture->loaded)
{
b32 is_light = sim_ent_has_prop(ent, Prop_LightTest);
b32 is_light = HasProp(ent, Prop_LightTest);
Vec3 emittance = ent->sprite_emittance;
u32 tint = ent->sprite_tint;
S_Frame frame = S_FrameFromIndex(sheet, ent->animation_frame);
@ -1154,7 +1154,7 @@ void UpdateUser(P_Window *window)
/* Draw tiles */
/* TODO: Something better */
if (sim_ent_has_prop(ent, Prop_TileChunk))
if (HasProp(ent, Prop_TileChunk))
{
Vec2I32 chunk_index = ent->tile_chunk_index;
S_Tag tile_sprite = S_TagFromPath(Lit("sprite/tile.ase"));
@ -1187,7 +1187,7 @@ void UpdateUser(P_Window *window)
{
TempArena temp = BeginTempArena(scratch.arena);
if (sim_ent_has_prop(ent, Prop_Kinematic) || sim_ent_has_prop(ent, Prop_Dynamic))
if (HasProp(ent, Prop_Kinematic) || HasProp(ent, Prop_Dynamic))
{
DrawDebugMovement(ent);
}
@ -1212,7 +1212,7 @@ void UpdateUser(P_Window *window)
}
/* Draw focus arrow */
if (ent == local_control || sim_ent_id_eq(ent->id, g->debug_following))
if (ent == local_control || EqEntityId(ent->id, g->debug_following))
{
S_Sheet *sheet = S_SheetFromTagAsync(sprite_frame_scope, ent->sprite);
S_Slice slice = S_SliceFromNameIndex(sheet, Lit("attach.wep"), ent->animation_frame);
@ -1269,10 +1269,10 @@ void UpdateUser(P_Window *window)
/* Draw weld joint */
#if 0
if (sim_ent_has_prop(ent, Prop_WeldJoint))
if (HasProp(ent, Prop_WeldJoint))
{
Entity *e1 = sim_ent_from_id(g->ss_blended, ent->weld_joint_data.e1);
Xform e1_xf = sim_ent_get_xform(e1);
Entity *e1 = EntityFromId(g->ss_blended, ent->weld_joint_data.e1);
Xform e1_xf = XformFromEntity(e1);
u32 color = ColorYellow;
f32 radius = 3;
@ -1285,10 +1285,10 @@ void UpdateUser(P_Window *window)
#endif
/* Draw mouse joint */
if (sim_ent_has_prop(ent, Prop_MouseJoint))
if (HasProp(ent, Prop_MouseJoint))
{
Entity *target = sim_ent_from_id(g->ss_blended, ent->mouse_joint_data.target);
Xform target_xf = sim_ent_get_xform(target);
Entity *target = EntityFromId(g->ss_blended, ent->mouse_joint_data.target);
Xform target_xf = XformFromEntity(target);
u32 color = ColorWhite;
Vec2 point_start = MulXformV2(target_xf, ent->mouse_joint_data.point_local_start);
Vec2 point_end = g->world_cursor;
@ -1338,11 +1338,11 @@ void UpdateUser(P_Window *window)
}
/* Draw contact constraint */
if (sim_ent_has_prop(ent, Prop_ContactConstraint))
if (HasProp(ent, Prop_ContactConstraint))
{
ContactConstraint *data = &ent->contact_constraint_data;
Entity *e0 = sim_ent_from_id(g->ss_blended, data->e0);
Entity *e1 = sim_ent_from_id(g->ss_blended, data->e1);
Entity *e0 = EntityFromId(g->ss_blended, data->e0);
Entity *e1 = EntityFromId(g->ss_blended, data->e1);
LAX e0;
LAX e1;
@ -1410,12 +1410,12 @@ void UpdateUser(P_Window *window)
/* Draw collision debug */
#if COLLIDER_DEBUG
if (sim_ent_has_prop(ent, Prop_CollisionDebug))
if (HasProp(ent, Prop_CollisionDebug))
{
CollisionDebugData *data = &ent->collision_debug_data;
CLD_CollisionData collision_reuslt = data->collision_result;
Entity *e0 = sim_ent_from_id(g->ss_blended, data->e0);
Entity *e1 = sim_ent_from_id(g->ss_blended, data->e1);
Entity *e0 = EntityFromId(g->ss_blended, data->e0);
Entity *e1 = EntityFromId(g->ss_blended, data->e1);
CLD_Shape e0_collider = e0->local_collider;
CLD_Shape e1_collider = e1->local_collider;
LAX e0_collider;
@ -1610,7 +1610,7 @@ void UpdateUser(P_Window *window)
#endif
/* Draw hierarchy */
if (sim_ent_has_prop(parent, Prop_Active) && !parent->is_root)
if (HasProp(parent, Prop_Active) && !parent->is_root)
{
u32 color = Rgba32F(0.6, 0.6, 1, 0.75);
f32 thickness = 2;
@ -1622,7 +1622,7 @@ void UpdateUser(P_Window *window)
}
/* Draw camera rect */
if (sim_ent_has_prop(ent, Prop_Camera))
if (HasProp(ent, Prop_Camera))
{
u32 color = ent == local_camera ? Rgba32F(1, 1, 1, 0.5) : Rgba32F(0, 0.75, 0, 0.5);
f32 thickness = 3;
@ -1731,7 +1731,7 @@ void UpdateUser(P_Window *window)
if (!g->debug_camera)
{
g->focus_send = SubVec2(g->world_cursor, sim_ent_get_xform(local_control).og);
g->focus_send = SubVec2(g->world_cursor, XformFromEntity(local_control).og);
}
Vec2 input_aim_dir = g->focus_send;
@ -2084,16 +2084,16 @@ void GenerateuserInputCmds(Client *user_input_client, u64 tick)
SharedUserState *g = &shared_user_state;
Snapshot *prev_user_input_ss = sim_snapshot_from_tick(user_input_client, user_input_client->last_tick);
Snapshot *user_input_ss = sim_snapshot_acquire(user_input_client, prev_user_input_ss, tick);
Entity *user_input_root = sim_ent_from_id(user_input_ss, SIM_ENT_ROOT_ID);
Entity *user_input_root = EntityFromId(user_input_ss, RootEntityId);
/* Find / create local control cmd ent */
Entity *control_cmd = sim_ent_find_first_match_one(user_input_ss, Prop_Cmd);
Entity *control_cmd = FirstEntityWithProp(user_input_ss, Prop_Cmd);
if (!control_cmd->valid)
{
control_cmd = sim_ent_acquire_sync_src(user_input_root);
control_cmd = AcquireSyncSrcEntity(user_input_root);
control_cmd->cmd_kind = SIM_CMD_KIND_CONTROL;
control_cmd->predictor = user_input_client->player_id;
sim_ent_enable_prop(control_cmd, Prop_Cmd);
sim_ent_activate(control_cmd, user_input_ss->tick);
EnableProp(control_cmd, Prop_Cmd);
ActivateEntity(control_cmd, user_input_ss->tick);
}
{
Lock lock = LockE(&g->user_sim_cmd_mutex);
@ -2106,7 +2106,7 @@ void GenerateuserInputCmds(Client *user_input_client, u64 tick)
/* Create chat cmd */
if (g->user_sim_cmd_chat.len > 0)
{
Entity *chat_cmd = sim_ent_acquire_sync_src(user_input_root);
Entity *chat_cmd = AcquireSyncSrcEntity(user_input_root);
chat_cmd->cmd_kind = SIM_CMD_KIND_CHAT;
//chat_cmd->chat_msg = ZI
}
@ -2382,10 +2382,10 @@ JobDef(SimJob, UNUSED sig, UNUSED id)
for (u64 i = 0; i < ss->num_ents_reserved; ++i)
{
Entity *ent = &ss->ents[i];
if (ent->valid && sim_ent_has_prop(ent, Prop_SyncDst))
if (ent->valid && HasProp(ent, Prop_SyncDst))
{
sim_ent_disable_prop(ent, Prop_SyncDst);
sim_ent_enable_prop(ent, Prop_SyncSrc);
DisableProp(ent, Prop_SyncDst);
EnableProp(ent, Prop_SyncSrc);
}
}
}
@ -2620,7 +2620,7 @@ JobDef(SimJob, UNUSED sig, UNUSED id)
if (master_ss->valid)
{
Entity *master_player = sim_ent_find_first_match_one(master_ss, Prop_IsMaster);
Entity *master_player = FirstEntityWithProp(master_ss, Prop_IsMaster);
/* Update ent id from master */
{

View File

@ -1,7 +1,7 @@
////////////////////////////////
//~ Acquire
Entity *sim_ent_acquire_raw(Snapshot *ss, Entity *parent, EntityId id)
Entity *AcquireEntityRaw(Snapshot *ss, Entity *parent, EntityId id)
{
Assert(parent->valid);
Assert(ss->valid);
@ -16,61 +16,61 @@ Entity *sim_ent_acquire_raw(Snapshot *ss, Entity *parent, EntityId id)
ent = PushStructNoZero(ss->ents_arena, Entity);
++ss->num_ents_reserved;
}
*ent = *sim_ent_nil();
*ent = *NilEntity();
ent->ss = ss;
ent->valid = 1;
ent->owner = ss->client->player_id;
ent->_is_xform_dirty = 1;
++ss->num_ents_allocated;
sim_ent_set_id(ent, id);
sim_ent_link_parent(ent, parent);
SetEntityId(ent, id);
LinkEntity(ent, parent);
return ent;
}
/* Acquires a new entity that will not sync */
Entity *sim_ent_acquire_local(Entity *parent)
Entity *AcquireLocalEntity(Entity *parent)
{
Snapshot *ss = parent->ss;
Entity *e = sim_ent_acquire_raw(ss, parent, sim_ent_random_id());
Entity *e = AcquireEntityRaw(ss, parent, RandomEntityId());
e->owner = ss->local_player;
return e;
}
Entity *sim_ent_acquire_local_with_id(Entity *parent, EntityId id)
Entity *AcquireLocalEntityWithId(Entity *parent, EntityId id)
{
Snapshot *ss = parent->ss;
Entity *e = sim_ent_acquire_raw(ss, parent, id);
Entity *e = AcquireEntityRaw(ss, parent, id);
e->owner = ss->local_player;
return e;
}
/* Acquires a new entity to be synced to clients */
Entity *sim_ent_acquire_sync_src(Entity *parent)
Entity *AcquireSyncSrcEntity(Entity *parent)
{
Snapshot *ss = parent->ss;
Entity *e = sim_ent_acquire_raw(ss, parent, sim_ent_random_id());
sim_ent_enable_prop(e, Prop_SyncSrc);
Entity *e = AcquireEntityRaw(ss, parent, RandomEntityId());
EnableProp(e, Prop_SyncSrc);
e->owner = ss->local_player;
return e;
}
Entity *sim_ent_acquire_sync_src_with_id(Entity *parent, EntityId id)
Entity *AcquireSyncSrcEntityWithId(Entity *parent, EntityId id)
{
Snapshot *ss = parent->ss;
Entity *e = sim_ent_acquire_raw(ss, parent, id);
sim_ent_enable_prop(e, Prop_SyncSrc);
Entity *e = AcquireEntityRaw(ss, parent, id);
EnableProp(e, Prop_SyncSrc);
e->owner = ss->local_player;
return e;
}
/* Acquires a new entity that will sync with incoming net src ents containing id, and coming from the specified owner */
Entity *sim_ent_acquire_sync_dst(Entity *parent, EntityId ent_id, EntityId owner_id)
Entity *AcquireSyncDstEntity(Entity *parent, EntityId ent_id, EntityId owner_id)
{
Snapshot *ss = parent->ss;
Entity *e = sim_ent_acquire_raw(ss, parent, ent_id);
sim_ent_enable_prop(e, Prop_SyncDst);
Entity *e = AcquireEntityRaw(ss, parent, ent_id);
EnableProp(e, Prop_SyncDst);
e->owner = owner_id;
return e;
}
@ -78,38 +78,38 @@ Entity *sim_ent_acquire_sync_dst(Entity *parent, EntityId ent_id, EntityId owner
////////////////////////////////
//~ Release
void sim_ent_release_raw(Entity *ent)
void ReleaseEntityRaw(Entity *ent)
{
Snapshot *ss = ent->ss;
/* Release children */
Entity *child = sim_ent_from_id(ss, ent->first);
Entity *child = EntityFromId(ss, ent->first);
while (child->valid) {
Entity *next = sim_ent_from_id(ss, child->next);
sim_ent_release_raw(child);
Entity *next = EntityFromId(ss, child->next);
ReleaseEntityRaw(child);
child = next;
}
/* Release uid */
sim_ent_set_id(ent, SIM_ENT_NIL_ID);
SetEntityId(ent, NilEntityId);
/* Release */
ent->valid = 0;
ent->next_free = ss->first_free_ent;
ss->first_free_ent = index_from_ent(ss, ent);
ss->first_free_ent = IndexFromEntity(ss, ent);
--ss->num_ents_allocated;
}
void sim_ent_release(Entity *ent)
void ReleaseEntity(Entity *ent)
{
Snapshot *ss = ent->ss;
Entity *parent = sim_ent_from_id(ss, ent->parent);
Entity *parent = EntityFromId(ss, ent->parent);
if (parent->valid) {
sim_ent_unlink_from_parent(ent);
UnlinkEntity(ent);
}
sim_ent_release_raw(ent);
ReleaseEntityRaw(ent);
}
void sim_ent_release_all_with_prop(Snapshot *ss, Prop prop)
void ReleaseAllEntitiesWithProp(Snapshot *ss, Prop prop)
{
TempArena scratch = BeginScratchNoConflict();
@ -117,7 +117,7 @@ void sim_ent_release_all_with_prop(Snapshot *ss, Prop prop)
u64 ents_to_release_count = 0;
for (u64 ent_index = 0; ent_index < ss->num_ents_reserved; ++ent_index) {
Entity *ent = &ss->ents[ent_index];
if (ent->valid && sim_ent_has_prop(ent, prop)) {
if (ent->valid && HasProp(ent, prop)) {
*PushStructNoZero(scratch.arena, Entity *) = ent;
++ents_to_release_count;
}
@ -128,8 +128,8 @@ void sim_ent_release_all_with_prop(Snapshot *ss, Prop prop)
* child entities will be released along with parent anyway) */
for (u64 i = 0; i < ents_to_release_count; ++i) {
Entity *ent = ents_to_release[i];
if (ent->valid && !ent->is_root && !sim_ent_has_prop(ent, Prop_Cmd) && !sim_ent_has_prop(ent, Prop_Player)) {
sim_ent_release(ent);
if (ent->valid && !ent->is_root && !HasProp(ent, Prop_Cmd) && !HasProp(ent, Prop_Player)) {
ReleaseEntity(ent);
}
}
@ -139,9 +139,9 @@ void sim_ent_release_all_with_prop(Snapshot *ss, Prop prop)
////////////////////////////////
//~ Activate
void sim_ent_activate(Entity *ent, u64 current_tick)
void ActivateEntity(Entity *ent, u64 current_tick)
{
sim_ent_enable_prop(ent, Prop_Active);
EnableProp(ent, Prop_Active);
ent->activation_tick = current_tick;
++ent->continuity_gen;
}
@ -149,44 +149,44 @@ void sim_ent_activate(Entity *ent, u64 current_tick)
////////////////////////////////
//~ Entity id
u32 index_from_ent(Snapshot *ss, Entity *ent)
u32 IndexFromEntity(Snapshot *ss, Entity *ent)
{
return ent - ss->ents;
}
Entity *ent_from_index(Snapshot *ss, u32 index)
Entity *EntityFromIndex(Snapshot *ss, u32 index)
{
if (index > 0 && index < ss->num_ents_reserved) {
return &ss->ents[index];
} else {
return sim_ent_nil();
return NilEntity();
}
}
EntBin *bin_from_id(Snapshot *ss, EntityId id)
EntBin *BinFromEntityId(Snapshot *ss, EntityId id)
{
return &ss->id_bins[id.uid.lo % ss->num_id_bins];
}
/* NOTE: This should only really happen during ent allocation (it doesn't make sense for an allocated ent's id to change) */
void sim_ent_set_id(Entity *ent, EntityId id)
void SetEntityId(Entity *ent, EntityId id)
{
Snapshot *ss = ent->ss;
EntityId old_id = ent->id;
if (!sim_ent_id_eq(old_id, id)) {
if (!EqEntityId(old_id, id)) {
/* Release old from lookup */
if (!sim_ent_id_is_nil(old_id)) {
EntBin *bin = bin_from_id(ss, old_id);
if (!IsNilEntityId(old_id)) {
EntBin *bin = BinFromEntityId(ss, old_id);
u32 prev_index = 0;
u32 next_index = 0;
u32 search_index = bin->first;
Entity *prev = sim_ent_nil();
Entity *next = sim_ent_nil();
Entity *search = ent_from_index(ss, search_index);
Entity *prev = NilEntity();
Entity *next = NilEntity();
Entity *search = EntityFromIndex(ss, search_index);
while (search->valid) {
next_index = search->next_in_id_bin;
next = ent_from_index(ss, next_index);
if (sim_ent_id_eq(search->id, old_id)) {
next = EntityFromIndex(ss, next_index);
if (EqEntityId(search->id, old_id)) {
break;
}
prev_index = search_index;
@ -212,18 +212,18 @@ void sim_ent_set_id(Entity *ent, EntityId id)
}
/* Insert new id into lookup */
if (!sim_ent_id_is_nil(id)) {
if (!IsNilEntityId(id)) {
#if RtcIsEnabled
{
Entity *existing = sim_ent_from_id(ss, id);
Entity *existing = EntityFromId(ss, id);
/* Collision should be extremely unlikely under normal circumstances, there's probably a logic error somewhere. */
Assert(!existing->valid);
}
#endif
EntBin *bin = bin_from_id(ss, id);
u32 ent_index = index_from_ent(ss, ent);
Entity *last = ent_from_index(ss, bin->last);
EntBin *bin = BinFromEntityId(ss, id);
u32 ent_index = IndexFromEntity(ss, ent);
Entity *last = EntityFromIndex(ss, bin->last);
if (last->valid) {
last->next_in_id_bin = ent_index;
ent->prev_in_id_bin = bin->last;
@ -239,13 +239,13 @@ void sim_ent_set_id(Entity *ent, EntityId id)
}
Entity *sim_ent_from_id(Snapshot *ss, EntityId id)
Entity *EntityFromId(Snapshot *ss, EntityId id)
{
Entity *result = sim_ent_nil();
if (!sim_ent_id_is_nil(id) && ss->valid) {
EntBin *bin = bin_from_id(ss, id);
for (Entity *e = ent_from_index(ss, bin->first); e->valid; e = ent_from_index(ss, e->next_in_id_bin)) {
if (sim_ent_id_eq(e->id, id)) {
Entity *result = NilEntity();
if (!IsNilEntityId(id) && ss->valid) {
EntBin *bin = BinFromEntityId(ss, id);
for (Entity *e = EntityFromIndex(ss, bin->first); e->valid; e = EntityFromIndex(ss, e->next_in_id_bin)) {
if (EqEntityId(e->id, id)) {
result = e;
break;
}
@ -254,7 +254,7 @@ Entity *sim_ent_from_id(Snapshot *ss, EntityId id)
return result;
}
EntityId sim_ent_random_id(void)
EntityId RandomEntityId(void)
{
EntityId result = ZI;
result.uid = UidFromTrueRand();
@ -262,10 +262,10 @@ EntityId sim_ent_random_id(void)
}
/* Returns the deterministic id of the contact constraint ent id that should be produced from e0 & e1 colliding */
EntityId sim_ent_contact_constraint_id_from_contacting_ids(EntityId player_id, EntityId id0, EntityId id1)
EntityId ContactConstraintIdFromContactingIds(EntityId player_id, EntityId id0, EntityId id1)
{
EntityId result = ZI;
result.uid = SIM_ENT_CONTACT_BASIS_Uid;
result.uid = ContactBasisUid;
result.uid = CombineUid(result.uid, player_id.uid);
result.uid = CombineUid(result.uid, id0.uid);
result.uid = CombineUid(result.uid, id1.uid);
@ -273,10 +273,10 @@ EntityId sim_ent_contact_constraint_id_from_contacting_ids(EntityId player_id, E
}
/* Returns the deterministic id of the debug contact constraint ent id that should be produced from e0 & e1 colliding */
EntityId sim_ent_collision_debug_id_from_ids(EntityId player_id, EntityId id0, EntityId id1)
EntityId CollisionDebugIdFromIds(EntityId player_id, EntityId id0, EntityId id1)
{
EntityId result = ZI;
result.uid = SIM_ENT_COLLISION_DEBUG_BASIS_Uid;
result.uid = CollisionDebugBasisUid;
result.uid = CombineUid(result.uid, player_id.uid);
result.uid = CombineUid(result.uid, id0.uid);
result.uid = CombineUid(result.uid, id1.uid);
@ -284,10 +284,10 @@ EntityId sim_ent_collision_debug_id_from_ids(EntityId player_id, EntityId id0, E
}
/* Returns the deterministic id of the tile chunk that should be produced at chunk pos */
EntityId sim_ent_tile_chunk_id_from_tile_chunk_index(Vec2I32 chunk_index)
EntityId TileChunkIdFromIndex(Vec2I32 chunk_index)
{
EntityId result = ZI;
result.uid = SIM_ENT_TILE_CHUNK_BASIS_Uid;
result.uid = TileChunkBasisUid;
result.uid = CombineUid(result.uid, UID(RandU64FromSeed(chunk_index.x), RandU64FromSeed(chunk_index.y)));
return result;
}
@ -295,20 +295,20 @@ EntityId sim_ent_tile_chunk_id_from_tile_chunk_index(Vec2I32 chunk_index)
////////////////////////////////
//~ Query
Entity *sim_ent_find_first_match_one(Snapshot *ss, Prop prop)
Entity *FirstEntityWithProp(Snapshot *ss, Prop prop)
{
u64 count = ss->num_ents_reserved;
Entity *entities = ss->ents;
for (u64 ent_index = 0; ent_index < count; ++ent_index) {
Entity *ent = &entities[ent_index];
if (ent->valid && sim_ent_has_prop(ent, prop)) {
if (ent->valid && HasProp(ent, prop)) {
return ent;
}
}
return sim_ent_nil();
return NilEntity();
}
Entity *sim_ent_find_first_match_all(Snapshot *ss, EntPropArray props)
Entity *FirstEntityWithAllProps(Snapshot *ss, PropArray props)
{
u64 count = ss->num_ents_reserved;
Entity *entities = ss->ents;
@ -317,7 +317,7 @@ Entity *sim_ent_find_first_match_all(Snapshot *ss, EntPropArray props)
if (ent->valid) {
b32 all = 1;
for (u64 i = 0; i < props.count; ++i) {
if (!sim_ent_has_prop(ent, props.props[i])) {
if (!HasProp(ent, props.props[i])) {
all = 0;
break;
}
@ -327,25 +327,25 @@ Entity *sim_ent_find_first_match_all(Snapshot *ss, EntPropArray props)
}
}
}
return sim_ent_nil();
return NilEntity();
}
////////////////////////////////
//~ Tree
void sim_ent_link_parent(Entity *ent, Entity *parent)
void LinkEntity(Entity *ent, Entity *parent)
{
Snapshot *ss = ent->ss;
Entity *old_parent = sim_ent_from_id(ss, ent->parent);
Entity *old_parent = EntityFromId(ss, ent->parent);
if (old_parent->valid) {
/* Unlink from current parent */
sim_ent_unlink_from_parent(ent);
UnlinkEntity(ent);
}
EntityId ent_id = ent->id;
EntityId last_child_id = parent->last;
Entity *last_child = sim_ent_from_id(ss, last_child_id);
Entity *last_child = EntityFromId(ss, last_child_id);
if (last_child->valid) {
ent->prev = last_child_id;
last_child->next = ent_id;
@ -365,14 +365,14 @@ void sim_ent_link_parent(Entity *ent, Entity *parent)
}
/* NOTE: Entity will be dangling after calling this, should re-link to root ent. */
void sim_ent_unlink_from_parent(Entity *ent)
void UnlinkEntity(Entity *ent)
{
Snapshot *ss = ent->ss;
EntityId parent_id = ent->parent;
Entity *parent = sim_ent_from_id(ss, parent_id);
Entity *prev = sim_ent_from_id(ss, ent->prev);
Entity *next = sim_ent_from_id(ss, ent->next);
Entity *parent = EntityFromId(ss, parent_id);
Entity *prev = EntityFromId(ss, ent->prev);
Entity *next = EntityFromId(ss, ent->next);
/* Unlink from parent & siblings */
if (prev->valid) {
@ -385,34 +385,34 @@ void sim_ent_unlink_from_parent(Entity *ent)
} else {
parent->last = prev->id;
}
ent->prev = SIM_ENT_NIL_ID;
ent->next = SIM_ENT_NIL_ID;
ent->prev = NilEntityId;
ent->next = NilEntityId;
}
////////////////////////////////
//~ Xform
void sim_ent_mark_child_xforms_dirty(Snapshot *ss, Entity *ent)
void MarkChildEntityXformsDirty(Snapshot *ss, Entity *ent)
{
for (Entity *child = sim_ent_from_id(ss, ent->first); child->valid; child = sim_ent_from_id(ss, child->next)) {
for (Entity *child = EntityFromId(ss, ent->first); child->valid; child = EntityFromId(ss, child->next)) {
if (child->_is_xform_dirty) {
break;
} else {
child->_is_xform_dirty = 1;
sim_ent_mark_child_xforms_dirty(ss, child);
MarkChildEntityXformsDirty(ss, child);
}
}
}
Xform sim_ent_get_xform_internal(Snapshot *ss, Entity *ent)
Xform XformFromEntity_(Snapshot *ss, Entity *ent)
{
Xform xf;
if (ent->_is_xform_dirty) {
if (ent->is_top) {
xf = ent->_local_xform;
} else {
Entity *parent = sim_ent_from_id(ss, ent->parent);
xf = sim_ent_get_xform_internal(ss, parent);
Entity *parent = EntityFromId(ss, ent->parent);
xf = XformFromEntity_(ss, parent);
xf = MulXform(xf, ent->_local_xform);
ent->_xform = xf;
ent->_is_xform_dirty = 0;
@ -425,7 +425,7 @@ Xform sim_ent_get_xform_internal(Snapshot *ss, Entity *ent)
return xf;
}
Xform sim_ent_get_xform(Entity *ent)
Xform XformFromEntity(Entity *ent)
{
Xform xf;
if (ent->_is_xform_dirty) {
@ -433,8 +433,8 @@ Xform sim_ent_get_xform(Entity *ent)
xf = ent->_local_xform;
} else {
Snapshot *ss = ent->ss;
Entity *parent = sim_ent_from_id(ss, ent->parent);
xf = sim_ent_get_xform_internal(ss, parent);
Entity *parent = EntityFromId(ss, ent->parent);
xf = XformFromEntity_(ss, parent);
xf = MulXform(xf, ent->_local_xform);
ent->_xform = xf;
ent->_is_xform_dirty = 0;
@ -447,12 +447,12 @@ Xform sim_ent_get_xform(Entity *ent)
return xf;
}
Xform sim_ent_get_local_xform(Entity *ent)
Xform LocalXformFromEntity(Entity *ent)
{
return ent->_local_xform;
}
void sim_ent_set_xform(Entity *ent, Xform xf)
void SetEntityXform(Entity *ent, Xform xf)
{
if (!EqXform(xf, ent->_xform)) {
Snapshot *ss = ent->ss;
@ -460,88 +460,88 @@ void sim_ent_set_xform(Entity *ent, Xform xf)
if (ent->is_top) {
ent->_local_xform = xf;
} else {
Entity *parent = sim_ent_from_id(ss, ent->parent);
Xform parent_global = sim_ent_get_xform_internal(ss, parent);
Entity *parent = EntityFromId(ss, ent->parent);
Xform parent_global = XformFromEntity_(ss, parent);
ent->_local_xform = MulXform(InvertXform(parent_global), xf);
}
ent->_xform = xf;
ent->_is_xform_dirty = 0;
sim_ent_mark_child_xforms_dirty(ss, ent);
MarkChildEntityXformsDirty(ss, ent);
}
}
void sim_ent_set_local_xform(Entity *ent, Xform xf)
void SetEntityLocalXform(Entity *ent, Xform xf)
{
if (!EqXform(xf, ent->_local_xform)) {
ent->_local_xform = xf;
ent->_is_xform_dirty = 1;
sim_ent_mark_child_xforms_dirty(ent->ss, ent);
MarkChildEntityXformsDirty(ent->ss, ent);
}
}
////////////////////////////////
//~ Movement
void sim_ent_set_linear_velocity(Entity *ent, Vec2 velocity)
void SetLinearVelocity(Entity *ent, Vec2 velocity)
{
if (sim_ent_has_prop(ent, Prop_Kinematic) || sim_ent_has_prop(ent, Prop_Dynamic)) {
if (HasProp(ent, Prop_Kinematic) || HasProp(ent, Prop_Dynamic)) {
ent->linear_velocity = ClampVec2Len(velocity, SIM_MAX_LINEAR_VELOCITY);
}
}
void sim_ent_set_angular_velocity(Entity *ent, f32 velocity)
void SetAngularVelocity(Entity *ent, f32 velocity)
{
if (sim_ent_has_prop(ent, Prop_Kinematic) || sim_ent_has_prop(ent, Prop_Dynamic)) {
if (HasProp(ent, Prop_Kinematic) || HasProp(ent, Prop_Dynamic)) {
ent->angular_velocity = ClampF32(velocity, -SIM_MAX_ANGULAR_VELOCITY, SIM_MAX_ANGULAR_VELOCITY);
}
}
void sim_ent_apply_linear_impulse(Entity *ent, Vec2 impulse, Vec2 point)
void ApplyLinearImpulse(Entity *ent, Vec2 impulse, Vec2 point)
{
if (sim_ent_has_prop(ent, Prop_Dynamic)) {
Xform xf = sim_ent_get_xform(ent);
if (HasProp(ent, Prop_Dynamic)) {
Xform xf = XformFromEntity(ent);
Vec2 center = xf.og;
f32 scale = AbsF32(DeterminantFromXform(xf));
f32 inv_mass = 1.f / (ent->mass_unscaled * scale);
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
Vec2 vcp = SubVec2(point, center);
sim_ent_set_linear_velocity(ent, AddVec2(ent->linear_velocity, MulVec2(impulse, inv_mass)));
sim_ent_set_angular_velocity(ent, WedgeVec2(vcp, impulse) * inv_inertia);
SetLinearVelocity(ent, AddVec2(ent->linear_velocity, MulVec2(impulse, inv_mass)));
SetAngularVelocity(ent, WedgeVec2(vcp, impulse) * inv_inertia);
}
}
void sim_ent_apply_linear_impulse_to_center(Entity *ent, Vec2 impulse)
void ApplyLinearImpulseToCenter(Entity *ent, Vec2 impulse)
{
if (sim_ent_has_prop(ent, Prop_Dynamic)) {
Xform xf = sim_ent_get_xform(ent);
if (HasProp(ent, Prop_Dynamic)) {
Xform xf = XformFromEntity(ent);
f32 scale = AbsF32(DeterminantFromXform(xf));
f32 inv_mass = 1.f / (ent->mass_unscaled * scale);
sim_ent_set_linear_velocity(ent, AddVec2(ent->linear_velocity, MulVec2(impulse, inv_mass)));
SetLinearVelocity(ent, AddVec2(ent->linear_velocity, MulVec2(impulse, inv_mass)));
}
}
void sim_ent_apply_force_to_center(Entity *ent, Vec2 force)
void ApplyForceToCenter(Entity *ent, Vec2 force)
{
if (sim_ent_has_prop(ent, Prop_Dynamic)) {
if (HasProp(ent, Prop_Dynamic)) {
ent->force = AddVec2(ent->force, force);
}
}
void sim_ent_apply_angular_impulse(Entity *ent, f32 impulse)
void ApplyAngularImpulse(Entity *ent, f32 impulse)
{
if (sim_ent_has_prop(ent, Prop_Dynamic)) {
Xform xf = sim_ent_get_xform(ent);
if (HasProp(ent, Prop_Dynamic)) {
Xform xf = XformFromEntity(ent);
f32 scale = AbsF32(DeterminantFromXform(xf));
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
sim_ent_set_angular_velocity(ent, ent->angular_velocity + impulse * inv_inertia);
SetAngularVelocity(ent, ent->angular_velocity + impulse * inv_inertia);
}
}
void sim_ent_apply_torque(Entity *ent, f32 torque)
void ApplyTorque(Entity *ent, f32 torque)
{
if (sim_ent_has_prop(ent, Prop_Dynamic)) {
if (HasProp(ent, Prop_Dynamic)) {
ent->torque += torque;
}
}
@ -549,21 +549,21 @@ void sim_ent_apply_torque(Entity *ent, f32 torque)
////////////////////////////////
//~ Tile
Entity *sim_tile_chunk_from_chunk_index(Snapshot *ss, Vec2I32 chunk_index)
Entity *TileChunkFromChunkIndex(Snapshot *ss, Vec2I32 chunk_index)
{
EntityId chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index);
Entity *chunk_ent = sim_ent_from_id(ss, chunk_id);
EntityId chunk_id = TileChunkIdFromIndex(chunk_index);
Entity *chunk_ent = EntityFromId(ss, chunk_id);
return chunk_ent;
}
Entity *sim_tile_chunk_from_world_tile_index(Snapshot *ss, Vec2I32 world_tile_index)
Entity *TileChunkFromWorldTileIndex(Snapshot *ss, Vec2I32 world_tile_index)
{
Vec2I32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index);
Entity *chunk_ent = sim_tile_chunk_from_chunk_index(ss, chunk_index);
Entity *chunk_ent = TileChunkFromChunkIndex(ss, chunk_index);
return chunk_ent;
}
TileKind sim_get_chunk_tile(Entity *chunk_ent, Vec2I32 local_tile_index)
TileKind TileKindFromChunk(Entity *chunk_ent, Vec2I32 local_tile_index)
{
TileKind result = chunk_ent->tile_chunk_tiles[local_tile_index.x + (local_tile_index.y * SIM_TILES_PER_CHUNK_SQRT)];
return result;
@ -572,18 +572,18 @@ TileKind sim_get_chunk_tile(Entity *chunk_ent, Vec2I32 local_tile_index)
////////////////////////////////
//~ Lerp
void sim_ent_lerp(Entity *e, Entity *e0, Entity *e1, f64 blend)
void LerpEntity(Entity *e, Entity *e0, Entity *e1, f64 blend)
{
if (sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)
&& sim_ent_id_eq(e0->id, e1->id)
if (IsValidAndActive(e0) && IsValidAndActive(e1)
&& EqEntityId(e0->id, e1->id)
&& e0->continuity_gen == e1->continuity_gen) {
e->_local_xform = LerpXform(e0->_local_xform, e1->_local_xform, blend);
if (e->is_top) {
/* TODO: Cache parent & child xforms in sim */
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
sim_ent_set_xform(e, LerpXform(e0_xf, e1_xf, blend));
Xform e0_xf = XformFromEntity(e0);
Xform e1_xf = XformFromEntity(e1);
SetEntityXform(e, LerpXform(e0_xf, e1_xf, blend));
}
e->control_force = LerpF32(e0->control_force, e1->control_force, blend);
@ -611,33 +611,33 @@ void sim_ent_lerp(Entity *e, Entity *e0, Entity *e1, f64 blend)
////////////////////////////////
//~ Sync
/* Walks a local & remote ent tree and allocates any missing net dst ents from remote src ents */
void sim_ent_sync_acquire_tree(Entity *local_parent, Entity *remote, EntityId remote_player)
/* Walks a local & remote ent tree and allocates any missing net dst ents from remote src ents */
void CreateMissingEntitiesFromSnapshots(Entity *local_parent, Entity *remote, EntityId remote_player)
{
__prof;
if (sim_ent_has_prop(remote, Prop_SyncSrc)) {
if (HasProp(remote, Prop_SyncSrc)) {
Snapshot *local_ss = local_parent->ss;
Snapshot *remote_ss = remote->ss;
EntityId id = remote->id;
Entity *local_ent = sim_ent_from_id(local_ss, id);
Entity *local_ent = EntityFromId(local_ss, id);
if (!local_ent->valid) {
local_ent = sim_ent_acquire_sync_dst(local_parent, id, remote_player);
local_ent = AcquireSyncDstEntity(local_parent, id, remote_player);
}
for (Entity *remote_child = sim_ent_from_id(remote_ss, remote->first); remote_child->valid; remote_child = sim_ent_from_id(remote_ss, remote_child->next)) {
sim_ent_sync_acquire_tree(local_ent, remote_child, remote_player);
for (Entity *remote_child = EntityFromId(remote_ss, remote->first); remote_child->valid; remote_child = EntityFromId(remote_ss, remote_child->next)) {
CreateMissingEntitiesFromSnapshots(local_ent, remote_child, remote_player);
}
}
}
/* Copies data between two synced entities */
void sim_ent_sync(Entity *local, Entity *remote)
void SyncEntity(Entity *local, Entity *remote)
{
Entity old = *local;
CopyStruct(local, remote);
/* Why would 2 ents w/ different uids ever be synced? */
Assert(sim_ent_id_eq(local->id, old.id));
Assert(EqEntityId(local->id, old.id));
local->ss = old.ss;
local->id = old.id;
@ -656,8 +656,8 @@ void sim_ent_sync(Entity *local, Entity *remote)
local->prev_in_id_bin = old.prev_in_id_bin;
local->next_free = old.next_free;
sim_ent_disable_prop(local, Prop_SyncSrc);
sim_ent_enable_prop(local, Prop_SyncDst);
DisableProp(local, Prop_SyncSrc);
EnableProp(local, Prop_SyncDst);
}
////////////////////////////////
@ -667,7 +667,7 @@ void sim_ent_sync(Entity *local, Entity *remote)
//- Encode
void sim_ent_encode(BB_Writer *bw, Entity *e0, Entity *e1)
void EncodeEntity(BB_Writer *bw, Entity *e0, Entity *e1)
{
Snapshot *ss = e1->ss;
/* FIXME: Things like xforms need to be retreived manually rather than memcopied. */
@ -692,7 +692,7 @@ void sim_ent_encode(BB_Writer *bw, Entity *e0, Entity *e1)
//- Decode
void sim_ent_decode(BB_Reader *br, Entity *e)
void DecodeEntity(BB_Reader *br, Entity *e)
{
Snapshot *old_ss = e->ss;
{
@ -715,7 +715,7 @@ void sim_ent_decode(BB_Reader *br, Entity *e)
//- Encode
void sim_ent_encode(BB_Writer *bw, Entity *e0, Entity *e1)
void EncodeEntity(BB_Writer *bw, Entity *e0, Entity *e1)
{
Snapshot *ss = e1->ss;
@ -746,7 +746,7 @@ void sim_ent_encode(BB_Writer *bw, Entity *e0, Entity *e1)
//- Decode
void sim_ent_decode(BB_Reader *br, Entity *e)
void DecodeEntity(BB_Reader *br, Entity *e)
{
Entity decoded = *e;
{
@ -767,8 +767,8 @@ void sim_ent_decode(BB_Reader *br, Entity *e)
EntityId new_id = decoded.id;
CopyStruct(e, &decoded);
e->id = old_id;
if (!sim_ent_id_eq(old_id, new_id)) {
sim_ent_set_id(e, new_id);
if (!EqEntityId(old_id, new_id)) {
SetEntityId(e, new_id);
}
}
#endif

View File

@ -1,7 +1,8 @@
////////////////////////////////
//~ Entity props
typedef i32 Prop; enum {
typedef i32 Prop; enum
{
Prop_Active,
Prop_Release,
@ -63,7 +64,8 @@ typedef i32 Prop; enum {
////////////////////////////////
//~ Entity
Struct(Entity) {
Struct(Entity)
{
Snapshot *ss;
//- Metadata
@ -233,7 +235,7 @@ Struct(Entity) {
f32 linear_ground_friction;
f32 angular_ground_friction;
/* Use sim_ent_set_linear_velocity & sim_ent_set_angular_velocity to set */
/* Use SetLinearVelocity & SetAngularVelocity to set */
Vec2 linear_velocity; /* m/s */
f32 angular_velocity; /* rad/s */
@ -367,22 +369,25 @@ Struct(Entity) {
f32 shake;
};
Struct(EntArray) {
Struct(EntityArray)
{
Entity *ents;
u64 count;
};
Struct(EntPropArray) {
Struct(PropArray)
{
Prop *props;
u64 count;
};
Struct(EntBin) {
Struct(EntBin)
{
u32 first;
u32 last;
};
Inline Entity *sim_ent_nil(void)
Inline Entity *NilEntity(void)
{
extern Readonly Entity **_g_sim_ent_nil;
return *_g_sim_ent_nil;
@ -391,74 +396,76 @@ Inline Entity *sim_ent_nil(void)
////////////////////////////////
//~ Id types
#define SIM_ENT_TILE_CHUNK_BASIS_Uid (UID(0x3ce42de071dd226b, 0x9b566f7df30c813a))
#define SIM_ENT_NIL_ID ((EntityId) { UID(0, 0) })
#define SIM_ENT_ROOT_ID ((EntityId) { UID(0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa) })
#define NilEntityId ((EntityId) { UID(0, 0) })
#define RootEntityId ((EntityId) { UID(0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa) })
/* Id magic number constants (to be used in conjunction with ent ids in deterministic id combinations) */
#define SIM_ENT_CONTACT_BASIS_Uid (UID(0x6a2a5d2dbecf534f, 0x0a8ca7c372a015af))
#define SIM_ENT_COLLISION_DEBUG_BASIS_Uid (UID(0x302c01182013bb02, 0x570bd270399d11a5))
#define TileChunkBasisUid (UID(0x3ce42de071dd226b, 0x9b566f7df30c813a))
#define ContactBasisUid (UID(0x6a2a5d2dbecf534f, 0x0a8ca7c372a015af))
#define CollisionDebugBasisUid (UID(0x302c01182013bb02, 0x570bd270399d11a5))
////////////////////////////////
//~ Id helpers
Inline b32 sim_ent_id_eq(EntityId a, EntityId b)
Inline b32 EqEntityId(EntityId a, EntityId b)
{
return EqUid(a.uid, b.uid);
}
Inline b32 sim_ent_id_is_nil(EntityId id)
Inline b32 IsNilEntityId(EntityId id)
{
return EqUid(id.uid, SIM_ENT_NIL_ID.uid);
return EqUid(id.uid, NilEntityId.uid);
}
////////////////////////////////
//~ Property helpers
Inline void sim_ent_enable_prop(Entity *ent, Prop prop)
Inline void EnableProp(Entity *ent, Prop prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
ent->props[index] |= ((u64)1 << bit);
}
Inline void sim_ent_disable_prop(Entity *ent, Prop prop)
Inline void DisableProp(Entity *ent, Prop prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
ent->props[index] &= ~((u64)1 << bit);
}
Inline b32 sim_ent_has_prop(Entity *ent, Prop prop)
Inline b32 HasProp(Entity *ent, Prop prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
return !!(ent->props[index] & ((u64)1 << bit));
}
Inline b32 sim_ent_is_valid_and_active(Entity *ent)
Inline b32 IsValidAndActive(Entity *ent)
{
return ent->valid && sim_ent_has_prop(ent, Prop_Active);
return ent->valid && HasProp(ent, Prop_Active);
}
Inline b32 sim_ent_should_predict(Entity *ent)
Inline b32 ShouldPredict(Entity *ent)
{
return sim_ent_id_eq(ent->predictor, ent->ss->local_player);
return EqEntityId(ent->predictor, ent->ss->local_player);
}
Inline b32 sim_ent_is_owner(Entity *ent)
Inline b32 IsOwner(Entity *ent)
{
return sim_ent_id_eq(ent->owner, ent->ss->local_player);
return EqEntityId(ent->owner, ent->ss->local_player);
}
Inline b32 sim_ent_should_simulate(Entity *ent)
Inline b32 ShouldSimulate(Entity *ent)
{
b32 result = 0;
if (sim_ent_is_valid_and_active(ent)) {
if (IsValidAndActive(ent))
{
result = 1;
if (sim_ent_has_prop(ent, Prop_SyncDst)) {
if (HasProp(ent, Prop_SyncDst))
{
EntityId local_player = ent->ss->local_player;
result = sim_ent_id_eq(local_player, ent->owner) || sim_ent_id_eq(local_player, ent->predictor);
result = EqEntityId(local_player, ent->owner) || EqEntityId(local_player, ent->predictor);
}
}
return result;
@ -467,91 +474,91 @@ Inline b32 sim_ent_should_simulate(Entity *ent)
////////////////////////////////
//~ Acquire operations
Entity *sim_ent_acquire_raw(Snapshot *ss, Entity *parent, EntityId id);
Entity *sim_ent_acquire_local(Entity *parent);
Entity *sim_ent_acquire_local_with_id(Entity *parent, EntityId id);
Entity *sim_ent_acquire_sync_src(Entity *parent);
Entity *sim_ent_acquire_sync_src_with_id(Entity *parent, EntityId id);
Entity *sim_ent_acquire_sync_dst(Entity *parent, EntityId ent_id, EntityId owner_id);
Entity *AcquireEntityRaw(Snapshot *ss, Entity *parent, EntityId id);
Entity *AcquireLocalEntity(Entity *parent);
Entity *AcquireLocalEntityWithId(Entity *parent, EntityId id);
Entity *AcquireSyncSrcEntity(Entity *parent);
Entity *AcquireSyncSrcEntityWithId(Entity *parent, EntityId id);
Entity *AcquireSyncDstEntity(Entity *parent, EntityId ent_id, EntityId owner_id);
////////////////////////////////
//~ Release operations
void sim_ent_release_raw(Entity *ent);
void sim_ent_release(Entity *ent);
void sim_ent_release_all_with_prop(Snapshot *ss, Prop prop);
void ReleaseEntityRaw(Entity *ent);
void ReleaseEntity(Entity *ent);
void ReleaseAllEntitiesWithProp(Snapshot *ss, Prop prop);
////////////////////////////////
//~ Activate operations
void sim_ent_activate(Entity *ent, u64 current_tick);
void ActivateEntity(Entity *ent, u64 current_tick);
////////////////////////////////
//~ Id operations
u32 index_from_ent(Snapshot *ss, Entity *ent);
Entity *ent_from_index(Snapshot *ss, u32 index);
EntBin *bin_from_id(Snapshot *ss, EntityId id);
void sim_ent_set_id(Entity *ent, EntityId id);
Entity *sim_ent_from_id(Snapshot *ss, EntityId id);
EntityId sim_ent_random_id(void);
EntityId sim_ent_contact_constraint_id_from_contacting_ids(EntityId player_id, EntityId id0, EntityId id1);
EntityId sim_ent_collision_debug_id_from_ids(EntityId player_id, EntityId id0, EntityId id1);
EntityId sim_ent_tile_chunk_id_from_tile_chunk_index(Vec2I32 chunk_start);
u32 IndexFromEntity(Snapshot *ss, Entity *ent);
Entity *EntityFromIndex(Snapshot *ss, u32 index);
EntBin *BinFromEntityId(Snapshot *ss, EntityId id);
void SetEntityId(Entity *ent, EntityId id);
Entity *EntityFromId(Snapshot *ss, EntityId id);
EntityId RandomEntityId(void);
EntityId ContactConstraintIdFromContactingIds(EntityId player_id, EntityId id0, EntityId id1);
EntityId CollisionDebugIdFromIds(EntityId player_id, EntityId id0, EntityId id1);
EntityId TileChunkIdFromIndex(Vec2I32 chunk_start);
////////////////////////////////
//~ Query operations
Entity *sim_ent_find_first_match_one(Snapshot *ss, Prop prop);
Entity *sim_ent_find_first_match_all(Snapshot *ss, EntPropArray props);
Entity *FirstEntityWithProp(Snapshot *ss, Prop prop);
Entity *FirstEntityWithAllProps(Snapshot *ss, PropArray props);
////////////////////////////////
//~ Tree operations
void sim_ent_link_parent(Entity *parent, Entity *child);
void sim_ent_unlink_from_parent(Entity *ent);
void LinkEntity(Entity *parent, Entity *child);
void UnlinkEntity(Entity *ent);
////////////////////////////////
//~ Xform operations
void sim_ent_mark_child_xforms_dirty(Snapshot *ss, Entity *ent);
Xform sim_ent_get_xform_internal(Snapshot *ss, Entity *ent);
Xform sim_ent_get_xform(Entity *ent);
Xform sim_ent_get_local_xform(Entity *ent);
void sim_ent_set_xform(Entity *ent, Xform xf);
void sim_ent_set_local_xform(Entity *ent, Xform xf);
void MarkChildEntityXformsDirty(Snapshot *ss, Entity *ent);
Xform XformFromEntity_(Snapshot *ss, Entity *ent);
Xform XformFromEntity(Entity *ent);
Xform LocalXformFromEntity(Entity *ent);
void SetEntityXform(Entity *ent, Xform xf);
void SetEntityLocalXform(Entity *ent, Xform xf);
////////////////////////////////
//~ Movement operations
void sim_ent_set_linear_velocity(Entity *ent, Vec2 velocity);
void sim_ent_set_angular_velocity(Entity *ent, f32 velocity);
void sim_ent_apply_linear_impulse(Entity *ent, Vec2 impulse, Vec2 world_point);
void sim_ent_apply_linear_impulse_to_center(Entity *ent, Vec2 impulse);
void sim_ent_apply_force_to_center(Entity *ent, Vec2 force);
void sim_ent_apply_angular_impulse(Entity *ent, f32 impulse);
void sim_ent_apply_torque(Entity *ent, f32 torque);
void SetLinearVelocity(Entity *ent, Vec2 velocity);
void SetAngularVelocity(Entity *ent, f32 velocity);
void ApplyLinearImpulse(Entity *ent, Vec2 impulse, Vec2 world_point);
void ApplyLinearImpulseToCenter(Entity *ent, Vec2 impulse);
void ApplyForceToCenter(Entity *ent, Vec2 force);
void ApplyAngularImpulse(Entity *ent, f32 impulse);
void ApplyTorque(Entity *ent, f32 torque);
////////////////////////////////
//~ Tile operations
Entity *sim_tile_chunk_from_chunk_index(Snapshot *ss, Vec2I32 chunk_index);
Entity *sim_tile_chunk_from_world_tile_index(Snapshot *ss, Vec2I32 world_tile_index);
TileKind sim_get_chunk_tile(Entity *chunk_ent, Vec2I32 local_tile_index);
Entity *TileChunkFromChunkIndex(Snapshot *ss, Vec2I32 chunk_index);
Entity *TileChunkFromWorldTileIndex(Snapshot *ss, Vec2I32 world_tile_index);
TileKind TileKindFromChunk(Entity *chunk_ent, Vec2I32 local_tile_index);
////////////////////////////////
//~ Lerp operations
void sim_ent_lerp(Entity *e, Entity *e0, Entity *e1, f64 blend);
void LerpEntity(Entity *e, Entity *e0, Entity *e1, f64 blend);
////////////////////////////////
//~ Sync operations
void sim_ent_sync_acquire_tree(Entity *local_parent, Entity *remote, EntityId remote_player);
void sim_ent_sync(Entity *local, Entity *remote);
void CreateMissingEntitiesFromSnapshots(Entity *local_parent, Entity *remote, EntityId remote_player);
void SyncEntity(Entity *local, Entity *remote);
////////////////////////////////
//~ Encode / decode operations
void sim_ent_encode(BB_Writer *bw, Entity *e0, Entity *e1);
void sim_ent_decode(BB_Reader *br, Entity *e);
void EncodeEntity(BB_Writer *bw, Entity *e0, Entity *e1);
void DecodeEntity(BB_Reader *br, Entity *e);

View File

@ -9,8 +9,8 @@ internal b32 can_contact(Entity *e0, Entity *e1)
{
b32 result = 0;
result = e0 != e1 &&
!sim_ent_id_eq(e0->top, e1->top) &&
!(sim_ent_has_prop(e0, Prop_Wall) && sim_ent_has_prop(e1, Prop_Wall));
!EqEntityId(e0->top, e1->top) &&
!(HasProp(e0, Prop_Wall) && HasProp(e1, Prop_Wall));
return result;
}
@ -23,25 +23,25 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_
EntityId local_player = ss->local_player;
phys_collision_callback_func *collision_callback = ctx->collision_callback;
Entity *root = sim_ent_from_id(ss, SIM_ENT_ROOT_ID);
Entity *root = EntityFromId(ss, RootEntityId);
u64 tick = ss->tick;
for (u64 check0_index = 0; check0_index < ss->num_ents_reserved; ++check0_index) {
Entity *check0 = &ss->ents[check0_index];
if (!sim_ent_is_valid_and_active(check0)) continue;
if (!(sim_ent_has_prop(check0, Prop_Solid) || sim_ent_has_prop(check0, Prop_Sensor))) continue;
if (!IsValidAndActive(check0)) continue;
if (!(HasProp(check0, Prop_Solid) || HasProp(check0, Prop_Sensor))) continue;
if (check0->local_collider.count <= 0) continue;
Xform check0_xf = sim_ent_get_xform(check0);
Xform check0_xf = XformFromEntity(check0);
CLD_Shape check0_collider = check0->local_collider;
Aabb aabb = CLD_AabbFromShape(&check0_collider, check0_xf);
SpaceIter iter = space_iter_begin_aabb(space, aabb);
SpaceEntry *space_entry;
while ((space_entry = space_iter_next(&iter)) != 0) {
Entity *check1 = sim_ent_from_id(ss, space_entry->ent);
if (!sim_ent_is_valid_and_active(check1)) continue;
if (!(sim_ent_has_prop(check1, Prop_Solid) || sim_ent_has_prop(check1, Prop_Sensor))) continue;
Entity *check1 = EntityFromId(ss, space_entry->ent);
if (!IsValidAndActive(check1)) continue;
if (!(HasProp(check1, Prop_Solid) || HasProp(check1, Prop_Sensor))) continue;
if (check1->local_collider.count <= 0) continue;
if (!can_contact(check0, check1)) continue;
@ -56,20 +56,20 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_
e0 = check0;
e1 = check1;
e0_xf = check0_xf;
e1_xf = sim_ent_get_xform(check1);
e1_xf = XformFromEntity(check1);
e0_collider = check0_collider;
e1_collider = check1->local_collider;
} else {
e0 = check1;
e1 = check0;
e0_xf = sim_ent_get_xform(check1);
e0_xf = XformFromEntity(check1);
e1_xf = check0_xf;
e0_collider = check1->local_collider;
e1_collider = check0_collider;
}
EntityId constraint_id = sim_ent_contact_constraint_id_from_contacting_ids(local_player, e0->id, e1->id);
Entity *constraint_ent = sim_ent_from_id(ss, constraint_id);
EntityId constraint_id = ContactConstraintIdFromContactingIds(local_player, e0->id, e1->id);
Entity *constraint_ent = EntityFromId(ss, constraint_id);
if (constraint_ent->valid) {
if (constraint_ent->contact_constraint_data.last_phys_iteration >= phys_iteration) {
@ -93,17 +93,17 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_
if (!constraint_ent->valid) {
is_start = 1;
/* Create constraint */
constraint_ent = sim_ent_acquire_local_with_id(root, constraint_id);
constraint_ent = AcquireLocalEntityWithId(root, constraint_id);
constraint_ent->contact_constraint_data.e0 = e0->id;
constraint_ent->contact_constraint_data.e1 = e1->id;
/* Both entities must be solid and one must be dynamic for a solve to be necessary. */
constraint_ent->contact_constraint_data.skip_solve = !sim_ent_has_prop(e0, Prop_Solid) || !sim_ent_has_prop(e1, Prop_Solid) ||
!(sim_ent_has_prop(e0, Prop_Dynamic) || sim_ent_has_prop(e1, Prop_Dynamic));
sim_ent_enable_prop(constraint_ent, Prop_Active);
constraint_ent->contact_constraint_data.skip_solve = !HasProp(e0, Prop_Solid) || !HasProp(e1, Prop_Solid) ||
!(HasProp(e0, Prop_Dynamic) || HasProp(e1, Prop_Dynamic));
EnableProp(constraint_ent, Prop_Active);
/* TODO: Should we recalculate normal as more contact points are added? */
sim_ent_enable_prop(constraint_ent, Prop_ContactConstraint);
sim_ent_activate(constraint_ent, tick);
EnableProp(constraint_ent, Prop_ContactConstraint);
ActivateEntity(constraint_ent, tick);
}
constraint = &constraint_ent->contact_constraint_data;
constraint->normal = collision_result.normal;
@ -228,12 +228,12 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_
/* TODO: Remove this (debugging) */
#if COLLIDER_DEBUG && COLLIDER_DEBUG_DETAILED
{
EntityId dbg_ent_id = sim_ent_collision_debug_id_from_ids(local_player, e0->id, e1->id);
Entity *dbg_ent = sim_ent_from_id(ss, dbg_ent_id);
EntityId dbg_ent_id = CollisionDebugIdFromIds(local_player, e0->id, e1->id);
Entity *dbg_ent = EntityFromId(ss, dbg_ent_id);
if (!dbg_ent->valid) {
/* FIXME: Entity never released */
dbg_ent = sim_ent_acquire_local_with_id(root, dbg_ent_id);
sim_ent_enable_prop(dbg_ent, Prop_CollisionDebug);
dbg_ent = AcquireLocalEntityWithId(root, dbg_ent_id);
EnableProp(dbg_ent, Prop_CollisionDebug);
}
CollisionDebugData *dbg = &dbg_ent->collision_debug_data;
@ -272,20 +272,20 @@ void phys_prepare_contacts(PhysStepCtx *ctx, u64 phys_iteration)
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *constraint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(constraint_ent)) continue;
if (!sim_ent_has_prop(constraint_ent, Prop_ContactConstraint)) continue;
if (!ShouldSimulate(constraint_ent)) continue;
if (!HasProp(constraint_ent, Prop_ContactConstraint)) continue;
ContactConstraint *constraint = &constraint_ent->contact_constraint_data;
u32 num_points = constraint->num_points;
Entity *e0 = sim_ent_from_id(ss, constraint->e0);
Entity *e1 = sim_ent_from_id(ss, constraint->e1);
if (constraint->last_phys_iteration >= phys_iteration && num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) {
Entity *e0 = EntityFromId(ss, constraint->e0);
Entity *e1 = EntityFromId(ss, constraint->e1);
if (constraint->last_phys_iteration >= phys_iteration && num_points > 0 && IsValidAndActive(e0) && IsValidAndActive(e1)) {
Vec2 normal = constraint->normal;
Vec2 tangent = PerpVec2(normal);
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
Xform e0_xf = XformFromEntity(e0);
Xform e1_xf = XformFromEntity(e1);
/* TODO: Cache this */
/* Calculate masses */
@ -295,14 +295,14 @@ void phys_prepare_contacts(PhysStepCtx *ctx, u64 phys_iteration)
f32 inv_i1 = 0;
{
/* If not simulated locally or ent is not dynamic, pretend contact mass is infinite */
if (sim_ent_should_simulate(e0) && sim_ent_has_prop(e0, Prop_Dynamic)) {
if (ShouldSimulate(e0) && HasProp(e0, Prop_Dynamic)) {
f32 scale = AbsF32(DeterminantFromXform(e0_xf));
f32 scaled_mass = e0->mass_unscaled * scale;
f32 scaled_inertia = e0->inertia_unscaled * scale;
inv_m0 = 1.f / scaled_mass;
inv_i0 = 1.f / scaled_inertia;
}
if (sim_ent_should_simulate(e1) && sim_ent_has_prop(e1, Prop_Dynamic)) {
if (ShouldSimulate(e1) && HasProp(e1, Prop_Dynamic)) {
f32 scale = AbsF32(DeterminantFromXform(e1_xf));
f32 scaled_mass = e1->mass_unscaled * scale;
f32 scaled_inertia = e1->inertia_unscaled * scale;
@ -346,8 +346,8 @@ void phys_prepare_contacts(PhysStepCtx *ctx, u64 phys_iteration)
} else {
/* Mark constraint for removal */
constraint_ent->contact_constraint_data.num_points = 0;
sim_ent_disable_prop(constraint_ent, Prop_Active);
sim_ent_enable_prop(constraint_ent, Prop_Release);
DisableProp(constraint_ent, Prop_Active);
EnableProp(constraint_ent, Prop_Release);
}
}
@ -356,19 +356,19 @@ void phys_prepare_contacts(PhysStepCtx *ctx, u64 phys_iteration)
/* Remove collision debug ents */
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *dbg_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(dbg_ent)) continue;
if (!sim_ent_has_prop(dbg_ent, Prop_CollisionDebug)) continue;
if (!ShouldSimulate(dbg_ent)) continue;
if (!HasProp(dbg_ent, Prop_CollisionDebug)) continue;
CollisionDebugData *dbg = &dbg_ent->collision_debug_data;
Entity *e0 = sim_ent_from_id(ss, dbg->e0);
Entity *e1 = sim_ent_from_id(ss, dbg->e1);
Entity *e0 = EntityFromId(ss, dbg->e0);
Entity *e1 = EntityFromId(ss, dbg->e1);
if (!(sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) ||
!(sim_ent_has_prop(e0, Prop_Solid) || sim_ent_has_prop(e0, Prop_Sensor)) ||
!(sim_ent_has_prop(e1, Prop_Solid) || sim_ent_has_prop(e1, Prop_Sensor))) {
if (!(ShouldSimulate(e0) && ShouldSimulate(e1)) ||
!(HasProp(e0, Prop_Solid) || HasProp(e0, Prop_Sensor)) ||
!(HasProp(e1, Prop_Solid) || HasProp(e1, Prop_Sensor))) {
/* Mark dbg ent for removal */
sim_ent_disable_prop(dbg_ent, Prop_Active);
sim_ent_enable_prop(dbg_ent, Prop_Release);
DisableProp(dbg_ent, Prop_Active);
EnableProp(dbg_ent, Prop_Release);
}
}
#endif
@ -381,16 +381,16 @@ void phys_warm_start_contacts(PhysStepCtx *ctx)
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *constraint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(constraint_ent)) continue;
if (!sim_ent_has_prop(constraint_ent, Prop_ContactConstraint)) continue;
if (!ShouldSimulate(constraint_ent)) continue;
if (!HasProp(constraint_ent, Prop_ContactConstraint)) continue;
ContactConstraint *constraint = &constraint_ent->contact_constraint_data;
u32 num_points = constraint->num_points;
Entity *e0 = sim_ent_from_id(ss, constraint->e0);
Entity *e1 = sim_ent_from_id(ss, constraint->e1);
Entity *e0 = EntityFromId(ss, constraint->e0);
Entity *e1 = EntityFromId(ss, constraint->e1);
if (num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1) && !constraint->skip_solve && !constraint->wrong_dir) {
if (num_points > 0 && IsValidAndActive(e0) && IsValidAndActive(e1) && !constraint->skip_solve && !constraint->wrong_dir) {
f32 inv_m0 = constraint->inv_m0;
f32 inv_m1 = constraint->inv_m1;
f32 inv_i0 = constraint->inv_i0;
@ -419,10 +419,10 @@ void phys_warm_start_contacts(PhysStepCtx *ctx)
w1 += WedgeVec2(vcp1, impulse) * inv_i1;
}
sim_ent_set_linear_velocity(e0, v0);
sim_ent_set_angular_velocity(e0, w0);
sim_ent_set_linear_velocity(e1, v1);
sim_ent_set_angular_velocity(e1, w1);
SetLinearVelocity(e0, v0);
SetAngularVelocity(e0, w0);
SetLinearVelocity(e1, v1);
SetAngularVelocity(e1, w1);
}
}
}
@ -433,13 +433,13 @@ void phys_solve_contacts(PhysStepCtx *ctx, f32 dt, b32 apply_bias)
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *constraint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(constraint_ent)) continue;
if (!sim_ent_has_prop(constraint_ent, Prop_ContactConstraint)) continue;
if (!ShouldSimulate(constraint_ent)) continue;
if (!HasProp(constraint_ent, Prop_ContactConstraint)) continue;
ContactConstraint *constraint = &constraint_ent->contact_constraint_data;
Entity *e0 = sim_ent_from_id(ss, constraint->e0);
Entity *e1 = sim_ent_from_id(ss, constraint->e1);
Entity *e0 = EntityFromId(ss, constraint->e0);
Entity *e1 = EntityFromId(ss, constraint->e1);
Vec2 v0 = e0->linear_velocity;
Vec2 v1 = e1->linear_velocity;
@ -447,9 +447,9 @@ void phys_solve_contacts(PhysStepCtx *ctx, f32 dt, b32 apply_bias)
f32 w1 = e1->angular_velocity;
u32 num_points = constraint->num_points;
if (num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1) && !constraint->skip_solve && !constraint->wrong_dir) {
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
if (num_points > 0 && IsValidAndActive(e0) && IsValidAndActive(e1) && !constraint->skip_solve && !constraint->wrong_dir) {
Xform e0_xf = XformFromEntity(e0);
Xform e1_xf = XformFromEntity(e1);
f32 inv_m0 = constraint->inv_m0;
f32 inv_m1 = constraint->inv_m1;
@ -536,10 +536,10 @@ void phys_solve_contacts(PhysStepCtx *ctx, f32 dt, b32 apply_bias)
w1 += WedgeVec2(vcp1, impulse) * inv_i1;
}
sim_ent_set_linear_velocity(e0, v0);
sim_ent_set_angular_velocity(e0, w0);
sim_ent_set_linear_velocity(e1, v1);
sim_ent_set_angular_velocity(e1, w1);
SetLinearVelocity(e0, v0);
SetAngularVelocity(e0, w0);
SetLinearVelocity(e1, v1);
SetAngularVelocity(e1, w1);
}
}
}
@ -571,17 +571,17 @@ void phys_prepare_motor_joints(PhysStepCtx *ctx)
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, Prop_MotorJoint)) continue;
if (!ShouldSimulate(joint_ent)) continue;
if (!HasProp(joint_ent, Prop_MotorJoint)) continue;
MotorJoint *joint = &joint_ent->motor_joint_data;
Entity *e0 = sim_ent_from_id(ss, joint->e0);
Entity *e1 = sim_ent_from_id(ss, joint->e1);
Entity *e0 = EntityFromId(ss, joint->e0);
Entity *e1 = EntityFromId(ss, joint->e1);
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
if (ShouldSimulate(e0) && ShouldSimulate(e1)) {
Xform e0_xf = XformFromEntity(e0);
Xform e1_xf = XformFromEntity(e1);
/* TODO: Cache this */
/* Calculate masses */
@ -623,8 +623,8 @@ void phys_prepare_motor_joints(PhysStepCtx *ctx)
#endif
} else {
/* Mark joint for removal */
sim_ent_disable_prop(joint_ent, Prop_Active);
sim_ent_enable_prop(joint_ent, Prop_Release);
DisableProp(joint_ent, Prop_Active);
EnableProp(joint_ent, Prop_Release);
}
}
}
@ -635,16 +635,16 @@ void phys_warm_start_motor_joints(PhysStepCtx *ctx)
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, Prop_MotorJoint)) continue;
if (!ShouldSimulate(joint_ent)) continue;
if (!HasProp(joint_ent, Prop_MotorJoint)) continue;
MotorJoint *joint = &joint_ent->motor_joint_data;
Entity *e0 = sim_ent_from_id(ss, joint->e0);
Entity *e1 = sim_ent_from_id(ss, joint->e1);
Entity *e0 = EntityFromId(ss, joint->e0);
Entity *e1 = EntityFromId(ss, joint->e1);
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
Xform e0_xf = XformFromEntity(e0);
Xform e1_xf = XformFromEntity(e1);
f32 inv_m0 = joint->inv_m0;
f32 inv_m1 = joint->inv_m1;
@ -654,8 +654,8 @@ void phys_warm_start_motor_joints(PhysStepCtx *ctx)
Vec2 vcp0 = SubVec2(MulXformV2(e0_xf, joint->point_local_e0), e0_xf.og);
Vec2 vcp1 = SubVec2(MulXformV2(e1_xf, joint->point_local_e1), e1_xf.og);
sim_ent_set_linear_velocity(e0, SubVec2(e0->linear_velocity, MulVec2(joint->linear_impulse, inv_m0)));
sim_ent_set_linear_velocity(e1, AddVec2(e1->linear_velocity, MulVec2(joint->linear_impulse, inv_m1)));
SetLinearVelocity(e0, SubVec2(e0->linear_velocity, MulVec2(joint->linear_impulse, inv_m0)));
SetLinearVelocity(e1, AddVec2(e1->linear_velocity, MulVec2(joint->linear_impulse, inv_m1)));
e0->angular_velocity -= (WedgeVec2(vcp0, joint->linear_impulse) + joint->angular_impulse) * inv_i0;
e1->angular_velocity += (WedgeVec2(vcp1, joint->linear_impulse) + joint->angular_impulse) * inv_i1;
}
@ -667,16 +667,16 @@ void phys_solve_motor_joints(PhysStepCtx *ctx, f32 dt)
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, Prop_MotorJoint)) continue;
if (!ShouldSimulate(joint_ent)) continue;
if (!HasProp(joint_ent, Prop_MotorJoint)) continue;
MotorJoint *joint = &joint_ent->motor_joint_data;
Entity *e0 = sim_ent_from_id(ss, joint->e0);
Entity *e1 = sim_ent_from_id(ss, joint->e1);
Entity *e0 = EntityFromId(ss, joint->e0);
Entity *e1 = EntityFromId(ss, joint->e1);
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
Xform e0_xf = XformFromEntity(e0);
Xform e1_xf = XformFromEntity(e1);
f32 inv_m0 = joint->inv_m0;
f32 inv_m1 = joint->inv_m1;
@ -731,10 +731,10 @@ void phys_solve_motor_joints(PhysStepCtx *ctx, f32 dt)
w1 += WedgeVec2(vcp1, delta) * inv_i1;
}
sim_ent_set_linear_velocity(e0, v0);
sim_ent_set_angular_velocity(e0, w0);
sim_ent_set_linear_velocity(e1, v1);
sim_ent_set_angular_velocity(e1, w1);
SetLinearVelocity(e0, v0);
SetAngularVelocity(e0, w0);
SetLinearVelocity(e1, v1);
SetAngularVelocity(e1, w1);
}
}
@ -773,13 +773,13 @@ void phys_prepare_mouse_joints(PhysStepCtx *ctx)
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, Prop_MouseJoint)) continue;
if (!ShouldSimulate(joint_ent)) continue;
if (!HasProp(joint_ent, Prop_MouseJoint)) continue;
MouseJoint *joint = &joint_ent->mouse_joint_data;
Entity *ent = sim_ent_from_id(ss, joint->target);
if (sim_ent_should_simulate(ent)) {
Xform xf = sim_ent_get_xform(ent);
Entity *ent = EntityFromId(ss, joint->target);
if (ShouldSimulate(ent)) {
Xform xf = XformFromEntity(ent);
/* TODO: Cache this */
/* Calculate masses */
@ -808,8 +808,8 @@ void phys_prepare_mouse_joints(PhysStepCtx *ctx)
#endif
} else {
/* Mark joint for removal */
sim_ent_disable_prop(joint_ent, Prop_Active);
sim_ent_enable_prop(joint_ent, Prop_Release);
DisableProp(joint_ent, Prop_Active);
EnableProp(joint_ent, Prop_Release);
}
}
}
@ -820,18 +820,18 @@ void phys_warm_start_mouse_joints(PhysStepCtx *ctx)
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, Prop_MouseJoint)) continue;
if (!ShouldSimulate(joint_ent)) continue;
if (!HasProp(joint_ent, Prop_MouseJoint)) continue;
MouseJoint *joint = &joint_ent->mouse_joint_data;
Entity *ent = sim_ent_from_id(ss, joint->target);
if (sim_ent_should_simulate(ent)) {
Entity *ent = EntityFromId(ss, joint->target);
if (ShouldSimulate(ent)) {
f32 inv_m = joint->inv_m;
f32 inv_i = joint->inv_i;
Xform xf = sim_ent_get_xform(ent);
Xform xf = XformFromEntity(ent);
Vec2 vcp = SubVec2(MulXformV2(xf, joint->point_local_start), xf.og);
sim_ent_set_linear_velocity(ent, AddVec2(ent->linear_velocity, MulVec2(joint->linear_impulse, inv_m)));
sim_ent_set_angular_velocity(ent, ent->angular_velocity + ((WedgeVec2(vcp, joint->linear_impulse) + joint->angular_impulse) * inv_i));
SetLinearVelocity(ent, AddVec2(ent->linear_velocity, MulVec2(joint->linear_impulse, inv_m)));
SetAngularVelocity(ent, ent->angular_velocity + ((WedgeVec2(vcp, joint->linear_impulse) + joint->angular_impulse) * inv_i));
}
}
}
@ -842,12 +842,12 @@ void phys_solve_mouse_joints(PhysStepCtx *ctx, f32 dt)
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, Prop_MouseJoint)) continue;
if (!ShouldSimulate(joint_ent)) continue;
if (!HasProp(joint_ent, Prop_MouseJoint)) continue;
MouseJoint *joint = &joint_ent->mouse_joint_data;
Entity *ent = sim_ent_from_id(ss, joint->target);
if (sim_ent_should_simulate(ent)) {
Entity *ent = EntityFromId(ss, joint->target);
if (ShouldSimulate(ent)) {
Vec2 v = ent->linear_velocity;
f32 w = ent->angular_velocity;
@ -868,7 +868,7 @@ void phys_solve_mouse_joints(PhysStepCtx *ctx, f32 dt)
{
f32 max_impulse = joint->max_force / dt;
Xform xf = sim_ent_get_xform(ent);
Xform xf = XformFromEntity(ent);
Vec2 point_start = MulXformV2(xf, joint->point_local_start);
Vec2 point_end = joint->point_end;
@ -899,8 +899,8 @@ void phys_solve_mouse_joints(PhysStepCtx *ctx, f32 dt)
w += WedgeVec2(vcp, impulse) * inv_i;
}
sim_ent_set_linear_velocity(ent, v);
sim_ent_set_angular_velocity(ent, w);
SetLinearVelocity(ent, v);
SetAngularVelocity(ent, w);
}
}
}
@ -938,17 +938,17 @@ void phys_prepare_weld_joints(PhysStepCtx *ctx)
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, Prop_WeldJoint)) continue;
if (!ShouldSimulate(joint_ent)) continue;
if (!HasProp(joint_ent, Prop_WeldJoint)) continue;
/* TODO: Lookup and disable collision for any contacts between e0 & e1? */
WeldJoint *joint = &joint_ent->weld_joint_data;
Entity *e0 = sim_ent_from_id(ss, joint->e0);
Entity *e1 = sim_ent_from_id(ss, joint->e1);
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
Entity *e0 = EntityFromId(ss, joint->e0);
Entity *e1 = EntityFromId(ss, joint->e1);
if (ShouldSimulate(e0) && ShouldSimulate(e1)) {
Xform e0_xf = XformFromEntity(e0);
Xform e1_xf = XformFromEntity(e1);
f32 inv_m0;
f32 inv_m1;
@ -975,8 +975,8 @@ void phys_prepare_weld_joints(PhysStepCtx *ctx)
#endif
} else {
/* Mark joint for removal */
sim_ent_disable_prop(joint_ent, Prop_Active);
sim_ent_enable_prop(joint_ent, Prop_Release);
DisableProp(joint_ent, Prop_Active);
EnableProp(joint_ent, Prop_Release);
}
}
}
@ -987,30 +987,30 @@ void phys_warm_start_weld_joints(PhysStepCtx *ctx)
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, Prop_WeldJoint)) continue;
if (!ShouldSimulate(joint_ent)) continue;
if (!HasProp(joint_ent, Prop_WeldJoint)) continue;
WeldJoint *joint = &joint_ent->weld_joint_data;
#if 0
Entity *e0 = sim_ent_from_id(ss, joint->e0);
if (sim_ent_should_simulate(e0)) {
Entity *e0 = EntityFromId(ss, joint->e0);
if (ShouldSimulate(e0)) {
f32 inv_m = joint->inv_m0;
f32 inv_i = joint->inv_i0;
Xform xf = sim_ent_get_xform(e1);
Xform xf = XformFromEntity(e1);
Vec2 vcp = SubVec2(MulXformV2(xf, joint->point_local_start), xf.og);
sim_ent_set_linear_velocity(ent, AddVec2(ent->linear_velocity, MulVec2(joint->linear_impulse, inv_m)));
SetLinearVelocity(ent, AddVec2(ent->linear_velocity, MulVec2(joint->linear_impulse, inv_m)));
ent->angular_velocity += (WedgeVec2(vcp, joint->linear_impulse) + joint->angular_impulse) * inv_i;
}
#endif
#if 1
Entity *e1 = sim_ent_from_id(ss, joint->e1);
if (sim_ent_should_simulate(e1)) {
Entity *e1 = EntityFromId(ss, joint->e1);
if (ShouldSimulate(e1)) {
f32 inv_m = joint->inv_m1;
f32 inv_i = joint->inv_i1;
sim_ent_set_linear_velocity(e1, AddVec2(e1->linear_velocity, MulVec2(joint->linear_impulse1, inv_m)));
sim_ent_set_angular_velocity(e1, e1->angular_velocity + joint->angular_impulse1 * inv_i);
SetLinearVelocity(e1, AddVec2(e1->linear_velocity, MulVec2(joint->linear_impulse1, inv_m)));
SetAngularVelocity(e1, e1->angular_velocity + joint->angular_impulse1 * inv_i);
}
#else
LAX joint;
@ -1024,15 +1024,15 @@ void phys_solve_weld_joints(PhysStepCtx *ctx, f32 dt)
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, Prop_WeldJoint)) continue;
if (!ShouldSimulate(joint_ent)) continue;
if (!HasProp(joint_ent, Prop_WeldJoint)) continue;
WeldJoint *joint = &joint_ent->weld_joint_data;
Entity *e0 = sim_ent_from_id(ss, joint->e0);
Entity *e1 = sim_ent_from_id(ss, joint->e1);
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
Xform xf0 = sim_ent_get_xform(e0);
Xform xf1 = sim_ent_get_xform(e1);
Entity *e0 = EntityFromId(ss, joint->e0);
Entity *e1 = EntityFromId(ss, joint->e1);
if (ShouldSimulate(e0) && ShouldSimulate(e1)) {
Xform xf0 = XformFromEntity(e0);
Xform xf1 = XformFromEntity(e1);
Xform target_xf1 = MulXform(xf0, joint->xf0_to_xf1);
@ -1076,8 +1076,8 @@ void phys_solve_weld_joints(PhysStepCtx *ctx, f32 dt)
}
sim_ent_set_linear_velocity(e1, v1);
sim_ent_set_angular_velocity(e1, w1);
SetLinearVelocity(e1, v1);
SetAngularVelocity(e1, w1);
}
}
}
@ -1088,7 +1088,7 @@ void phys_solve_weld_joints(PhysStepCtx *ctx, f32 dt)
internal Xform get_derived_xform(Entity *ent, f32 dt)
{
Xform xf = sim_ent_get_xform(ent);
Xform xf = XformFromEntity(ent);
Vec2 step_linear_velocity = MulVec2(ent->linear_velocity, dt);
f32 step_angular_velocity = ent->angular_velocity * dt;
@ -1104,10 +1104,10 @@ void phys_integrate_forces(PhysStepCtx *ctx, f32 dt)
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (!ShouldSimulate(ent)) continue;
b32 is_dynamic = sim_ent_has_prop(ent, Prop_Dynamic);
b32 is_kinematic = sim_ent_has_prop(ent, Prop_Kinematic);
b32 is_dynamic = HasProp(ent, Prop_Dynamic);
b32 is_kinematic = HasProp(ent, Prop_Kinematic);
if (is_dynamic || is_kinematic) {
Vec2 linear_velocity = ent->linear_velocity;
f32 angular_velocity = ent->angular_velocity;
@ -1116,7 +1116,7 @@ void phys_integrate_forces(PhysStepCtx *ctx, f32 dt)
/* Integrate forces */
if (is_dynamic) {
Xform xf = sim_ent_get_xform(ent);
Xform xf = XformFromEntity(ent);
f32 det_abs = AbsF32(DeterminantFromXform(xf));
f32 mass = ent->mass_unscaled * det_abs;
f32 inertia = ent->inertia_unscaled * det_abs;
@ -1131,8 +1131,8 @@ void phys_integrate_forces(PhysStepCtx *ctx, f32 dt)
angular_velocity *= angular_damping_factor;
/* Update entity */
sim_ent_set_linear_velocity(ent, linear_velocity);
sim_ent_set_angular_velocity(ent, angular_velocity);
SetLinearVelocity(ent, linear_velocity);
SetAngularVelocity(ent, angular_velocity);
ent->force = VEC2(0, 0);
ent->torque = 0;
}
@ -1146,11 +1146,11 @@ void phys_integrate_velocities(PhysStepCtx *ctx, f32 dt)
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (!sim_ent_has_prop(ent, Prop_Dynamic) && !sim_ent_has_prop(ent, Prop_Kinematic)) continue;
if (!ShouldSimulate(ent)) continue;
if (!HasProp(ent, Prop_Dynamic) && !HasProp(ent, Prop_Kinematic)) continue;
Xform xf = get_derived_xform(ent, dt);
sim_ent_set_xform(ent, xf);
SetEntityXform(ent, xf);
}
}
@ -1167,13 +1167,13 @@ f32 phys_determine_earliest_toi(PhysStepCtx *ctx, f32 step_dt, f32 tolerance, u3
for (u64 e0_index = 0; e0_index < ss->num_ents_reserved; ++e0_index) {
Entity *e0 = &ss->ents[e0_index];
if (!sim_ent_should_simulate(e0)) continue;
if (!(sim_ent_has_prop(e0, Prop_Solid) || sim_ent_has_prop(e0, Prop_Sensor))) continue;
if (!sim_ent_has_prop(e0, Prop_Toi)) continue;
if (!ShouldSimulate(e0)) continue;
if (!(HasProp(e0, Prop_Solid) || HasProp(e0, Prop_Sensor))) continue;
if (!HasProp(e0, Prop_Toi)) continue;
if (e0->local_collider.count <= 0) continue;
CLD_Shape e0_collider = e0->local_collider;
Xform e0_xf_t0 = sim_ent_get_xform(e0);
Xform e0_xf_t0 = XformFromEntity(e0);
Xform e0_xf_t1 = get_derived_xform(e0, step_dt);
/* TODO: Use swept aabb rather than combined aabb. This should prevent spikes from bullets returning 0 positive TOIs with irrelevant entities. */
@ -1184,14 +1184,14 @@ f32 phys_determine_earliest_toi(PhysStepCtx *ctx, f32 step_dt, f32 tolerance, u3
SpaceIter iter = space_iter_begin_aabb(space, combined_aabb);
SpaceEntry *entry;
while ((entry = space_iter_next(&iter)) != 0) {
Entity *e1 = sim_ent_from_id(ss, entry->ent);
if (!sim_ent_should_simulate(e1)) continue;
if (!(sim_ent_has_prop(e1, Prop_Solid) || sim_ent_has_prop(e1, Prop_Sensor))) continue;
Entity *e1 = EntityFromId(ss, entry->ent);
if (!ShouldSimulate(e1)) continue;
if (!(HasProp(e1, Prop_Solid) || HasProp(e1, Prop_Sensor))) continue;
if (e1->local_collider.count <= 0) continue;
if (!can_contact(e0, e1)) continue;
CLD_Shape e1_collider = e1->local_collider;
Xform e1_xf_t0 = sim_ent_get_xform(e1);
Xform e1_xf_t0 = XformFromEntity(e1);
Xform e1_xf_t1 = get_derived_xform(e1, step_dt);
f32 t = CLD_TimeOfImpact(&e0_collider, &e1_collider, e0_xf_t0, e1_xf_t0, e0_xf_t1, e1_xf_t1, tolerance, max_iterations);
@ -1216,9 +1216,9 @@ void phys_update_aabbs(PhysStepCtx *ctx)
Space *space = ctx->sim_step_ctx->accel->space;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Entity *ent = &ss->ents[sim_ent_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
if (!IsValidAndActive(ent)) continue;
if (ent->local_collider.count > 0) {
Xform xf = sim_ent_get_xform(ent);
Xform xf = XformFromEntity(ent);
SpaceEntry *space_entry = space_entry_from_handle(space, ent->space_handle);
if (!space_entry->valid) {
space_entry = space_entry_acquire(space, ent->id);

View File

@ -49,7 +49,7 @@ Readonly Client **_g_sim_client_nil = &G.nil_client;
/* Accessed via `sim_snapshot_nil()` */
Readonly Snapshot **_g_sim_snapshot_nil = &G.nil_snapshot;
/* Accessed via `sim_ent_nil()` */
/* Accessed via `NilEntity()` */
Readonly Entity **_g_sim_ent_nil = &G.nil_ent;
void StartupSim(void)
@ -75,7 +75,7 @@ void StartupSim(void)
G.nil_ent = PushStruct(G.nil_arena, Entity);
G.nil_ent->ss = sim_snapshot_nil();
G.nil_ent->valid = 0;
G.nil_ent->id = SIM_ENT_NIL_ID;
G.nil_ent->id = NilEntityId;
G.nil_ent->_local_xform = XformIdentity;
G.nil_ent->_xform = XformIdentity;
G.nil_ent->_is_xform_dirty = 0;
@ -328,7 +328,7 @@ Snapshot *sim_snapshot_acquire(Client *client, Snapshot *src, u64 tick)
if (ss->num_ents_reserved == 0) {
/* Copying from nil snapshot, need to create blank & root entity */
/* Push blank ent at index 0 (because index 0 is never valid anyway since it maps to sim_ent_nil()) */
/* Push blank ent at index 0 (because index 0 is never valid anyway since it maps to NilEntity()) */
{
PushStruct(ss->ents_arena, Entity);
++ss->num_ents_allocated;
@ -338,13 +338,13 @@ Snapshot *sim_snapshot_acquire(Client *client, Snapshot *src, u64 tick)
/* Push root ent with constant id */
{
Entity *root = PushStructNoZero(ss->ents_arena, Entity);
*root = *sim_ent_nil();
*root = *NilEntity();
root->ss = ss;
root->valid = 1;
root->is_root = 1;
root->mass_unscaled = F32Infinity;
root->inertia_unscaled = F32Infinity;
sim_ent_set_id(root, SIM_ENT_ROOT_ID);
SetEntityId(root, RootEntityId);
++ss->num_ents_allocated;
++ss->num_ents_reserved;
}
@ -592,12 +592,12 @@ void sim_snapshot_set_tile(Snapshot *ss, Vec2I32 world_tile_index, TileKind tile
{
Vec2I32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index);
EntityId chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index);
Entity *chunk_ent = sim_ent_from_id(ss, chunk_id);
EntityId chunk_id = TileChunkIdFromIndex(chunk_index);
Entity *chunk_ent = EntityFromId(ss, chunk_id);
if (!chunk_ent->valid) {
Entity *root = sim_ent_from_id(ss, SIM_ENT_ROOT_ID);
chunk_ent = sim_ent_acquire_sync_src_with_id(root, chunk_id);
sim_ent_enable_prop(chunk_ent, Prop_TileChunk);
Entity *root = EntityFromId(ss, RootEntityId);
chunk_ent = AcquireSyncSrcEntityWithId(root, chunk_id);
EnableProp(chunk_ent, Prop_TileChunk);
chunk_ent->tile_chunk_index = chunk_index;
}
@ -647,7 +647,7 @@ Snapshot *sim_snapshot_acquire_from_lerp(Client *client, Snapshot *ss0, Snapshot
Entity *e = &ss->ents[i];
Entity *e0 = &ss0->ents[i];
Entity *e1 = &ss1->ents[i];
sim_ent_lerp(e, e0, e1, blend);
LerpEntity(e, e0, e1, blend);
}
}
}
@ -669,36 +669,36 @@ void sim_snapshot_sync_ents(Snapshot *local_ss, Snapshot *remote_ss, EntityId re
* - Determine new UUids for newly created ents
*/
Entity *local_root = sim_ent_from_id(local_ss, SIM_ENT_ROOT_ID);
Entity *remote_root = sim_ent_from_id(remote_ss, SIM_ENT_ROOT_ID);
Entity *local_root = EntityFromId(local_ss, RootEntityId);
Entity *remote_root = EntityFromId(remote_ss, RootEntityId);
/* Create new ents from remote */
for (Entity *remote_top = sim_ent_from_id(remote_ss, remote_root->first); remote_top->valid; remote_top = sim_ent_from_id(remote_ss, remote_top->next)) {
sim_ent_sync_acquire_tree(local_root, remote_top, remote_player);
for (Entity *remote_top = EntityFromId(remote_ss, remote_root->first); remote_top->valid; remote_top = EntityFromId(remote_ss, remote_top->next)) {
CreateMissingEntitiesFromSnapshots(local_root, remote_top, remote_player);
}
/* Sync ents with remote, skipping index 0 (nil) & index 1 (root) */
for (u64 i = 2; i < local_ss->num_ents_reserved; ++i) {
Entity *local_ent = &local_ss->ents[i];
if (local_ent->valid && sim_ent_has_prop(local_ent, Prop_SyncDst)) {
b32 should_sync = sim_ent_id_eq(local_ent->owner, remote_player) || sim_ent_id_is_nil(remote_player);
if ((sync_flags & SIM_SYNC_FLAG_NOSYNC_PREDICTABLES) && sim_ent_id_eq(local_ent->predictor, local_ss->local_player)) {
if (local_ent->valid && HasProp(local_ent, Prop_SyncDst)) {
b32 should_sync = EqEntityId(local_ent->owner, remote_player) || IsNilEntityId(remote_player);
if ((sync_flags & SIM_SYNC_FLAG_NOSYNC_PREDICTABLES) && EqEntityId(local_ent->predictor, local_ss->local_player)) {
should_sync = 0;
}
if (should_sync) {
Entity *remote_ent = sim_ent_from_id(remote_ss, local_ent->id);
Entity *remote_ent = EntityFromId(remote_ss, local_ent->id);
if (remote_ent->valid) {
/* Copy all ent data from remote */
sim_ent_sync(local_ent, remote_ent);
SyncEntity(local_ent, remote_ent);
} else {
/* Remote ent is no longer valid / networked, release it */
sim_ent_enable_prop(local_ent, Prop_Release);
sim_ent_disable_prop(local_ent, Prop_SyncDst);
EnableProp(local_ent, Prop_Release);
DisableProp(local_ent, Prop_SyncDst);
}
}
}
}
sim_ent_release_all_with_prop(local_ss, Prop_Release);
ReleaseAllEntitiesWithProp(local_ss, Prop_Release);
}
@ -773,12 +773,12 @@ void sim_snapshot_encode(BB_Writer *bw, Client *receiver, Snapshot *ss0, Snapsho
BB_WriteDebugMarker(bw, StringFromStruct(&ss1->num_ents_reserved));
for (u64 i = 1; i < ss1->num_ents_reserved; ++i) {
Entity *e0 = sim_ent_nil();
Entity *e0 = NilEntity();
if (i < ss0->num_ents_reserved) {
e0 = &ss0->ents[i];
}
Entity *e1 = &ss1->ents[i];
sim_ent_encode(bw, e0, e1);
EncodeEntity(bw, e0, e1);
}
BB_WriteDebugMarker(bw, Lit("SNAPSHOT END"));
@ -840,7 +840,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
PushStructsNoZero(ss->ents_arena, Entity, reserve_diff);
for (u64 i = old_num_ents_reserved; i < ss->num_ents_reserved; ++i) {
Entity *e = &ss->ents[i];
*e = *sim_ent_nil();
*e = *NilEntity();
e->ss = ss;
}
} else if (reserve_diff < 0) {
@ -855,7 +855,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
for (u64 i = 1; i < ss->num_ents_reserved; ++i) {
Entity *e = &ss->ents[i];
e->ss = ss;
sim_ent_decode(br, e);
DecodeEntity(br, e);
}
BB_ReadDebugMarker(br, Lit("SNAPSHOT END"));
@ -900,7 +900,7 @@ void sim_snapshot_encode(BB_Writer *bw, Client *receiver, Snapshot *ss0, Snapsho
BB_AlignWriter(bw);
for (u64 i = 0; i < ss1->num_ents_reserved; ++i) {
Entity *e0 = sim_ent_nil();
Entity *e0 = NilEntity();
if (i < ss0->num_ents_reserved) {
e0 = &ss0->ents[i];
}
@ -917,7 +917,7 @@ void sim_snapshot_encode(BB_Writer *bw, Client *receiver, Snapshot *ss0, Snapsho
if (e1->valid) {
Entity *e1 = &ss1->ents[i];
sim_ent_encode(bw, e0, e1);
EncodeEntity(bw, e0, e1);
}
}
}
@ -961,7 +961,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
PushStructsNoZero(ss->ents_arena, Entity, reserve_diff);
for (u64 i = old_num_ents_reserved; i < ss->num_ents_reserved; ++i) {
Entity *e = &ss->ents[i];
*e = *sim_ent_nil();
*e = *NilEntity();
e->ss = ss;
}
}
@ -984,7 +984,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
Entity *e = sim_ent_from_index(ss, e);
Assert(e->valid); /* An entity that we don't have allocated should never have been marked for release */
if (e->valid) {
sim_ent_enable_prop(e, Prop_Release);
EnableProp(e, Prop_Release);
}
} else {
alloc_parent_index = BB_ReadUV();
@ -1019,13 +1019,13 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
if (n->is_new) {
u32 index = n->index;
Entity *parent = sim_ent_from_index(ss, n->alloc_parent_index);
Assert(!sim_ent_from_index(ss, index)->valid && !sim_ent_from_id(ss, alloc_ent_id)->valid); /* An entity that we have allocated already should never be marked for allocation */
Assert(!sim_ent_from_index(ss, index)->valid && !EntityFromId(ss, alloc_ent_id)->valid); /* An entity that we have allocated already should never be marked for allocation */
Assert(parent->valid); /* Parent for new entity allocation should always be valid */
if (parent->valid && index < ss->num_ents_reserved) {
Entity *ent = &ss->ents[index];
ent->valid = 1;
sim_ent_set_id(ent, n->alloc_ent_id);
sim_ent_link_parent(parent, ent);
SetEntityId(ent, n->alloc_ent_id);
LinkEntity(parent, ent);
} else {
/* Received an invalid entity allocation */
Assert(0);
@ -1039,7 +1039,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
u32 index = n->index;
Entity *e = sim_ent_from_index(ss, index);
if (e->valid) {
sim_ent_decode(&ent_br, e);
DecodeEntity(&ent_br, e);
} else {
/* Received delta for unallocated ent */
Assert(0);
@ -1058,7 +1058,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
PushStructsNoZero(ss->ents_arena, Entity, reserve_diff);
for (u64 i = old_num_ents_reserved; i < ss->num_ents_reserved; ++i) {
Entity *e = &ss->ents[i];
*e = *sim_ent_nil();
*e = *NilEntity();
e->ss = ss;
}
}
@ -1070,7 +1070,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
if (BB_ReadBit(br)) {
struct sim_ent_decode_node *n = PushStruct(scratch.arena, struct sim_ent_decode_node)
} else {
sim_ent_enable_prop(e, Prop_Release);
EnableProp(e, Prop_Release);
}
}
}
@ -1089,13 +1089,13 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
/* Why is an already released ent being marked as released? */
Assert(e->valid);
if (e->valid) {
sim_ent_enable_prop(e, Prop_Release);
EnableProp(e, Prop_Release);
}
} else {
sim_ent_decode(br, e);
DecodeEntity(br, e);
}
}
sim_ent_release_all_with_prop(ss, Prop_Release);
ReleaseAllEntitiesWithProp(ss, Prop_Release);
#endif
EndScratch(scratch);

View File

@ -3,7 +3,7 @@
/* Offset in bytes from start of space struct to start of entry array (assume adjacently allocated) */
#define SPACE_ENTRIES_OFFSET (sizeof(Space) + (sizeof(Space) % alignof(SpaceEntry)))
/* Accessed via sim_ent_nil() */
/* Accessed via NilEntity() */
Readonly SpaceEntry _g_space_entry_nil = { .valid = 0 };
Readonly SpaceCell _g_space_cell_nil = { .valid = 0 };
Readonly Space _g_space_nil = { .valid = 0 };

File diff suppressed because it is too large Load Diff