// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using Microsoft.MixedReality.Toolkit.Utilities; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace Microsoft.MixedReality.Toolkit.Input { /// /// Container used to efficiently store a sequence of input animation keyframes while recording /// public class InputRecordingBuffer : IEnumerable { /// /// The input state for a single frame /// public class Keyframe { public float Time { get; set; } public bool LeftTracked { get; set; } public bool RightTracked { get; set; } public bool LeftPinch { get; set; } public bool RightPinch { get; set; } public MixedRealityPose CameraPose { get; set; } public Ray GazeRay { get; set; } public Dictionary LeftJoints { get; set; } public Dictionary RightJoints { get; set; } public Keyframe(float time) { Time = time; LeftJoints = new Dictionary(); RightJoints = new Dictionary(); } } /// /// The time of the first keyframe in the buffer /// public float StartTime => keyframes.Peek().Time; private Keyframe currentKeyframe; private Queue keyframes; /// /// Default constructor /// public InputRecordingBuffer() => keyframes = new Queue(); /// /// Removes all keyframes from the buffer /// public void Clear() { keyframes.Clear(); currentKeyframe = null; } /// /// Removes all keyframes before a given time /// public void RemoveBeforeTime(float time) { while (keyframes.Count > 0 && keyframes.Peek().Time < time) { keyframes.Dequeue(); } } /// /// Sets the camera pose to be stored in the newest keyframe /// public void SetCameraPose(MixedRealityPose pose) => currentKeyframe.CameraPose = pose; /// /// Sets the eye gaze ray to be stored in the newest keyframe /// public void SetGazeRay(Ray ray) => currentKeyframe.GazeRay = ray; /// /// Sets the state of a given hand to be stored in the newest keyframe /// public void SetHandState(Handedness handedness, bool tracked, bool pinching) { if (handedness == Handedness.Left) { currentKeyframe.LeftTracked = tracked; currentKeyframe.LeftPinch = pinching; } else { currentKeyframe.RightTracked = tracked; currentKeyframe.RightPinch = pinching; } } /// /// Sets the pose of a given joint to be stored in the newest keyframe /// public void SetJointPose(Handedness handedness, TrackedHandJoint joint, MixedRealityPose pose) { if (handedness == Handedness.Left) { currentKeyframe.LeftJoints.Add(joint, pose); } else { currentKeyframe.RightJoints.Add(joint, pose); } } /// /// Creates a new, empty keyframe with a given time at the end of the buffer /// /// The index of the new keyframe public int NewKeyframe(float time) { currentKeyframe = new Keyframe(time); keyframes.Enqueue(currentKeyframe); return keyframes.Count - 1; } /// /// Returns a sequence of all keyframes in the buffer /// public IEnumerator GetEnumerator() => keyframes.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } }