diff --git a/MUNGA/MOVER.cpp b/MUNGA/MOVER.cpp index 2b0095b..a20a648 100644 --- a/MUNGA/MOVER.cpp +++ b/MUNGA/MOVER.cpp @@ -12,6 +12,15 @@ #include "app.h" #include "notation.h" +// +// The blend fraction the last dead-reckoned step used, and whether it +// blended at all rather than snapping. Only read by the RP412CAMLOG trace +// in Mover::DeadReckon, which needs them from the branch that computes +// them a few lines earlier. +// +static Logical gLastLerpUsed = False; +static Scalar gLastPercent = 0.0f; + //############################################################################# //############################### Mover ################################# //############################################################################# @@ -513,6 +522,10 @@ void Scalar percent = time_slice / ((nextUpdate - lastPerformance) + time_slice); + // for the RP412CAMLOG trace at the end of this function + gLastLerpUsed = True; + gLastPercent = percent; + // //------------------------------------------ // Do a spherical lerp on the angular motion @@ -562,6 +575,7 @@ void } else { + gLastLerpUsed = False; // snapped, not blended localOrigin = projectedOrigin; worldLinearVelocity = projectedVelocity.linearMotion; localVelocity.angularMotion = projectedVelocity.angularMotion; @@ -581,6 +595,105 @@ void localToWorld = localOrigin; } UpdateLocalMotion(); + + // + // RP412CAMLOG: is a replicant's motion actually uniform? + // + // Measured HERE, in the replicant's own step, and nowhere else. + // Every previous attempt at this question sampled from another + // clock - the camera's step grid, or an arriving packet's + // timestamp - and two independent clocks alias against each other + // whatever the game is doing, so those numbers could never + // separate a real hitch from the measurement's own beat. This one + // has a single frame of reference: consecutive steps of the entity + // being asked about. + // + // percent is the whole mechanism above: it is how far this step + // moves toward the projected position, and it depends on + // nextUpdate being a decent guess at when the next packet lands. + // If that guess is poor the fraction swings, and swinging fraction + // is uneven motion no matter how clean the packets were. + // + // One entity only - the first replicant seen - because these + // counters are shared and a grid full of pods would blend into + // noise. + // + if (RPCameraLog()) + { + static EntityID watched = EntityID::Null; + static Logical latched = False; + + if (!latched) + { + latched = True; + watched = GetEntityID(); + } + if (watched == GetEntityID()) + { + static Scalar next_say = 0.0f; + static Point3D last_pos(0.0f, 0.0f, 0.0f); + static Logical have_last = False; + static int steps = 0; + static int spikes = 0; + static int stalls = 0; + static int lerped = 0; + static Scalar mean_step = 0.0f; + static Scalar min_percent = 1.0f; + static Scalar max_percent = 0.0f; + + ++steps; + if (have_last) + { + Vector3D moved; + moved.Subtract(localOrigin.linearPosition, last_pos); + Scalar distance = moved.Length(); + + if (distance > 50.0f) + { + mean_step = 0.0f; // respawn, not motion + } + else if (mean_step > 0.01f) + { + Scalar ratio = distance / mean_step; + if (ratio > 2.5f) { ++spikes; } + else if (ratio < 0.4f) { ++stalls; } + mean_step = mean_step * 0.9f + distance * 0.1f; + } + else + { + mean_step = distance; + } + } + last_pos = localOrigin.linearPosition; + have_last = True; + + if ((Scalar) Now() >= next_say) + { + if (next_say > 0.0f) + { + DEBUG_STREAM << "CamLog: replicant motion - " << steps + << " own steps, " << spikes << " spike(s), " + << stalls << " stall(s), " << lerped + << " lerped, percent " << min_percent << ".." + << max_percent << ", mean step " << mean_step + << "m\n" << std::flush; + } + next_say = ((Scalar) Now()) + 5.0f; + steps = 0; + spikes = 0; + stalls = 0; + lerped = 0; + min_percent = 1.0f; + max_percent = 0.0f; + } + if (gLastLerpUsed) + { + ++lerped; + if (gLastPercent < min_percent) { min_percent = gLastPercent; } + if (gLastPercent > max_percent) { max_percent = gLastPercent; } + } + } + } } Check_Fpu(); }