feat(physics): Task 2 — true sphere collision primitive (CSphere::intersects_sphere)
Setup.Spheres were previously coerced to short cylinders (CylHeight=2*r), which is geometrically wrong: a cylinder has flat caps; a sphere does not. This ported CSphere::intersects_sphere (0x00537A80) so sphere-typed shadow entries are tested as spheres — 3-D distance, no height clamping. Changes: - ShadowObjectRegistry.cs: added ShadowCollisionType.Sphere (enum value 2). The BuildFloodSpheres anyCyl dedup at :232 is unaffected: only Cylinder sets anyCyl=true; Sphere shapes fall through to the BSP-fallback path (anyCyl=false → included), which is correct. - ShadowShapeBuilder.cs: FromSetup now emits ShadowCollisionType.Sphere (CylHeight=0) for Setup.Spheres instead of a short Cylinder. - CollisionPrimitives.cs: added SweptSphereHitsSphere — quadratic swept solve ported from ACE Sphere.cs::FindTimeOfCollision, which is a C# port of retail's CSphere::intersects_sphere @ 0x00537A80. Sign convention confirmed against the decomp: retail negates the root to produce a forward t ∈ (0,1]. - TransitionTypes.cs: added Sphere narrow-phase branch between BSP and Cylinder in FindObjCollisionsInCell; uses 3-D distance for overlap (not XY-only). Added SphereCollision() method implementing the 3-D wall-slide response. Updated diagnostic logging at :2734 to cover Sphere. - Updated ShadowShapeBuilderTests for new Sphere type assertion. - New SphereIntersectsSphereConformanceTests: 9 geometrically-anchored cases (head-on, tangent, perpendicular-miss, lateral-near-miss, sweep-away, beyond-step, degenerate-zero-sweep, already-overlapping, vertical-sweep). Retail oracle: CSphere::intersects_sphere @ 0x00537A80 (named-retail); ACE Sphere.cs::FindTimeOfCollision (C# port, cross-confirmed). Build: 0 errors, 10 warnings (pre-existing). Tests: 1576 pass / 0 fail / 2 skip (1578 total). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
79dee342f2
commit
78e5758185
7 changed files with 609 additions and 16 deletions
|
|
@ -57,14 +57,17 @@ public class ShadowShapeBuilderTests
|
|||
|
||||
Assert.Equal(4, shapes.Count);
|
||||
|
||||
int cylinderCount = 0;
|
||||
// Task 2 (2026-06-24): Setup.Spheres now emit ShadowCollisionType.Sphere,
|
||||
// not Cylinder. A door's Sphere entry contributes the Sphere-typed shape;
|
||||
// the 3 parts (all with physics BSP) contribute the 3 BSP shapes.
|
||||
int sphereCount = 0;
|
||||
int bspCount = 0;
|
||||
foreach (var s in shapes)
|
||||
{
|
||||
if (s.CollisionType == ShadowCollisionType.Cylinder) cylinderCount++;
|
||||
if (s.CollisionType == ShadowCollisionType.Sphere) sphereCount++;
|
||||
else if (s.CollisionType == ShadowCollisionType.BSP) bspCount++;
|
||||
}
|
||||
Assert.Equal(1, cylinderCount);
|
||||
Assert.Equal(1, sphereCount);
|
||||
Assert.Equal(3, bspCount);
|
||||
}
|
||||
|
||||
|
|
@ -74,12 +77,16 @@ public class ShadowShapeBuilderTests
|
|||
var setup = CreateDoorSetup();
|
||||
var shapes = ShadowShapeBuilder.FromSetup(setup, 1.0f, _ => true);
|
||||
|
||||
var sphereAsCyl = shapes.FirstOrDefault(s => s.CollisionType == ShadowCollisionType.Cylinder);
|
||||
Assert.NotEqual(default, sphereAsCyl);
|
||||
Assert.Equal(0f, sphereAsCyl.LocalPosition.X, 4);
|
||||
Assert.Equal(0f, sphereAsCyl.LocalPosition.Y, 4);
|
||||
Assert.Equal(0.018f, sphereAsCyl.LocalPosition.Z, 4);
|
||||
Assert.Equal(0.100f, sphereAsCyl.Radius, 4);
|
||||
// Task 2 (2026-06-24): Spheres emit ShadowCollisionType.Sphere (not Cylinder).
|
||||
// Retail: CSphere::intersects_sphere @ 0x00537A80 uses 3-D distance; no height cap.
|
||||
var sphereShape = shapes.FirstOrDefault(s => s.CollisionType == ShadowCollisionType.Sphere);
|
||||
Assert.NotEqual(default, sphereShape);
|
||||
Assert.Equal(0f, sphereShape.LocalPosition.X, 4);
|
||||
Assert.Equal(0f, sphereShape.LocalPosition.Y, 4);
|
||||
Assert.Equal(0.018f, sphereShape.LocalPosition.Z, 4);
|
||||
Assert.Equal(0.100f, sphereShape.Radius, 4);
|
||||
// CylHeight must be 0 — spheres have no height cap.
|
||||
Assert.Equal(0f, sphereShape.CylHeight, 4);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue