Skip to content

feat: interpolation for network transform #1060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 92 commits into from
Sep 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
0ad1fb0
setting correct default
SamuelBellomo Jul 5, 2021
24231cc
Merge branch 'develop' into sam/feature/interpolation-for-network-tra…
SamuelBellomo Jul 12, 2021
9682498
Merge branch 'develop' into sam/feature/interpolation-for-network-tra…
SamuelBellomo Jul 19, 2021
bc4d373
adding test benchmark for interpolation
SamuelBellomo Jul 20, 2021
3956a5d
Merge branch 'develop' into sam/feature/interpolation-for-network-tra…
SamuelBellomo Jul 22, 2021
03262b3
#
SamuelBellomo Jul 23, 2021
c81f65a
#
SamuelBellomo Jul 28, 2021
4a4aa7b
#
SamuelBellomo Jul 29, 2021
5fc7b50
#
SamuelBellomo Aug 5, 2021
bb7dc83
#
SamuelBellomo Aug 5, 2021
db9688c
#
SamuelBellomo Aug 6, 2021
e7bbd12
#
SamuelBellomo Aug 10, 2021
b776957
Merge branch 'develop' into sam/feature/interpolation-for-network-tra…
SamuelBellomo Aug 10, 2021
7b93e90
fixes for latest develop merge
SamuelBellomo Aug 11, 2021
3f937b5
#
SamuelBellomo Aug 11, 2021
b927f2c
cleanup
SamuelBellomo Aug 11, 2021
4a86539
renames
SamuelBellomo Aug 11, 2021
2cdbb1b
#
SamuelBellomo Aug 11, 2021
07c3d07
#
SamuelBellomo Aug 11, 2021
f6290e0
cleanup
SamuelBellomo Aug 13, 2021
c492349
#
SamuelBellomo Aug 13, 2021
6b6c5ca
#
SamuelBellomo Aug 13, 2021
890420e
#
SamuelBellomo Aug 13, 2021
a2b885f
adding interface for testing
SamuelBellomo Aug 14, 2021
d5936cc
smooth
SamuelBellomo Aug 14, 2021
3817962
Adding basis for tests
SamuelBellomo Aug 17, 2021
7ca5ced
#
SamuelBellomo Aug 17, 2021
e9ee9fd
#
SamuelBellomo Aug 17, 2021
c3cc8b9
#
SamuelBellomo Aug 17, 2021
e2b85c1
cleanup
SamuelBellomo Aug 17, 2021
9fb4e30
#
SamuelBellomo Aug 17, 2021
796ab67
#
SamuelBellomo Aug 17, 2021
ebdc1fd
#
SamuelBellomo Aug 17, 2021
2efc972
fix, server can have 0 buffer
SamuelBellomo Aug 20, 2021
ce03d58
test fixes
SamuelBellomo Aug 23, 2021
ad5d9ac
moving things to right place for future merge
SamuelBellomo Aug 23, 2021
3c1543b
Merge branch 'develop' into sam/feature/interpolation-for-network-tra…
SamuelBellomo Aug 23, 2021
43ef524
moving tests too
SamuelBellomo Aug 23, 2021
f3d14f9
fix
SamuelBellomo Aug 23, 2021
716aad7
Merge branch 'develop' into sam/feature/interpolation-for-network-tra…
SamuelBellomo Aug 23, 2021
bac5c85
merge branch 'develop' into 'sam/feature/interpolation-for-network-tr…
0xFA11 Aug 24, 2021
496fa82
some fixes
SamuelBellomo Aug 26, 2021
3b8a47e
Merge branch 'sam/feature/interpolation-for-network-transform' of git…
SamuelBellomo Aug 26, 2021
522558f
#
SamuelBellomo Aug 26, 2021
2f57fa9
#
SamuelBellomo Aug 26, 2021
b6ac562
smooth now
SamuelBellomo Sep 1, 2021
669b878
Merge branch 'develop' into sam/feature/interpolation-for-network-tra…
SamuelBellomo Sep 1, 2021
54ee62e
fixes after merge
SamuelBellomo Sep 1, 2021
35606d7
#
SamuelBellomo Sep 2, 2021
3d56986
#
SamuelBellomo Sep 3, 2021
9374e4b
#
SamuelBellomo Sep 3, 2021
6c9b905
#
SamuelBellomo Sep 3, 2021
dcf36fc
Merge branch 'develop' into sam/feature/interpolation-for-network-tra…
SamuelBellomo Sep 3, 2021
ae56748
#
SamuelBellomo Sep 3, 2021
544de80
Merge branch 'sam/feature/interpolation-for-network-transform' of git…
SamuelBellomo Sep 3, 2021
83998c7
Update com.unity.netcode.gameobjects/Prototyping/Interpolator/Buffere…
SamuelBellomo Sep 7, 2021
68ae5be
Update com.unity.netcode.gameobjects/Prototyping/Interpolator/Buffere…
SamuelBellomo Sep 7, 2021
9432c94
Update com.unity.netcode.gameobjects/Prototyping/Interpolator/Buffere…
SamuelBellomo Sep 7, 2021
1ebd1e5
Update com.unity.netcode.gameobjects/Prototyping/Interpolator/IInterp…
SamuelBellomo Sep 7, 2021
5b1761b
code review feedback
SamuelBellomo Sep 7, 2021
1fb7bbf
Merge branch 'sam/feature/interpolation-for-network-transform' of git…
SamuelBellomo Sep 8, 2021
35815a3
cleanup, removing IInterpolator interface, removing other interpolato…
SamuelBellomo Sep 8, 2021
5d4470a
adding some comments
SamuelBellomo Sep 8, 2021
0747544
comment cleanup
SamuelBellomo Sep 9, 2021
b0cc994
after investigation, UseFixedUpdate isn't needed anymore with latest …
SamuelBellomo Sep 9, 2021
41aeef0
Fix axis sync issue.
SamuelBellomo Sep 10, 2021
d92cc1e
reverting back hasXX changes, we still need isDirty checks since hasX…
SamuelBellomo Sep 10, 2021
33751fe
using "SyncXX" instead of "HasXX". HasXX is never reset to false and …
SamuelBellomo Sep 10, 2021
93e8be7
fixing issue where we needed to do a first movement to get over netwo…
SamuelBellomo Sep 10, 2021
f207820
updating zoosam with latest changes
SamuelBellomo Sep 13, 2021
ee5b308
updating zoosam with latest changes
SamuelBellomo Sep 13, 2021
81fb86d
Merge branch 'sam/feature/interpolation-for-network-transform' of git…
SamuelBellomo Sep 13, 2021
0260b4b
Merge branch 'develop' into sam/feature/interpolation-for-network-tra…
SamuelBellomo Sep 13, 2021
7dfecfd
fixing bad ref
SamuelBellomo Sep 13, 2021
3167e52
restricting access to buffered interpolator
SamuelBellomo Sep 13, 2021
8845a59
adding jira to todo
SamuelBellomo Sep 13, 2021
3883bfb
removing commented lines
SamuelBellomo Sep 13, 2021
92b9a55
removing useless lines
SamuelBellomo Sep 13, 2021
2e3f566
fixing default scene for builds
SamuelBellomo Sep 14, 2021
67689eb
adding missing meta files
SamuelBellomo Sep 14, 2021
2c4e6d1
reverting changes to samplescene, it was already in ZooSam
SamuelBellomo Sep 14, 2021
976002a
bumping exec order
SamuelBellomo Sep 16, 2021
f5e27b9
restricting public api
SamuelBellomo Sep 16, 2021
8545ea9
Merge branch 'develop' into sam/feature/interpolation-for-network-tra…
SamuelBellomo Sep 16, 2021
9e22bfa
removing not submitted LiteNetLib from ZooSam
SamuelBellomo Sep 16, 2021
fd83c0a
Merge branch 'develop' into sam/feature/interpolation-for-network-tra…
SamuelBellomo Sep 16, 2021
96eef69
fixing formatting issue
SamuelBellomo Sep 16, 2021
5258c9b
more formatting
SamuelBellomo Sep 16, 2021
39ec721
fixing line issue
SamuelBellomo Sep 16, 2021
211f0f9
removing useless meta files
SamuelBellomo Sep 16, 2021
4ea092d
Merge branch 'develop' into sam/feature/interpolation-for-network-tra…
NoelStephensUnity Sep 16, 2021
5775f36
Merge branch 'develop' into sam/feature/interpolation-for-network-tra…
SamuelBellomo Sep 16, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions com.unity.netcode.gameobjects/Components/Interpolator.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
using System;
using System.Collections.Generic;
using UnityEngine;

namespace Unity.Netcode
{
/// <summary>
/// Solves for incoming values that are jittered
/// Partially solves for message loss. Unclamped lerping helps hide this, but not completely
/// </summary>
/// <typeparam name="T"></typeparam>
internal abstract class BufferedLinearInterpolator<T> where T : struct
{
// interface for mock testing, abstracting away external systems
internal interface IInterpolatorTime
{
double BufferedServerTime { get; }
double BufferedServerFixedTime { get; }
int TickRate { get; }
}

private class InterpolatorTime : IInterpolatorTime
{
public double BufferedServerTime => NetworkManager.Singleton.ServerTime.Time;
public double BufferedServerFixedTime => NetworkManager.Singleton.ServerTime.FixedTime;
public int TickRate => NetworkManager.Singleton.ServerTime.TickRate;
}

internal IInterpolatorTime InterpolatorTimeProxy = new InterpolatorTime();

private struct BufferedItem
{
public T Item;
public NetworkTime TimeSent;
}


/// <summary>
/// Override this if you want configurable buffering, right now using ServerTick's own global buffering
/// </summary>
private double ServerTimeBeingHandledForBuffering => InterpolatorTimeProxy.BufferedServerTime;

private double RenderTime => InterpolatorTimeProxy.BufferedServerTime - 1f / InterpolatorTimeProxy.TickRate;

private T m_InterpStartValue;
private T m_CurrentInterpValue;
private T m_InterpEndValue;

private NetworkTime m_EndTimeConsumed;
private NetworkTime m_StartTimeConsumed;

private readonly List<BufferedItem> m_Buffer = new List<BufferedItem>();
private const int k_BufferSizeLimit = 100;

private int m_LifetimeConsumedCount;

public void ResetTo(T targetValue)
{
m_LifetimeConsumedCount = 1;
m_InterpStartValue = targetValue;
m_InterpEndValue = targetValue;
m_CurrentInterpValue = targetValue;
m_Buffer.Clear();
m_EndTimeConsumed = new NetworkTime(InterpolatorTimeProxy.TickRate, 0);
m_StartTimeConsumed = new NetworkTime(InterpolatorTimeProxy.TickRate, 0);

Update(0);
}


// todo if I have value 1, 2, 3 and I'm treating 1 to 3, I shouldn't interpolate between 1 and 3, I should interpolate from 1 to 2, then from 2 to 3 to get the best path
private void TryConsumeFromBuffer()
{
int consumedCount = 0;
// only consume if we're ready
if (RenderTime >= m_EndTimeConsumed.Time)
{
// buffer is sorted so older (smaller) time values are at the end.
for (int i = m_Buffer.Count - 1; i >= 0; i--) // todo stretch: consume ahead if we see we're missing values
{
var bufferedValue = m_Buffer[i];
// Consume when ready. This can consume multiple times
if (bufferedValue.TimeSent.Time <= ServerTimeBeingHandledForBuffering)
{
if (m_LifetimeConsumedCount == 0)
{
m_StartTimeConsumed = bufferedValue.TimeSent;
m_InterpStartValue = bufferedValue.Item;
}
else if (consumedCount == 0)
{
m_StartTimeConsumed = m_EndTimeConsumed;
m_InterpStartValue = m_InterpEndValue;
}

m_EndTimeConsumed = bufferedValue.TimeSent;
m_InterpEndValue = bufferedValue.Item;
m_Buffer.RemoveAt(i);
consumedCount++;
m_LifetimeConsumedCount++;
}
}
}
}

public T Update(float deltaTime)
{
TryConsumeFromBuffer();

if (m_LifetimeConsumedCount == 0 && m_Buffer.Count == 0)
{
throw new InvalidOperationException("trying to update interpolator when no data has been added to it yet");
}

// Interpolation example to understand the math below
// 4 4.5 6 6.5
// | | | |
// A render B Server

if (m_LifetimeConsumedCount >= 1) // shouldn't interpolate between default values, let's wait to receive data first, should only interpolate between real measurements
{
double range = m_EndTimeConsumed.Time - m_StartTimeConsumed.Time;
float t;
if (range == 0)
{
t = 1;
}
else
{
t = (float)((RenderTime - m_StartTimeConsumed.Time) / range);
}

if (t > 3) // max extrapolation
{
// TODO this causes issues with teleport, investigate
// todo make this configurable
t = 1;
}

if (Debug.isDebugBuild)
{
Debug.Assert(t >= 0, $"t must be bigger than or equal to 0. range {range}, RenderTime {RenderTime}, Start time {m_StartTimeConsumed.Time}, end time {m_EndTimeConsumed.Time}");
}

var target = InterpolateUnclamped(m_InterpStartValue, m_InterpEndValue, t);
float maxInterpTime = 0.1f;
m_CurrentInterpValue = Interpolate(m_CurrentInterpValue, target, deltaTime / maxInterpTime); // second interpolate to smooth out extrapolation jumps
}

return m_CurrentInterpValue;
}

public void AddMeasurement(T newMeasurement, NetworkTime sentTime)
{
if (m_Buffer.Count >= k_BufferSizeLimit)
{
Debug.LogWarning("Going over buffer size limit while adding new interpolation values, interpolation buffering isn't consuming fast enough, removing oldest value now.");
m_Buffer.RemoveAt(m_Buffer.Count - 1);
}

if (sentTime.Time > m_EndTimeConsumed.Time || m_LifetimeConsumedCount == 0) // treat only if value is newer than the one being interpolated to right now
{
m_Buffer.Add(new BufferedItem { Item = newMeasurement, TimeSent = sentTime });
m_Buffer.Sort((item1, item2) => item2.TimeSent.Time.CompareTo(item1.TimeSent.Time));
}
}

public T GetInterpolatedValue()
{
return m_CurrentInterpValue;
}

protected abstract T Interpolate(T start, T end, float time);
protected abstract T InterpolateUnclamped(T start, T end, float time);
}

internal class BufferedLinearInterpolatorFloat : BufferedLinearInterpolator<float>
{
protected override float InterpolateUnclamped(float start, float end, float time)
{
return Mathf.LerpUnclamped(start, end, time);
}

protected override float Interpolate(float start, float end, float time)
{
return Mathf.Lerp(start, end, time);
}
}

internal class BufferedLinearInterpolatorQuaternion : BufferedLinearInterpolator<Quaternion>
{
protected override Quaternion InterpolateUnclamped(Quaternion start, Quaternion end, float time)
{
return Quaternion.SlerpUnclamped(start, end, time);
}

protected override Quaternion Interpolate(Quaternion start, Quaternion end, float time)
{
return Quaternion.SlerpUnclamped(start, end, time);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading