forked from JLPM22/MotionMatching
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFeatureSerializer.cs
More file actions
238 lines (225 loc) · 12.8 KB
/
Copy pathFeatureSerializer.cs
File metadata and controls
238 lines (225 loc) · 12.8 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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
using System.IO;
using Unity.Collections;
using Unity.Mathematics;
using UnityEngine;
namespace MotionMatching
{
using static BinarySerializerExtensions;
public class FeatureSerializer
{
/// <summary>
/// Stores the features for Motion Matching in a binary format
/// in the specified path with name filename and extension .mmfeatures
/// </summary>
public void Serialize(FeatureSet featureSet, MotionMatchingData mmData, string path, string fileName)
{
Directory.CreateDirectory(path); // create directory and parent directories if they don't exist
// Write Features
using (var stream = File.Open(Path.Combine(path, fileName + ".mmfeatures"), FileMode.Create))
{
using (var writer = new BinaryWriter(stream, System.Text.Encoding.UTF8))
{
// Serialize Number Feature Vectors
writer.Write((uint)featureSet.NumberFeatureVectors);
// Serialize Number Features Static Dimension
writer.Write((uint)featureSet.FeatureStaticSize);
// Serialize Number Features Dimension
writer.Write((uint)featureSet.FeatureSize);
// Serialize Number Features
writer.Write((uint)(featureSet.NumberTrajectoryFeatures + featureSet.NumberPoseFeatures + featureSet.NumberEnvironmentFeatures));
// Serialize Mean & StandardDeviation
for (int i = 0; i < featureSet.FeatureStaticSize; ++i)
{
writer.Write(featureSet.GetMean(i));
writer.Write(featureSet.GetStandardDeviation(i));
}
// Serialize Features
for (int t = 0; t < mmData.TrajectoryFeatures.Count; ++t)
{
var trajectoryFeature = mmData.TrajectoryFeatures[t];
writer.Write(trajectoryFeature.Name);
writer.Write(trajectoryFeature.GetSize());
writer.Write((uint)trajectoryFeature.FramesPrediction.Length);
}
for (int p = 0; p < mmData.PoseFeatures.Count; ++p)
{
var poseFeature = mmData.PoseFeatures[p];
writer.Write(poseFeature.Name);
writer.Write(3u);
writer.Write(1u);
}
for (int d = 0; d < mmData.EnvironmentFeatures.Count; ++d)
{
var environmentFeature = mmData.EnvironmentFeatures[d];
writer.Write(environmentFeature.Name);
writer.Write(environmentFeature.GetSize());
writer.Write((uint)environmentFeature.FramesPrediction.Length);
}
// Serialize Feature Vectors
for (int i = 0; i < featureSet.NumberFeatureVectors; ++i)
{
writer.Write(featureSet.IsValidFeature(i) ? 1u : 0u);
// Trajectory
for (int t = 0; t < mmData.TrajectoryFeatures.Count; ++t)
{
var trajectoryFeature = mmData.TrajectoryFeatures[t];
int featureSize = trajectoryFeature.GetSize();
for (int p = 0; p < trajectoryFeature.FramesPrediction.Length; ++p)
{
if (featureSize == 4)
{
float4 value4D = featureSet.Get4DTrajectoryFeature(i, t, p);
WriteFloat4(writer, value4D);
}
else if (featureSize == 3)
{
float3 value3D = featureSet.Get3DTrajectoryFeature(i, t, p);
WriteFloat3(writer, value3D);
}
else if (featureSize == 2)
{
float2 value2D = featureSet.Get2DTrajectoryFeature(i, t, p);
WriteFloat2(writer, value2D);
}
else if (featureSize == 1)
{
float value1D = featureSet.Get1DTrajectoryFeature(i, t, p);
writer.Write(value1D);
}
else
{
Debug.Assert(false, "Invalid trajectory feature");
}
}
}
// Pose
for (int p = 0; p < mmData.PoseFeatures.Count; ++p)
{
WriteFloat3(writer, featureSet.GetPoseFeature(i, p));
}
// Environment
for (int d = 0; d < mmData.EnvironmentFeatures.Count; ++d)
{
var environmentFeature = mmData.EnvironmentFeatures[d];
int featureSize = environmentFeature.GetSize();
for (int p = 0; p < environmentFeature.FramesPrediction.Length; ++p)
{
if (featureSize == 4)
{
float4 value4D = featureSet.Get4DEnvironmentFeature(i, d, p);
WriteFloat4(writer, value4D);
}
else if (featureSize == 3)
{
float3 value3D = featureSet.Get3DEnvironmentFeature(i, d, p);
WriteFloat3(writer, value3D);
}
else if (featureSize == 2)
{
float2 value2D = featureSet.Get2DEnvironmentFeature(i, d, p);
WriteFloat2(writer, value2D);
}
else if (featureSize == 1)
{
float value1D = featureSet.Get1DEnvironmentFeature(i, d, p);
writer.Write(value1D);
}
else
{
Debug.Assert(false, "Invalid environment feature");
}
}
}
}
}
}
}
/// <summary>
/// Reads the features for Motion Matching from a binary format
/// from the specified path with name filename and extension .mmfeatures
/// Returns true if featureSet was successfully deserialized, false otherwise
/// </summary>
public bool Deserialize(string path, string fileName, MotionMatchingData mmData, out FeatureSet featureSet)
{
featureSet = null;
// Read Features
string featuresPath = Path.Combine(path, fileName + ".mmfeatures");
if (File.Exists(featuresPath))
{
using (var stream = File.Open(featuresPath, FileMode.Open))
{
using (var reader = new BinaryReader(stream, System.Text.Encoding.UTF8))
{
// Deserialize Number Feature Vectors
uint numberFeatureVectors = reader.ReadUInt32();
// Deserialize Number Features Static Dimension
uint featuresStaticDimension = reader.ReadUInt32();
// Deserialize Number Features Dimension
uint featuresDimension = reader.ReadUInt32();
// Deserialize Number Features
uint numberFeatures = reader.ReadUInt32();
// Deserialize Mean & StandardDeviation
float[] mean = new float[featuresStaticDimension];
float[] standardDeviation = new float[featuresStaticDimension];
for (int i = 0; i < featuresStaticDimension; ++i)
{
mean[i] = reader.ReadSingle();
standardDeviation[i] = reader.ReadSingle();
}
// Deserialize Features (basically check that everything is correct)
Debug.Assert(numberFeatures == (mmData.TrajectoryFeatures.Count + mmData.PoseFeatures.Count + mmData.EnvironmentFeatures.Count), "Number of features in file does not match number of features in Motion Matching Data");
for (int t = 0; t < mmData.TrajectoryFeatures.Count; ++t)
{
var trajectoryFeature = mmData.TrajectoryFeatures[t];
string name = reader.ReadString();
uint nFloatsType = reader.ReadUInt32();
uint nElements = reader.ReadUInt32();
Debug.Assert(name == trajectoryFeature.Name, "Name of trajectory feature does not match");
Debug.Assert(nFloatsType == (uint)trajectoryFeature.GetSize(), "Projection type of trajectory feature does not match");
Debug.Assert(nElements == (uint)trajectoryFeature.FramesPrediction.Length, "Number of frames prediction of trajectory feature does not match");
}
for (int p = 0; p < mmData.PoseFeatures.Count; ++p)
{
var poseFeature = mmData.PoseFeatures[p];
string name = reader.ReadString();
uint nFloatsType = reader.ReadUInt32();
uint nElements = reader.ReadUInt32();
Debug.Assert(name == poseFeature.Name, "Name of pose feature does not match");
Debug.Assert(nFloatsType == 3u, "Projection type of pose feature does not match");
Debug.Assert(nElements == 1u, "Number of frames prediction of pose feature does not match");
}
for (int t = 0; t < mmData.EnvironmentFeatures.Count; ++t)
{
var environmentFeature = mmData.EnvironmentFeatures[t];
string name = reader.ReadString();
uint nFloatsType = reader.ReadUInt32();
uint nElements = reader.ReadUInt32();
Debug.Assert(name == environmentFeature.Name, "Name of environment feature does not match");
Debug.Assert(nFloatsType == (uint)environmentFeature.GetSize(), "Projection type of environment feature does not match");
Debug.Assert(nElements == (uint)environmentFeature.FramesPrediction.Length, "Number of frames prediction of environment feature does not match");
}
// Deserialize Feature Vectors
NativeArray<bool> valid = new NativeArray<bool>((int)numberFeatureVectors, Allocator.Persistent);
NativeArray<float> features = new NativeArray<float>((int)(numberFeatureVectors * featuresDimension), Allocator.Persistent);
for (int i = 0; i < numberFeatureVectors; ++i)
{
int featureIndex = i * (int)featuresDimension;
valid[i] = reader.ReadUInt32() != 0u;
for (int f = 0; f < featuresDimension; ++f)
{
features[featureIndex + f] = reader.ReadSingle();
}
}
featureSet = new FeatureSet(mmData, (int)numberFeatureVectors);
featureSet.SetValid(valid);
featureSet.SetFeatures(features);
featureSet.SetMean(mean);
featureSet.SetStandardDeviation(standardDeviation);
}
}
}
else return false;
return true;
}
}
}