diff --git a/MUNGA_L4/L4VIDRND.cpp b/MUNGA_L4/L4VIDRND.cpp index bc31eb1..66dcb7e 100644 --- a/MUNGA_L4/L4VIDRND.cpp +++ b/MUNGA_L4/L4VIDRND.cpp @@ -1153,11 +1153,34 @@ void static int interval_count = 0; static int frames = 0; static int lurches = 0; + static int stalls = 0; + static Scalar last_angle = 0.0f; + static Logical have_angle = False; + static Scalar fraction_sum = 0.0f; + static int pinned_high = 0; + static int pinned_low = 0; Vector3D dir; dir.Divide(to_pod, range); ++frames; + // + // How far through the physics step this frame is being + // drawn. This is the number the interpolation actually + // uses, so it is worth reading directly rather than + // inferring from the picture. It should sweep smoothly + // from 0 to 1 and wrap. Pinned at 1 means the + // simulation is behind and interpolation has degenerated + // to drawing the latest step over and over - which IS + // stepping, at the physics rate, however smooth the + // packets were. + // + Scalar fraction = myEntity->renderStepFraction; + + fraction_sum += fraction; + if (fraction > 0.99f) { ++pinned_high; } + if (fraction < 0.01f) { ++pinned_low; } + if (have_last) { Scalar dot = @@ -1169,15 +1192,31 @@ void Scalar angle = (Scalar) acos((double) dot); // - // Only judge while the pod is actually crossing the - // view. A pod held near the centre subtends almost - // no angle and every ratio against it is noise. + // Compare each frame against the frame BEFORE it, + // not against a running mean. The angular step + // varies six hundredfold between a pod at 119m and + // the same pod at 5m, so a long mean cannot keep up + // during a pass and reports its own lag as a lurch - + // which is precisely what the previous version of + // this trace did, in the one window that mattered. // - if (mean_angle > 0.0002f) + // Consecutive frames of a smooth pass are nearly + // equal however fast the sweep, so their ratio is + // immune to range. A tick is one frame that barely + // moves followed by one that catches up, so the + // stall is the event worth timing. + // + if (have_angle && last_angle > 0.00002f) { - if (angle > mean_angle * 2.5f) + Scalar ratio = angle / last_angle; + + if (ratio > 2.5f) { ++lurches; + } + else if (ratio < 0.4f) + { + ++stalls; Scalar now = (Scalar) Now(); @@ -1193,6 +1232,9 @@ void last_event = now; } } + last_angle = angle; + have_angle = True; + mean_angle = (mean_angle > 0.0f) ? (mean_angle * 0.95f + angle * 0.05f) : angle; @@ -1205,21 +1247,36 @@ void if (next_say > 0.0f) { DEBUG_STREAM << "CamLog: on-screen motion - " << frames - << " frames, " << lurches << " lurch(es), period " + << " frames, " << stalls << " stall(s), " + << lurches << " lurch(es), period " << ((interval_count > 0) ? (interval_sum / interval_count) : 0.0f) << "s (" << interval_min << ".." << interval_max << "), mean step " << (mean_angle * 1000.0f) << " mrad, range " << range << "m\n" << std::flush; + + DEBUG_STREAM << "CamLog: render fraction - mean " + << ((frames > 0) ? (fraction_sum / frames) : 0.0f) + << ", " << pinned_high << " pinned at 1, " + << pinned_low << " at 0, of " << frames + << " frames (" + << ((pinned_high * 4 > frames) + ? "simulation is behind, interpolation degenerate" + : "sweeping normally") + << ")\n" << std::flush; } next_say = ((Scalar) Now()) + 5.0f; frames = 0; lurches = 0; + stalls = 0; interval_sum = 0.0f; interval_min = 1000.0f; interval_max = 0.0f; interval_count = 0; + fraction_sum = 0.0f; + pinned_high = 0; + pinned_low = 0; } } }