Files
2025-11-30 08:35:03 +02:00

104 lines
3.0 KiB
C#

using GLTF.Extensions;
using Newtonsoft.Json;
namespace GLTF.Schema
{
public enum InterpolationType
{
LINEAR,
STEP,
CATMULLROMSPLINE,
CUBICSPLINE
}
/// <summary>
/// Combines input and output accessors with an interpolation algorithm to define a keyframe graph (but not its target).
/// </summary>
public class AnimationSampler : GLTFProperty
{
/// <summary>
/// The index of an accessor containing keyframe input values, e.G., time.
/// That accessor must have componentType `FLOAT`. The values represent time in
/// seconds with `time[0] >= 0.0`, and strictly increasing values,
/// i.e., `time[n + 1] > time[n]`
/// </summary>
public AccessorId Input;
/// <summary>
/// Interpolation algorithm. When an animation targets a node's rotation,
/// and the animation's interpolation is `\"LINEAR\"`, spherical linear
/// interpolation (slerp) should be used to interpolate quaternions. When
/// interpolation is `\"STEP\"`, animated value remains constant to the value
/// of the first point of the timeframe, until the next timeframe.
/// </summary>
public InterpolationType Interpolation;
/// <summary>
/// The index of an accessor, containing keyframe output values. Output and input
/// accessors must have the same `count`. When sampler is used with TRS target,
/// output accessor's componentType must be `FLOAT`.
/// </summary>
public AccessorId Output;
public AnimationSampler()
{
}
public AnimationSampler(AnimationSampler animationSampler, GLTFRoot gltfRoot) : base(animationSampler)
{
if (animationSampler == null) return;
Input = new AccessorId(animationSampler.Input, gltfRoot);
Interpolation = animationSampler.Interpolation;
Output = new AccessorId(animationSampler.Output, gltfRoot);
}
public static AnimationSampler Deserialize(GLTFRoot root, JsonReader reader)
{
var animationSampler = new AnimationSampler();
while (reader.Read() && reader.TokenType == JsonToken.PropertyName)
{
var curProp = reader.Value.ToString();
switch (curProp)
{
case "input":
animationSampler.Input = AccessorId.Deserialize(root, reader);
break;
case "interpolation":
animationSampler.Interpolation = reader.ReadStringEnum<InterpolationType>();
break;
case "output":
animationSampler.Output = AccessorId.Deserialize(root, reader);
break;
default:
animationSampler.DefaultPropertyDeserializer(root, reader);
break;
}
}
return animationSampler;
}
public override void Serialize(JsonWriter writer)
{
writer.WriteStartObject();
writer.WritePropertyName("input");
writer.WriteValue(Input.Id);
// the spec defines "LINEAR" as default, but we need to explicitly export this since there are issues with Google SceneViewer when no interpolation is specified
writer.WritePropertyName("interpolation");
writer.WriteValue(Interpolation.ToString());
writer.WritePropertyName("output");
writer.WriteValue(Output.Id);
base.Serialize(writer);
writer.WriteEndObject();
}
}
}