using GLTF.Extensions; using Newtonsoft.Json; namespace GLTF.Schema { public enum InterpolationType { LINEAR, STEP, CATMULLROMSPLINE, CUBICSPLINE } /// /// Combines input and output accessors with an interpolation algorithm to define a keyframe graph (but not its target). /// public class AnimationSampler : GLTFProperty { /// /// 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]` /// public AccessorId Input; /// /// 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. /// public InterpolationType Interpolation; /// /// 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`. /// 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(); 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(); } } }