Render-clock tracking timestamps (menu toggle), physics step cap 6, docs for step 2.7

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
FoxyzandClaude Opus 5.5 committed 2026-10-02 20:43:49 +03:00
1 parent 22159aa902
commit ca60df3d75
9 files changed
+111 -11

No files matched your search

+16 -7
View File
@@ -21,19 +21,25 @@ public sealed class PoseFilter
public void Reset() => _has = false;
public Transform3D Sample(Transform3D raw, double now)
// sampleTime: when the pose was really measured (the render time of the frame that delivered it),
// in the same clock as `now`. Without it a sample is timestamped by the first tick that saw it,
// which at 144 Hz under 90 Hz frames alternates 1 and 2 ticks late: the extrapolated motion
// then beats at 18 Hz (±30% speed per frame — bible v2, measured). With it the age is exact
// and motion uniform, at a constant ~2-tick lag. May be negative (a tick before the sample).
public Transform3D Sample(Transform3D raw, double now, double? sampleTime = null)
{
double stamp = sampleTime ?? now;
if (!_has)
{
_has = true;
_last = raw;
_tLast = now;
_tLast = stamp;
Velocity = AngularVelocity = Vector3.Zero;
return raw;
}
if (raw != _last)
{
float interval = (float)(now - _tLast);
float interval = (float)(stamp - _tLast);
if (interval > 1e-4f)
{
if (raw.Origin.DistanceTo(_last.Origin) > JumpDistance)
@@ -49,9 +55,9 @@ public sealed class PoseFilter
}
}
_last = raw;
_tLast = now;
_tLast = stamp;
}
float age = Mathf.Min((float)(now - _tLast), MaxExtrapolation);
float age = Mathf.Clamp((float)(now - _tLast), -MaxExtrapolation, MaxExtrapolation);
Basis spin = AngularVelocity.LengthSquared() > 1e-10f
? new Basis(AngularVelocity.Normalized(), AngularVelocity.Length() * age) : Basis.Identity;
return new Transform3D(spin * _last.Basis.Orthonormalized(), _last.Origin + Velocity * age);
@@ -78,11 +84,14 @@ public sealed class RagdollDriver
// origin = play space (modified by the correction); raw* = origin-local tracked poses as last
// reported (repeat between tracking updates); moveVelocity = intended origin velocity (stick),
// the only origin motion that is real hand motion for the guides' feed-forward.
// trackingAge: how long ago (s) the current tracking poses were measured, if known (PlayerRig
// derives it from the render clock); null = timestamp by arrival (the spike's simulated input).
public void Tick(BodyProfile profile, ref Transform3D origin, Transform3D rawHead, Transform3D rawLeft, Transform3D rawRight,
Vector3 moveVelocity, float dt)
Vector3 moveVelocity, float dt, double? trackingAge = null)
{
_now += dt;
Transform3D head = Head.Sample(rawHead, _now), left = Left.Sample(rawLeft, _now), right = Right.Sample(rawRight, _now);
double? stamp = trackingAge.HasValue ? _now - trackingAge.Value : null;
Transform3D head = Head.Sample(rawHead, _now, stamp), left = Left.Sample(rawLeft, _now, stamp), right = Right.Sample(rawRight, _now, stamp);
if (Ragdoll.Built && !RebuildRequested)
origin.Origin += Ragdoll.OriginCorrection((origin * head).Origin, origin.Origin.Y + StickCrouch, dt);
float floorY = origin.Origin.Y + StickCrouch;