#124: the aimed pick now intersects the DRAWN GEOMETRY -- sphere

approximation retired; shared-hull hits route through the cylinder

The zone-walk matrix caught the pick red-handed: with the servo
verifiably holding the reticle on the dtorso segment, the per-segment
BOUNDING-SPHERE pick returned rgun/ruleg -- the gun pods and legs
thread the ray before the torso from most angles (its own comments
admitted a foot could be unhittable behind its own knee). The 1995
pick was a dpl scene intersection against the drawn geometry.

Restored that semantic:
* BTGetPickMesh caches each segment d3d_OBJECT's triangles CPU-side
  once (its own BGF VB/IB, managed-pool locks); MechSegmentPick now
  runs sphere PRE-FILTER -> Moller-Trumbore nearest-hit across the
  threaded segments' posed meshes; the old smallest-sphere selection
  survives only as the no-triangle fallback.
* Segments claimed as CARRIER by 2+ zones (the shared hull: madcat
  seg 4 carries dtorso+ltorso+rtorso+utorso+rears) cannot resolve one
  zone from geometry -- those hits return zone -1 WITH the accurate
  triangle point, and the victim's bit-verified (frame-fixed) cylinder
  assigns the panel by band/wedge. Unique carriers (legs, feet, arms,
  gun pods) keep the direct zone.
* ZoneAimPoint: the walker aims at a zone's VISUAL center (largest
  pick object's cull-center) instead of the segment origin -- joint
  origins made feet/lower legs strike the part above.
* Walker upgrades from live operation: 3-column truth (aim/pick/land),
  engage gate, damped servo with polarity watchdog, approach port.

Zone-walk verdict (full cycles, spinning target, real MP): limbs 5-6/6
direct in-zone; every hull panel routes CYL; the victim's landed zones
now include ltorso/rtorso/reardtorso/rearutorso/rearrtorso -- the
panels night-10 reported unhittable. Residuals tracked on #124:
rtorso/utorso aim-anchor placement, doors/searchlight small-zone
sample, twisted-torso twist-sign verify.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Joe DiPrima
2026-08-03 10:38:24 -05:00
co-authored by Claude Fable 5
parent 16e75d6e1a
commit 1a3c268278
4 changed files with 253 additions and 11 deletions
+16 -3
View File
@@ -6126,9 +6126,18 @@ void
<< "' seg=" << segIdx << " target="
<< target->GetEntityID() << "\n" << std::flush;
}
extern int BTMechZoneAimPoint(void *mech, int zone, float out3[3]);
int haveAim = 0;
if (BTMechZoneSegAndName(target, s_zwZone, &segIdx, &zname)
&& segIdx >= 0
&& BTResolveSegmentWorld((void *)target, segIdx, sp, rows))
&& segIdx >= 0)
{
// prefer the zone's VISUAL center (its pick geometry's
// cull-center); the segment ORIGIN sits at the joint
// and made feet/lower legs strike the part above.
haveAim = BTMechZoneAimPoint(target, s_zwZone, sp)
|| BTResolveSegmentWorld((void *)target, segIdx, sp, rows);
}
if (haveAim)
{
float wx = sp[0]-rs[0], wy = sp[1]-rs[1], wz = sp[2]-rs[2];
float wl = sqrtf(wx*wx + wy*wy + wz*wz);
@@ -6193,9 +6202,13 @@ void
{
gBTLaserKey = 1;
++s_zwShots;
// pick= is the LIVE picked zone (hotZone via the
// target slot) -- the 3-column truth: AIMED zone
// vs PICKED zone here, LANDED zone on the victim.
DEBUG_STREAM << "[walk] FIRE " << s_zwShots
<< " zone " << s_zwZone << " '" << zname
<< "' range=" << wl << "\n" << std::flush;
<< "' pick=" << MECH_TARGET_SUBIDX(this)
<< " range=" << wl << "\n" << std::flush;
}
}
}