fix(physics): water depth submersion + sphere-safety-push steep-slope correction
Two coupled physics fixes that together resolve "+Acdream walks on top of water instead of submerged" and "brief Falling animation when running up steep hills". ## 1. Water depth = physics adjustment, not rendering Retail has NO separate water surface mesh. Characters visually submerge in water because ValidateWalkable adds `waterDepth` to its signed-distance check (ACE ObjectInfo.cs:124), letting the character's feet sit below the terrain plane by that amount before the push-up fires. Rendered character below rendered terrain = looks submerged. Our ValidateWalkable didn't carry a waterDepth, so feet were always snapped exactly to the plane. Water cells looked like walking on water. Added: - TerrainSurface now carries per-vertex water flags (bits 2-6 of TerrainInfo → SurfChar lookup) and per-cell classification. - TerrainSurface.SampleWaterDepth(localX, localY) returns 0.0 (dry), 0.45 (partial-water near water corner), 0.9 (entirely water). Deviates from retail's 0.1 fallback for "dry corner of partial-water cell" — that 0.1 destabilizes the "feet exactly on plane" contact-touch check in ValidateWalkable (dist > EPSILON, SetContactPlane skipped, ValidateTransition clears OnWalkable, gravity applies, character micro-falls each frame). - PhysicsEngine.SampleWaterDepth is the world-space wrapper. - FindEnvCollisions samples the per-point depth and forwards it. - ValidateWalkable adds +waterDepth to the signed-distance check (this is the ACE-line-124 port). GameWindow.ApplyLoadedTerrain extracts the low byte of each TerrainInfo ushort and passes it to the TerrainSurface ctor so classification works. ## 2. AdjustOffset safety-push threshold on sloped planes The LocalSphere is positioned at `(0, 0, radius)` — center along world +Z from the character root. On a tilted plane the sphere center's perpendicular distance to that plane is `radius * Normal.Z`, NOT `radius`. The original threshold `dist < radius - EPS` therefore fires spuriously on every slope and the follow-up push-up lifts feet by `radius * (sec θ - 1)` — 7 cm at 30°, 20 cm at 45°, 48 cm at 60°. The steep-slope lift is large enough to break ValidateWalkable's contact-touch check, ValidateTransition then clears OnWalkable, calc_acceleration applies gravity, and the character flickers into the Falling animation for ~0.3s while running uphill. User-observed on steep hills after today's water-depth work made the artifact visible (before that, general hover masked it). Fix: the threshold is `radius * Normal.Z` (the natural resting distance of a Z-axis sphere on the plane). The push fires only when feet are actually penetrating below natural resting, not on any sloped plane. ACE's Transition.cs AdjustOffset has the original threshold but the bug is invisible server-side. All 717 tests green. Water submersion + steep-slope running both user-visually verified. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
40f120617d
commit
f562215e6c
4 changed files with 179 additions and 13 deletions
|
|
@ -2706,8 +2706,17 @@ public sealed class GameWindow : IDisposable
|
|||
{
|
||||
uint lbPhysX = (lb.LandblockId >> 24) & 0xFFu;
|
||||
uint lbPhysY = (lb.LandblockId >> 16) & 0xFFu;
|
||||
// Extract per-vertex terrain-type bytes so TerrainSurface can
|
||||
// classify water cells for ValidateWalkable's water-depth
|
||||
// adjustment. Each TerrainInfo is a ushort with Type in bits
|
||||
// 2-6; taking the low byte preserves those bits (+ Road in 0-1,
|
||||
// which the classifier masks off).
|
||||
var terrainBytes = new byte[81];
|
||||
for (int i = 0; i < 81; i++)
|
||||
terrainBytes[i] = (byte)(ushort)lb.Heightmap.Terrain[i];
|
||||
|
||||
var terrainSurface = new AcDream.Core.Physics.TerrainSurface(
|
||||
lb.Heightmap.Height, _heightTable, lbPhysX, lbPhysY);
|
||||
lb.Heightmap.Height, _heightTable, lbPhysX, lbPhysY, terrainBytes);
|
||||
|
||||
var cellSurfaces = new List<AcDream.Core.Physics.CellSurface>();
|
||||
var portalPlanes = new List<AcDream.Core.Physics.PortalPlane>();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue