-
Notifications
You must be signed in to change notification settings - Fork 464
Expand file tree
/
Copy pathHalfVector3.cs
More file actions
182 lines (165 loc) · 6.71 KB
/
Copy pathHalfVector3.cs
File metadata and controls
182 lines (165 loc) · 6.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
using System;
using System.Runtime.CompilerServices;
using Unity.Mathematics;
using UnityEngine;
namespace Unity.Netcode.Components
{
/// <summary>
/// Half float precision <see cref="Vector3"/>.
/// </summary>
/// <remarks>
/// The Vector3T<ushort> values are half float values returned by <see cref="Mathf.FloatToHalf(float)"/> for each
/// individual axis and the 16 bits of the half float are stored as <see cref="ushort"/> values since C# does not have
/// a half float type.
/// </remarks>
[Serializable]
public struct HalfVector3 : INetworkSerializable
{
internal const int Length = 3;
/// <summary>
/// The half float precision value of the x-axis as a <see cref="half"/>.
/// </summary>
public half X => Axis.x;
/// <summary>
/// The half float precision value of the y-axis as a <see cref="half"/>.
/// </summary>
public half Y => Axis.y;
/// <summary>
/// The half float precision value of the z-axis as a <see cref="half"/>.
/// </summary>
public half Z => Axis.z;
/// <summary>
/// Used to store the half float precision values as a <see cref="half3"/>
/// </summary>
public half3 Axis;
/// <summary>
/// Determine which axis will be synchronized during serialization
/// </summary>
public bool3 AxisToSynchronize;
/// <summary>
/// Directly sets each axial value to the passed in full precision values
/// that are converted to half precision
/// </summary>
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;
}
}
}
/// <inheritdoc />
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
{
if (serializer.IsReader)
{
SerializeRead(serializer.GetFastBufferReader());
}
else
{
SerializeWrite(serializer.GetFastBufferWriter());
}
}
/// <summary>
/// Gets the full precision value as a <see cref="Vector3"/>.
/// </summary>
/// <returns>a <see cref="Vector3"/> as the full precision value.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3 ToVector3()
{
return ToFloat3(Axis, AxisToSynchronize);
}
/// <summary>
/// The <see cref="float3"/> based implementation of <see cref="ToVector3"/>.
/// </summary>
/// <remarks>
/// This is a job safe method to be used in place of <see cref="ToVector3"/>.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static float3 ToFloat3(half3 axis, bool3 axisToSynchronize)
{
return math.select(float3.zero, math.float3(axis), axisToSynchronize);
}
/// <summary>
/// Converts a full precision <see cref="Vector3"/> to half precision and updates the current instance.
/// </summary>
/// <param name="vector3">The <see cref="Vector3"/> to convert.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void UpdateFrom(ref Vector3 vector3)
{
Axis = UpdatedAxis(Axis, math.float3(vector3), AxisToSynchronize);
}
/// <summary>
/// The <see cref="half3"/> based implementation of <see cref="UpdateFrom(ref Vector3)"/>.
/// </summary>
/// <remarks>
/// This is a job safe method to be used in place of <see cref="UpdateFrom(ref Vector3)"/>.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static half3 UpdatedAxis(half3 axis, float3 value, bool3 axisToSynchronize)
{
var updated = math.half3(value);
axis.x = axisToSynchronize.x ? updated.x : axis.x;
axis.y = axisToSynchronize.y ? updated.y : axis.y;
axis.z = axisToSynchronize.z ? updated.z : axis.z;
return axis;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="vector3">The initial axial values (converted to half floats) when instantiated.</param>
/// <param name="axisToSynchronize">The axis to synchronize.</param>
public HalfVector3(Vector3 vector3, bool3 axisToSynchronize)
{
Axis = half3.zero;
AxisToSynchronize = axisToSynchronize;
UpdateFrom(ref vector3);
}
/// <summary>
/// Constructor that defaults to all axis being synchronized.
/// </summary>
/// <param name="vector3">The initial axial values (converted to half floats) when instantiated.</param>
public HalfVector3(Vector3 vector3) : this(vector3, math.bool3(true))
{
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="x">The initial x axis (converted to half float) value when instantiated.</param>
/// <param name="y">The initial y axis (converted to half float) value when instantiated.</param>
/// <param name="z">The initial z axis (converted to half float) value when instantiated.</param>
/// <param name="axisToSynchronize">The axis to synchronize.</param>
public HalfVector3(float x, float y, float z, bool3 axisToSynchronize) : this(new Vector3(x, y, z), axisToSynchronize)
{
}
/// <summary>
/// Constructor that defaults to all axis being synchronized.
/// </summary>
/// <param name="x">The initial x axis (converted to half float) value when instantiated.</param>
/// <param name="y">The initial y axis (converted to half float) value when instantiated.</param>
/// <param name="z">The initial z axis (converted to half float) value when instantiated.</param>
public HalfVector3(float x, float y, float z) : this(new Vector3(x, y, z), math.bool3(true))
{
}
}
}