@@ -131,22 +131,14 @@ internal struct CurrentState
131131 public T Phase1Value ;
132132 public T Phase2Value ;
133133
134- private float m_AverageDeltaTime ;
134+ private float m_CurrentDeltaTime ;
135135
136- public float AverageDeltaTime => m_AverageDeltaTime ;
136+ public float CurrentDeltaTime => m_CurrentDeltaTime ;
137137 public double FinalTimeToTarget => Math . Max ( 0.0 , TimeToTargetValue - DeltaTime ) ;
138138
139139 public void AddDeltaTime ( float deltaTime )
140140 {
141- if ( m_AverageDeltaTime == 0.0f )
142- {
143- m_AverageDeltaTime = deltaTime ;
144- }
145- else
146- {
147- m_AverageDeltaTime += deltaTime ;
148- m_AverageDeltaTime *= 0.5f ;
149- }
141+ m_CurrentDeltaTime = deltaTime ;
150142 DeltaTime = Math . Min ( DeltaTime + deltaTime , TimeToTargetValue ) ;
151143 DeltaTimePredict = Math . Min ( DeltaTime + deltaTime , TimeToTargetValue + MaxDeltaTime ) ;
152144 LerpT = ( float ) ( TimeToTargetValue == 0.0 ? 1.0 : DeltaTime / TimeToTargetValue ) ;
@@ -162,21 +154,20 @@ public void AddDeltaTime(float deltaTime)
162154
163155 public void SetTimeToTarget ( double timeToTarget )
164156 {
165- m_AverageDeltaTime = 0.0f ;
166157 DeltaTimePredict = 0.0f ;
167158 LerpTPredict = 0.0f ;
168159 LerpT = 0.0f ;
169160 DeltaTime = 0.0f ;
170161 TimeToTargetValue = timeToTarget ;
171162 }
172163
173- public bool TargetTimeAproximatelyReached ( float adjustForNext = 1.0f )
164+ public bool TargetTimeAproximatelyReached ( bool nextStatePending )
174165 {
175166 if ( ! Target . HasValue )
176167 {
177168 return false ;
178169 }
179- return ( m_AverageDeltaTime * adjustForNext ) >= FinalTimeToTarget ;
170+ return ( m_CurrentDeltaTime * ( nextStatePending ? ( LerpT * 1.30f ) : 1.0f ) ) >= FinalTimeToTarget ;
180171 }
181172
182173 public void Reset ( T currentValue )
@@ -196,7 +187,7 @@ public void Reset(T currentValue)
196187 TimeToTargetValue = 0.0f ;
197188 DeltaTime = 0.0f ;
198189 DeltaTimePredict = 0.0f ;
199- m_AverageDeltaTime = 0.0f ;
190+ m_CurrentDeltaTime = 0.0f ;
200191 }
201192 }
202193
@@ -244,11 +235,6 @@ public void Reset(T currentValue)
244235 /// </summary>
245236 private T m_PredictedRateOfChange ;
246237
247- /// <summary>
248- /// When true, the value <see cref="T"/> is an angular numeric representation.
249- /// </summary>
250- private protected bool m_IsAngularValue ;
251-
252238 /// <summary>
253239 /// Resets interpolator to the defaults.
254240 /// </summary>
@@ -270,21 +256,19 @@ public void Clear()
270256 /// </remarks>
271257 /// <param name="targetValue">The target value to reset the interpolator to</param>
272258 /// <param name="serverTime">The current server time</param>
273- /// <param name="isAngularValue">When rotation is expressed as Euler values (i.e. Vector3 and/or float) this helps determine what kind of smooth dampening to use.</param>
274- public void ResetTo ( T targetValue , double serverTime , bool isAngularValue = false )
259+ public void ResetTo ( T targetValue , double serverTime )
275260 {
276261 // Clear the interpolator
277262 Clear ( ) ;
278- InternalReset ( targetValue , serverTime , isAngularValue ) ;
263+ InternalReset ( targetValue , serverTime ) ;
279264 }
280265
281- private void InternalReset ( T targetValue , double serverTime , bool isAngularValue = false , bool addMeasurement = true )
266+ private void InternalReset ( T targetValue , double serverTime , bool addMeasurement = true )
282267 {
283268 m_RateOfChange = default ;
284269 m_PredictedRateOfChange = default ;
285270 // Set our initial value
286271 InterpolateState . Reset ( targetValue ) ;
287- m_IsAngularValue = isAngularValue ;
288272
289273 if ( addMeasurement )
290274 {
@@ -297,10 +281,11 @@ private void InternalReset(T targetValue, double serverTime, bool isAngularValue
297281 /// <summary>
298282 /// TryConsumeFromBuffer: Smooth Dampening Version
299283 /// </summary>
300- /// <param name="renderTime">render time: the time in "ticks ago" relative to the current tick latency</param>
301- /// <param name="minDeltaTime">minimum time delta (defaults to tick frequency)</param>
302- /// <param name="maxDeltaTime">maximum time delta which defines the maximum time duration when consuming more than one item from the buffer</param>
303- private void TryConsumeFromBuffer ( double renderTime , double minDeltaTime , double maxDeltaTime , bool isPredictedLerp )
284+ /// <param name="renderTime">render time: the time in "ticks ago" relative to the current tick latency.</param>
285+ /// <param name="minDeltaTime">minimum time delta (defaults to tick frequency).</param>
286+ /// <param name="maxDeltaTime">maximum time delta which defines the maximum time duration when consuming more than one item from the buffer.</param>
287+ /// <param name="extrapolateAhead">when true, the predicted target <see cref="CurrentState.Phase2Value"/> will lerp slightly ahead of the target.</param>
288+ private void TryConsumeFromBuffer ( double renderTime , double minDeltaTime , double maxDeltaTime , bool extrapolateAhead )
304289 {
305290 BufferedItem ? previousItem = null ;
306291 var startTime = 0.0 ;
@@ -333,7 +318,7 @@ private void TryConsumeFromBuffer(double renderTime, double minDeltaTime, double
333318 if ( ! noStateSet )
334319 {
335320 potentialItemNeedsProcessing = ( potentialItem . TimeSent <= renderTime ) && potentialItem . TimeSent >= InterpolateState . Target . Value . TimeSent ;
336- currentTargetTimeReached = InterpolateState . TargetTimeAproximatelyReached ( potentialItemNeedsProcessing ? 1.15f : 1.0f ) || InterpolateState . TargetReached ;
321+ currentTargetTimeReached = InterpolateState . TargetTimeAproximatelyReached ( potentialItemNeedsProcessing ) || InterpolateState . TargetReached ;
337322 if ( ! InterpolateState . TargetReached )
338323 {
339324 InterpolateState . TargetReached = IsAproximately ( InterpolateState . CurrentValue , InterpolateState . Target . Value . Item ) ;
@@ -344,7 +329,7 @@ private void TryConsumeFromBuffer(double renderTime, double minDeltaTime, double
344329 // then pull the BufferedItem from the queue. The second portion of this accounts for scenarios where there
345330 // was bad latency and the buffer has more than one item in the queue that is less than the renderTime. Under
346331 // this scenario, we just want to continue pulling items from the queue until the last item pulled from the
347- // queue is greater than the redner time or greater than the currently targeted item.
332+ // queue is greater than the redner time or greater than the currently targeted item's sent time .
348333 if ( noStateSet || ( ( currentTargetTimeReached || InterpolateState . TargetReached ) && potentialItemNeedsProcessing ) )
349334 {
350335 if ( m_BufferQueue . TryDequeue ( out BufferedItem target ) )
@@ -372,21 +357,16 @@ private void TryConsumeFromBuffer(double renderTime, double minDeltaTime, double
372357 alreadyHasBufferItem = true ;
373358 InterpolateState . TargetReached = false ;
374359 startTime = InterpolateState . Target . Value . TimeSent ;
375- if ( isPredictedLerp )
376- {
377- InterpolateState . Phase1Value = InterpolateState . PreviousValue ;
378- InterpolateState . Phase2Value = Interpolate ( InterpolateState . PredictValue , target . Item , InterpolateState . AverageDeltaTime ) ;
379- }
380- else
381- {
382- InterpolateState . PredictValue = InterpolateState . PreviousValue ;
383- InterpolateState . PreviousValue = InterpolateState . CurrentValue ;
384- }
385360 InterpolateState . MaxDeltaTime = maxDeltaTime ;
386361 InterpolateState . PredictingNext = m_BufferQueue . Count > 0 ;
362+ InterpolateState . Phase1Value = InterpolateState . PreviousValue ;
363+ if ( extrapolateAhead && InterpolateState . PredictingNext )
364+ {
365+ InterpolateState . Phase2Value = InterpolateState . PredictingNext ? Interpolate ( InterpolateState . PredictValue , target . Item , InterpolateState . CurrentDeltaTime )
366+ : InterpolateState . Phase2Value = InterpolateState . PredictValue ;
367+ }
387368 }
388- // We continue to stretch the time out if we are far behind in processing the buffer.
389- // TODO: We need to compress time when there is a large amount of items to be processed.
369+
390370 InterpolateState . SetTimeToTarget ( Math . Max ( ( float ) ( target . TimeSent - startTime ) , minDeltaTime ) ) ;
391371 InterpolateState . Target = target ;
392372 }
@@ -444,8 +424,8 @@ internal T Update(float deltaTime, double tickLatencyAsTime, double minDeltaTime
444424 // SmoothDampen or LerpExtrapolateBlend
445425 if ( ! isLerpAndExtrapolate )
446426 {
447- InterpolateState . PreviousValue = SmoothDamp ( InterpolateState . PreviousValue , InterpolateState . Target . Value . Item , ref m_RateOfChange , ( float ) InterpolateState . TimeToTargetValue , ( float ) InterpolateState . DeltaTime ) ;
448- InterpolateState . PredictValue = SmoothDamp ( InterpolateState . PredictValue , InterpolateState . Target . Value . Item , ref m_PredictedRateOfChange , ( float ) InterpolateState . TimeToTargetValue , ( float ) ( InterpolateState . DeltaTime + deltaTime ) ) ;
427+ InterpolateState . PreviousValue = SmoothDamp ( InterpolateState . PreviousValue , InterpolateState . Target . Value . Item , ref m_RateOfChange , ( float ) InterpolateState . TimeToTargetValue , ( float ) InterpolateState . TimeToTargetValue * InterpolateState . LerpT ) ;
428+ InterpolateState . PredictValue = SmoothDamp ( InterpolateState . PredictValue , InterpolateState . Target . Value . Item , ref m_PredictedRateOfChange , ( float ) InterpolateState . TimeToTargetValue , ( float ) ( InterpolateState . TimeToTargetValue * InterpolateState . LerpTPredict ) ) ;
449429 }
450430 else
451431 {
@@ -645,7 +625,7 @@ public void AddMeasurement(T newMeasurement, double sentTime)
645625 // Clear the interpolator
646626 Clear ( ) ;
647627 // Reset to the new value but don't automatically add the measurement (prevents recursion)
648- InternalReset ( newMeasurement , sentTime , m_IsAngularValue , false ) ;
628+ InternalReset ( newMeasurement , sentTime , false ) ;
649629 m_LastMeasurementAddedTime = sentTime ;
650630 m_LastBufferedItemReceived = new BufferedItem ( newMeasurement , sentTime , m_BufferCount ) ;
651631 // Next line keeps renderTime above m_StartTimeConsumed. Fixes pause/unpause issues
@@ -654,7 +634,7 @@ public void AddMeasurement(T newMeasurement, double sentTime)
654634 return ;
655635 }
656636
657- // Drop measurements that are received out of order/late
637+ // Drop measurements that are received out of order/late (i.e. user unreliable delta)
658638 if ( sentTime > m_LastMeasurementAddedTime || m_BufferCount == 0 )
659639 {
660640 m_BufferCount ++ ;
0 commit comments