This commit is contained in:
jacob 2025-11-13 22:39:14 -06:00
parent 3a21ad4886
commit eb38e3d926
5 changed files with 95 additions and 12 deletions

View File

@ -40,7 +40,7 @@
#define SIM_TILES_PER_UNIT_SQRT (4) #define SIM_TILES_PER_UNIT_SQRT (4)
#define SIM_TILES_PER_CHUNK_SQRT (16) #define SIM_TILES_PER_CHUNK_SQRT (16)
#define SIM_TICKS_PER_SECOND 50 #define SIM_TICKS_PER_SECOND 100
//#define SIM_TIMESCALE 1 //#define SIM_TIMESCALE 1
/* Like USER_INTERP_RATIO, but applies to snapshots received by the local sim from the /* Like USER_INTERP_RATIO, but applies to snapshots received by the local sim from the
* master sim (how far back in time should the client render the server's state) */ * master sim (how far back in time should the client render the server's state) */

View File

@ -307,6 +307,7 @@ JobDef(S_SimWorker, _, __)
S_World *world = PushStruct(perm, S_World); S_World *world = PushStruct(perm, S_World);
world->ents = ArenaFirst(ents_arena, S_Ent); world->ents = ArenaFirst(ents_arena, S_Ent);
i64 first_free_ent_num = 0; i64 first_free_ent_num = 0;
i64 sim_time_ns = 0;
////////////////////////////// //////////////////////////////
//- Sim loop //- Sim loop
@ -322,6 +323,8 @@ JobDef(S_SimWorker, _, __)
//- Begin sim frame //- Begin sim frame
i64 frame_begin_ns = TimeNs(); i64 frame_begin_ns = TimeNs();
i64 sim_dt_ns = NsFromSeconds(1) / SIM_TICKS_PER_SECOND;
f64 sim_dt = SecondsFromNs(sim_dt_ns);
////////////////////////////// //////////////////////////////
//- Create root ent //- Create root ent
@ -501,17 +504,48 @@ JobDef(S_SimWorker, _, __)
{ {
xf = XformWithWorldRotation(xf, AngleFromVec2(ent->look)); xf = XformWithWorldRotation(xf, AngleFromVec2(ent->look));
} }
xf.og = AddVec2(xf.og, ent->move); xf.og = AddVec2(xf.og, MulVec2(ent->move, ent->move_speed));
ent->local_xf = xf; ent->local_xf = xf;
} }
////////////////////////////// //////////////////////////////
//- Compute final world transforms //- Compute pre-solve world transforms
for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); ent->active; ent = S_NextEnt(frame_arena, &iter)) for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); ent->active; ent = S_NextEnt(frame_arena, &iter))
{ {
S_Ent *parent = S_EntFromKey(&lookup, ent->parent); ent->old_world_xf = ent->world_xf;
ent->world_xf = MulXform(parent->world_xf, ent->local_xf); ent->world_xf = MulXform(S_EntFromKey(&lookup, ent->parent)->world_xf, ent->local_xf);
}
//////////////////////////////
//- Solve followers
for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); ent->active; ent = S_NextEnt(frame_arena, &iter))
{
S_Ent *follow = S_EntFromKey(&lookup, ent->follow);
if (follow->active)
{
f32 follow_speed = 20 * sim_dt;
Vec2 look_ratio = ZI;
look_ratio.x = 0.25;
look_ratio.y = (16.0 / 9.0) * look_ratio.x;
Vec2 target = MulXformV2(follow->world_xf, follow->local_shape.centroid);
target = AddVec2(target, MulVec2Vec2(follow->look, look_ratio));
Xform xf = ent->local_xf;
// xf.og = AddVec2(xf.og, SubVec2(follow->world_xf.og, follow->old_world_xf.og));
xf.og = LerpVec2(xf.og, target, follow_speed);
ent->local_xf = xf;
}
}
//////////////////////////////
//- Compute post-solve world transforms
for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); ent->active; ent = S_NextEnt(frame_arena, &iter))
{
ent->world_xf = MulXform(S_EntFromKey(&lookup, ent->parent)->world_xf, ent->local_xf);
} }
////////////////////////////// //////////////////////////////
@ -550,6 +584,7 @@ JobDef(S_SimWorker, _, __)
i64 frame_end_ns = TimeNs(); i64 frame_end_ns = TimeNs();
sim_time_ns += sim_dt_ns;
++world->tick; ++world->tick;
////////////////////////////// //////////////////////////////

View File

@ -71,6 +71,11 @@ Struct(S_Ent)
Vec2 move; Vec2 move;
Vec2 look; Vec2 look;
//////////////////////////////
//- Pre-solve data
Xform old_world_xf;
////////////////////////////// //////////////////////////////
//- Post-solve data //- Post-solve data

View File

@ -145,6 +145,7 @@ JobDef(V_VisWorker, _, __)
ent->tint = Color_Red; ent->tint = Color_Red;
ent->key = player_key; ent->key = player_key;
ent->camera = camera_key; ent->camera = camera_key;
ent->move_speed = 10;
{ {
ent->local_shape = S_ShapeFromDesc( ent->local_shape = S_ShapeFromDesc(
.mass = 10, .mass = 10,
@ -179,7 +180,8 @@ JobDef(V_VisWorker, _, __)
/* Test camera */ /* Test camera */
case 2: case 2:
{ {
// ent->key = camera_key; ent->key = camera_key;
ent->follow = player_key;
} break; } break;
default: default:
@ -199,7 +201,6 @@ JobDef(V_VisWorker, _, __)
ui_frame_flags |= UI_FrameFlag_Vsync * !!VSYNC; ui_frame_flags |= UI_FrameFlag_Vsync * !!VSYNC;
UI_Frame ui_frame = UI_BeginFrame(ui_frame_flags, swapchain_color); UI_Frame ui_frame = UI_BeginFrame(ui_frame_flags, swapchain_color);
WND_Frame window_frame = ui_frame.window_frame; WND_Frame window_frame = ui_frame.window_frame;
Vec2 ui_cursor = ui_frame.cursor_pos;
/* Restore window */ /* Restore window */
{ {
@ -250,7 +251,47 @@ JobDef(V_VisWorker, _, __)
} }
////////////////////////////// //////////////////////////////
//- Process controller events vis cmds //- Initialize camera
Vec2 camera_pos = ZI;
f32 camera_zoom = 1;
{
S_Ent *player = S_EntFromKey(&lookup, player_key);
S_Ent *camera = S_EntFromKey(&lookup, player->camera);
camera_pos = MulXformV2(camera->world_xf, camera->local_shape.centroid);
}
//////////////////////////////
//- Initialize world <-> draw <-> ui transforms
/* World <-> draw */
Xform world_to_draw_xf = XformIdentity;
Xform draw_to_world_xf = XformIdentity;
{
world_to_draw_xf.og = AddVec2(NegVec2(camera_pos), MulVec2(Vec2FromFields(draw_size), 0.5));
draw_to_world_xf = InvertXform(world_to_draw_xf);
}
/* Draw <-> ui */
Xform draw_to_ui_xf = XformIdentity;
Xform ui_to_draw_xf = XformIdentity;
{
ui_to_draw_xf = InvertXform(draw_to_ui_xf);
}
/* World <-> ui */
Xform world_to_ui_xf = XformIdentity;
Xform ui_to_world_xf = XformIdentity;
{
world_to_ui_xf = MulXform(world_to_draw_xf, draw_to_ui_xf);
ui_to_world_xf = InvertXform(world_to_ui_xf);
}
/* Cursors */
Vec2 ui_cursor = ui_frame.cursor_pos;
Vec2 draw_cursor = MulXformV2(ui_to_draw_xf, ui_cursor);
Vec2 world_cursor = MulXformV2(ui_to_world_xf, ui_cursor);
//////////////////////////////
//- Process controller events into vis cmds
u64 cmds_count = 0; u64 cmds_count = 0;
V_CmdNode *first_cmd_node = 0; V_CmdNode *first_cmd_node = 0;
@ -425,7 +466,7 @@ JobDef(V_VisWorker, _, __)
{ {
S_Ent *player = S_EntFromKey(&lookup, player_key); S_Ent *player = S_EntFromKey(&lookup, player_key);
Vec2 center = MulXformV2(player->world_xf, player->local_shape.centroid); Vec2 center = MulXformV2(player->world_xf, player->local_shape.centroid);
look = SubVec2(UI_CursorPos(), center); look = SubVec2(world_cursor, center);
} }
cmd->target = player_key; cmd->target = player_key;
cmd->move = move; cmd->move = move;
@ -462,14 +503,16 @@ JobDef(V_VisWorker, _, __)
for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); ent->active; ent = S_NextEnt(frame_arena, &iter)) for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); ent->active; ent = S_NextEnt(frame_arena, &iter))
{ {
Xform ent_to_world_xf = ent->world_xf;
Xform ent_to_draw_xf = MulXform(world_to_draw_xf, ent_to_world_xf);
/* Draw shape */ /* Draw shape */
b32 is_visible = ent->tint.w != 0; b32 is_visible = ent->tint.w != 0;
if (is_visible) if (is_visible)
{ {
Xform xf = ent->world_xf;
Vec4 color = ent->tint; Vec4 color = ent->tint;
i32 detail = 32; i32 detail = 32;
S_Shape shape = S_MulXformShape(ent->world_xf, ent->local_shape); S_Shape shape = S_MulXformShape(ent_to_draw_xf, ent->local_shape);
V_DrawShape(dverts_arena, dvert_idx_arena, shape, LinearFromSrgb(color), detail, V_DrawFlag_Line); V_DrawShape(dverts_arena, dvert_idx_arena, shape, LinearFromSrgb(color), detail, V_DrawFlag_Line);
} }
} }

View File

@ -10,7 +10,7 @@ void V_DrawPoly(Arena *verts_arena, Arena *idx_arena, Vec2Array points, Vec4 col
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
{ {
f32 half_thickness = 0.5; f32 half_thickness = 1;
i32 lines_count = verts_count == 2 ? 1 : verts_count; i32 lines_count = verts_count == 2 ? 1 : verts_count;
i32 line_verts_count = lines_count * 4; i32 line_verts_count = lines_count * 4;
i32 idx_count = lines_count * 6; i32 idx_count = lines_count * 6;