pp refactor progress
This commit is contained in:
parent
bb300b9ef4
commit
b25bd21b72
138
src/pp/pp_core.c
138
src/pp/pp_core.c
@ -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 */
|
||||
{
|
||||
|
||||
292
src/pp/pp_ent.c
292
src/pp/pp_ent.c
@ -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
|
||||
|
||||
151
src/pp/pp_ent.h
151
src/pp/pp_ent.h
@ -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);
|
||||
|
||||
318
src/pp/pp_phys.c
318
src/pp/pp_phys.c
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 };
|
||||
|
||||
514
src/pp/pp_step.c
514
src/pp/pp_step.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user