Aetheria/Assets/Scripts/ServerShared/DrawAhead.cs
Meta Vens 257a8a4795 Sim speed fix: scripted poses are not drawn ahead; a step cannot reset its clock; DrawAhead.Time deleted
DrawAhead leaves a ship in a wormhole animation where the step put it. The clock is
one static instance; a zone entered inside a step ends that frame's stepping and the
clock resets between frames (SimClock.Reset throws inside Advance). DrawAhead.Time had
no consumer.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 23:39:30 +02:00

40 lines
2.1 KiB
C#

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
using CultMath;
using static CultMath.math;
// Where a presenter draws the latest sim state when the frame falls Lead sim seconds after the last step. Pure reads
// of the simulation for presenters (never called by ServerShared): the sim owns every pose and no presenter stores
// one, a previous state or a velocity of its own.
public static class DrawAhead
{
// A ship in a wormhole animation has its pose scripted by the step, not integrated from Velocity and TurnRate,
// so it is drawn where the step put it: extrapolating a scripted pose draws a streak that resets every step.
public static float3 Position(Entity entity, float lead) =>
entity is Ship { WormholeAnimationInProgress: true }
? entity.Position
: entity.Position + float3(entity.Velocity.x, 0, entity.Velocity.y) * lead;
// The ship's rotation turned about its own up axis by the rate its last step turned, for lead seconds.
public static quaternion Rotation(Ship ship, float lead) =>
ship.WormholeAnimationInProgress ? ship.Rotation : Turned(ship.Rotation, ship.TurnRate * lead);
// q turned about its own up axis by the angle, in the sense Direction turns for a positive TurnRate.
public static quaternion Turned(quaternion q, float angle)
{
var u = float3(q.x, q.y, q.z);
var up = float3(0, 1, 0);
up += 2 * (q.w * cross(u, up) + cross(u, cross(u, up)));
var half = angle * .5f;
var s = sin(half);
var t = new quaternion(up.x * s, up.y * s, up.z * s, cos(half));
// Hamilton product t * q: CultMath carries no quaternion product (a gap in CultMath, not filled here).
return normalize(new quaternion(
t.w * q.x + t.x * q.w + t.y * q.z - t.z * q.y,
t.w * q.y - t.x * q.z + t.y * q.w + t.z * q.x,
t.w * q.z + t.x * q.y - t.y * q.x + t.z * q.w,
t.w * q.w - t.x * q.x - t.y * q.y - t.z * q.z));
}
}