From e328baf2b4aa9a9f7a9db2d243a07571462f616b Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 23 Oct 2001 22:54:13 +0000 Subject: [PATCH] enable predictive smoothing --- direct/src/deadrec/smoothMover.cxx | 34 ++++++++++++++++++++++++++---- direct/src/deadrec/smoothMover.h | 5 +++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/direct/src/deadrec/smoothMover.cxx b/direct/src/deadrec/smoothMover.cxx index 92180aff7b..4844da6bb0 100644 --- a/direct/src/deadrec/smoothMover.cxx +++ b/direct/src/deadrec/smoothMover.cxx @@ -214,10 +214,15 @@ compute_smooth_position(double timestamp) { int point_after = -1; double timestamp_after = 0.0; + // This loop doesn't make any assumptions about the ordering of + // timestamps in the queue. We could probably make it faster by + // assuming timestamps are ordered from oldest to newest (as they + // are generally guaranteed to be, except for the minor detail of + // clients occasionally resetting their clocks). int num_points = _points.size(); for (int i = 0; i < num_points; i++) { const SamplePoint &point = _points[i]; - if (point._timestamp <= timestamp) { + if (point._timestamp < timestamp) { // This point is before the desired time. Find the newest of // these. if (point_before == -1 || point._timestamp > timestamp_before) { @@ -251,9 +256,30 @@ compute_smooth_position(double timestamp) { bool result = true; - if (point_after == -1 || timestamp_before == timestamp_after) { - // If we only have a before point, we have to stop there, unless - // we have prediction in effect. + if (point_after == -1 && _prediction_mode != PM_off) { + // With prediction in effect, we're allowed to anticipate where + // the avatar is going by a tiny bit, if we don't have current + // enough data. This works only if we have at least two points of + // old data, and they're not *too* old. + if (point_before > 0 && + timestamp - timestamp_before <= _max_position_age) { + // To implement simple prediction, we simply back up in time to + // the previous two timestamps, and base our linear + // interpolation off of those two, extending into the future. + int point_before_before = point_before - 1; + const SamplePoint &point = _points[point_before_before]; + if (point._timestamp < timestamp_before) { + point_after = point_before; + timestamp_after = timestamp_before; + point_before = point_before_before; + timestamp_before = point._timestamp; + } + } + } + + if (point_after == -1) { + // If we only have a before point even after we've checked for the + // possibility of using prediction, then we have to stop there. const SamplePoint &point = _points[point_before]; set_smooth_pos(point._pos, point._hpr, timestamp); if (timestamp - point._timestamp > _reset_velocity_age) { diff --git a/direct/src/deadrec/smoothMover.h b/direct/src/deadrec/smoothMover.h index a7aabd2eaf..257b02ffce 100644 --- a/direct/src/deadrec/smoothMover.h +++ b/direct/src/deadrec/smoothMover.h @@ -100,10 +100,15 @@ PUBLISHED: enum SmoothMode { SM_off, SM_on, + // We might conceivably add more kinds of smooth modes later, for + // instance, SM_spline. }; enum PredictionMode { PM_off, PM_on, + // Similarly for other kinds of prediction modes. I don't know + // why, though; linear interpolation seems to work pretty darn + // well. }; INLINE static void set_smooth_mode(SmoothMode mode);