Ask whether the pod stalled or the pan did
Two things are now ruled out with evidence rather than argument. Render interpolation is healthy. behind is computed by Time::operator-, which subtracts ticks and only then converts to float, so it carries the clock full millisecond precision. With a 20ms step that gives the fraction twenty possible values, and the measured 17 frames of 293 sitting at zero is 5.8% against the 5% a sawtooth crossing zero would produce by itself. Mean 0.474, never once pinned at 1: it is sweeping correctly. And the trace period was never a period. Every interval it reported - 0.03125, 0.125, 0.375, 1.90625 - is a multiple of 1/32s, which is the spacing of a float32 near 474196. That is this machine uptime in seconds, because GetRTC returns QueryPerformanceCounter scaled to milliseconds since boot, so (Scalar) Now() is a number near half a million and its resolution has decayed to 31ms - coarser than the physics step it is being used to time. The stall COUNT is unaffected and real, at three to five a second; the interval between them was measurement noise. Logged separately as its own defect. What is left is that the angle is measured BETWEEN the pod and the eye, so a hitch in the pan reads exactly like a hitch in the pod - and the symptom is a pod moving PAST, which is when the pan rate peaks. Measure each one on its own, by the same consecutive-frame ratio, and let the trace say which. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1159,11 +1159,68 @@ void
|
|||||||
static Scalar fraction_sum = 0.0f;
|
static Scalar fraction_sum = 0.0f;
|
||||||
static int pinned_high = 0;
|
static int pinned_high = 0;
|
||||||
static int pinned_low = 0;
|
static int pinned_low = 0;
|
||||||
|
static Point3D last_pod(0.0f, 0.0f, 0.0f);
|
||||||
|
static Point3D last_eye(0.0f, 0.0f, 0.0f);
|
||||||
|
static Logical have_pod = False;
|
||||||
|
static Scalar last_pod_step = 0.0f;
|
||||||
|
static Scalar last_eye_step = 0.0f;
|
||||||
|
static Scalar eye_travel = 0.0f;
|
||||||
|
static int pod_stalls = 0;
|
||||||
|
static int eye_stalls = 0;
|
||||||
|
|
||||||
Vector3D dir;
|
Vector3D dir;
|
||||||
dir.Divide(to_pod, range);
|
dir.Divide(to_pod, range);
|
||||||
++frames;
|
++frames;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Split the pod's motion from the camera's.
|
||||||
|
//
|
||||||
|
// The angle above is measured BETWEEN the two, so a
|
||||||
|
// hitch in the pan and a hitch in the pod are the same
|
||||||
|
// reading - and the symptom is specifically a pod moving
|
||||||
|
// past, which is when the pan rate peaks. Measuring each
|
||||||
|
// on its own says which one to go and fix.
|
||||||
|
//
|
||||||
|
// Same ratio test as the angle, and for the same reason:
|
||||||
|
// consecutive frames of smooth motion are near equal
|
||||||
|
// whatever the speed.
|
||||||
|
//
|
||||||
|
Point3D pod_now;
|
||||||
|
pod_now.x = renderToWorld(3,0);
|
||||||
|
pod_now.y = renderToWorld(3,1);
|
||||||
|
pod_now.z = renderToWorld(3,2);
|
||||||
|
|
||||||
|
if (have_pod)
|
||||||
|
{
|
||||||
|
Vector3D pod_moved;
|
||||||
|
pod_moved.Subtract(pod_now, last_pod);
|
||||||
|
|
||||||
|
Vector3D eye_moved;
|
||||||
|
eye_moved.x = gEyeWorld.x - last_eye.x;
|
||||||
|
eye_moved.y = gEyeWorld.y - last_eye.y;
|
||||||
|
eye_moved.z = gEyeWorld.z - last_eye.z;
|
||||||
|
|
||||||
|
Scalar pod_step = pod_moved.Length();
|
||||||
|
Scalar eye_step = eye_moved.Length();
|
||||||
|
|
||||||
|
if (last_pod_step > 0.0001f && pod_step < last_pod_step * 0.4f)
|
||||||
|
{
|
||||||
|
++pod_stalls;
|
||||||
|
}
|
||||||
|
if (last_eye_step > 0.0001f && eye_step < last_eye_step * 0.4f)
|
||||||
|
{
|
||||||
|
++eye_stalls;
|
||||||
|
}
|
||||||
|
last_pod_step = pod_step;
|
||||||
|
last_eye_step = eye_step;
|
||||||
|
eye_travel += eye_step;
|
||||||
|
}
|
||||||
|
last_pod = pod_now;
|
||||||
|
last_eye.x = gEyeWorld.x;
|
||||||
|
last_eye.y = gEyeWorld.y;
|
||||||
|
last_eye.z = gEyeWorld.z;
|
||||||
|
have_pod = True;
|
||||||
|
|
||||||
//
|
//
|
||||||
// How far through the physics step this frame is being
|
// How far through the physics step this frame is being
|
||||||
// drawn. This is the number the interpolation actually
|
// drawn. This is the number the interpolation actually
|
||||||
@@ -1265,6 +1322,17 @@ void
|
|||||||
? "simulation is behind, interpolation degenerate"
|
? "simulation is behind, interpolation degenerate"
|
||||||
: "sweeping normally")
|
: "sweeping normally")
|
||||||
<< ")\n" << std::flush;
|
<< ")\n" << std::flush;
|
||||||
|
|
||||||
|
DEBUG_STREAM << "CamLog: motion split - pod "
|
||||||
|
<< pod_stalls << " stall(s), eye "
|
||||||
|
<< eye_stalls << " stall(s), eye travelled "
|
||||||
|
<< eye_travel << "m, verdict "
|
||||||
|
<< ((pod_stalls > eye_stalls * 2)
|
||||||
|
? "the pod"
|
||||||
|
: ((eye_stalls > pod_stalls * 2)
|
||||||
|
? "the camera"
|
||||||
|
: "both, or neither"))
|
||||||
|
<< "\n" << std::flush;
|
||||||
}
|
}
|
||||||
next_say = ((Scalar) Now()) + 5.0f;
|
next_say = ((Scalar) Now()) + 5.0f;
|
||||||
frames = 0;
|
frames = 0;
|
||||||
@@ -1277,6 +1345,9 @@ void
|
|||||||
fraction_sum = 0.0f;
|
fraction_sum = 0.0f;
|
||||||
pinned_high = 0;
|
pinned_high = 0;
|
||||||
pinned_low = 0;
|
pinned_low = 0;
|
||||||
|
pod_stalls = 0;
|
||||||
|
eye_stalls = 0;
|
||||||
|
eye_travel = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user