feat(selection): port retail offscreen target indicator
This commit is contained in:
parent
ea4f52ec51
commit
ec1bb19609
9 changed files with 404 additions and 97 deletions
|
|
@ -3,10 +3,9 @@ using System.Numerics;
|
|||
namespace AcDream.Core.Selection;
|
||||
|
||||
/// <summary>
|
||||
/// Shared screen-space projection math for the target indicator and the
|
||||
/// world picker. Both call into <see cref="TryProjectSphereToScreenRect"/>
|
||||
/// so the click hit-area is guaranteed to match the visible indicator
|
||||
/// rect — "what you see is what you click".
|
||||
/// Screen-space selection-sphere projection used by SmartBox's vivid target
|
||||
/// indicator. World picking separately ports retail's visible GfxObj polygon
|
||||
/// ray tests; the persistent marker intentionally ignores world occlusion.
|
||||
///
|
||||
/// <para>
|
||||
/// Retail equivalent: <c>SmartBox::GetObjectBoundingBox</c> at
|
||||
|
|
@ -35,8 +34,7 @@ public static class ScreenProjection
|
|||
/// <param name="depth">Out: camera-space depth (<c>clip.W</c>) of the sphere
|
||||
/// center — use this for nearest-first sorting when multiple rects overlap.</param>
|
||||
/// <param name="minSidePixels">Minimum side length of the rect. Distant
|
||||
/// entities clamp to this so they remain pickable / visible. 12 px
|
||||
/// matches the indicator's clamp floor.</param>
|
||||
/// entities may clamp to this for a stable presentation.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the sphere is in front of the camera and the rect was
|
||||
/// produced; <c>false</c> if the center is behind the camera
|
||||
|
|
@ -74,9 +72,7 @@ public static class ScreenProjection
|
|||
if (screenX + screenRadius < -viewport.X || screenX - screenRadius > 2f * viewport.X) return false;
|
||||
if (screenY + screenRadius < -viewport.Y || screenY - screenRadius > 2f * viewport.Y) return false;
|
||||
|
||||
// Floor at minSidePixels so distant entities still get a visible /
|
||||
// clickable rect. The picker must apply the same floor as the
|
||||
// indicator or distant clicks won't match the visible bracket.
|
||||
// Optional presentation floor for very distant spheres.
|
||||
if (screenRadius < minSidePixels * 0.5f) screenRadius = minSidePixels * 0.5f;
|
||||
|
||||
rectMin = new Vector2(screenX - screenRadius, screenY - screenRadius);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue