using System;
using AOT;
using Unity.Assertions;
using Unity.Burst;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Mathematics;
using Unity.NetCode;
using Unity.Transforms;
namespace Unity.MegaCity.Gameplay
{
///
/// The MegaCity-tuned prediction error function for the component.
///
[BurstCompile]
public unsafe struct MegaCitySmoothingAction
{
///
/// The default value for the if the no user data is passed to the function.
/// Position is corrected if the prediction error is at least 1 unit (usually mt) and less than 10 unit (usually mt)
///
public sealed class DefaultStaticUserParams
{
internal static readonly SharedStatic maxDist = SharedStatic.GetOrCreate();
internal static readonly SharedStatic delta = SharedStatic.GetOrCreate();
static DefaultStaticUserParams()
{
maxDist.Data = 20;
delta.Data = 0.5f;
}
class MaxDistKey {}
class DeltaKey {}
}
///
/// Return a the burst compatible function pointer that can be used to register the smoothing action to the
/// singleton.
///
public static readonly PortableFunctionPointer
Action = new(SmoothingAction);
[BurstCompile(DisableDirectCall = true)]
[MonoPInvokeCallback(typeof(GhostPredictionSmoothing.SmoothingActionDelegate))]
private static void SmoothingAction(IntPtr currentData, IntPtr previousData, IntPtr usrData)
{
ref var trans = ref UnsafeUtility.AsRef((void*)currentData);
ref var backup = ref UnsafeUtility.AsRef((void*)previousData);
float maxDist = DefaultStaticUserParams.maxDist.Data;
float delta = DefaultStaticUserParams.delta.Data;
Assert.IsTrue(usrData.ToPointer() == null);
var dist = math.distance(trans.Position, backup.Position);
if (dist < maxDist && dist > delta && dist > 0)
{
trans.Position = backup.Position + (trans.Position - backup.Position) * delta / dist;
}
}
}
}