fix(app): terrain cull exempt + yaw preservation on Tab toggle
1. Terrain culling: TerrainRenderer.Draw now accepts neverCullLandblockId, matching StaticMeshRenderer. Both renderers skip frustum-culling the player's current landblock. Previously only entities were exempt but the terrain under the player still disappeared when looking away. 2. Yaw drift on Tab toggle: render loop stores rotation as Yaw - PI/2 (AC model facing offset), but yaw extraction on re-entering player mode didn't compensate. Each Tab cycle rotated the player 90 degrees. Now adds PI/2 back when extracting from the quaternion. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a3b389603d
commit
29fe0c0714
2 changed files with 10 additions and 7 deletions
|
|
@ -224,13 +224,15 @@ public sealed class GameWindow : IDisposable
|
|||
playerEntity.Position, pinitCellId & 0xFFFFu,
|
||||
System.Numerics.Vector3.Zero, 100f); // huge step height for initial snap
|
||||
_playerController.SetPosition(initResult.Position, initResult.CellId);
|
||||
// Derive initial yaw from the entity's server-sent rotation
|
||||
// rather than hardcoding. Extract yaw from the quaternion.
|
||||
// Derive initial yaw from the entity's rotation.
|
||||
// The render loop stores rotation as Yaw - PI/2 (to
|
||||
// compensate for AC models facing +Y at identity), so
|
||||
// we add PI/2 back when extracting to get the real yaw.
|
||||
var q = playerEntity.Rotation;
|
||||
float yaw = MathF.Atan2(
|
||||
float rawYaw = MathF.Atan2(
|
||||
2f * (q.W * q.Z + q.X * q.Y),
|
||||
1f - 2f * (q.Y * q.Y + q.Z * q.Z));
|
||||
_playerController.Yaw = yaw;
|
||||
_playerController.Yaw = rawYaw + MathF.PI / 2f;
|
||||
|
||||
_chaseCamera = new AcDream.App.Rendering.ChaseCamera
|
||||
{
|
||||
|
|
@ -1756,7 +1758,7 @@ public sealed class GameWindow : IDisposable
|
|||
{
|
||||
var camera = _cameraController.Active;
|
||||
var frustum = AcDream.App.Rendering.FrustumPlanes.FromViewProjection(camera.View * camera.Projection);
|
||||
_terrain?.Draw(camera, frustum);
|
||||
|
||||
// Never cull the landblock the player is currently on.
|
||||
uint? playerLb = null;
|
||||
if (_playerMode && _playerController is not null)
|
||||
|
|
@ -1766,6 +1768,7 @@ public sealed class GameWindow : IDisposable
|
|||
int ply = _liveCenterY + (int)System.Math.Floor(pp.Y / 192f);
|
||||
playerLb = (uint)((plx << 24) | (ply << 16) | 0xFFFF);
|
||||
}
|
||||
_terrain?.Draw(camera, frustum, neverCullLandblockId: playerLb);
|
||||
_staticMesh?.Draw(camera, _worldState.LandblockEntries, frustum,
|
||||
neverCullLandblockId: playerLb);
|
||||
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ public sealed unsafe class TerrainRenderer : IDisposable
|
|||
_landblocks.Remove(landblockId);
|
||||
}
|
||||
|
||||
public void Draw(ICamera camera, FrustumPlanes? frustum = null)
|
||||
public void Draw(ICamera camera, FrustumPlanes? frustum = null, uint? neverCullLandblockId = null)
|
||||
{
|
||||
_shader.Use();
|
||||
_shader.SetMatrix4("uView", camera.View);
|
||||
|
|
@ -135,7 +135,7 @@ public sealed unsafe class TerrainRenderer : IDisposable
|
|||
|
||||
foreach (var lb in _landblocks.Values)
|
||||
{
|
||||
if (frustum is not null)
|
||||
if (frustum is not null && lb.LandblockId != neverCullLandblockId)
|
||||
{
|
||||
var aabbMin = new Vector3(lb.WorldOrigin.X, lb.WorldOrigin.Y, lb.MinZ);
|
||||
var aabbMax = new Vector3(lb.WorldOrigin.X + 192f, lb.WorldOrigin.Y + 192f, lb.MaxZ);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue