fix(app): multi-point Z sampling + never-cull player landblock
1. Slope clipping: replaced single foot-forward Z sample with 4-point sampling (forward, back, left, right at 0.7 units). Takes the max Z across all samples so both uphill and downhill slopes keep feet above the terrain mesh surface. Removed the +0.1 Z bias entirely. 2. Player culling: replaced per-entity scan (alwaysVisibleEntityId) with per-landblock skip (neverCullLandblockId). The player's current landblock is computed from _playerController.Position and passed to the renderer. Simpler, faster, and more reliable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6f05c298cf
commit
a3b389603d
4 changed files with 42 additions and 40 deletions
|
|
@ -206,22 +206,32 @@ public sealed class PlayerMovementController
|
|||
}
|
||||
}
|
||||
|
||||
// Foot-forward Z sampling: on slopes the visual terrain at the
|
||||
// character's feet (slightly forward) can be higher than at the center.
|
||||
// Sample a point ~1 unit ahead in the walk direction and use the MAX
|
||||
// of center and foot Z. Only when grounded and moving.
|
||||
if (!IsAirborne && (dx != 0f || dy != 0f))
|
||||
// Multi-point Z sampling: on slopes the visual terrain mesh can be
|
||||
// higher or lower than the center-point physics sample. Sample 4
|
||||
// points around the character (forward, back, left, right at ~0.7
|
||||
// units — roughly foot distance) and use the MAX Z. This prevents
|
||||
// feet clipping on both uphill and downhill slopes.
|
||||
if (!IsAirborne)
|
||||
{
|
||||
float footX = result.Position.X + forwardX * 1.0f;
|
||||
float footY = result.Position.Y + forwardY * 1.0f;
|
||||
var footResult = _physics.Resolve(
|
||||
new Vector3(footX, footY, newZ), CellId,
|
||||
Vector3.Zero, StepUpHeight);
|
||||
if (footResult.IsOnGround && footResult.Position.Z > newZ)
|
||||
newZ = footResult.Position.Z;
|
||||
const float sampleDist = 0.7f;
|
||||
ReadOnlySpan<(float ox, float oy)> offsets = stackalloc (float, float)[]
|
||||
{
|
||||
( forwardX * sampleDist, forwardY * sampleDist), // forward
|
||||
(-forwardX * sampleDist, -forwardY * sampleDist), // back
|
||||
( forwardY * sampleDist, -forwardX * sampleDist), // right
|
||||
(-forwardY * sampleDist, forwardX * sampleDist), // left
|
||||
};
|
||||
foreach (var (ox, oy) in offsets)
|
||||
{
|
||||
var sampleResult = _physics.Resolve(
|
||||
new Vector3(result.Position.X + ox, result.Position.Y + oy, newZ),
|
||||
CellId, Vector3.Zero, StepUpHeight);
|
||||
if (sampleResult.IsOnGround && sampleResult.Position.Z > newZ)
|
||||
newZ = sampleResult.Position.Z;
|
||||
}
|
||||
}
|
||||
_prevGroundZ = newZ;
|
||||
Position = new Vector3(result.Position.X, result.Position.Y, newZ + 0.1f);
|
||||
Position = new Vector3(result.Position.X, result.Position.Y, newZ);
|
||||
CellId = result.CellId;
|
||||
|
||||
// 4. Determine current motion commands.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue