using System.Runtime.CompilerServices;
using Unity.Mathematics;
using UnityEngine;
namespace Unity.Netcode.Components
{
///
/// Half float precision .
///
///
/// The Vector3T<ushort> values are half float values returned by for each
/// individual axis and the 16 bits of the half float are stored as values since C# does not have
/// a half float type.
///
public struct HalfVector3 : INetworkSerializable
{
internal const int Length = 3;
///
/// The half float precision value of the x-axis as a .
///
public half X => Axis.x;
///
/// The half float precision value of the y-axis as a .
///
public half Y => Axis.y;
///
/// The half float precision value of the z-axis as a .
///
public half Z => Axis.z;
///
/// Used to store the half float precision values as a
///
public half3 Axis;
///
/// Determine which axis will be synchronized during serialization
///
public bool3 AxisToSynchronize;
///
/// Directly sets each axial value to the passed in full precision values
/// that are converted to half precision
///
internal void Set(float x, float y, float z)
{
Axis.x = math.half(x);
Axis.y = math.half(y);
Axis.z = math.half(z);
}
private void SerializeWrite(FastBufferWriter writer)
{
for (int i = 0; i < Length; i++)
{
if (AxisToSynchronize[i])
{
writer.WriteUnmanagedSafe(Axis[i]);
}
}
}
private void SerializeRead(FastBufferReader reader)
{
for (int i = 0; i < Length; i++)
{
if (AxisToSynchronize[i])
{
var axisValue = Axis[i];
reader.ReadUnmanagedSafe(out axisValue);
Axis[i] = axisValue;
}
}
}
///
/// The serialization implementation of .
///
public void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter
{
if (serializer.IsReader)
{
SerializeRead(serializer.GetFastBufferReader());
}
else
{
SerializeWrite(serializer.GetFastBufferWriter());
}
}
///
/// Gets the full precision value as a .
///
/// a as the full precision value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3 ToVector3()
{
Vector3 fullPrecision = Vector3.zero;
Vector3 fullConversion = math.float3(Axis);
for (int i = 0; i < Length; i++)
{
if (AxisToSynchronize[i])
{
fullPrecision[i] = fullConversion[i];
}
}
return fullPrecision;
}
///
/// Converts a full precision to half precision and updates the current instance.
///
/// The to convert.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void UpdateFrom(ref Vector3 vector3)
{
var half3Full = math.half3(vector3);
for (int i = 0; i < Length; i++)
{
if (AxisToSynchronize[i])
{
Axis[i] = half3Full[i];
}
}
}
///
/// Constructor
///
/// The initial axial values (converted to half floats) when instantiated.
/// The axis to synchronize.
public HalfVector3(Vector3 vector3, bool3 axisToSynchronize)
{
Axis = half3.zero;
AxisToSynchronize = axisToSynchronize;
UpdateFrom(ref vector3);
}
///
/// Constructor that defaults to all axis being synchronized.
///
/// The initial axial values (converted to half floats) when instantiated.
public HalfVector3(Vector3 vector3) : this(vector3, math.bool3(true))
{
}
///
/// Constructor
///
/// The initial x axis (converted to half float) value when instantiated.
/// The initial y axis (converted to half float) value when instantiated.
/// The initial z axis (converted to half float) value when instantiated.
/// The axis to synchronize.
public HalfVector3(float x, float y, float z, bool3 axisToSynchronize) : this(new Vector3(x, y, z), axisToSynchronize)
{
}
///
/// Constructor that defaults to all axis being synchronized.
///
/// The initial x axis (converted to half float) value when instantiated.
/// The initial y axis (converted to half float) value when instantiated.
/// The initial z axis (converted to half float) value when instantiated.
public HalfVector3(float x, float y, float z) : this(new Vector3(x, y, z), math.bool3(true))
{
}
}
}