您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
111 行
4.5 KiB
111 行
4.5 KiB
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.CompilerServices;
|
|
using Unity.Collections.LowLevel.Unsafe;
|
|
using UnityEngine;
|
|
using UnityEngine.Profiling;
|
|
|
|
public class NetworkPrediction
|
|
{
|
|
// Predict snapshot from baselines. Returns true if prediction is different from baseline 0 (if it need to be automatically predicted next frame).
|
|
unsafe public static void PredictSnapshot(uint* outputData, byte[] fieldsChangedPrediction, NetworkSchema schema, uint numBaselines, uint time0, uint* baselineData0, uint time1, uint* baselineData1, uint time2, uint* baselineData2, uint time, byte fieldMask)
|
|
{
|
|
for (int i = 0, l = fieldsChangedPrediction.Length; i < l; ++i)
|
|
fieldsChangedPrediction[i] = 0;
|
|
|
|
if (numBaselines < 3)
|
|
{
|
|
for (int i = 0, c = schema.GetByteSize() / 4; i < c; i++)
|
|
{
|
|
outputData[i] = baselineData0[i];
|
|
}
|
|
return;
|
|
}
|
|
|
|
long timel = time;
|
|
long timel0 = time0;
|
|
long timel1 = time1;
|
|
long timel2 = time2;
|
|
|
|
long frac0 = 16 * (timel0 - timel2) / (timel1 - timel2);
|
|
long frac = 16 * (timel - timel1) / (timel0 - timel1);
|
|
|
|
fixed(uint* plans = schema.predictPlan)
|
|
{
|
|
int index = 0;
|
|
for (int i = 0, c = schema.numFields; i < c; ++i)
|
|
{
|
|
var plan = plans[i];
|
|
bool masked = ((fieldMask << 2) & plan) != 0;
|
|
bool array = (plan & 1) != 0;
|
|
bool delta = (plan & 2) != 0;
|
|
|
|
int count = (int)(plan >> 8);
|
|
if (array)
|
|
{
|
|
for (int j = 0; j < count; ++j)
|
|
{
|
|
outputData[index + j] = baselineData0[index + j];
|
|
}
|
|
index += count;
|
|
}
|
|
else
|
|
{
|
|
for (int j = 0; j < count; j++)
|
|
{
|
|
uint baseline0 = baselineData0[index];
|
|
uint baseline1 = baselineData1[index];
|
|
uint baseline2 = baselineData2[index];
|
|
uint prediction = baseline0;
|
|
|
|
if (!masked)
|
|
{
|
|
if (delta)
|
|
{
|
|
bool predictionLikelyWrong;
|
|
// Do actual prediction
|
|
{
|
|
predictionLikelyWrong = false;
|
|
|
|
if (numBaselines < 3)
|
|
prediction = baseline0;
|
|
|
|
long vl2 = baseline2;
|
|
long vl1 = baseline1;
|
|
long vl0 = baseline0;
|
|
|
|
long pl0 = vl2 + (vl1 - vl2) * frac0 / 16;// (timel0 - timel2) / (timel1 - timel2);
|
|
|
|
long d1 = vl0 - pl0;
|
|
long d2 = vl0 - vl1;
|
|
d1 = d1 > 0 ? d1 : -d1;
|
|
d2 = d2 > 0 ? d2 : -d2;
|
|
if (d1 < d2)
|
|
{
|
|
long pl = vl1 + (vl0 - vl1) * frac / 16;// (timel - timel1) / (timel0 - timel1);
|
|
predictionLikelyWrong = pl0 != vl0;
|
|
prediction = (uint)pl;
|
|
}
|
|
else
|
|
{
|
|
predictionLikelyWrong = (baseline0 != baseline1) && (baseline1 != baseline2);
|
|
prediction = baseline0;
|
|
}
|
|
}
|
|
if (predictionLikelyWrong)
|
|
fieldsChangedPrediction[i >> 3] |= (byte)(1 << (i & 7));
|
|
}
|
|
else
|
|
{
|
|
if (baseline0 != baseline1 && baseline1 != baseline2)
|
|
fieldsChangedPrediction[i >> 3] |= (byte)(1 << (i & 7));
|
|
}
|
|
}
|
|
outputData[index] = prediction;
|
|
index++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|