From 76cf7a85ecd0cc9b2027add0a74502a1ce2ddc50 Mon Sep 17 00:00:00 2001 From: Erik Date: Tue, 14 Apr 2026 13:32:59 +0200 Subject: [PATCH] fix(physics): use max(CylSphere.Radius, Setup.Radius) for collision The CylSphere.Radius from the dat is often smaller than the visual trunk base. Setup.Radius is the overall bounding radius which better matches the visual footprint. Use the larger of the two to prevent clipping into wide tree bases. Also use Setup.Height as fallback when CylSphere.Height is zero. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/AcDream.App/Rendering/GameWindow.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index 1831713..7db0c83 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -1810,16 +1810,21 @@ public sealed class GameWindow : IDisposable if (setup is not null && setup.CylSpheres.Count > 0) { var cyl = setup.CylSpheres[0]; - float cylRadius = cyl.Radius > 0 ? cyl.Radius : setup.Radius; + // Use the LARGER of CylSphere.Radius and Setup.Radius. + // Setup.Radius is the overall bounding radius of the object. + float cylRadius = MathF.Max(cyl.Radius, setup.Radius); + if (cylRadius <= 0) cylRadius = 1f; + float cylHeight = cyl.Height > 0 ? cyl.Height : setup.Height; + if (cylHeight <= 0) cylHeight = cylRadius * 4f; + if (cylRadius > 0) { - // Use entity.Id directly (not partId) for the CylSphere entry. _physicsEngine.ShadowObjects.Register( entity.Id, entity.SourceGfxObjOrSetupId, entity.Position + new System.Numerics.Vector3(cyl.Origin.X, cyl.Origin.Y, cyl.Origin.Z), entity.Rotation, cylRadius, origin.X, origin.Y, lb.LandblockId, - AcDream.Core.Physics.ShadowCollisionType.Cylinder, cyl.Height); + AcDream.Core.Physics.ShadowCollisionType.Cylinder, cylHeight); } } else if (setup is not null && setup.Spheres.Count > 0 && partIndex == 0)