fix(movement): correct facing direction quaternion convention
AC heading convention: 0=West, 90=North, 180=East, 270=South. Our internal yaw: 0=+X (East), PI/2=+Y (North). Conversion: heading_deg = 180 - yaw_degrees, then holtburger's from_heading formula: theta=(450-heading).toRad, w=cos(θ/2), z=sin(θ/2). Previously sent raw Yaw as axis-angle rotation which was ~90° off. Other clients now see correct facing direction. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5634e7114b
commit
6523c7199b
1 changed files with 29 additions and 2 deletions
|
|
@ -1896,8 +1896,7 @@ public sealed class GameWindow : IDisposable
|
|||
float localY = result.Position.Y - (lbY - _liveCenterY) * 192f;
|
||||
uint wireCellId = ((uint)lbX << 24) | ((uint)lbY << 16) | (result.CellId & 0xFFFFu);
|
||||
var wirePos = new System.Numerics.Vector3(localX, localY, result.Position.Z);
|
||||
var wireRot = System.Numerics.Quaternion.CreateFromAxisAngle(
|
||||
System.Numerics.Vector3.UnitZ, _playerController.Yaw);
|
||||
var wireRot = YawToAcQuaternion(_playerController.Yaw);
|
||||
|
||||
if (result.MotionStateChanged)
|
||||
{
|
||||
|
|
@ -1956,6 +1955,34 @@ public sealed class GameWindow : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert our internal yaw (math convention: 0=+X East, PI/2=+Y North)
|
||||
/// to AC's quaternion heading convention.
|
||||
/// AC heading: 0=West, 90=North, 180=East, 270=South.
|
||||
/// Formula from holtburger Quaternion::from_heading.
|
||||
/// </summary>
|
||||
private static System.Numerics.Quaternion YawToAcQuaternion(float yaw)
|
||||
{
|
||||
// Our yaw → AC heading in degrees:
|
||||
// yaw=0 → East → AC 180°, yaw=PI/2 → North → AC 90°
|
||||
// heading_deg = 180 - yaw_degrees
|
||||
float yawDeg = yaw * (180f / MathF.PI);
|
||||
float headingDeg = 180f - yawDeg;
|
||||
if (headingDeg < 0f) headingDeg += 360f;
|
||||
if (headingDeg >= 360f) headingDeg -= 360f;
|
||||
|
||||
// holtburger from_heading: theta = (450 - heading_deg) in radians
|
||||
float theta = (450f - headingDeg) * (MathF.PI / 180f);
|
||||
float halfTheta = theta * 0.5f;
|
||||
float w = MathF.Cos(halfTheta);
|
||||
float z = MathF.Sin(halfTheta);
|
||||
|
||||
// Canonicalize: w must be non-negative
|
||||
if (w < 0f) { w = -w; z = -z; }
|
||||
|
||||
return new System.Numerics.Quaternion(0f, 0f, z, w);
|
||||
}
|
||||
|
||||
private void OnCameraModeChanged(bool isFlyMode)
|
||||
{
|
||||
if (_input is null) return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue