fix(combat): track targets with retail camera
Port ClientCombatSystem's Keep in View consumer through CameraSet's pivot-to-target boom heading, including the transformed half-metre target offset and melee/missile validity gates. Preserve the existing stateful chase damping and collision architecture, with conformance coverage and named-retail pseudocode. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
927fa7881a
commit
33cc9aa16a
5 changed files with 159 additions and 14 deletions
|
|
@ -143,28 +143,31 @@ public sealed class RetailChaseCamera : ICamera
|
|||
Vector3 contactPlaneNormal,
|
||||
float dt,
|
||||
uint cellId = 0,
|
||||
uint selfEntityId = 0)
|
||||
uint selfEntityId = 0,
|
||||
Vector3? trackedTargetPoint = null)
|
||||
{
|
||||
// 1. Push velocity into 5-frame ring, get average.
|
||||
PushVelocity(_velocityRing, ref _velocityCount, playerVelocity);
|
||||
Vector3 avgVel = AverageVelocity(_velocityRing, _velocityCount);
|
||||
|
||||
// 2. Heading vector — player's facing projected onto the contact
|
||||
// plane (grounded) or world XY (airborne). See ComputeHeading
|
||||
// doc + retail decomp :95644-95795 for why this is facing-based
|
||||
// rather than velocity-based.
|
||||
Vector3 heading = ComputeHeading(
|
||||
avgVel,
|
||||
playerYaw + YawOffset,
|
||||
isOnGround,
|
||||
contactPlaneNormal,
|
||||
CameraDiagnostics.AlignToSlope);
|
||||
// 2. Heading vector. TrackTarget uses the pivot-to-target direction;
|
||||
// otherwise this is the player's facing projected onto the contact
|
||||
// plane (grounded) or world XY (airborne). See named retail
|
||||
// CameraSet::TrackTarget 0x00458280 and CameraManager::UpdateCamera
|
||||
// 0x00456826-0x00456915.
|
||||
Vector3 pivotWorld = playerPosition + new Vector3(0f, 0f, PivotHeight);
|
||||
Vector3 heading = ComputeTrackedHeading(pivotWorld, trackedTargetPoint)
|
||||
?? ComputeHeading(
|
||||
avgVel,
|
||||
playerYaw + YawOffset,
|
||||
isOnGround,
|
||||
contactPlaneNormal,
|
||||
CameraDiagnostics.AlignToSlope);
|
||||
|
||||
// 3. Orthonormal heading-frame basis.
|
||||
var (forward, _, up) = BuildBasis(heading);
|
||||
|
||||
// 4. Target pose.
|
||||
Vector3 pivotWorld = playerPosition + new Vector3(0f, 0f, PivotHeight);
|
||||
float horizontal = Distance * MathF.Cos(Pitch);
|
||||
float vertical = Distance * MathF.Sin(Pitch);
|
||||
// viewer_offset = -horizontal along forward + vertical along up.
|
||||
|
|
@ -359,6 +362,24 @@ public sealed class RetailChaseCamera : ICamera
|
|||
return Vector3.Normalize(projected);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Port of the LOOK_AT_OBJECT direction contribution in retail
|
||||
/// CameraManager::UpdateCamera (0x00456826-0x00456915). The caller
|
||||
/// supplies the transformed world-space target point, including retail's
|
||||
/// local (0,0,0.5) target offset. A coincident point cannot define a
|
||||
/// heading, so the ordinary player-facing path remains active.
|
||||
/// </summary>
|
||||
internal static Vector3? ComputeTrackedHeading(Vector3 pivotWorld, Vector3? trackedTargetPoint)
|
||||
{
|
||||
if (trackedTargetPoint is not Vector3 targetPoint)
|
||||
return null;
|
||||
|
||||
Vector3 towardTarget = targetPoint - pivotWorld;
|
||||
return towardTarget.LengthSquared() < 1e-8f
|
||||
? null
|
||||
: Vector3.Normalize(towardTarget);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build an orthonormal basis with <c>forward = heading</c>. World
|
||||
/// up is <c>(0, 0, 1)</c>; if <c>heading</c> is near-parallel to it
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue