From ffa3378a54425d23661903ffaf6131ae428da4ec Mon Sep 17 00:00:00 2001 From: jacob Date: Mon, 9 Feb 2026 17:49:50 -0600 Subject: [PATCH] one-way wall collision --- src/config.h | 31 +++---------------------------- src/pp/pp.c | 45 +++++++++++++++++---------------------------- src/pp/pp.h | 1 + 3 files changed, 21 insertions(+), 56 deletions(-) diff --git a/src/config.h b/src/config.h index 1becab49..ece442e3 100644 --- a/src/config.h +++ b/src/config.h @@ -1,11 +1,5 @@ // Project-wide configurable constants -// Rendered texture size + extra room for off-screen light falloff -#define RENDER_WIDTH (640 + 250) -#define RENDER_HEIGHT (360 + 250) - -#define PIXELS_PER_UNIT ((f64)640 / (f64)DEFAULT_CAMERA_WIDTH) - // How many ticks back in time should the user thread blend between? // = * // E.g: At 1.5, the user thread will render 75ms back in time if the sim runs at 50tps @@ -13,34 +7,15 @@ #define USER_INTERP_ENABLED 1 #define SIM_MAX_PING 5.0 + +#define SIM_PHYSICS_SUBSTEPS 8 + #define SIM_TICKS_PER_SECOND 64 #define SIM_TICK_INTERVAL_NS (NsFromSeconds(1) / SIM_TICKS_PER_SECOND) // 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) #define SIM_CLIENT_INTERP_RATIO 2.0 -#define SIM_PHYSICS_SUBSTEPS 4 -#define SIM_PHYSICS_ENABLE_WARM_STARTING 1 -#define SIM_PHYSICS_ENABLE_RELAXATION 1 -#define SIM_PHYSICS_ENABLE_TOI 1 - -#define SIM_PHYSICS_ENABLE_COLLISION 1 -#define SIM_SPAWN_TESTENT 0 -#define SIM_PLAYER_AIM 1 - -#if 0 - #define SIM_MAX_LINEAR_VELOCITY 500 - #define SIM_MAX_ANGULAR_VELOCITY (Tau * 20) -#else - #define SIM_MAX_LINEAR_VELOCITY F32Infinity - #define SIM_MAX_ANGULAR_VELOCITY F32Infinity -#endif - -#define COLLIDER_DEBUG 0 -#define COLLIDER_DEBUG_DETAILED 1 -#define COLLIDER_DEBUG_DETAILED_DRAW_MENKOWSKI 1 - -#define FLOOD_DEBUG 0 #define GPU_DEBUG 0 #define GPU_DEBUG_VALIDATION 0 diff --git a/src/pp/pp.c b/src/pp/pp.c index 420f1300..99377df0 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -194,7 +194,7 @@ P_Shape P_LocalShapeFromEnt(P_Ent *ent) result = P_ShapeFromDesc( .mass = 10, .count = 1, - .radius = 0.3, + .radius = 0.25, ); // f32 guy_width = 0.75; @@ -202,7 +202,7 @@ P_Shape P_LocalShapeFromEnt(P_Ent *ent) // result = P_ShapeFromDesc( // .mass = 10, // .count = 2, - // .points = { VEC2(-guy_width / 2 + (guy_height / 2), 0), VEC2(guy_width / 2 - (guy_height / 2), 0) }, + // .points = { VEC2(0, -guy_width / 2 + (guy_height / 2)), VEC2(0, guy_width / 2 - (guy_height / 2)) }, // .radius = guy_height / 2, // ); @@ -1369,7 +1369,6 @@ P_Space P_SpaceFromFrame(Arena *arena, P_Frame *frame) { Vec2 p0 = VEC2(wall->start.x / P_TilesPerMeter - P_WorldPitch / 2, wall->start.y / P_TilesPerMeter - P_WorldPitch / 2); Vec2 p1 = VEC2(wall->end.x / P_TilesPerMeter - P_WorldPitch / 2, wall->end.y / P_TilesPerMeter - P_WorldPitch / 2); - // P_Shape shape = P_ShapeFromDesc(.count = 2, .points = { p0, p1 }); P_Shape shape = P_ShapeFromDesc(.count = 2, .points = { p0, p1 }, .radius = 0.01 ); Rng2 aabb = P_BoundingBoxFromShape(shape); aabb = AddRng2Vec2(aabb, VEC2(P_WorldPitch / 2.0, P_WorldPitch / 2.0)); @@ -1392,31 +1391,11 @@ P_Space P_SpaceFromFrame(Arena *arena, P_Frame *frame) SllStackPush(cell->first, entry); entry->shape = shape; entry->shape_id = id; + entry->dir.x = (wall->dir == WallDir_Right) + ((wall->dir == WallDir_Left) * -1); + entry->dir.y = (wall->dir == WallDir_Down) + ((wall->dir == WallDir_Up) * -1); } } - - // P_DebugDrawShape(shape, Color_Cyan); } - - //- Debug draw walls - // { - // i64 wall_idx = 0; - // for (GenWall *wall = first_wall; wall; wall = wall->next) - // { - // Vec2 p0 = VEC2(wall->start.x / P_TilesPerMeter - P_WorldPitch / 2, wall->start.y / P_TilesPerMeter - P_WorldPitch / 2); - // Vec2 p1 = VEC2(wall->end.x / P_TilesPerMeter - P_WorldPitch / 2, wall->end.y / P_TilesPerMeter - P_WorldPitch / 2); - // u64 color_seed0 = MixU64(wall_idx + 1); - // u64 color_seed1 = MixU64(color_seed0); - // u64 color_seed2 = MixU64(color_seed1); - // Vec4 color = Color_White; - // color.r = Norm24(color_seed0) * 0.75 + 0.25; - // color.g = Norm24(color_seed1) * 0.75 + 0.25; - // color.b = Norm24(color_seed2) * 0.75 + 0.25; - // P_DebugDrawLine(p0, p1, color); - // ++wall_idx; - // } - // ++wall_idx; - // } } @@ -2051,11 +2030,11 @@ void P_StepFrame(P_Frame *frame) ////////////////////////////// //- Setup constraints store - i32 solver_steps_count = 4; + i32 solver_steps_count = SIM_PHYSICS_SUBSTEPS; f32 solver_dt = sim_dt / solver_steps_count; // Solid params - SoftSpring solid_spring = MakeSpring(TweakFloat("Contact spring hz", 25, 5, 100), TweakFloat("Contact spring damp", 10, 5, 100), solver_dt); + SoftSpring solid_spring = MakeSpring(TweakFloat("Contact spring hz", 100, 5, 200), TweakFloat("Contact spring damp", 10, 5, 100), solver_dt); f32 solid_pushout_velocity = TweakFloat("Contact spring pushout", 3, 0, 50); // Gentle params @@ -2128,7 +2107,17 @@ void P_StepFrame(P_Frame *frame) if (constraint->last_touched_tick < frame->tick) { P_CollisionResult collision = P_CollisionResultFromShapes(shape0, shape1); - if (collision.collision_points_count > 0) + + b32 skip_collision = 0; + skip_collision = skip_collision || collision.collision_points_count <= 0; + if (!skip_collision && !IsVec2Zero(space_entry->dir)) + { + // Skip collision if normal violates one-way direction + f32 threshold = 0.5; + skip_collision = DotVec2(space_entry->dir, collision.collision_normal) >= threshold; + } + + if (!skip_collision) { if (P_IsConstraintNil(constraint)) { diff --git a/src/pp/pp.h b/src/pp/pp.h index 5035d2ed..309ac0f7 100644 --- a/src/pp/pp.h +++ b/src/pp/pp.h @@ -257,6 +257,7 @@ Struct(P_SpaceEntry) P_SpaceEntry *next; P_Shape shape; u64 shape_id; + Vec2 dir; }; Struct(P_SpaceCell)