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)) { } } }