// 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();
}
}