예제 #1
0
        public void Compute_Step4_InterpolateWithThreeOldEnoughSnapshots()
        {
            // add three old enough snapshots.
            // (localTime - bufferTime)
            SimpleSnapshot first  = new SimpleSnapshot(0, 0, 1);
            SimpleSnapshot second = new SimpleSnapshot(1, 1, 2);
            SimpleSnapshot third  = new SimpleSnapshot(2, 2, 2);

            buffer.Add(first.remoteTimestamp, first);
            buffer.Add(second.remoteTimestamp, second);
            buffer.Add(third.remoteTimestamp, third);

            // compute with initialized remoteTime and buffer time of 2 seconds
            // and a delta time to be sure that we move along it no matter what.
            double localTime         = 4;
            double deltaTime         = 0.5;
            double interpolationTime = 0;
            float  bufferTime        = 2;
            int    catchupThreshold  = Int32.MaxValue;
            float  catchupMultiplier = 0;
            bool   result            = SnapshotInterpolation.Compute(localTime, deltaTime, ref interpolationTime, bufferTime, buffer, catchupThreshold, catchupMultiplier, SimpleSnapshot.Interpolate, out SimpleSnapshot computed);

            // should spit out the interpolated snapshot
            Assert.That(result, Is.True);
            // interpolation started just now, from 0.
            // and deltaTime is 0.5, so we should be at 0.5 now.
            Assert.That(interpolationTime, Is.EqualTo(0.5));
            // buffer should be untouched, we are still interpolating between
            // the first two. third should still be there.
            Assert.That(buffer.Count, Is.EqualTo(3));
            // computed snapshot should be interpolated in the middle
            Assert.That(computed.value, Is.EqualTo(1.5).Within(Mathf.Epsilon));
        }
예제 #2
0
        public void Compute_Step4_InterpolateWithTwoOldEnoughSnapshots()
        {
            // add two old enough snapshots
            // (localTime - bufferTime)
            SimpleSnapshot first = new SimpleSnapshot(0, 0, 1);
            // IMPORTANT: second snapshot delta is != 1 so we can be sure that
            //            interpolationTime result is actual time, not 't' ratio.
            //            for a delta of 1, absolute and relative values would
            //            return the same results.
            SimpleSnapshot second = new SimpleSnapshot(2, 2, 2);

            buffer.Add(first.remoteTimestamp, first);
            buffer.Add(second.remoteTimestamp, second);

            // compute with initialized remoteTime and buffer time of 2 seconds
            // and a delta time to be sure that we move along it no matter what.
            double localTime         = 4;
            double deltaTime         = 1.5;
            double interpolationTime = 0;
            float  bufferTime        = 2;
            int    catchupThreshold  = Int32.MaxValue;
            float  catchupMultiplier = 0;
            bool   result            = SnapshotInterpolation.Compute(localTime, deltaTime, ref interpolationTime, bufferTime, buffer, catchupThreshold, catchupMultiplier, SimpleSnapshot.Interpolate, out SimpleSnapshot computed);

            // should spit out the interpolated snapshot
            Assert.That(result, Is.True);
            // interpolation started just now, from 0.
            // and deltaTime is 1.5, so we should be at 1.5 now.
            Assert.That(interpolationTime, Is.EqualTo(1.5));
            // buffer should be untouched, we are still interpolating between the two
            Assert.That(buffer.Count, Is.EqualTo(2));
            // interpolationTime is at 1.5, so 3/4 between first & second.
            // computed snapshot should be interpolated at 3/4ths.
            Assert.That(computed.value, Is.EqualTo(1.75).Within(Mathf.Epsilon));
        }
예제 #3
0
        public void Compute_Step3_WaitsUntilBufferTime()
        {
            // add two snapshots that are barely not old enough
            // (localTime - bufferTime)
            // IMPORTANT: use a 'definitely old enough' remoteTime to make sure
            //            that compute() actually checks LOCAL, not REMOTE time!
            SimpleSnapshot first  = new SimpleSnapshot(0.1, 0.1, 0);
            SimpleSnapshot second = new SimpleSnapshot(0.9, 1.1, 0);

            buffer.Add(first.remoteTimestamp, first);
            buffer.Add(second.remoteTimestamp, second);

            // compute with initialized remoteTime and buffer time of 2 seconds
            // and a delta time to be sure that we move along it no matter what.
            double localTime         = 3;
            double deltaTime         = 0.5;
            double interpolationTime = 0;
            float  bufferTime        = 2;
            int    catchupThreshold  = Int32.MaxValue;
            float  catchupMultiplier = 0;
            bool   result            = SnapshotInterpolation.Compute(localTime, deltaTime, ref interpolationTime, bufferTime, buffer, catchupThreshold, catchupMultiplier, SimpleSnapshot.Interpolate, out SimpleSnapshot computed);

            // should not spit out any snapshot to apply
            Assert.That(result, Is.False);
            // no interpolation should happen yet (not old enough)
            Assert.That(interpolationTime, Is.EqualTo(0));
            // buffer should be untouched
            Assert.That(buffer.Count, Is.EqualTo(2));
        }
예제 #4
0
        public void Compute_Step5_OvershootWithEnoughSnapshots_2x_MovesToSecondNextSnapshot()
        {
            // add two old enough snapshots
            // (localTime - bufferTime)
            SimpleSnapshot first  = new SimpleSnapshot(0, 0, 1);
            SimpleSnapshot second = new SimpleSnapshot(1, 1, 2);
            // IMPORTANT: third snapshot needs to be:
            // - a different time delta
            //   to test if overflow is correct if deltas are different.
            //   it's not obvious if we ever use t ratio between [0,1] where an
            //   overflow of 0.1 between A,B could speed up B,C interpolation if
            //   that's not the same delta, since t is a ratio.
            // - a different value delta to check if it really _interpolates_,
            //   not just extrapolates further after A,B
            SimpleSnapshot third  = new SimpleSnapshot(3, 3, 4);
            SimpleSnapshot fourth = new SimpleSnapshot(5, 5, 6);

            buffer.Add(first.remoteTimestamp, first);
            buffer.Add(second.remoteTimestamp, second);
            buffer.Add(third.remoteTimestamp, third);
            buffer.Add(fourth.remoteTimestamp, fourth);

            // compute with initialized remoteTime and buffer time of 2 seconds
            // and a delta time to be sure that we move along it no matter what.
            // -> interpolation time is already at '1' at the end.
            // -> compute will add 1.5 deltaTime
            // -> so we should overshoot beyond second and third even
            //
            // localTime is 7. fourth snapshot localTime is at 5.
            // bufferTime is 2.
            // so fourth is exactly old enough and we should move there.
            double localTime         = 7;
            double deltaTime         = 2.5;
            double interpolationTime = 1;
            float  bufferTime        = 2;
            int    catchupThreshold  = Int32.MaxValue;
            float  catchupMultiplier = 0;
            bool   result            = SnapshotInterpolation.Compute(localTime, deltaTime, ref interpolationTime, bufferTime, buffer, catchupThreshold, catchupMultiplier, SimpleSnapshot.Interpolate, out SimpleSnapshot computed);

            // should spit out the interpolated snapshot
            Assert.That(result, Is.True);
            // interpolation started at the end = 1
            // and deltaTime is 2.5, so we were at 4.5 internally.
            // we have more snapshots, so we:
            //   * jump to third, subtract delta of 1-0 = 1 => 2.5
            //   * jump to fourth, subtract delta of 3-1 = 2 => 0.5
            //   * end up at 0.5 again, between third and fourth
            Assert.That(interpolationTime, Is.EqualTo(0.5));
            // buffer's first entry should have been removed
            Assert.That(buffer.Count, Is.EqualTo(2));
            // computed snapshot should be 1/4 way between second and third
            // because delta is 2 and interpolationTime is at 0.5 which is 1/4
            Assert.That(computed.value, Is.EqualTo(4.5).Within(Mathf.Epsilon));
        }
예제 #5
0
        public void Compute_Step1_DefaultDoesNothing()
        {
            // compute with defaults
            double localTime         = 0;
            double deltaTime         = 0;
            double interpolationTime = 0;
            float  bufferTime        = 0;
            int    catchupThreshold  = Int32.MaxValue;
            float  catchupMultiplier = 0;
            bool   result            = SnapshotInterpolation.Compute(localTime, deltaTime, ref interpolationTime, bufferTime, buffer, catchupThreshold, catchupMultiplier, SimpleSnapshot.Interpolate, out SimpleSnapshot computed);

            // should not spit out any snapshot to apply
            Assert.That(result, Is.False);
            // no interpolation should have happened yet
            Assert.That(interpolationTime, Is.EqualTo(0));
            // buffer should still be untouched
            Assert.That(buffer.Count, Is.EqualTo(0));
        }
예제 #6
0
        public void Compute_Step4_InterpolateAfterLongPause()
        {
            // add two immediate, and one that arrives 100s later
            // (localTime - bufferTime)
            SimpleSnapshot first  = new SimpleSnapshot(0, 0, 0);
            SimpleSnapshot second = new SimpleSnapshot(1, 1, 1);
            SimpleSnapshot third  = new SimpleSnapshot(101, 2, 101);

            buffer.Add(first.remoteTimestamp, first);
            buffer.Add(second.remoteTimestamp, second);
            buffer.Add(third.remoteTimestamp, third);

            // compute where we are half way between first and second,
            // and now are updated 1 minute later.
            double localTime         = 103;  // 1011+bufferTime so third snapshot is old enough
            double deltaTime         = 98.5; // 99s - interpolation time
            double interpolationTime = 0.5;  // half way between first and second
            float  bufferTime        = 2;
            int    catchupThreshold  = Int32.MaxValue;
            float  catchupMultiplier = 0;
            bool   result            = SnapshotInterpolation.Compute(localTime, deltaTime, ref interpolationTime, bufferTime, buffer, catchupThreshold, catchupMultiplier, SimpleSnapshot.Interpolate, out SimpleSnapshot computed);

            // should spit out the interpolated snapshot
            Assert.That(result, Is.True);
            // interpolation started at 0.5, right between first & second.
            // we received another snapshot at t=101.
            // delta = 98.5 seconds
            // => interpolationTime = 99
            // => overshoots second goal, so we move to third goal and subtract 1
            // => so we should be at 98 now
            Assert.That(interpolationTime, Is.EqualTo(98));
            // we moved to the next snapshot. so only 2 should be in buffer now.
            Assert.That(buffer.Count, Is.EqualTo(2));
            // delta between second and third is 100.
            // interpolationTime is at 98
            // interpolationTime is relative to second.time
            // => InverseLerp(1, 101, 1 + 98) = 0.98
            // which is at 98% of the value
            // => Lerp(1, 101, 0.98): 101-1 is 100. 98% are 98. relative to '1'
            //    makes it 99.
            Assert.That(computed.value, Is.EqualTo(99).Within(Mathf.Epsilon));
        }
예제 #7
0
        public void Compute_Step5_OvershootWithoutEnoughSnapshots()
        {
            // add two old enough snapshots
            // (localTime - bufferTime)
            SimpleSnapshot first  = new SimpleSnapshot(0, 0, 1);
            SimpleSnapshot second = new SimpleSnapshot(1, 1, 2);

            buffer.Add(first.remoteTimestamp, first);
            buffer.Add(second.remoteTimestamp, second);

            // compute with initialized remoteTime and buffer time of 2 seconds
            // and a delta time to be sure that we move along it no matter what.
            // -> interpolation time is already at '1' at the end.
            // -> compute will add 0.5 deltaTime
            // -> so we should NOT overshoot aka extrapolate beyond second snap.
            double localTime         = 3;
            double deltaTime         = 0.5;
            double interpolationTime = 1;
            float  bufferTime        = 2;
            int    catchupThreshold  = Int32.MaxValue;
            float  catchupMultiplier = 0;
            bool   result            = SnapshotInterpolation.Compute(localTime, deltaTime, ref interpolationTime, bufferTime, buffer, catchupThreshold, catchupMultiplier, SimpleSnapshot.Interpolate, out SimpleSnapshot computed);

            // should spit out the interpolated snapshot
            Assert.That(result, Is.True);
            // interpolation started at the end = 1
            // and deltaTime is 0.5, so it's at 1.5 internally.
            //
            // BUT there's NO reason to overshoot interpolationTime if there's
            // no other snapshots to move to.
            // interpolationTime overshoot is only for smooth transitions WHILE
            // moving.
            // for example, if we keep overshooting to 100, then we would
            // instantly skip the next 20 snapshots.
            // => so it should be capped at second.remoteTime
            Assert.That(interpolationTime, Is.EqualTo(1));
            // buffer should be untouched, we are still interpolating between the two
            Assert.That(buffer.Count, Is.EqualTo(2));
            // computed snapshot should NOT extrapolate beyond second snap.
            Assert.That(computed.value, Is.EqualTo(2).Within(Mathf.Epsilon));
        }
예제 #8
0
        public void Compute_Step4_InterpolateWithCatchup()
        {
            // add two old enough snapshots
            // (localTime - bufferTime)
            SimpleSnapshot first  = new SimpleSnapshot(0, 0, 1);
            SimpleSnapshot second = new SimpleSnapshot(1, 1, 2);

            buffer.Add(first.remoteTimestamp, first);
            buffer.Add(second.remoteTimestamp, second);

            // start applying 25% catchup per excess when > 2.
            int   catchupThreshold  = 2;
            float catchupMultiplier = 0.25f;

            // two excess snapshots to make sure that multiplier is accumulated
            SimpleSnapshot excess1 = new SimpleSnapshot(2, 2, 3);
            SimpleSnapshot excess2 = new SimpleSnapshot(3, 3, 4);

            buffer.Add(excess1.remoteTimestamp, excess1);
            buffer.Add(excess2.remoteTimestamp, excess2);

            // compute with initialized remoteTime and buffer time of 2 seconds
            // and a delta time to be sure that we move along it no matter what.
            double localTime         = 3;
            double deltaTime         = 0.5;
            double interpolationTime = 0;
            float  bufferTime        = 2;
            bool   result            = SnapshotInterpolation.Compute(localTime, deltaTime, ref interpolationTime, bufferTime, buffer, catchupThreshold, catchupMultiplier, SimpleSnapshot.Interpolate, out SimpleSnapshot computed);

            // should spit out the interpolated snapshot
            Assert.That(result, Is.True);
            // interpolation started just now, from 0.
            // and deltaTime is 0.5 + 50% catchup, so we should be at 0.75 now
            Assert.That(interpolationTime, Is.EqualTo(0.75));
            // buffer should be untouched, we are still interpolating between
            // the first two.
            Assert.That(buffer.Count, Is.EqualTo(4));
            // computed snapshot should be interpolated in 3/4 because
            // interpolationTime is at 3/4
            Assert.That(computed.value, Is.EqualTo(1.75).Within(Mathf.Epsilon));
        }
예제 #9
0
        public void Compute_Step3_WaitsForSecondSnapshot()
        {
            // add a snapshot at t = 0
            SimpleSnapshot first = new SimpleSnapshot(0, 0, 0);

            buffer.Add(first.remoteTimestamp, first);

            // compute at localTime = 2 with bufferTime = 1
            // so the threshold is anything < t=1
            double localTime         = 2;
            double deltaTime         = 0;
            double interpolationTime = 0;
            float  bufferTime        = 1;
            int    catchupThreshold  = Int32.MaxValue;
            float  catchupMultiplier = 0;
            bool   result            = SnapshotInterpolation.Compute(localTime, deltaTime, ref interpolationTime, bufferTime, buffer, catchupThreshold, catchupMultiplier, SimpleSnapshot.Interpolate, out SimpleSnapshot computed);

            // should not spit out any snapshot to apply
            Assert.That(result, Is.False);
            // no interpolation should happen yet (not enough snapshots)
            Assert.That(interpolationTime, Is.EqualTo(0));
            // buffer should be untouched
            Assert.That(buffer.Count, Is.EqualTo(1));
        }
예제 #10
0
        public void Compute_Step5_OvershootWithEnoughSnapshots_NextIsntOldEnough()
        {
            // add two old enough snapshots
            // (localTime - bufferTime)
            //
            // IMPORTANT: second.time needs to be != second.time-first.time
            //            to guarantee that we cap interpolationTime (which is
            //            RELATIVE from 0..delta) at delta, not at second.time.
            //            this was a bug before.
            SimpleSnapshot first  = new SimpleSnapshot(1, 1, 1);
            SimpleSnapshot second = new SimpleSnapshot(2, 2, 2);
            // IMPORTANT: third snapshot needs to be:
            // - a different time delta
            //   to test if overflow is correct if deltas are different.
            //   it's not obvious if we ever use t ratio between [0,1] where an
            //   overflow of 0.1 between A,B could speed up B,C interpolation if
            //   that's not the same delta, since t is a ratio.
            // - a different value delta to check if it really _interpolates_,
            //   not just extrapolates further after A,B
            SimpleSnapshot third = new SimpleSnapshot(4, 4, 4);

            buffer.Add(first.remoteTimestamp, first);
            buffer.Add(second.remoteTimestamp, second);
            buffer.Add(third.remoteTimestamp, third);

            // compute with initialized remoteTime and buffer time of 2 seconds
            // and a delta time to be sure that we move along it no matter what.
            // -> interpolation time is already at '1' at the end.
            // -> compute will add 0.5 deltaTime
            // -> so we overshoot beyond the second one and move to the next
            //
            // localTime is at 4
            // third snapshot localTime is at 4.
            // bufferTime is 2, so it is NOT old enough and we should wait!
            double localTime         = 4;
            double deltaTime         = 0.5;
            double interpolationTime = 1;
            float  bufferTime        = 2;
            int    catchupThreshold  = Int32.MaxValue;
            float  catchupMultiplier = 0;
            bool   result            = SnapshotInterpolation.Compute(localTime, deltaTime, ref interpolationTime, bufferTime, buffer, catchupThreshold, catchupMultiplier, SimpleSnapshot.Interpolate, out SimpleSnapshot computed);

            // should still spit out a result between first & second.
            Assert.That(result, Is.True);
            // interpolation started at the end = 1
            // and deltaTime is 0.5, so we were at 1.5 internally.
            //
            // BUT there's NO reason to overshoot interpolationTime while we
            // wait for the next snapshot which isn't old enough.
            // we stopped movement anyway.
            // interpolationTime overshoot is only for smooth transitions WHILE
            // moving.
            // for example, if we overshoot to 100 while waiting, then we would
            // instantly skip the next 20 snapshots.
            // => so it should be capped at max
            // => which is always 0..delta, NOT first.time .. second.time!!
            Assert.That(interpolationTime, Is.EqualTo(1));
            // buffer should be untouched. shouldn't have moved to third yet.
            Assert.That(buffer.Count, Is.EqualTo(3));
            // computed snapshot should be all the way at second snapshot.
            Assert.That(computed.value, Is.EqualTo(2).Within(Mathf.Epsilon));
        }