265 lines
9.3 KiB
C#
265 lines
9.3 KiB
C#
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using UnityEngine;
|
|
|
|
namespace Microsoft.MixedReality.Toolkit.Input
|
|
{
|
|
/// <summary>
|
|
/// Functions for serializing input animation data to and from binary files.
|
|
/// </summary>
|
|
public static class InputAnimationSerializationUtils
|
|
{
|
|
public const string Extension = "bin";
|
|
|
|
const long Magic = 0x6a8faf6e0f9e42c6;
|
|
|
|
public const int VersionMajor = 1;
|
|
public const int VersionMinor = 1;
|
|
|
|
/// <summary>
|
|
/// Generate a file name for export.
|
|
/// </summary>
|
|
public static string GetOutputFilename(string baseName = "InputAnimation", bool appendTimestamp = true)
|
|
{
|
|
string filename;
|
|
if (appendTimestamp)
|
|
{
|
|
filename = string.Format("{0}-{1}.{2}", baseName, DateTime.UtcNow.ToString("yyyyMMdd-HHmmss"), Extension);
|
|
}
|
|
else
|
|
{
|
|
filename = baseName;
|
|
}
|
|
return filename;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write a header for the input animation file format into the stream.
|
|
/// </summary>
|
|
public static void WriteHeader(BinaryWriter writer)
|
|
{
|
|
writer.Write(Magic);
|
|
writer.Write(VersionMajor);
|
|
writer.Write(VersionMinor);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write a header for the input animation file format into the stream.
|
|
/// </summary>
|
|
public static void ReadHeader(BinaryReader reader, out int fileVersionMajor, out int fileVersionMinor)
|
|
{
|
|
long fileMagic = reader.ReadInt64();
|
|
if (fileMagic != Magic)
|
|
{
|
|
throw new Exception("File is not an input animation file");
|
|
}
|
|
|
|
fileVersionMajor = reader.ReadInt32();
|
|
fileVersionMinor = reader.ReadInt32();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Serialize an animation curve with tangents as binary data.
|
|
/// </summary>
|
|
public static void WriteFloatCurve(BinaryWriter writer, AnimationCurve curve, float startTime)
|
|
{
|
|
writer.Write((int)curve.preWrapMode);
|
|
writer.Write((int)curve.postWrapMode);
|
|
|
|
writer.Write(curve.length);
|
|
for (int i = 0; i < curve.length; ++i)
|
|
{
|
|
var keyframe = curve.keys[i];
|
|
writer.Write(keyframe.time - startTime);
|
|
writer.Write(keyframe.value);
|
|
writer.Write(keyframe.inTangent);
|
|
writer.Write(keyframe.outTangent);
|
|
writer.Write(keyframe.inWeight);
|
|
writer.Write(keyframe.outWeight);
|
|
writer.Write((int)keyframe.weightedMode);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deserialize an animation curve with tangents from binary data.
|
|
/// </summary>
|
|
public static void ReadFloatCurve(BinaryReader reader, AnimationCurve curve)
|
|
{
|
|
curve.preWrapMode = (WrapMode)reader.ReadInt32();
|
|
curve.postWrapMode = (WrapMode)reader.ReadInt32();
|
|
|
|
int keyframeCount = reader.ReadInt32();
|
|
|
|
Keyframe[] keys = new Keyframe[keyframeCount];
|
|
for (int i = 0; i < keyframeCount; ++i)
|
|
{
|
|
keys[i].time = reader.ReadSingle();
|
|
keys[i].value = reader.ReadSingle();
|
|
keys[i].inTangent = reader.ReadSingle();
|
|
keys[i].outTangent = reader.ReadSingle();
|
|
keys[i].inWeight = reader.ReadSingle();
|
|
keys[i].outWeight = reader.ReadSingle();
|
|
keys[i].weightedMode = (WeightedMode)reader.ReadInt32();
|
|
}
|
|
|
|
curve.keys = keys;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Serialize an animation curve as binary data, ignoring tangents.
|
|
/// </summary>
|
|
public static void WriteBoolCurve(BinaryWriter writer, AnimationCurve curve, float startTime)
|
|
{
|
|
writer.Write((int)curve.preWrapMode);
|
|
writer.Write((int)curve.postWrapMode);
|
|
|
|
writer.Write(curve.length);
|
|
for (int i = 0; i < curve.length; ++i)
|
|
{
|
|
var keyframe = curve.keys[i];
|
|
writer.Write(keyframe.time - startTime);
|
|
writer.Write(keyframe.value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deserialize an animation curve from binary data, ignoring tangents.
|
|
/// </summary>
|
|
public static void ReadBoolCurve(BinaryReader reader, AnimationCurve curve)
|
|
{
|
|
curve.preWrapMode = (WrapMode)reader.ReadInt32();
|
|
curve.postWrapMode = (WrapMode)reader.ReadInt32();
|
|
|
|
int keyframeCount = reader.ReadInt32();
|
|
|
|
Keyframe[] keys = new Keyframe[keyframeCount];
|
|
for (int i = 0; i < keyframeCount; ++i)
|
|
{
|
|
keys[i].time = reader.ReadSingle();
|
|
keys[i].value = reader.ReadSingle();
|
|
keys[i].outWeight = 1.0e6f;
|
|
keys[i].weightedMode = WeightedMode.Both;
|
|
}
|
|
|
|
curve.keys = keys;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Serialize an animation curve with tangents as binary data. Only encodes keyframe position and time.
|
|
/// </summary>
|
|
public static void WriteFloatCurveSimple(BinaryWriter writer, AnimationCurve curve, float startTime)
|
|
{
|
|
writer.Write((int)curve.preWrapMode);
|
|
writer.Write((int)curve.postWrapMode);
|
|
|
|
writer.Write(curve.length);
|
|
for (int i = 0; i < curve.length; ++i)
|
|
{
|
|
var keyframe = curve.keys[i];
|
|
writer.Write(keyframe.time - startTime);
|
|
writer.Write(keyframe.value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deserialize an animation curve with tangents from binary data. Only decodes keyframe position and time.
|
|
/// </summary>
|
|
/// <remarks>Only use for curves serialized using WriteFloatCurvesSimple</remarks>
|
|
public static void ReadFloatCurveSimple(BinaryReader reader, AnimationCurve curve)
|
|
{
|
|
curve.preWrapMode = (WrapMode)reader.ReadInt32();
|
|
curve.postWrapMode = (WrapMode)reader.ReadInt32();
|
|
|
|
int keyframeCount = reader.ReadInt32();
|
|
|
|
Keyframe[] keys = new Keyframe[keyframeCount];
|
|
for (int i = 0; i < keyframeCount; ++i)
|
|
{
|
|
keys[i].time = reader.ReadSingle();
|
|
keys[i].value = reader.ReadSingle();
|
|
keys[i].weightedMode = WeightedMode.Both;
|
|
}
|
|
|
|
curve.keys = keys;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Serialize an array of animation curves with tangents as binary data.
|
|
/// </summary>
|
|
public static void WriteFloatCurveArray(BinaryWriter writer, AnimationCurve[] curves, float startTime)
|
|
{
|
|
foreach (AnimationCurve curve in curves)
|
|
{
|
|
InputAnimationSerializationUtils.WriteFloatCurve(writer, curve, startTime);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deserialize an array of animation curves with tangents from binary data.
|
|
/// </summary>
|
|
public static void ReadFloatCurveArray(BinaryReader reader, AnimationCurve[] curves)
|
|
{
|
|
foreach (AnimationCurve curve in curves)
|
|
{
|
|
InputAnimationSerializationUtils.ReadFloatCurve(reader, curve);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Serialize an array of animation curves as binary data, ignoring tangents.
|
|
/// </summary>
|
|
public static void WriteBoolCurveArray(BinaryWriter writer, AnimationCurve[] curves, float startTime)
|
|
{
|
|
foreach (AnimationCurve curve in curves)
|
|
{
|
|
InputAnimationSerializationUtils.WriteBoolCurve(writer, curve, startTime);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deserialize an array of animation curves from binary data, ignoring tangents.
|
|
/// </summary>
|
|
public static void ReadBoolCurveArray(BinaryReader reader, AnimationCurve[] curves)
|
|
{
|
|
foreach (AnimationCurve curve in curves)
|
|
{
|
|
InputAnimationSerializationUtils.ReadBoolCurve(reader, curve);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Serialize a list of markers.
|
|
/// </summary>
|
|
public static void WriteMarkerList(BinaryWriter writer, List<InputAnimationMarker> markers, float startTime)
|
|
{
|
|
writer.Write(markers.Count);
|
|
foreach (var marker in markers)
|
|
{
|
|
writer.Write(marker.time - startTime);
|
|
writer.Write(marker.name);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deserialize a list of markers.
|
|
/// </summary>
|
|
public static void ReadMarkerList(BinaryReader reader, List<InputAnimationMarker> markers)
|
|
{
|
|
markers.Clear();
|
|
int count = reader.ReadInt32();
|
|
markers.Capacity = count;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
var marker = new InputAnimationMarker();
|
|
marker.time = reader.ReadSingle();
|
|
marker.name = reader.ReadString();
|
|
markers.Add(marker);
|
|
}
|
|
}
|
|
}
|
|
}
|