@@ -312,6 +312,17 @@ private void TryConsumeFromBuffer(double renderTime, double minDeltaTime, double
312312 var currentTargetTimeReached = false ;
313313 var dequeuedCount = 0 ;
314314
315+ // In the event there is nothing left in the queue (i.e. motion/change stopped), we still need to determine if the target has been reached.
316+ if ( ! noStateSet && m_BufferQueue . Count == 0 )
317+ {
318+ if ( ! InterpolateState . TargetReached )
319+ {
320+ InterpolateState . TargetReached = IsAproximately ( InterpolateState . CurrentValue , InterpolateState . Target . Value . Item ) ;
321+ }
322+ return ;
323+ }
324+
325+ // Continue to process any remaining state updates in the queue (if any)
315326 while ( m_BufferQueue . TryPeek ( out BufferedItem potentialItem ) )
316327 {
317328 // If we are still on the same buffered item (FIFO Queue), then exit early as there is nothing
@@ -325,7 +336,7 @@ private void TryConsumeFromBuffer(double renderTime, double minDeltaTime, double
325336 {
326337 potentialItemNeedsProcessing = ( potentialItem . TimeSent <= renderTime ) && potentialItem . TimeSent >= InterpolateState . Target . Value . TimeSent ;
327338 currentTargetTimeReached = InterpolateState . TargetTimeAproximatelyReached ( potentialItemNeedsProcessing ? 1.0f : 0.85f ) || InterpolateState . TargetReached ;
328- if ( ! potentialItemNeedsProcessing && ! InterpolateState . TargetReached )
339+ if ( ! InterpolateState . TargetReached )
329340 {
330341 InterpolateState . TargetReached = IsAproximately ( InterpolateState . CurrentValue , InterpolateState . Target . Value . Item ) ;
331342 }
@@ -366,14 +377,19 @@ private void TryConsumeFromBuffer(double renderTime, double minDeltaTime, double
366377 if ( isPredictedLerp )
367378 {
368379 InterpolateState . Phase1Value = InterpolateState . PreviousValue ;
369- InterpolateState . Phase2Value = Interpolate ( InterpolateState . PredictValue , target . Item , InterpolateState . AverageDeltaTime ) ;
380+ InterpolateState . Phase2Value = Interpolate ( InterpolateState . PreviousValue , target . Item , InterpolateState . AverageDeltaTime ) ;
381+ }
382+ else
383+ {
384+ InterpolateState . PredictValue = InterpolateState . PreviousValue ;
385+ InterpolateState . PreviousValue = InterpolateState . CurrentValue ;
370386 }
371387 InterpolateState . MaxDeltaTime = maxDeltaTime ;
372388 InterpolateState . PredictingNext = m_BufferQueue . Count > 0 ;
373389 }
374- // TODO: We might consider creating yet another queue to add these items to and assure that the time is accelerated
375- // for each item as opposed to losing the resolution of the values .
376- InterpolateState . SetTimeToTarget ( Math . Clamp ( ( float ) ( target . TimeSent - startTime ) , minDeltaTime , maxDeltaTime * dequeuedCount ) ) ;
390+ // We continue to stretch the time out if we are far behind in processing the buffer.
391+ // TODO: We need to compress time when there is a large amount of items to be processed .
392+ InterpolateState . SetTimeToTarget ( Math . Max ( ( float ) ( target . TimeSent - startTime ) , minDeltaTime ) ) ;
377393 InterpolateState . Target = target ;
378394 }
379395 }
@@ -446,17 +462,29 @@ internal T Update(float deltaTime, double tickLatencyAsTime, double minDeltaTime
446462 // If lerp smoothing is enabled, then smooth current value towards the target value
447463 if ( LerpSmoothEnabled )
448464 {
449- // Progress by 1/3rd of the way towards the target in order to assure the target is reached sooner
450- var oneThirdPoint = Interpolate ( InterpolateState . CurrentValue , targetValue , 0.3333f ) ;
451465 // Apply the smooth lerp from the oneThirpoint to the target to help smooth the final value
452- InterpolateState . CurrentValue = Interpolate ( oneThirdPoint , targetValue , deltaTime / MaximumInterpolationTime ) ;
466+ InterpolateState . CurrentValue = Interpolate ( InterpolateState . CurrentValue , targetValue , deltaTime / MaximumInterpolationTime ) ;
453467 }
454468 else
455469 {
456470 // Otherwise, just assign the target value.
457471 InterpolateState . CurrentValue = targetValue ;
458472 }
459473 }
474+ else // If the target is reached and we have no more state updates, we want to check to see if we need to reset.
475+ if ( m_BufferQueue . Count == 0 )
476+ {
477+ // When the delta between the time sent and the current tick latency time-window is greater than the max delta time
478+ // plus the minimum delta time (a rough estimate of time to wait before we consider rate of change equal to zero),
479+ // we will want to reset the interpolator with the current known value. This prevents the next received state update's
480+ // time to be calculated against the last calculated time which if there is an extended period of time between the two
481+ // it would cause a large delta time period between the two states (i.e. it stops moving for a second or two and then
482+ // starts moving again).
483+ if ( ( tickLatencyAsTime - InterpolateState . Target . Value . TimeSent ) > InterpolateState . MaxDeltaTime + minDeltaTime )
484+ {
485+ InterpolateState . Reset ( InterpolateState . CurrentValue ) ;
486+ }
487+ }
460488 }
461489 m_NbItemsReceivedThisFrame = 0 ;
462490 return InterpolateState . CurrentValue ;
@@ -567,8 +595,7 @@ public T Update(float deltaTime, double renderTime, double serverTime)
567595 if ( LerpSmoothEnabled )
568596 {
569597 // Assure our MaximumInterpolationTime is valid and that the second lerp time ranges between deltaTime and 1.0f.
570- var secondLerpTime = Mathf . Clamp ( deltaTime / MaximumInterpolationTime , deltaTime , 1.0f ) ;
571- InterpolateState . CurrentValue = Interpolate ( InterpolateState . CurrentValue , target , secondLerpTime ) ;
598+ InterpolateState . CurrentValue = Interpolate ( InterpolateState . CurrentValue , target , deltaTime / MaximumInterpolationTime ) ;
572599 }
573600 else
574601 {
0 commit comments