Commit 29de0c28 authored by BlackAngle233's avatar BlackAngle233
Browse files

10.19 learned

parent 912976bb
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using Microsoft.MixedReality.Toolkit.Utilities;
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
namespace Microsoft.MixedReality.Toolkit.Input
{
/// <summary>
/// A used-defined marker on the input animation timeline.
/// </summary>
[Serializable]
public class InputAnimationMarker
{
/// <summary>
/// Placement of the marker relative to the input animation start time.
/// </summary>
public float time = 0.0f;
/// <summary>
/// Custom name of the marker.
/// </summary>
public string name = "";
}
/// <summary>
/// Contains a set of animation curves that describe motion of camera and hands.
/// </summary>
[System.Serializable]
public class InputAnimation
{
protected static readonly int jointCount = Enum.GetNames(typeof(TrackedHandJoint)).Length;
/// <summary>
/// Maximum duration of all animations curves.
/// </summary>
[SerializeField]
private float duration = 0.0f;
public float Duration => duration;
public class PoseCurves
{
readonly public AnimationCurve PositionX = new AnimationCurve();
readonly public AnimationCurve PositionY = new AnimationCurve();
readonly public AnimationCurve PositionZ = new AnimationCurve();
readonly public AnimationCurve RotationX = new AnimationCurve();
readonly public AnimationCurve RotationY = new AnimationCurve();
readonly public AnimationCurve RotationZ = new AnimationCurve();
readonly public AnimationCurve RotationW = new AnimationCurve();
}
[SerializeField]
private AnimationCurve handTrackedCurveLeft;
[SerializeField]
private AnimationCurve handTrackedCurveRight;
[SerializeField]
private AnimationCurve handPinchCurveLeft;
[SerializeField]
private AnimationCurve handPinchCurveRight;
[SerializeField]
private Dictionary<TrackedHandJoint, PoseCurves> handJointCurvesLeft;
[SerializeField]
private Dictionary<TrackedHandJoint, PoseCurves> handJointCurvesRight;
[SerializeField]
private PoseCurves cameraCurves;
public PoseCurves CameraCurves => cameraCurves;
/// <summary>
/// Number of markers in the animation.
/// </summary>
[SerializeField]
private List<InputAnimationMarker> markers;
public int markerCount => markers.Count;
internal class CompareMarkers : IComparer<InputAnimationMarker>
{
public int Compare(InputAnimationMarker a, InputAnimationMarker b)
{
return a.time.CompareTo(b.time);
}
}
public InputAnimation()
{
handTrackedCurveLeft = new AnimationCurve();
handTrackedCurveRight = new AnimationCurve();
handPinchCurveLeft = new AnimationCurve();
handPinchCurveRight = new AnimationCurve();
handJointCurvesLeft = new Dictionary<TrackedHandJoint, PoseCurves>();
handJointCurvesRight = new Dictionary<TrackedHandJoint, PoseCurves>();
cameraCurves = new PoseCurves();
markers = new List<InputAnimationMarker>();
}
/// <summary>
/// Get animation curves for the pose of the given hand joint, if they exist.
/// </summary>
public bool TryGetHandJointCurves(Handedness handedness, TrackedHandJoint joint, out PoseCurves curves)
{
if (handedness == Handedness.Left)
{
return handJointCurvesLeft.TryGetValue(joint, out curves);
}
else if (handedness == Handedness.Right)
{
return handJointCurvesRight.TryGetValue(joint, out curves);
}
curves = null;
return false;
}
/// <summary>
/// Make sure the pose animation curves for the given hand joint exist.
/// </summary>
public PoseCurves CreateHandJointCurves(Handedness handedness, TrackedHandJoint joint)
{
if (handedness == Handedness.Left)
{
if (!handJointCurvesLeft.TryGetValue(joint, out PoseCurves curves))
{
curves = new PoseCurves();
handJointCurvesLeft.Add(joint, curves);
}
return curves;
}
else if (handedness == Handedness.Right)
{
if (!handJointCurvesRight.TryGetValue(joint, out PoseCurves curves))
{
curves = new PoseCurves();
handJointCurvesRight.Add(joint, curves);
}
return curves;
}
return null;
}
/// <summary>
/// Add a keyframe for the tracking state of a hand.
/// </summary>
public void AddHandStateKey(float time, Handedness handedness, bool isTracked, bool isPinching)
{
if (handedness == Handedness.Left)
{
AddHandStateKey(time, isTracked, isPinching, handTrackedCurveLeft, handPinchCurveLeft);
}
else if (handedness == Handedness.Right)
{
AddHandStateKey(time, isTracked, isPinching, handTrackedCurveRight, handPinchCurveRight);
}
}
/// <summary>
/// Add a keyframe for one hand joint.
/// </summary>
public void AddHandJointKey(float time, Handedness handedness, TrackedHandJoint joint, MixedRealityPose jointPose, float positionThreshold, float rotationThreshold)
{
if (handedness == Handedness.Left)
{
AddHandJointKey(time, joint, jointPose, handJointCurvesLeft, positionThreshold, rotationThreshold);
}
else if (handedness == Handedness.Right)
{
AddHandJointKey(time, joint, jointPose, handJointCurvesRight, positionThreshold, rotationThreshold);
}
}
/// Add a keyframe for the tracking state of a hand.
private void AddHandStateKey(float time, bool isTracked, bool isPinching, AnimationCurve trackedCurve, AnimationCurve pinchCurve)
{
AddBoolKeyFiltered(trackedCurve, time, isTracked);
AddBoolKeyFiltered(pinchCurve, time, isPinching);
duration = Mathf.Max(duration, time);
}
/// Add a keyframe for one hand joint.
private void AddHandJointKey(float time, TrackedHandJoint joint, MixedRealityPose jointPose, Dictionary<TrackedHandJoint, PoseCurves> jointCurves, float positionThreshold, float rotationThreshold)
{
if (!jointCurves.TryGetValue(joint, out PoseCurves curves))
{
curves = new PoseCurves();
jointCurves.Add(joint, curves);
}
AddPoseKeyFiltered(curves, time, jointPose, positionThreshold, rotationThreshold);
duration = Mathf.Max(duration, time);
}
/// <summary>
/// Add a keyframe for the camera transform.
/// </summary>
public void AddCameraPoseKey(float time, MixedRealityPose cameraPose, float positionThreshold, float rotationThreshold)
{
AddPoseKeyFiltered(cameraCurves, time, cameraPose, positionThreshold, rotationThreshold);
duration = Mathf.Max(duration, time);
}
private static void AddPoseKey(PoseCurves curves, float time, MixedRealityPose pose)
{
AddFloatKey(curves.PositionX, time, pose.Position.x);
AddFloatKey(curves.PositionY, time, pose.Position.y);
AddFloatKey(curves.PositionZ, time, pose.Position.z);
AddFloatKey(curves.RotationX, time, pose.Rotation.x);
AddFloatKey(curves.RotationY, time, pose.Rotation.y);
AddFloatKey(curves.RotationZ, time, pose.Rotation.z);
AddFloatKey(curves.RotationW, time, pose.Rotation.w);
}
/// Add a pose keyframe to an animation curve.
/// Keys are only added if the value changes sufficiently.
private static void AddPoseKeyFiltered(PoseCurves curves, float time, MixedRealityPose pose, float positionThreshold, float rotationThreshold)
{
AddPositionKeyFiltered(curves.PositionX, curves.PositionY, curves.PositionZ, time, pose.Position, positionThreshold);
AddRotationKeyFiltered(curves.RotationX, curves.RotationY, curves.RotationZ, curves.RotationW, time, pose.Rotation, rotationThreshold);
}
// Add a vector keyframe to animation curve if the threshold distance to the previous value is exceeded.
// Otherwise replace the last keyframe instead of adding a new one.
private static void AddPositionKeyFiltered(AnimationCurve curveX, AnimationCurve curveY, AnimationCurve curveZ, float time, Vector3 position, float threshold)
{
float sqrThreshold = threshold * threshold;
int iX = FindKeyframeInterval(curveX, time);
int iY = FindKeyframeInterval(curveY, time);
int iZ = FindKeyframeInterval(curveZ, time);
if (iX > 0 && iY > 0 && iZ > 0)
{
Vector3 v0 = new Vector3(curveX.keys[iX - 1].value, curveY.keys[iY - 1].value, curveZ.keys[iZ - 1].value);
Vector3 v1 = new Vector3(curveX.keys[iX].value, curveY.keys[iY].value, curveZ.keys[iZ].value);
// Merge the preceding two intervals if difference is small enough
if ((v1 - v0).sqrMagnitude <= sqrThreshold && (position - v1).sqrMagnitude <= sqrThreshold)
{
curveX.RemoveKey(iX);
curveY.RemoveKey(iY);
curveZ.RemoveKey(iZ);
}
}
AddFloatKey(curveX, time, position.x);
AddFloatKey(curveY, time, position.y);
AddFloatKey(curveZ, time, position.z);
}
// Add a quaternion keyframe to animation curve if the threshold angular distance to the previous value is exceeded.
// Otherwise replace the last keyframe instead of adding a new one.
private static void AddRotationKeyFiltered(AnimationCurve curveX, AnimationCurve curveY, AnimationCurve curveZ, AnimationCurve curveW, float time, Quaternion rotation, float threshold)
{
float sqrThreshold = threshold * threshold;
int iX = FindKeyframeInterval(curveX, time);
int iY = FindKeyframeInterval(curveY, time);
int iZ = FindKeyframeInterval(curveZ, time);
int iW = FindKeyframeInterval(curveW, time);
if (iX > 0 && iY > 0 && iZ > 0 && iW > 0)
{
Quaternion q0 = new Quaternion(curveX.keys[iX - 1].value, curveY.keys[iY - 1].value, curveZ.keys[iZ - 1].value, curveW.keys[iW - 1].value);
Quaternion q1 = new Quaternion(curveX.keys[iX].value, curveY.keys[iY].value, curveZ.keys[iZ].value, curveW.keys[iW].value);
// Merge the preceding two intervals if difference is small enough
(q0 * Quaternion.Inverse(q1)).ToAngleAxis(out float angle0, out Vector3 axis0);
(rotation * Quaternion.Inverse(q0)).ToAngleAxis(out float angle1, out Vector3 axis1);
if (angle0 <= sqrThreshold && angle1 <= sqrThreshold)
{
curveX.RemoveKey(iX);
curveY.RemoveKey(iY);
curveZ.RemoveKey(iZ);
curveW.RemoveKey(iW);
}
}
AddFloatKey(curveX, time, rotation.x);
AddFloatKey(curveY, time, rotation.y);
AddFloatKey(curveZ, time, rotation.z);
AddFloatKey(curveW, time, rotation.w);
}
/// Add a float value to an animation curve.
/// Returns the index of the newly added keyframe.
private static int AddFloatKey(AnimationCurve curve, float time, float value)
{
// Use linear interpolation by setting tangents and weights to zero.
var keyframe = new Keyframe(time, value, 0.0f, 0.0f, 0.0f, 0.0f);
keyframe.weightedMode = WeightedMode.Both;
return curve.AddKey(keyframe);
}
/// Arbitrarily large weight for representing a boolean value in float curves.
const float boolOutWeight = 1.0e6f;
/// Utility function that creates a non-interpolated keyframe suitable for boolean values.
/// Returns the index of the newly added keyframe.
private static int AddBoolKey(AnimationCurve curve, float time, bool value)
{
float fvalue = value ? 1.0f : 0.0f;
// Set tangents and weights such than the input value is cut off and out tangent is constant.
var keyframe = new Keyframe(time, fvalue, 0.0f, 0.0f, 0.0f, boolOutWeight);
keyframe.weightedMode = WeightedMode.Both;
return curve.AddKey(keyframe);
}
/// Utility function that creates a non-interpolated keyframe suitable for boolean values.
/// Keys are only added if the value changes.
/// Returns the index of the newly added keyframe, or -1 if no keyframe has been added.
private static int AddBoolKeyFiltered(AnimationCurve curve, float time, bool value)
{
float fvalue = value ? 1.0f : 0.0f;
// Set tangents and weights such than the input value is cut off and out tangent is constant.
var keyframe = new Keyframe(time, fvalue, 0.0f, 0.0f, 0.0f, boolOutWeight);
keyframe.weightedMode = WeightedMode.Both;
int insertAfter = FindKeyframeInterval(curve, time);
if (insertAfter >= 0 && curve.keys[insertAfter].value == fvalue)
{
// Value unchanged from previous key, ignore
return -1;
}
int insertBefore = insertAfter + 1;
if (insertBefore < curve.keys.Length && curve.keys[insertBefore].value == fvalue)
{
// Same value as next key, replace next key
return curve.MoveKey(insertBefore, keyframe);
}
return curve.AddKey(keyframe);
}
/// <summary>
/// Remove all keyframes from all animation curves with time values before the given cutoff time.
/// </summary>
/// <remarks>
/// If keyframes exists before the cutoff time then one preceding keyframe will be retained,
/// so that interpolation at the cutoff time yields the same result.
/// </remarks>
public void CutoffBeforeTime(float time)
{
foreach (var curve in AnimationCurves)
{
CutoffBeforeTime(curve, time);
}
}
private void CutoffBeforeTime(AnimationCurve curve, float time)
{
// Keep the keyframe before the cutoff time to ensure correct value at the beginning
int idx0 = FindKeyframeInterval(curve, time);
if (idx0 > 0)
{
Keyframe[] newKeys = new Keyframe[curve.keys.Length - idx0];
for (int i = 0; i < newKeys.Length; ++i)
{
newKeys[i] = curve.keys[idx0 + i];
}
curve.keys = newKeys;
}
}
/// <summary>
/// Remove all keyframes from all animation curves.
/// </summary>
public void Clear()
{
foreach (var curve in AnimationCurves)
{
curve.keys = new Keyframe[0];
}
}
// Helper class to enumerate all curves in the input animation
internal class AnimationCurveEnumerable : IEnumerable<AnimationCurve>
{
private InputAnimation animation;
public AnimationCurveEnumerable(InputAnimation animation)
{
this.animation = animation;
}
public IEnumerator<AnimationCurve> GetEnumerator()
{
yield return animation.handTrackedCurveLeft;
yield return animation.handTrackedCurveRight;
yield return animation.handPinchCurveLeft;
yield return animation.handPinchCurveRight;
foreach (var curves in animation.handJointCurvesLeft.Values)
{
yield return curves.PositionX;
yield return curves.PositionY;
yield return curves.PositionZ;
yield return curves.RotationX;
yield return curves.RotationY;
yield return curves.RotationZ;
yield return curves.RotationW;
}
foreach (var curves in animation.handJointCurvesRight.Values)
{
yield return curves.PositionX;
yield return curves.PositionY;
yield return curves.PositionZ;
yield return curves.RotationX;
yield return curves.RotationY;
yield return curves.RotationZ;
yield return curves.RotationW;
}
yield return animation.cameraCurves.PositionX;
yield return animation.cameraCurves.PositionY;
yield return animation.cameraCurves.PositionZ;
yield return animation.cameraCurves.RotationX;
yield return animation.cameraCurves.RotationY;
yield return animation.cameraCurves.RotationZ;
yield return animation.cameraCurves.RotationW;
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
private IEnumerable<AnimationCurve> AnimationCurves => new AnimationCurveEnumerable(this);
/// <summary>
/// Find an index i in the sorted events list, such that events[i].time <= time < events[i+1].time.
/// </summary>
/// <returns>
/// 0 <= i < eventCount if a full interval could be found.
/// -1 if time is less than the first event time.
/// eventCount-1 if time is greater than the last event time.
/// </returns>
/// <remarks>
/// Uses binary search.
/// </remarks>
private static int FindKeyframeInterval(AnimationCurve curve, float time)
{
var keys = curve.keys;
int lowIdx = -1;
int highIdx = keys.Length;
while (lowIdx < highIdx - 1)
{
int midIdx = (lowIdx + highIdx) >> 1;
if (time >= keys[midIdx].time)
{
lowIdx = midIdx;
}
else
{
highIdx = midIdx;
}
}
return lowIdx;
}
/// <summary>
/// Add a user-defined marker.
/// </summary>
public void AddMarker(InputAnimationMarker marker)
{
int index = FindMarkerInterval(marker.time) + 1;
markers.Insert(index, marker);
}
/// <summary>
/// Remove the user-defined marker at the given index.
/// </summary>
public void RemoveMarker(int index)
{
markers.RemoveAt(index);
}
/// <summary>
/// Change the time of the marker at the given index.
/// </summary>
public void SetMarkerTime(int index, float time)
{
InputAnimationMarker marker = markers[index];
markers.RemoveAt(index);
int newIndex = FindMarkerInterval(time) + 1;
marker.time = time;
markers.Insert(newIndex, marker);
}
/// <summary>
/// Evaluate hand tracking state at the given time.
/// </summary>
public void EvaluateHandState(float time, Handedness handedness, out bool isTracked, out bool isPinching)
{
if (handedness == Handedness.Left)
{
EvaluateHandState(time, handTrackedCurveLeft, handPinchCurveLeft, out isTracked, out isPinching);
}
else if (handedness == Handedness.Right)
{
EvaluateHandState(time, handTrackedCurveRight, handPinchCurveRight, out isTracked, out isPinching);
}
else
{
isTracked = false;
isPinching = false;
}
}
/// Evaluate hand tracking state at the given time.
private void EvaluateHandState(float time, AnimationCurve trackedCurve, AnimationCurve pinchCurve, out bool isTracked, out bool isPinching)
{
isTracked = (trackedCurve.Evaluate(time) > 0.5f);
isPinching = (pinchCurve.Evaluate(time) > 0.5f);
}
/// <summary>
/// Evaluate joint pose at the given time.
/// </summary>
public MixedRealityPose EvaluateHandJoint(float time, Handedness handedness, TrackedHandJoint joint)
{
if (handedness == Handedness.Left)
{
return EvaluateHandJoint(time, joint, handJointCurvesLeft);
}
else if (handedness == Handedness.Right)
{
return EvaluateHandJoint(time, joint, handJointCurvesRight);
}
else
{
return MixedRealityPose.ZeroIdentity;
}
}
/// Evaluate joint pose at the given time.
private MixedRealityPose EvaluateHandJoint(float time, TrackedHandJoint joint, Dictionary<TrackedHandJoint, PoseCurves> jointCurves)
{
if (jointCurves.TryGetValue(joint, out PoseCurves curves))
{
return EvaluatePose(curves, time);
}
else
{
return MixedRealityPose.ZeroIdentity;
}
}
/// <summary>
/// Evaluate the camera transform at the given time.
/// </summary>
public MixedRealityPose EvaluateCameraPose(float time)
{
return EvaluatePose(cameraCurves, time);
}
private static MixedRealityPose EvaluatePose(PoseCurves curves, float time)
{
float px = curves.PositionX.Evaluate(time);
float py = curves.PositionY.Evaluate(time);
float pz = curves.PositionZ.Evaluate(time);
float rx = curves.RotationX.Evaluate(time);
float ry = curves.RotationY.Evaluate(time);
float rz = curves.RotationZ.Evaluate(time);
float rw = curves.RotationW.Evaluate(time);
var pose = new MixedRealityPose();
pose.Position = new Vector3(px, py, pz);
pose.Rotation = new Quaternion(rx, ry, rz, rw);
pose.Rotation.Normalize();
return pose;
}
/// <summary>
/// Get the marker at the given index.
/// </summary>
public InputAnimationMarker GetMarker(int index)
{
return markers[index];
}
/// <summary>
/// Find an index i in the sorted events list, such that events[i].time &lt;= time &lt; events[i+1].time.
/// </summary>
/// <returns>
/// 0 &lt;= i &lt; eventCount if a full interval could be found.
/// -1 if time is less than the first event time.
/// eventCount-1 if time is greater than the last event time.
/// </returns>
/// <remarks>
/// Uses binary search.
/// </remarks>
public int FindMarkerInterval(float time)
{
int lowIdx = -1;
int highIdx = markers.Count;
while (lowIdx < highIdx - 1)
{
int midIdx = (lowIdx + highIdx) >> 1;
if (time >= markers[midIdx].time)
{
lowIdx = midIdx;
}
else
{
highIdx = midIdx;
}
}
return lowIdx;
}
private void ComputeDuration()
{
duration = 0.0f;
foreach (var curve in AnimationCurves)
{
float curveDuration = (curve.length > 0 ? curve.keys[curve.length - 1].time : 0.0f);
duration = Mathf.Max(duration, curveDuration);
}
}
/// <summary>
/// Serialize animation data into a stream.
/// </summary>
public void ToStream(Stream stream, float startTime)
{
PoseCurves defaultCurves = new PoseCurves();
var writer = new BinaryWriter(stream);
InputAnimationSerializationUtils.WriteHeader(writer);
PoseCurvesToStream(writer, cameraCurves, startTime);
InputAnimationSerializationUtils.WriteBoolCurve(writer, handTrackedCurveLeft, startTime);
InputAnimationSerializationUtils.WriteBoolCurve(writer, handTrackedCurveRight, startTime);
InputAnimationSerializationUtils.WriteBoolCurve(writer, handPinchCurveLeft, startTime);
InputAnimationSerializationUtils.WriteBoolCurve(writer, handPinchCurveRight, startTime);
for (int i = 0; i < jointCount; ++i)
{
if (!handJointCurvesLeft.TryGetValue((TrackedHandJoint)i, out PoseCurves curves))
{
curves = defaultCurves;
}
PoseCurvesToStream(writer, curves, startTime);
}
for (int i = 0; i < jointCount; ++i)
{
if (!handJointCurvesRight.TryGetValue((TrackedHandJoint)i, out PoseCurves curves))
{
curves = defaultCurves;
}
PoseCurvesToStream(writer, curves, startTime);
}
InputAnimationSerializationUtils.WriteMarkerList(writer, markers, startTime);
}
/// <summary>
/// Deserialize animation data from a stream.
/// </summary>
public void FromStream(Stream stream)
{
var reader = new BinaryReader(stream);
InputAnimationSerializationUtils.ReadHeader(reader, out int versionMajor, out int versionMinor);
if (versionMajor != 1 || versionMinor != 0)
{
Debug.LogError("Only version 1.0 of input animation file format is supported.");
return;
}
PoseCurvesFromStream(reader, cameraCurves);
InputAnimationSerializationUtils.ReadBoolCurve(reader, handTrackedCurveLeft);
InputAnimationSerializationUtils.ReadBoolCurve(reader, handTrackedCurveRight);
InputAnimationSerializationUtils.ReadBoolCurve(reader, handPinchCurveLeft);
InputAnimationSerializationUtils.ReadBoolCurve(reader, handPinchCurveRight);
for (int i = 0; i < jointCount; ++i)
{
if (!handJointCurvesLeft.TryGetValue((TrackedHandJoint)i, out PoseCurves curves))
{
curves = new PoseCurves();
handJointCurvesLeft.Add((TrackedHandJoint)i, curves);
}
PoseCurvesFromStream(reader, curves);
}
for (int i = 0; i < jointCount; ++i)
{
if (!handJointCurvesRight.TryGetValue((TrackedHandJoint)i, out PoseCurves curves))
{
curves = new PoseCurves();
handJointCurvesRight.Add((TrackedHandJoint)i, curves);
}
PoseCurvesFromStream(reader, curves);
}
InputAnimationSerializationUtils.ReadMarkerList(reader, markers);
ComputeDuration();
}
private static void PoseCurvesToStream(BinaryWriter writer, PoseCurves curves, float startTime)
{
InputAnimationSerializationUtils.WriteFloatCurve(writer, curves.PositionX, startTime);
InputAnimationSerializationUtils.WriteFloatCurve(writer, curves.PositionY, startTime);
InputAnimationSerializationUtils.WriteFloatCurve(writer, curves.PositionZ, startTime);
InputAnimationSerializationUtils.WriteFloatCurve(writer, curves.RotationX, startTime);
InputAnimationSerializationUtils.WriteFloatCurve(writer, curves.RotationY, startTime);
InputAnimationSerializationUtils.WriteFloatCurve(writer, curves.RotationZ, startTime);
InputAnimationSerializationUtils.WriteFloatCurve(writer, curves.RotationW, startTime);
}
private static void PoseCurvesFromStream(BinaryReader reader, PoseCurves curves)
{
InputAnimationSerializationUtils.ReadFloatCurve(reader, curves.PositionX);
InputAnimationSerializationUtils.ReadFloatCurve(reader, curves.PositionY);
InputAnimationSerializationUtils.ReadFloatCurve(reader, curves.PositionZ);
InputAnimationSerializationUtils.ReadFloatCurve(reader, curves.RotationX);
InputAnimationSerializationUtils.ReadFloatCurve(reader, curves.RotationY);
InputAnimationSerializationUtils.ReadFloatCurve(reader, curves.RotationZ);
InputAnimationSerializationUtils.ReadFloatCurve(reader, curves.RotationW);
}
}
}
\ No newline at end of file
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using Microsoft.MixedReality.Toolkit.Utilities;
using UnityEngine;
using System;
using System.Collections.Generic;
using System.IO;
namespace Microsoft.MixedReality.Toolkit.Input
{
/// <summary>
/// Functions for serializing input animation data to and from binary files.
/// </summary>
public static class InputAnimationSerializationUtils
{
private static readonly int jointCount = Enum.GetNames(typeof(TrackedHandJoint)).Length;
public const string Extension = "bin";
const long Magic = 0x6a8faf6e0f9e42c6;
public const int VersionMajor = 1;
public const int VersionMinor = 0;
/// <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"), InputAnimationSerializationUtils.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].inTangent = 0.0f;
keys[i].outTangent = 0.0f;
keys[i].inWeight = 0.0f;
keys[i].outWeight = 1.0e6f;
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);
}
}
}
}
\ No newline at end of file
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using Microsoft.MixedReality.Toolkit.Utilities;
using System;
using System.IO;
using UnityEngine;
namespace Microsoft.MixedReality.Toolkit.Input
{
/// <summary>
/// Provides input recording into an internal buffer and exporting to files.
/// </summary>
[MixedRealityDataProvider(
typeof(IMixedRealityInputSystem),
(SupportedPlatforms)(-1), // Supported on all platforms
"Input Recording Service",
"Profiles/DefaultMixedRealityInputRecordingProfile.asset",
"MixedRealityToolkit.SDK",
true)]
public class InputRecordingService :
BaseInputDeviceManager,
IMixedRealityInputRecordingService
{
private static readonly int jointCount = Enum.GetNames(typeof(TrackedHandJoint)).Length;
public event Action OnRecordingStarted;
public event Action OnRecordingStopped;
/// <summary>
/// Constructor.
/// </summary>
/// <param name="registrar">The <see cref="IMixedRealityServiceRegistrar"/> instance that loaded the data provider.</param>
/// <param name="inputSystem">The <see cref="Microsoft.MixedReality.Toolkit.Input.IMixedRealityInputSystem"/> instance that receives data from this provider.</param>
/// <param name="name">Friendly name of the service.</param>
/// <param name="priority">Service priority. Used to determine order of instantiation.</param>
/// <param name="profile">The service's configuration profile.</param>
[Obsolete("This constructor is obsolete (registrar parameter is no longer required) and will be removed in a future version of the Microsoft Mixed Reality Toolkit.")]
public InputRecordingService(
IMixedRealityServiceRegistrar registrar,
IMixedRealityInputSystem inputSystem,
string name = null,
uint priority = DefaultPriority,
BaseMixedRealityProfile profile = null) : this(inputSystem, name, priority, profile)
{
Registrar = registrar;
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="inputSystem">The <see cref="Microsoft.MixedReality.Toolkit.Input.IMixedRealityInputSystem"/> instance that receives data from this provider.</param>
/// <param name="name">Friendly name of the service.</param>
/// <param name="priority">Service priority. Used to determine order of instantiation.</param>
/// <param name="profile">The service's configuration profile.</param>
public InputRecordingService(
IMixedRealityInputSystem inputSystem,
string name = null,
uint priority = DefaultPriority,
BaseMixedRealityProfile profile = null) : base(inputSystem, name, priority, profile)
{ }
/// <summary>
/// Return the service profile and ensure that the type is correct.
/// </summary>
public MixedRealityInputRecordingProfile InputRecordingProfile
{
get
{
var profile = ConfigurationProfile as MixedRealityInputRecordingProfile;
if (!profile)
{
Debug.LogError("Profile for Input Recording Service must be a MixedRealityInputRecordingProfile");
}
return profile;
}
}
/// <summary>
/// Service has been enabled.
/// </summary>
public bool IsEnabled { get; private set; } = false;
/// <inheritdoc />
public bool IsRecording { get; private set; } = false;
private bool useBufferTimeLimit = true;
/// <inheritdoc />
public bool UseBufferTimeLimit
{
get { return useBufferTimeLimit; }
set
{
if (useBufferTimeLimit && !value)
{
// Start at buffer limit when making buffer unlimited
unlimitedRecordingStartTime = StartTime;
}
useBufferTimeLimit = value;
if (useBufferTimeLimit)
{
PruneBuffer();
}
}
}
private float recordingBufferTimeLimit = 30.0f;
/// <inheritdoc />
public float RecordingBufferTimeLimit
{
get { return recordingBufferTimeLimit; }
set
{
recordingBufferTimeLimit = Mathf.Max(value, 0.0f);
if (useBufferTimeLimit)
{
PruneBuffer();
}
}
}
private InputAnimation recordingBuffer = null;
// Start time of recording if buffer is unlimited.
// Nullable to determine when time needs to be reset.
private float? unlimitedRecordingStartTime = null;
public float StartTime
{
get
{
if (unlimitedRecordingStartTime.HasValue)
{
if (useBufferTimeLimit)
{
return Mathf.Max(unlimitedRecordingStartTime.Value, Time.time - recordingBufferTimeLimit);
}
else
{
return unlimitedRecordingStartTime.Value;
}
}
return Time.time;
}
}
private void ResetStartTime()
{
if (IsRecording)
{
unlimitedRecordingStartTime = Time.time;
}
else
{
unlimitedRecordingStartTime = null;
}
}
/// <inheritdoc />
public override void Enable()
{
IsEnabled = true;
recordingBuffer = new InputAnimation();
}
/// <inheritdoc />
public override void Disable()
{
IsEnabled = false;
recordingBuffer = null;
ResetStartTime();
}
/// <inheritdoc />
public void StartRecording()
{
IsRecording = true;
if (UseBufferTimeLimit)
{
PruneBuffer();
}
if (!unlimitedRecordingStartTime.HasValue)
{
unlimitedRecordingStartTime = Time.time;
}
OnRecordingStarted?.Invoke();
}
/// <inheritdoc />
public void StopRecording()
{
IsRecording = false;
OnRecordingStopped?.Invoke();
}
/// <inheritdoc />
public override void LateUpdate()
{
if (IsEnabled)
{
if (IsRecording)
{
if (UseBufferTimeLimit)
{
PruneBuffer();
}
RecordKeyframe();
}
}
}
/// <inheritdoc />
public void DiscardRecordedInput()
{
if (IsEnabled)
{
recordingBuffer.Clear();
ResetStartTime();
}
}
/// <summary>
/// Record a keyframe at the given time for the main camera and tracked input devices.
/// </summary>
private void RecordKeyframe()
{
float time = Time.time;
var profile = InputRecordingProfile;
RecordInputHandData(Handedness.Left);
RecordInputHandData(Handedness.Right);
if (CameraCache.Main)
{
var cameraPose = new MixedRealityPose(CameraCache.Main.transform.position, CameraCache.Main.transform.rotation);
recordingBuffer.AddCameraPoseKey(time, cameraPose, profile.CameraPositionThreshold, profile.CameraRotationThreshold);
}
}
/// <summary>
/// Record a keyframe at the given time for a hand with the given handedness it is tracked.
/// </summary>
private bool RecordInputHandData(Handedness handedness)
{
float time = Time.time;
var profile = InputRecordingProfile;
var hand = HandJointUtils.FindHand(handedness);
if (hand == null)
{
recordingBuffer.AddHandStateKey(time, handedness, false, false);
return false;
}
bool isTracked = (hand.TrackingState == TrackingState.Tracked);
// Extract extra information from current interactions
bool isPinching = false;
for (int i = 0; i < hand.Interactions?.Length; i++)
{
var interaction = hand.Interactions[i];
switch (interaction.InputType)
{
case DeviceInputType.Select:
isPinching = interaction.BoolData;
break;
}
}
recordingBuffer.AddHandStateKey(time, handedness, isTracked, isPinching);
if (isTracked)
{
for (int i = 0; i < jointCount; ++i)
{
if (hand.TryGetJoint((TrackedHandJoint)i, out MixedRealityPose jointPose))
{
recordingBuffer.AddHandJointKey(time, handedness, (TrackedHandJoint)i, jointPose, profile.JointPositionThreshold, profile.JointRotationThreshold);
}
}
}
return true;
}
/// <inheritdoc />
public string SaveInputAnimation(string directory = null)
{
return SaveInputAnimation(InputAnimationSerializationUtils.GetOutputFilename(), directory);
}
/// <inheritdoc />
public string SaveInputAnimation(string filename, string directory = null)
{
if (IsEnabled)
{
string path = Path.Combine(directory ?? Application.persistentDataPath, filename);
try
{
using (Stream fileStream = File.Open(path, FileMode.Create))
{
PruneBuffer();
recordingBuffer.ToStream(fileStream, StartTime);
Debug.Log($"Recorded input animation exported to {path}");
}
return path;
}
catch (IOException ex)
{
Debug.LogWarning(ex.Message);
}
}
return "";
}
/// Discard keyframes before the cutoff time.
private void PruneBuffer()
{
recordingBuffer.CutoffBeforeTime(StartTime);
}
}
}
{
"name": "Microsoft.MixedReality.Toolkit.Services.InputAnimation",
"references": [
"Microsoft.MixedReality.Toolkit"
],
"optionalUnityReferences": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false
}
\ No newline at end of file
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using Microsoft.MixedReality.Toolkit.Utilities;
using UnityEngine;
namespace Microsoft.MixedReality.Toolkit.Input
{
/// <summary>
/// Settings for recording input animation assets.
/// </summary>
[CreateAssetMenu(menuName = "Mixed Reality Toolkit/Profiles/Mixed Reality Input Recording Profile", fileName = "MixedRealityInputRecordingProfile", order = (int)CreateProfileMenuItemIndices.Input)]
[MixedRealityServiceProfile(typeof(IMixedRealityInputRecordingService))]
public class MixedRealityInputRecordingProfile : BaseMixedRealityProfile
{
[SerializeField]
[Tooltip("Minimum movement of hand joints to record a keyframe")]
private float jointPositionThreshold = 0.001f;
public float JointPositionThreshold => jointPositionThreshold;
[SerializeField]
[Tooltip("Minimum movement of hand joints to record a keyframe")]
private float jointRotationThreshold = 0.02f;
public float JointRotationThreshold => jointRotationThreshold;
[SerializeField]
[Tooltip("Minimum movement of the camera to record a keyframe")]
private float cameraPositionThreshold = 0.002f;
public float CameraPositionThreshold => cameraPositionThreshold;
[SerializeField]
[Tooltip("Minimum rotation angle of the camera to record a keyframe")]
private float cameraRotationThreshold = 0.02f;
public float CameraRotationThreshold => cameraRotationThreshold;
}
}
\ No newline at end of file
{
"items": [
{
"joint": "None",
"pose": {
"position": {
"x": -0.0470723882317543,
"y": -0.18403607606887818,
"z": -0.5408412218093872
},
"rotation": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
}
}
},
{
"joint": "Wrist",
"pose": {
"position": {
"x": 0.06179157271981239,
"y": -0.15333214402198792,
"z": -0.0469515398144722
},
"rotation": {
"x": -0.5501163005828857,
"y": -0.11712269484996796,
"z": 0.001836930401623249,
"w": 0.8265576958656311
}
}
},
{
"joint": "Palm",
"pose": {
"position": {
"x": 0.05801215022802353,
"y": -0.1058567613363266,
"z": -0.02556976117193699
},
"rotation": {
"x": -0.5501163005828857,
"y": -0.11712269484996796,
"z": 0.001836930401623249,
"w": 0.8265576958656311
}
}
},
{
"joint": "ThumbMetacarpalJoint",
"pose": {
"position": {
"x": 0.03695414960384369,
"y": -0.1407443881034851,
"z": -0.03328647091984749
},
"rotation": {
"x": -0.5855690240859985,
"y": -0.10429229587316513,
"z": 0.5890942811965942,
"w": 0.547493577003479
}
}
},
{
"joint": "ThumbProximalJoint",
"pose": {
"position": {
"x": 0.00045104348100721836,
"y": -0.11720659583806992,
"z": -0.01997363194823265
},
"rotation": {
"x": -0.5386121273040772,
"y": 0.04485885053873062,
"z": 0.5422580242156982,
"w": 0.6437124609947205
}
}
},
{
"joint": "ThumbDistalJoint",
"pose": {
"position": {
"x": -0.016296127811074258,
"y": -0.09359179437160492,
"z": -0.006718119606375694
},
"rotation": {
"x": -0.6040476560592651,
"y": -0.08891747146844864,
"z": 0.5752687454223633,
"w": 0.5448194742202759
}
}
},
{
"joint": "ThumbTip",
"pose": {
"position": {
"x": -0.03216664865612984,
"y": -0.08244754374027252,
"z": -0.001603197306394577
},
"rotation": {
"x": -0.6040476560592651,
"y": -0.08891747146844864,
"z": 0.5752687454223633,
"w": 0.5448194742202759
}
}
},
{
"joint": "IndexMetacarpal",
"pose": {
"position": {
"x": 0.04794362187385559,
"y": -0.13700048625469209,
"z": -0.03438100963830948
},
"rotation": {
"x": -0.534980297088623,
"y": -0.28449201583862307,
"z": -0.061086010187864307,
"w": 0.7931764721870422
}
}
},
{
"joint": "IndexKnuckle",
"pose": {
"position": {
"x": 0.023209279403090478,
"y": -0.08038382232189179,
"z": -0.017351558431982995
},
"rotation": {
"x": -0.599485456943512,
"y": -0.1474478840827942,
"z": 0.04840812832117081,
"w": 0.7852058410644531
}
}
},
{
"joint": "IndexMiddleJoint",
"pose": {
"position": {
"x": 0.009743190370500088,
"y": -0.03727291524410248,
"z": -0.006295463070273399
},
"rotation": {
"x": -0.6344203948974609,
"y": -0.08629350364208222,
"z": 0.11939872056245804,
"w": 0.7588865756988525
}
}
},
{
"joint": "IndexDistalJoint",
"pose": {
"position": {
"x": 0.0026917937211692335,
"y": -0.013759316876530648,
"z": -0.0017971978522837163
},
"rotation": {
"x": -0.6451734304428101,
"y": -0.12336783856153488,
"z": 0.00809548981487751,
"w": 0.7542511224746704
}
}
},
{
"joint": "IndexTip",
"pose": {
"position": {
"x": -0.0002534952946007252,
"y": 0.0007631087210029364,
"z": 0.0002575620310381055
},
"rotation": {
"x": -0.6451734304428101,
"y": -0.12336783856153488,
"z": 0.00809548981487751,
"w": 0.7542511224746704
}
}
},
{
"joint": "MiddleMetacarpal",
"pose": {
"position": {
"x": 0.056570135056972507,
"y": -0.13634957373142243,
"z": -0.03486650064587593
},
"rotation": {
"x": -0.6017327308654785,
"y": -0.1049300879240036,
"z": 0.008752312511205674,
"w": 0.7917264699935913
}
}
},
{
"joint": "MiddleKnuckle",
"pose": {
"position": {
"x": 0.045069482177495959,
"y": -0.07444917410612107,
"z": -0.018345370888710023
},
"rotation": {
"x": -0.5885983109474182,
"y": -0.10035836696624756,
"z": 0.025189023464918138,
"w": 0.8017893433570862
}
}
},
{
"joint": "MiddleMiddleJoint",
"pose": {
"position": {
"x": 0.035030756145715716,
"y": -0.025001518428325654,
"z": -0.0032290546223521234
},
"rotation": {
"x": -0.6631931662559509,
"y": -0.09005288034677506,
"z": -0.0027521485462784769,
"w": 0.7431085109710693
}
}
},
{
"joint": "MiddleDistalJoint",
"pose": {
"position": {
"x": 0.031546302139759067,
"y": 0.0013798222644254566,
"z": -0.0004363078624010086
},
"rotation": {
"x": -0.6468731164932251,
"y": -0.11953263729810715,
"z": -0.06937266886234284,
"w": 0.7504633665084839
}
}
},
{
"joint": "MiddleTip",
"pose": {
"position": {
"x": 0.030048875138163568,
"y": 0.017790958285331727,
"z": 0.0018172836862504483
},
"rotation": {
"x": -0.6468731164932251,
"y": -0.11953263729810715,
"z": -0.06937266886234284,
"w": 0.7504633665084839
}
}
},
{
"joint": "RingMetacarpal",
"pose": {
"position": {
"x": 0.06806596368551254,
"y": -0.13525664806365968,
"z": -0.034837257117033008
},
"rotation": {
"x": -0.5803540945053101,
"y": 0.014031633734703064,
"z": 0.05480925738811493,
"w": 0.8123965859413147
}
}
},
{
"joint": "RingKnuckle",
"pose": {
"position": {
"x": 0.06544187664985657,
"y": -0.07453925907611847,
"z": -0.013881120830774308
},
"rotation": {
"x": -0.6466344594955444,
"y": -0.03600946068763733,
"z": 0.02467469871044159,
"w": 0.7615609765052795
}
}
},
{
"joint": "RingMiddleJoint",
"pose": {
"position": {
"x": 0.06159381568431854,
"y": -0.03093438223004341,
"z": -0.006733019836246967
},
"rotation": {
"x": -0.6550348401069641,
"y": -0.06099399924278259,
"z": -0.04121965169906616,
"w": 0.7520787715911865
}
}
},
{
"joint": "RingDistalJoint",
"pose": {
"position": {
"x": 0.06070023775100708,
"y": -0.007464663125574589,
"z": -0.003544492181390524
},
"rotation": {
"x": -0.6712727546691895,
"y": -0.05777180939912796,
"z": -0.05727298930287361,
"w": 0.7370488047599793
}
}
},
{
"joint": "RingTip",
"pose": {
"position": {
"x": 0.060552775859832767,
"y": 0.010114867240190506,
"z": -0.0019072332652285696
},
"rotation": {
"x": -0.6712727546691895,
"y": -0.05777180939912796,
"z": -0.05727298930287361,
"w": 0.7370488047599793
}
}
},
{
"joint": "PinkyMetacarpal",
"pose": {
"position": {
"x": 0.07710164040327072,
"y": -0.13650110363960267,
"z": -0.032643478363752368
},
"rotation": {
"x": -0.5344982147216797,
"y": 0.1545339822769165,
"z": 0.10820292681455612,
"w": 0.8238464593887329
}
}
},
{
"joint": "PinkyKnuckle",
"pose": {
"position": {
"x": 0.08530370891094208,
"y": -0.08254323154687882,
"z": -0.010162543505430222
},
"rotation": {
"x": -0.6702333688735962,
"y": 0.05704934149980545,
"z": 0.006686835549771786,
"w": 0.7399358749389648
}
}
},
{
"joint": "PinkyMiddleJoint",
"pose": {
"position": {
"x": 0.08779342472553253,
"y": -0.049793362617492679,
"z": -0.0070251524448394779
},
"rotation": {
"x": -0.6393072605133057,
"y": 0.030266048386693,
"z": -0.15569603443145753,
"w": 0.7524937987327576
}
}
},
{
"joint": "PinkyDistalJoint",
"pose": {
"position": {
"x": 0.09219621121883393,
"y": -0.03264733776450157,
"z": -0.0037694787606596948
},
"rotation": {
"x": -0.6555882692337036,
"y": -0.0018634665757417679,
"z": -0.09289215505123139,
"w": 0.7497090101242065
}
}
},
{
"joint": "PinkyTip",
"pose": {
"position": {
"x": 0.09392204880714417,
"y": -0.018381092697381974,
"z": -0.0017222119495272637
},
"rotation": {
"x": -0.6555882692337036,
"y": -0.0018634665757417679,
"z": -0.09289215505123139,
"w": 0.7497090101242065
}
}
}
]
}
\ No newline at end of file
{
"items": [
{
"joint": "None",
"pose": {
"position": {
"x": -0.08690944314002991,
"y": 0.013536587357521057,
"z": -0.3781388998031616
},
"rotation": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
}
}
},
{
"joint": "Wrist",
"pose": {
"position": {
"x": 0.059647563844919208,
"y": -0.018170714378356935,
"z": -0.07320141047239304
},
"rotation": {
"x": -0.44069746136665347,
"y": -0.3151600956916809,
"z": -0.029152734205126764,
"w": 0.8398429155349731
}
}
},
{
"joint": "Palm",
"pose": {
"position": {
"x": 0.040150947868824008,
"y": 0.022433746606111528,
"z": -0.04928050562739372
},
"rotation": {
"x": -0.44069746136665347,
"y": -0.3151600956916809,
"z": -0.029152734205126764,
"w": 0.8398429155349731
}
}
},
{
"joint": "ThumbMetacarpalJoint",
"pose": {
"position": {
"x": 0.033823080360889438,
"y": -0.014000600203871727,
"z": -0.06483504176139832
},
"rotation": {
"x": 0.46251192688941958,
"y": 0.15892137587070466,
"z": -0.748396635055542,
"w": -0.44902268052101138
}
}
},
{
"joint": "ThumbProximalJoint",
"pose": {
"position": {
"x": -0.0048112208023667339,
"y": -0.005827075336128473,
"z": -0.04063580185174942
},
"rotation": {
"x": 0.32614850997924807,
"y": -0.017511412501335145,
"z": -0.7735356688499451,
"w": -0.5439797639846802
}
}
},
{
"joint": "ThumbDistalJoint",
"pose": {
"position": {
"x": -0.02188277430832386,
"y": 0.0075818500481545929,
"z": -0.01290540024638176
},
"rotation": {
"x": 0.22856087982654572,
"y": -0.09300848096609116,
"z": -0.7769821286201477,
"w": -0.5795565247535706
}
}
},
{
"joint": "ThumbTip",
"pose": {
"position": {
"x": -0.026505667716264726,
"y": 0.015197398141026497,
"z": 0.0034610535949468614
},
"rotation": {
"x": 0.22856087982654572,
"y": -0.09300848096609116,
"z": -0.7769821286201477,
"w": -0.5795565247535706
}
}
},
{
"joint": "IndexMetacarpal",
"pose": {
"position": {
"x": 0.04238410294055939,
"y": -0.007463002577424049,
"z": -0.06319385766983032
},
"rotation": {
"x": -0.420803427696228,
"y": -0.44982725381851199,
"z": -0.04907778277993202,
"w": 0.7862387895584106
}
}
},
{
"joint": "IndexKnuckle",
"pose": {
"position": {
"x": -0.0008817678317427635,
"y": 0.03838954120874405,
"z": -0.04752813279628754
},
"rotation": {
"x": 0.004830620251595974,
"y": 0.18448397517204286,
"z": -0.1560613363981247,
"w": -0.9703620672225952
}
}
},
{
"joint": "IndexMiddleJoint",
"pose": {
"position": {
"x": -0.014839660376310349,
"y": 0.03651837632060051,
"z": -0.01135229505598545
},
"rotation": {
"x": -0.5098936557769775,
"y": 0.03039226494729519,
"z": -0.30394697189331057,
"w": -0.8042332530021668
}
}
},
{
"joint": "IndexDistalJoint",
"pose": {
"position": {
"x": -0.008270945399999619,
"y": 0.015406630001962185,
"z": 0.0006891884841024876
},
"rotation": {
"x": -0.7222777009010315,
"y": -0.08202659338712692,
"z": -0.2391108274459839,
"w": -0.6440979242324829
}
}
},
{
"joint": "IndexTip",
"pose": {
"position": {
"x": -0.0009594520088285208,
"y": 0.000933439121581614,
"z": -0.00021468542399816215
},
"rotation": {
"x": -0.7222777009010315,
"y": -0.08202659338712692,
"z": -0.2391108274459839,
"w": -0.6440979242324829
}
}
},
{
"joint": "MiddleMetacarpal",
"pose": {
"position": {
"x": 0.04958740621805191,
"y": -0.004707379266619682,
"z": -0.06129273772239685
},
"rotation": {
"x": -0.5128890872001648,
"y": -0.29369285702705386,
"z": 0.018453821539878846,
"w": 0.8064419627189636
}
}
},
{
"joint": "MiddleKnuckle",
"pose": {
"position": {
"x": 0.020074930042028428,
"y": 0.04420189931988716,
"z": -0.04323747381567955
},
"rotation": {
"x": -0.07308150827884674,
"y": 0.17278942465782166,
"z": -0.10241489112377167,
"w": -0.9769001603126526
}
}
},
{
"joint": "MiddleMiddleJoint",
"pose": {
"position": {
"x": 0.005748542491346598,
"y": 0.0362907275557518,
"z": -0.001959702931344509
},
"rotation": {
"x": -0.7482351660728455,
"y": 0.06403420120477677,
"z": -0.2061866670846939,
"w": -0.6274414658546448
}
}
},
{
"joint": "MiddleDistalJoint",
"pose": {
"position": {
"x": 0.012452101334929467,
"y": 0.007901951670646668,
"z": -0.0057104239240288738
},
"rotation": {
"x": -0.9225407838821411,
"y": -0.07818678766489029,
"z": -0.1428528130054474,
"w": -0.3514384627342224
}
}
},
{
"joint": "MiddleTip",
"pose": {
"position": {
"x": 0.01802952028810978,
"y": -0.003061514813452959,
"z": -0.01820256933569908
},
"rotation": {
"x": -0.9225407838821411,
"y": -0.07818678766489029,
"z": -0.1428528130054474,
"w": -0.3514384627342224
}
}
},
{
"joint": "RingMetacarpal",
"pose": {
"position": {
"x": 0.05912885442376137,
"y": -0.0009383354336023331,
"z": -0.05809984356164932
},
"rotation": {
"x": -0.49521127343177798,
"y": -0.17924758791923524,
"z": 0.07874160259962082,
"w": 0.846425473690033
}
}
},
{
"joint": "RingKnuckle",
"pose": {
"position": {
"x": 0.038666337728500369,
"y": 0.04252086579799652,
"z": -0.03421220928430557
},
"rotation": {
"x": -0.1513676941394806,
"y": 0.15960678458213807,
"z": -0.05129222199320793,
"w": -0.9741657376289368
}
}
},
{
"joint": "RingMiddleJoint",
"pose": {
"position": {
"x": 0.02693704515695572,
"y": 0.030163494870066644,
"z": 0.0016453623538836837
},
"rotation": {
"x": -0.8552912473678589,
"y": 0.0920121893286705,
"z": -0.11032526195049286,
"w": -0.4979609251022339
}
}
},
{
"joint": "RingDistalJoint",
"pose": {
"position": {
"x": 0.029263043776154519,
"y": 0.009234108030796051,
"z": -0.009864533320069313
},
"rotation": {
"x": -0.9685380458831787,
"y": -0.018125316128134729,
"z": -0.094183549284935,
"w": -0.23075833916664124
}
}
},
{
"joint": "RingTip",
"pose": {
"position": {
"x": 0.032915160059928897,
"y": 0.0007288604974746704,
"z": -0.02667597308754921
},
"rotation": {
"x": -0.9685380458831787,
"y": -0.018125316128134729,
"z": -0.094183549284935,
"w": -0.23075833916664124
}
}
},
{
"joint": "PinkyMetacarpal",
"pose": {
"position": {
"x": 0.0675557404756546,
"y": -0.0004099104553461075,
"z": -0.05376683175563812
},
"rotation": {
"x": -0.44121748208999636,
"y": -0.05341072380542755,
"z": 0.14569664001464845,
"w": 0.8838818073272705
}
}
},
{
"joint": "PinkyKnuckle",
"pose": {
"position": {
"x": 0.05575947463512421,
"y": 0.04002845287322998,
"z": -0.02176406979560852
},
"rotation": {
"x": -0.2122899889945984,
"y": 0.1802181601524353,
"z": 0.03122050315141678,
"w": -0.959945559501648
}
}
},
{
"joint": "PinkyMiddleJoint",
"pose": {
"position": {
"x": 0.046450983732938769,
"y": 0.029760107398033143,
"z": 0.0001273825764656067
},
"rotation": {
"x": -0.8192430138587952,
"y": 0.16303858160972596,
"z": -0.0602981373667717,
"w": -0.5465834140777588
}
}
},
{
"joint": "PinkyDistalJoint",
"pose": {
"position": {
"x": 0.044868819415569308,
"y": 0.011532457545399666,
"z": -0.007741663604974747
},
"rotation": {
"x": -0.9710148572921753,
"y": 0.04234015569090843,
"z": 0.042903631925582889,
"w": -0.23259779810905457
}
}
},
{
"joint": "PinkyTip",
"pose": {
"position": {
"x": 0.04328276216983795,
"y": 0.004625056870281696,
"z": -0.0214386023581028
},
"rotation": {
"x": -0.9710148572921753,
"y": 0.04234015569090843,
"z": 0.042903631925582889,
"w": -0.23259779810905457
}
}
}
]
}
\ No newline at end of file
{
"items": [
{
"joint": "None",
"pose": {
"position": {
"x": -0.0780251994729042,
"y": -0.05990780144929886,
"z": -0.3291178047657013
},
"rotation": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
}
}
},
{
"joint": "Wrist",
"pose": {
"position": {
"x": 0.07397598028182984,
"y": -0.1239677220582962,
"z": -0.05636374652385712
},
"rotation": {
"x": -0.5306746959686279,
"y": -0.24036270380020142,
"z": -0.0010364949703216553,
"w": 0.8126773834228516
}
}
},
{
"joint": "Palm",
"pose": {
"position": {
"x": 0.06148417666554451,
"y": -0.08249785006046295,
"z": -0.04003134369850159
},
"rotation": {
"x": -0.5306746959686279,
"y": -0.24036270380020142,
"z": -0.0010364949703216553,
"w": 0.8126773834228516
}
}
},
{
"joint": "ThumbMetacarpalJoint",
"pose": {
"position": {
"x": 0.05004027485847473,
"y": -0.1168040931224823,
"z": -0.046657364815473559
},
"rotation": {
"x": -0.5606539249420166,
"y": -0.098196841776371,
"z": 0.670694887638092,
"w": 0.4761941432952881
}
}
},
{
"joint": "ThumbProximalJoint",
"pose": {
"position": {
"x": 0.014790681190788746,
"y": -0.1000247374176979,
"z": -0.031946491450071338
},
"rotation": {
"x": -0.5155644416809082,
"y": -0.0010041594505310059,
"z": 0.6619959473609924,
"w": 0.5445378422737122
}
}
},
{
"joint": "ThumbDistalJoint",
"pose": {
"position": {
"x": -0.0062080565840005878,
"y": -0.0828109011054039,
"z": -0.01753186620771885
},
"rotation": {
"x": -0.5490170121192932,
"y": -0.08343470841646195,
"z": 0.6728134751319885,
"w": 0.48939600586891177
}
}
},
{
"joint": "ThumbTip",
"pose": {
"position": {
"x": -0.02095535211265087,
"y": -0.07516473531723023,
"z": -0.010627731680870057
},
"rotation": {
"x": -0.5490170121192932,
"y": -0.08343470841646195,
"z": 0.6728134751319885,
"w": 0.48939600586891177
}
}
},
{
"joint": "IndexMetacarpal",
"pose": {
"position": {
"x": 0.058891069144010547,
"y": -0.11150021106004715,
"z": -0.047359079122543338
},
"rotation": {
"x": -0.5242606997489929,
"y": -0.3638727068901062,
"z": 0.0003723353147506714,
"w": 0.7699006795883179
}
}
},
{
"joint": "IndexKnuckle",
"pose": {
"position": {
"x": 0.025922514498233796,
"y": -0.06404880434274674,
"z": -0.036451879888772967
},
"rotation": {
"x": -0.5153175592422485,
"y": -0.13684964179992677,
"z": 0.0975230410695076,
"w": 0.840372622013092
}
}
},
{
"joint": "IndexMiddleJoint",
"pose": {
"position": {
"x": 0.012116845697164536,
"y": -0.028988275676965715,
"z": -0.0184309259057045
},
"rotation": {
"x": -0.5083625912666321,
"y": -0.08690404891967774,
"z": 0.1772240400314331,
"w": 0.8382880687713623
}
}
},
{
"joint": "IndexDistalJoint",
"pose": {
"position": {
"x": 0.0047910469584167,
"y": -0.01052884478121996,
"z": -0.007911253720521927
},
"rotation": {
"x": -0.4986042380332947,
"y": -0.10437075048685074,
"z": 0.07316453754901886,
"w": 0.8577484488487244
}
}
},
{
"joint": "IndexTip",
"pose": {
"position": {
"x": 0.0011067038867622614,
"y": 0.0017288230592384935,
"z": -0.0008905145805329084
},
"rotation": {
"x": -0.4986042380332947,
"y": -0.10437075048685074,
"z": 0.07316453754901886,
"w": 0.8577484488487244
}
}
},
{
"joint": "MiddleMetacarpal",
"pose": {
"position": {
"x": 0.06627093255519867,
"y": -0.1093648374080658,
"z": -0.04731958359479904
},
"rotation": {
"x": -0.5980523824691773,
"y": -0.19373856484889985,
"z": 0.061999037861824039,
"w": 0.7752125859260559
}
}
},
{
"joint": "MiddleKnuckle",
"pose": {
"position": {
"x": 0.04579643905162811,
"y": -0.05998942255973816,
"z": -0.035861626267433169
},
"rotation": {
"x": 0.07707051932811737,
"y": 0.09493987262248993,
"z": -0.06967925280332566,
"w": -0.9900561571121216
}
}
},
{
"joint": "MiddleMiddleJoint",
"pose": {
"position": {
"x": 0.03759719431400299,
"y": -0.054239436984062198,
"z": 0.004158938303589821
},
"rotation": {
"x": -0.5364435911178589,
"y": 0.035090312361717227,
"z": -0.1292860358953476,
"w": -0.8333183526992798
}
}
},
{
"joint": "MiddleDistalJoint",
"pose": {
"position": {
"x": 0.039636775851249698,
"y": -0.07725092768669129,
"z": 0.014920881018042565
},
"rotation": {
"x": -0.7898687720298767,
"y": -0.05351902171969414,
"z": -0.050689004361629489,
"w": -0.6095116138458252
}
}
},
{
"joint": "MiddleTip",
"pose": {
"position": {
"x": 0.04198702797293663,
"y": -0.09284322708845139,
"z": 0.010831182822585106
},
"rotation": {
"x": -0.7898687720298767,
"y": -0.05351902171969414,
"z": -0.050689004361629489,
"w": -0.6095116138458252
}
}
},
{
"joint": "RingMetacarpal",
"pose": {
"position": {
"x": 0.07596171647310257,
"y": -0.10612225532531738,
"z": -0.04667811840772629
},
"rotation": {
"x": -0.5675100088119507,
"y": -0.08019199222326279,
"z": 0.10617346316576004,
"w": 0.8125444054603577
}
}
},
{
"joint": "RingKnuckle",
"pose": {
"position": {
"x": 0.06377431005239487,
"y": -0.06213853880763054,
"z": -0.030012063682079316
},
"rotation": {
"x": -0.03975258022546768,
"y": 0.09559198468923569,
"z": -0.024301081895828248,
"w": -0.9943375587463379
}
}
},
{
"joint": "RingMiddleJoint",
"pose": {
"position": {
"x": 0.056988153606653216,
"y": -0.06515654176473618,
"z": 0.005276134237647057
},
"rotation": {
"x": -0.7588484287261963,
"y": 0.0701710507273674,
"z": -0.045488141477108,
"w": -0.6459669470787048
}
}
},
{
"joint": "RingDistalJoint",
"pose": {
"position": {
"x": 0.05652663856744766,
"y": -0.08611556887626648,
"z": 0.0018516592681407929
},
"rotation": {
"x": -0.9129649996757507,
"y": -0.005179869011044502,
"z": -0.007560268044471741,
"w": -0.408629447221756
}
}
},
{
"joint": "RingTip",
"pose": {
"position": {
"x": 0.056841082870960239,
"y": -0.09943331778049469,
"z": -0.010053567588329316
},
"rotation": {
"x": -0.9129649996757507,
"y": -0.005179869011044502,
"z": -0.007560268044471741,
"w": -0.408629447221756
}
}
},
{
"joint": "PinkyMetacarpal",
"pose": {
"position": {
"x": 0.08423660695552826,
"y": -0.10567539930343628,
"z": -0.044220417737960818
},
"rotation": {
"x": -0.5077040791511536,
"y": 0.04072892665863037,
"z": 0.1517779380083084,
"w": 0.8470779657363892
}
}
},
{
"joint": "PinkyKnuckle",
"pose": {
"position": {
"x": 0.0801829993724823,
"y": -0.06412312388420105,
"z": -0.021305494010448457
},
"rotation": {
"x": -0.08299122005701065,
"y": 0.1249239444732666,
"z": 0.04155319184064865,
"w": -0.9878235459327698
}
}
},
{
"joint": "PinkyMiddleJoint",
"pose": {
"position": {
"x": 0.07411551475524903,
"y": -0.0677957683801651,
"z": 0.0015332028269767762
},
"rotation": {
"x": -0.715654730796814,
"y": 0.1371033787727356,
"z": 0.001321159303188324,
"w": -0.6849520206451416
}
}
},
{
"joint": "PinkyDistalJoint",
"pose": {
"position": {
"x": 0.07075578719377518,
"y": -0.08515383303165436,
"z": 0.00044181570410728455
},
"rotation": {
"x": -0.8999292254447937,
"y": 0.06855495274066925,
"z": 0.11455988883972168,
"w": -0.41592133045196535
}
}
},
{
"joint": "PinkyTip",
"pose": {
"position": {
"x": 0.0670883059501648,
"y": -0.09537018835544586,
"z": -0.008319821208715439
},
"rotation": {
"x": -0.8999292254447937,
"y": 0.06855495274066925,
"z": 0.11455988883972168,
"w": -0.41592133045196535
}
}
}
]
}
\ No newline at end of file
{
"items": [
{
"joint": "None",
"pose": {
"position": {
"x": -0.0681008753599599,
"y": -0.023189845320302993,
"z": -0.32335868163499981
},
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"w": 0
}
}
},
{
"joint": "Wrist",
"pose": {
"position": {
"x": 0.083900304394774139,
"y": -0.087249765929300338,
"z": -0.050604623393155634
},
"rotation": {
"x": -0.53067469596862793,
"y": -0.24036270380020142,
"z": -0.0010364949703216553,
"w": 0.81267738342285156
}
}
},
{
"joint": "Palm",
"pose": {
"position": {
"x": 0.071408500778488815,
"y": -0.045779893931467086,
"z": -0.034272220567800105
},
"rotation": {
"x": -0.53067469596862793,
"y": -0.24036270380020142,
"z": -0.0010364949703216553,
"w": 0.81267738342285156
}
}
},
{
"joint": "ThumbMetacarpalJoint",
"pose": {
"position": {
"x": 0.059964598971419036,
"y": -0.080086136993486434,
"z": -0.040898241684772074
},
"rotation": {
"x": -0.5606539249420166,
"y": -0.098196841776371,
"z": 0.670694887638092,
"w": 0.47619414329528809
}
}
},
{
"joint": "ThumbProximalJoint",
"pose": {
"position": {
"x": 0.024715005303733051,
"y": -0.063306781288702041,
"z": -0.026187368319369853
},
"rotation": {
"x": -0.5155644416809082,
"y": -0.0010041594505310059,
"z": 0.66199594736099243,
"w": 0.54453784227371216
}
}
},
{
"joint": "ThumbDistalJoint",
"pose": {
"position": {
"x": 0.0037162675289437175,
"y": -0.046092944976408035,
"z": -0.011772743077017367
},
"rotation": {
"x": -0.54901701211929321,
"y": -0.083434708416461945,
"z": 0.67281347513198853,
"w": 0.48939600586891174
}
}
},
{
"joint": "ThumbTip",
"pose": {
"position": {
"x": -0.011031027999706566,
"y": -0.038446779188234359,
"z": -0.0048686085501685739
},
"rotation": {
"x": -0.54901701211929321,
"y": -0.083434708416461945,
"z": 0.67281347513198853,
"w": 0.48939600586891174
}
}
},
{
"joint": "IndexMetacarpal",
"pose": {
"position": {
"x": 0.068815393256954849,
"y": -0.074782254931051284,
"z": -0.041599955991841853
},
"rotation": {
"x": -0.52426069974899292,
"y": -0.3638727068901062,
"z": 0.00037233531475067139,
"w": 0.76990067958831787
}
}
},
{
"joint": "IndexKnuckle",
"pose": {
"position": {
"x": 0.0358468386111781,
"y": -0.027330848213750869,
"z": -0.030692756758071482
},
"rotation": {
"x": -0.51531755924224854,
"y": -0.13684964179992676,
"z": 0.0975230410695076,
"w": 0.840372622013092
}
}
},
{
"joint": "IndexMiddleJoint",
"pose": {
"position": {
"x": 0.02204116981010884,
"y": 0.0077296804520301521,
"z": -0.012671802775003016
},
"rotation": {
"x": -0.50836259126663208,
"y": -0.086904048919677734,
"z": 0.17722404003143311,
"w": 0.8382880687713623
}
}
},
{
"joint": "IndexDistalJoint",
"pose": {
"position": {
"x": 0.014715371071361005,
"y": 0.026189111347775906,
"z": -0.0021521305898204446
},
"rotation": {
"x": -0.49860423803329468,
"y": -0.10437075048685074,
"z": 0.07316453754901886,
"w": 0.85774844884872437
}
}
},
{
"joint": "IndexTip",
"pose": {
"position": {
"x": 0.011031027999706566,
"y": 0.038446779188234359,
"z": 0.0048686085501685739
},
"rotation": {
"x": -0.49860423803329468,
"y": -0.10437075048685074,
"z": 0.07316453754901886,
"w": 0.85774844884872437
}
}
},
{
"joint": "MiddleMetacarpal",
"pose": {
"position": {
"x": 0.076195256668142974,
"y": -0.07264688127906993,
"z": -0.041560460464097559
},
"rotation": {
"x": -0.59805238246917725,
"y": -0.19373856484889984,
"z": 0.061999037861824036,
"w": 0.77521258592605591
}
}
},
{
"joint": "MiddleKnuckle",
"pose": {
"position": {
"x": 0.055720763164572418,
"y": -0.023271466430742294,
"z": -0.030102503136731684
},
"rotation": {
"x": 0.077070519328117371,
"y": 0.094939872622489929,
"z": -0.069679252803325653,
"w": -0.99005615711212158
}
}
},
{
"joint": "MiddleMiddleJoint",
"pose": {
"position": {
"x": 0.047521518426947296,
"y": -0.017521480855066329,
"z": 0.0099180614342913032
},
"rotation": {
"x": -0.53644359111785889,
"y": 0.035090312361717224,
"z": -0.1292860358953476,
"w": -0.83331835269927979
}
}
},
{
"joint": "MiddleDistalJoint",
"pose": {
"position": {
"x": 0.049561099964194,
"y": -0.040532971557695419,
"z": 0.020680004148744047
},
"rotation": {
"x": -0.78986877202987671,
"y": -0.053519021719694138,
"z": -0.050689004361629486,
"w": -0.6095116138458252
}
}
},
{
"joint": "MiddleTip",
"pose": {
"position": {
"x": 0.051911352085880935,
"y": -0.05612527095945552,
"z": 0.016590305953286588
},
"rotation": {
"x": -0.78986877202987671,
"y": -0.053519021719694138,
"z": -0.050689004361629486,
"w": -0.6095116138458252
}
}
},
{
"joint": "RingMetacarpal",
"pose": {
"position": {
"x": 0.085886040586046875,
"y": -0.069404299196321517,
"z": -0.040918995277024806
},
"rotation": {
"x": -0.56751000881195068,
"y": -0.080191992223262787,
"z": 0.10617346316576004,
"w": 0.81254440546035767
}
}
},
{
"joint": "RingKnuckle",
"pose": {
"position": {
"x": 0.073698634165339172,
"y": -0.025420582678634673,
"z": -0.024252940551377833
},
"rotation": {
"x": -0.039752580225467682,
"y": 0.095591984689235687,
"z": -0.024301081895828247,
"w": -0.99433755874633789
}
}
},
{
"joint": "RingMiddleJoint",
"pose": {
"position": {
"x": 0.066912477719597518,
"y": -0.02843858563574031,
"z": 0.011035257368348539
},
"rotation": {
"x": -0.75884842872619629,
"y": 0.0701710507273674,
"z": -0.045488141477108,
"w": -0.64596694707870483
}
}
},
{
"joint": "RingDistalJoint",
"pose": {
"position": {
"x": 0.066450962680391967,
"y": -0.049397612747270614,
"z": 0.0076107823988422751
},
"rotation": {
"x": -0.91296499967575073,
"y": -0.0051798690110445023,
"z": -0.0075602680444717407,
"w": -0.408629447221756
}
}
},
{
"joint": "RingTip",
"pose": {
"position": {
"x": 0.066765406983904541,
"y": -0.062715361651498824,
"z": -0.0042944444576278329
},
"rotation": {
"x": -0.91296499967575073,
"y": -0.0051798690110445023,
"z": -0.0075602680444717407,
"w": -0.408629447221756
}
}
},
{
"joint": "PinkyMetacarpal",
"pose": {
"position": {
"x": 0.094160931068472564,
"y": -0.068957443174440414,
"z": -0.038461294607259333
},
"rotation": {
"x": -0.50770407915115356,
"y": 0.040728926658630371,
"z": 0.15177793800830841,
"w": 0.84707796573638916
}
}
},
{
"joint": "PinkyKnuckle",
"pose": {
"position": {
"x": 0.0901073234854266,
"y": -0.027405167755205184,
"z": -0.015546370879746974
},
"rotation": {
"x": -0.082991220057010651,
"y": 0.1249239444732666,
"z": 0.041553191840648651,
"w": -0.98782354593276978
}
}
},
{
"joint": "PinkyMiddleJoint",
"pose": {
"position": {
"x": 0.084039838868193328,
"y": -0.031077812251169235,
"z": 0.0072923259576782584
},
"rotation": {
"x": -0.715654730796814,
"y": 0.1371033787727356,
"z": 0.001321159303188324,
"w": -0.6849520206451416
}
}
},
{
"joint": "PinkyDistalJoint",
"pose": {
"position": {
"x": 0.080680111306719482,
"y": -0.048435876902658492,
"z": 0.0062009388348087668
},
"rotation": {
"x": -0.8999292254447937,
"y": 0.06855495274066925,
"z": 0.11455988883972168,
"w": -0.41592133045196533
}
}
},
{
"joint": "PinkyTip",
"pose": {
"position": {
"x": 0.0770126300631091,
"y": -0.058652232226449996,
"z": -0.0025606980780139565
},
"rotation": {
"x": -0.8999292254447937,
"y": 0.06855495274066925,
"z": 0.11455988883972168,
"w": -0.41592133045196533
}
}
}
]
}
\ No newline at end of file
{
"items": [
{
"joint": "None",
"pose": {
"position": {
"x": -0.055795830441638827,
"y": -0.050494263647124171,
"z": -0.31160801439546049
},
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"w": 0
}
}
},
{
"joint": "Wrist",
"pose": {
"position": {
"x": 0.094970445381477475,
"y": -0.071920572547242045,
"z": -0.043240679195150733
},
"rotation": {
"x": -0.57126933336257935,
"y": -0.40886738896369934,
"z": -0.11714609712362289,
"w": 0.70179426670074463
}
}
},
{
"joint": "Palm",
"pose": {
"position": {
"x": 0.078446935163810849,
"y": -0.025236195651814342,
"z": -0.038608604809269309
},
"rotation": {
"x": -0.57126933336257935,
"y": -0.40886738896369934,
"z": -0.11714609712362289,
"w": 0.70179426670074463
}
}
},
{
"joint": "ThumbMetacarpalJoint",
"pose": {
"position": {
"x": 0.0704388425219804,
"y": -0.063463031081482768,
"z": -0.0446559542324394
},
"rotation": {
"x": 0.59957319498062134,
"y": 0.056990712881088257,
"z": -0.661469042301178,
"w": -0.44784826040267944
}
}
},
{
"joint": "ThumbProximalJoint",
"pose": {
"position": {
"x": 0.030931103276088834,
"y": -0.041895947186276317,
"z": -0.03173214360140264
},
"rotation": {
"x": 0.48144450783729553,
"y": -0.077987000346183777,
"z": -0.66726517677307129,
"w": -0.56365346908569336
}
}
},
{
"joint": "ThumbDistalJoint",
"pose": {
"position": {
"x": 0.011377685004845262,
"y": -0.0191096484195441,
"z": -0.013179950183257461
},
"rotation": {
"x": 0.48974254727363586,
"y": -0.04340343177318573,
"z": -0.678149402141571,
"w": -0.54698729515075684
}
}
},
{
"joint": "ThumbTip",
"pose": {
"position": {
"x": -0.00054007698781788349,
"y": -0.0076306506525725126,
"z": -0.0031634948682039976
},
"rotation": {
"x": 0.48974254727363586,
"y": -0.04340343177318573,
"z": -0.678149402141571,
"w": -0.54698729515075684
}
}
},
{
"joint": "IndexMetacarpal",
"pose": {
"position": {
"x": 0.079071666346862912,
"y": -0.057821920840069652,
"z": -0.042442125966772437
},
"rotation": {
"x": -0.54839807748794556,
"y": -0.5408281683921814,
"z": -0.10956580191850662,
"w": 0.6282992959022522
}
}
},
{
"joint": "IndexKnuckle",
"pose": {
"position": {
"x": 0.042313426034525037,
"y": -0.0047555731143802404,
"z": -0.054694456746801734
},
"rotation": {
"x": 0.33803752064704895,
"y": 0.34615525603294373,
"z": -0.075356766581535339,
"w": -0.87192034721374512
}
}
},
{
"joint": "IndexMiddleJoint",
"pose": {
"position": {
"x": 0.015641395235434175,
"y": 0.0171373023185879,
"z": -0.033025106182321906
},
"rotation": {
"x": 0.011520777828991413,
"y": 0.23532292246818543,
"z": -0.26723867654800415,
"w": -0.93442928791046143
}
}
},
{
"joint": "IndexDistalJoint",
"pose": {
"position": {
"x": 0.0043656446505337954,
"y": 0.014503426151350141,
"z": -0.01055326103232801
},
"rotation": {
"x": -0.18848013877868652,
"y": 0.1752738356590271,
"z": -0.23216751217842102,
"w": -0.938201367855072
}
}
},
{
"joint": "IndexTip",
"pose": {
"position": {
"x": 0.0011067038867622614,
"y": 0.0017288230592384935,
"z": -0.0008905145805329084
},
"rotation": {
"x": -0.4986042380332947,
"y": -0.10437075048685074,
"z": 0.07316453754901886,
"w": 0.8577484488487244
}
}
},
{
"joint": "MiddleMetacarpal",
"pose": {
"position": {
"x": 0.085573996650055051,
"y": -0.055481004295870662,
"z": -0.039088224759325385
},
"rotation": {
"x": -0.64046329259872437,
"y": -0.373137503862381,
"z": -0.082113638520240784,
"w": 0.66620767116546631
}
}
},
{
"joint": "MiddleKnuckle",
"pose": {
"position": {
"x": 0.061702992068603635,
"y": 0.00021764193661510944,
"z": -0.04510785429738462
},
"rotation": {
"x": 0.1714177131652832,
"y": 0.3295632004737854,
"z": -0.056909773498773575,
"w": -0.92670679092407227
}
}
},
{
"joint": "MiddleMiddleJoint",
"pose": {
"position": {
"x": 0.033647007541731,
"y": 0.01268923026509583,
"z": -0.012882571434602141
},
"rotation": {
"x": -0.52955335378646851,
"y": 0.20503298938274384,
"z": -0.28541553020477295,
"w": -0.77215194702148438
}
}
},
{
"joint": "MiddleDistalJoint",
"pose": {
"position": {
"x": 0.033218997763469815,
"y": -0.014666470466181636,
"z": -0.00248397677205503
},
"rotation": {
"x": -0.80611693859100342,
"y": 0.037188127636909485,
"z": -0.25478187203407288,
"w": -0.5337793231010437
}
}
},
{
"joint": "MiddleTip",
"pose": {
"position": {
"x": 0.039724528091028333,
"y": -0.030166196404024959,
"z": -0.0077722163405269384
},
"rotation": {
"x": -0.80611693859100342,
"y": 0.037188127636909485,
"z": -0.25478187203407288,
"w": -0.5337793231010437
}
}
},
{
"joint": "RingMetacarpal",
"pose": {
"position": {
"x": 0.094046983169391751,
"y": -0.05198403331451118,
"z": -0.034078513970598578
},
"rotation": {
"x": -0.63099503517150879,
"y": -0.25767973065376282,
"z": -0.040025528520345688,
"w": 0.73064666986465454
}
}
},
{
"joint": "RingKnuckle",
"pose": {
"position": {
"x": 0.076233054744079709,
"y": -0.00047668232582509518,
"z": -0.030205076327547431
},
"rotation": {
"x": 0.061521425843238831,
"y": 0.32744783163070679,
"z": -0.026347285136580467,
"w": -0.94250476360321045
}
}
},
{
"joint": "RingMiddleJoint",
"pose": {
"position": {
"x": 0.051643508719280362,
"y": 0.003435472259297967,
"z": 0.00062574469484388828
},
"rotation": {
"x": -0.7006344199180603,
"y": 0.22492779791355133,
"z": -0.23193849623203278,
"w": -0.63627457618713379
}
}
},
{
"joint": "RingDistalJoint",
"pose": {
"position": {
"x": 0.0525671869982034,
"y": -0.0204183969181031,
"z": -0.0013549791183322668
},
"rotation": {
"x": -0.88947725296020508,
"y": 0.068172931671142578,
"z": -0.23703967034816742,
"w": -0.38538727164268494
}
}
},
{
"joint": "RingTip",
"pose": {
"position": {
"x": 0.0596969083417207,
"y": -0.034293188480660319,
"z": -0.0127856710460037
},
"rotation": {
"x": -0.88947725296020508,
"y": 0.068172931671142578,
"z": -0.23703967034816742,
"w": -0.38538727164268494
}
}
},
{
"joint": "PinkyMetacarpal",
"pose": {
"position": {
"x": 0.10081055318005383,
"y": -0.050989105133339763,
"z": -0.027507969876751304
},
"rotation": {
"x": -0.58761417865753174,
"y": -0.13647006452083588,
"z": 0.010980717837810516,
"w": 0.79747408628463745
}
}
},
{
"joint": "PinkyKnuckle",
"pose": {
"position": {
"x": 0.088435876416042447,
"y": -0.00084916572086513042,
"z": -0.01290042488835752
},
"rotation": {
"x": -0.015533886849880219,
"y": 0.36132562160491943,
"z": 0.044756371527910233,
"w": -0.9312441349029541
}
}
},
{
"joint": "PinkyMiddleJoint",
"pose": {
"position": {
"x": 0.071086059557273984,
"y": -0.000761339208111167,
"z": 0.0060971176717430353
},
"rotation": {
"x": -0.6863744854927063,
"y": 0.30161058902740479,
"z": -0.18428879976272583,
"w": -0.63567912578582764
}
}
},
{
"joint": "PinkyDistalJoint",
"pose": {
"position": {
"x": 0.068500611232593656,
"y": -0.02024311083368957,
"z": 0.0036448633763939142
},
"rotation": {
"x": -0.93071597814559937,
"y": 0.13045383989810944,
"z": -0.11257931590080261,
"w": -0.32351988554000854
}
}
},
{
"joint": "PinkyTip",
"pose": {
"position": {
"x": 0.070451776729896665,
"y": -0.030086855171248317,
"z": -0.00828781514428556
},
"rotation": {
"x": -0.93071597814559937,
"y": 0.13045383989810944,
"z": -0.11257931590080261,
"w": -0.32351988554000854
}
}
}
]
}
\ No newline at end of file
{
"items": [
{
"joint": "None",
"pose": {
"position": {
"x": -0.06115446984767914,
"y": -0.09662134945392609,
"z": -0.2845369577407837
},
"rotation": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
}
}
},
{
"joint": "Wrist",
"pose": {
"position": {
"x": 0.09835253655910492,
"y": -0.13776640594005586,
"z": -0.039533719420433047
},
"rotation": {
"x": -0.5504903793334961,
"y": -0.3628506064414978,
"z": 0.009051494300365448,
"w": 0.7516400218009949
}
}
},
{
"joint": "Palm",
"pose": {
"position": {
"x": 0.0762285590171814,
"y": -0.0935618057847023,
"z": -0.03025330975651741
},
"rotation": {
"x": -0.5504903793334961,
"y": -0.3628506064414978,
"z": 0.009051494300365448,
"w": 0.7516400218009949
}
}
},
{
"joint": "ThumbMetacarpalJoint",
"pose": {
"position": {
"x": 0.0726172998547554,
"y": -0.13283079862594605,
"z": -0.03489827364683151
},
"rotation": {
"x": 0.5268919467926025,
"y": 0.07137523591518402,
"z": -0.7376347184181213,
"w": -0.4172084629535675
}
}
},
{
"joint": "ThumbProximalJoint",
"pose": {
"position": {
"x": 0.033425573259592059,
"y": -0.11720558255910874,
"z": -0.01445704698562622
},
"rotation": {
"x": 0.434413880109787,
"y": -0.0821000337600708,
"z": -0.7344200611114502,
"w": -0.5157689452171326
}
}
},
{
"joint": "ThumbDistalJoint",
"pose": {
"position": {
"x": 0.014360085129737854,
"y": -0.09762166440486908,
"z": 0.006609674543142319
},
"rotation": {
"x": 0.4773363769054413,
"y": 0.019135713577270509,
"z": -0.7483649849891663,
"w": -0.4610738456249237
}
}
},
{
"joint": "ThumbTip",
"pose": {
"position": {
"x": -0.00011064158752560616,
"y": -0.08949866145849228,
"z": 0.017393887042999269
},
"rotation": {
"x": 0.4773363769054413,
"y": 0.019135713577270509,
"z": -0.7483649849891663,
"w": -0.4610738456249237
}
}
},
{
"joint": "IndexMetacarpal",
"pose": {
"position": {
"x": 0.08073623478412628,
"y": -0.125896617770195,
"z": -0.034658633172512057
},
"rotation": {
"x": -0.5162340998649597,
"y": -0.5017301440238953,
"z": 0.006298713386058807,
"w": 0.6940672993659973
}
}
},
{
"joint": "IndexKnuckle",
"pose": {
"position": {
"x": 0.03474228084087372,
"y": -0.0794244259595871,
"z": -0.03704426437616348
},
"rotation": {
"x": 0.24844542145729066,
"y": 0.2553045451641083,
"z": -0.1957876831293106,
"w": -0.9136616587638855
}
}
},
{
"joint": "IndexMiddleJoint",
"pose": {
"position": {
"x": 0.011708781123161316,
"y": -0.06496208906173706,
"z": -0.006560325622558594
},
"rotation": {
"x": -0.07294681668281555,
"y": 0.11601599305868149,
"z": -0.3479400873184204,
"w": -0.9274918437004089
}
}
},
{
"joint": "IndexDistalJoint",
"pose": {
"position": {
"x": 0.007551820017397404,
"y": -0.07041776180267334,
"z": 0.017747312784194948
},
"rotation": {
"x": -0.23120707273483277,
"y": 0.04230353981256485,
"z": -0.283862441778183,
"w": -0.9298091530799866
}
}
},
{
"joint": "IndexTip",
"pose": {
"position": {
"x": 0.008366326801478863,
"y": -0.07753925025463104,
"z": 0.03171003982424736
},
"rotation": {
"x": -0.23120707273483277,
"y": 0.04230353981256485,
"z": -0.283862441778183,
"w": -0.9298091530799866
}
}
},
{
"joint": "MiddleMetacarpal",
"pose": {
"position": {
"x": 0.08751480281352997,
"y": -0.12250128388404846,
"z": -0.03293202817440033
},
"rotation": {
"x": -0.6167790293693543,
"y": -0.3379325270652771,
"z": 0.047245174646377566,
"w": 0.7093328237533569
}
}
},
{
"joint": "MiddleKnuckle",
"pose": {
"position": {
"x": 0.05473826080560684,
"y": -0.07110955566167832,
"z": -0.03227551281452179
},
"rotation": {
"x": 0.14497825503349305,
"y": 0.23276910185813905,
"z": -0.15017877519130708,
"w": -0.9498769640922546
}
}
},
{
"joint": "MiddleMiddleJoint",
"pose": {
"position": {
"x": 0.03288401663303375,
"y": -0.061863791197538379,
"z": 0.005947750061750412
},
"rotation": {
"x": -0.529046893119812,
"y": 0.08228799700737,
"z": -0.27945762872695925,
"w": -0.7971096038818359
}
}
},
{
"joint": "MiddleDistalJoint",
"pose": {
"position": {
"x": 0.03765859827399254,
"y": -0.08771546185016632,
"z": 0.018359089270234109
},
"rotation": {
"x": -0.7883356809616089,
"y": -0.06667964905500412,
"z": -0.20251651108264924,
"w": -0.5779290795326233
}
}
},
{
"joint": "MiddleTip",
"pose": {
"position": {
"x": 0.044593729078769687,
"y": -0.10324498265981674,
"z": 0.013978719711303711
},
"rotation": {
"x": -0.7883356809616089,
"y": -0.06667964905500412,
"z": -0.20251651108264924,
"w": -0.5779290795326233
}
}
},
{
"joint": "RingMetacarpal",
"pose": {
"position": {
"x": 0.09642073512077332,
"y": -0.11764736473560333,
"z": -0.03004951775074005
},
"rotation": {
"x": -0.6103544235229492,
"y": -0.2158902883529663,
"z": 0.09254944324493408,
"w": 0.756500780582428
}
}
},
{
"joint": "RingKnuckle",
"pose": {
"position": {
"x": 0.07221101969480515,
"y": -0.06899281591176987,
"z": -0.021143771708011628
},
"rotation": {
"x": 0.05531589314341545,
"y": 0.22126297652721406,
"z": -0.10504759848117829,
"w": -0.9679690599441528
}
}
},
{
"joint": "RingMiddleJoint",
"pose": {
"position": {
"x": 0.05479241907596588,
"y": -0.06659357994794846,
"z": 0.014326661825180054
},
"rotation": {
"x": -0.7176058888435364,
"y": 0.09858439117670059,
"z": -0.19834160804748536,
"w": -0.6603801846504211
}
}
},
{
"joint": "RingDistalJoint",
"pose": {
"position": {
"x": 0.05848679319024086,
"y": -0.09022481739521027,
"z": 0.013152096420526505
},
"rotation": {
"x": -0.902705729007721,
"y": -0.04138700291514397,
"z": -0.16108426451683045,
"w": -0.39749816060066225
}
}
},
{
"joint": "RingTip",
"pose": {
"position": {
"x": 0.0647393986582756,
"y": -0.10384124517440796,
"z": 0.000916551798582077
},
"rotation": {
"x": -0.902705729007721,
"y": -0.04138700291514397,
"z": -0.16108426451683045,
"w": -0.39749816060066225
}
}
},
{
"joint": "PinkyMetacarpal",
"pose": {
"position": {
"x": 0.10431554913520813,
"y": -0.11550788581371308,
"z": -0.02525215595960617
},
"rotation": {
"x": -0.5731514096260071,
"y": -0.08393544703722,
"z": 0.14239011704921723,
"w": 0.8026066422462463
}
}
},
{
"joint": "PinkyKnuckle",
"pose": {
"position": {
"x": 0.08813987672328949,
"y": -0.06685832887887955,
"z": -0.0073963552713394169
},
"rotation": {
"x": 0.004650826565921307,
"y": 0.2523718476295471,
"z": -0.022669829428195955,
"w": -0.967362105846405
}
}
},
{
"joint": "PinkyMiddleJoint",
"pose": {
"position": {
"x": 0.07569940388202667,
"y": -0.066920705139637,
"z": 0.014825716614723206
},
"rotation": {
"x": -0.6876563429832459,
"y": 0.1765523999929428,
"z": -0.14831064641475678,
"w": -0.6885376572608948
}
}
},
{
"joint": "PinkyDistalJoint",
"pose": {
"position": {
"x": 0.0749262273311615,
"y": -0.08663906902074814,
"z": 0.014672402292490006
},
"rotation": {
"x": -0.927348792552948,
"y": 0.0344926156103611,
"z": -0.02340996265411377,
"w": -0.37271565198898318
}
}
},
{
"joint": "PinkyTip",
"pose": {
"position": {
"x": 0.07520446181297302,
"y": -0.09743660688400269,
"z": 0.0034288540482521059
},
"rotation": {
"x": -0.927348792552948,
"y": 0.0344926156103611,
"z": -0.02340996265411377,
"w": -0.37271565198898318
}
}
}
]
}
\ No newline at end of file
{
"items": [
{
"joint": "None",
"pose": {
"position": {
"x": -0.0002162586897611618,
"y": -0.07638707756996155,
"z": -0.5826087594032288
},
"rotation": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
}
}
},
{
"joint": "Wrist",
"pose": {
"position": {
"x": 0.042526353150606158,
"y": -0.05274807661771774,
"z": -0.002824799157679081
},
"rotation": {
"x": -0.3676998019218445,
"y": -0.23572500050067902,
"z": -0.11507342755794525,
"w": 0.8920522332191467
}
}
},
{
"joint": "Palm",
"pose": {
"position": {
"x": 0.03201436251401901,
"y": -0.019188636913895608,
"z": 0.02868746407330036
},
"rotation": {
"x": -0.3676998019218445,
"y": -0.23572500050067902,
"z": -0.11507342755794525,
"w": 0.8920522332191467
}
}
},
{
"joint": "ThumbMetacarpalJoint",
"pose": {
"position": {
"x": 0.020570117980241777,
"y": -0.04709470272064209,
"z": 0.006985310930758715
},
"rotation": {
"x": 0.3615202307701111,
"y": 0.20331884920597077,
"z": -0.6839582324028015,
"w": -0.6008830666542053
}
}
},
{
"joint": "ThumbProximalJoint",
"pose": {
"position": {
"x": -0.009850621223449707,
"y": -0.04070408642292023,
"z": 0.034042149782180789
},
"rotation": {
"x": 0.21800242364406587,
"y": 0.02305757999420166,
"z": -0.7068297266960144,
"w": -0.673233151435852
}
}
},
{
"joint": "ThumbDistalJoint",
"pose": {
"position": {
"x": -0.02049688994884491,
"y": -0.03254491835832596,
"z": 0.06248035654425621
},
"rotation": {
"x": 0.258157342672348,
"y": 0.0635419636964798,
"z": -0.7039065957069397,
"w": -0.6593562960624695
}
}
},
{
"joint": "ThumbTip",
"pose": {
"position": {
"x": -0.028410332277417184,
"y": -0.028122693300247194,
"z": 0.07770571112632752
},
"rotation": {
"x": 0.258157342672348,
"y": 0.0635419636964798,
"z": -0.7039065957069397,
"w": -0.6593562960624695
}
}
},
{
"joint": "IndexMetacarpal",
"pose": {
"position": {
"x": 0.029027197510004045,
"y": -0.042809583246707919,
"z": 0.009094133973121643
},
"rotation": {
"x": -0.3631853759288788,
"y": -0.3677399158477783,
"z": -0.1473514586687088,
"w": 0.8432979583740234
}
}
},
{
"joint": "IndexKnuckle",
"pose": {
"position": {
"x": -0.0017803632654249669,
"y": 0.0004678480327129364,
"z": 0.03705211728811264
},
"rotation": {
"x": -0.27657586336135867,
"y": -0.15855258703231812,
"z": 0.0009860674617812038,
"w": 0.947831392288208
}
}
},
{
"joint": "IndexMiddleJoint",
"pose": {
"position": {
"x": -0.014122002758085728,
"y": 0.021943308413028718,
"z": 0.06970683485269547
},
"rotation": {
"x": -0.2553846836090088,
"y": -0.12617842853069306,
"z": 0.09538201987743378,
"w": 0.9538831114768982
}
}
},
{
"joint": "IndexDistalJoint",
"pose": {
"position": {
"x": -0.020550768822431566,
"y": 0.0322258397936821,
"z": 0.08830686658620835
},
"rotation": {
"x": -0.30963119864463808,
"y": -0.11118883639574051,
"z": -0.031351685523986819,
"w": 0.9441277980804443
}
}
},
{
"joint": "IndexTip",
"pose": {
"position": {
"x": -0.02332291379570961,
"y": 0.04081675410270691,
"z": 0.09968645870685578
},
"rotation": {
"x": -0.30963119864463808,
"y": -0.11118883639574051,
"z": -0.031351685523986819,
"w": 0.9441277980804443
}
}
},
{
"joint": "MiddleMetacarpal",
"pose": {
"position": {
"x": 0.035866666585206988,
"y": -0.041708216071128848,
"z": 0.010740639641880989
},
"rotation": {
"x": -0.43399062752723696,
"y": -0.2068476676940918,
"z": -0.05406999588012695,
"w": 0.8751816153526306
}
}
},
{
"joint": "MiddleKnuckle",
"pose": {
"position": {
"x": 0.018060242757201196,
"y": 0.002479703165590763,
"z": 0.04112553596496582
},
"rotation": {
"x": 0.005038086324930191,
"y": 0.1527022123336792,
"z": 0.021530797705054284,
"w": -0.9880359768867493
}
}
},
{
"joint": "MiddleMiddleJoint",
"pose": {
"position": {
"x": 0.005449346732348204,
"y": 0.0031707696616649629,
"z": 0.08099328726530075
},
"rotation": {
"x": -0.49786925315856936,
"y": 0.13922974467277528,
"z": -0.07507844269275665,
"w": -0.8527824878692627
}
}
},
{
"joint": "MiddleDistalJoint",
"pose": {
"position": {
"x": 0.0013555703917518259,
"y": -0.01869615726172924,
"z": 0.09269960224628449
},
"rotation": {
"x": -0.7163864970207214,
"y": 0.07041004300117493,
"z": -0.030646607279777528,
"w": -0.6939578652381897
}
}
},
{
"joint": "MiddleTip",
"pose": {
"position": {
"x": 0.0004728742642328143,
"y": -0.03479576110839844,
"z": 0.09213778376579285
},
"rotation": {
"x": -0.7163864970207214,
"y": 0.07041004300117493,
"z": -0.030646607279777528,
"w": -0.6939578652381897
}
}
},
{
"joint": "RingMetacarpal",
"pose": {
"position": {
"x": 0.044932689517736438,
"y": -0.04016602039337158,
"z": 0.013597620651125908
},
"rotation": {
"x": -0.3939853310585022,
"y": -0.10114617645740509,
"z": 0.016117071732878686,
"w": 0.9133923053741455
}
}
},
{
"joint": "RingKnuckle",
"pose": {
"position": {
"x": 0.03491469845175743,
"y": -0.003818823955953121,
"z": 0.047541361302137378
},
"rotation": {
"x": -0.11738020181655884,
"y": 0.15373656153678895,
"z": 0.05639626830816269,
"w": -0.9795019030570984
}
}
},
{
"joint": "RingMiddleJoint",
"pose": {
"position": {
"x": 0.023768775165081025,
"y": -0.01135534793138504,
"z": 0.08033758401870728
},
"rotation": {
"x": -0.7923092842102051,
"y": 0.16401034593582154,
"z": -0.02978098951280117,
"w": -0.5869977474212647
}
}
},
{
"joint": "RingDistalJoint",
"pose": {
"position": {
"x": 0.02067880891263485,
"y": -0.031320542097091678,
"z": 0.0737735852599144
},
"rotation": {
"x": -0.9346709847450256,
"y": 0.0874316394329071,
"z": -0.023773543536663057,
"w": -0.344605952501297
}
}
},
{
"joint": "RingTip",
"pose": {
"position": {
"x": 0.020386409014463426,
"y": -0.04289411008358002,
"z": 0.06018315628170967
},
"rotation": {
"x": -0.9346709847450256,
"y": 0.0874316394329071,
"z": -0.023773543536663057,
"w": -0.344605952501297
}
}
},
{
"joint": "PinkyMetacarpal",
"pose": {
"position": {
"x": 0.05288681760430336,
"y": -0.041848354041576388,
"z": 0.01654883660376072
},
"rotation": {
"x": -0.33144858479499819,
"y": 0.002071807160973549,
"z": 0.085218146443367,
"w": 0.9396145343780518
}
}
},
{
"joint": "PinkyKnuckle",
"pose": {
"position": {
"x": 0.050300415605306628,
"y": -0.011202438734471798,
"z": 0.054917603731155398
},
"rotation": {
"x": -0.16419324278831483,
"y": 0.1696346402168274,
"z": 0.12252454459667206,
"w": -0.9639865159988403
}
}
},
{
"joint": "PinkyMiddleJoint",
"pose": {
"position": {
"x": 0.04166591167449951,
"y": -0.017666997388005258,
"z": 0.07580538094043732
},
"rotation": {
"x": -0.7474591135978699,
"y": 0.20672142505645753,
"z": 0.04626481607556343,
"w": -0.6297129392623901
}
}
},
{
"joint": "PinkyDistalJoint",
"pose": {
"position": {
"x": 0.03587989881634712,
"y": -0.03386271744966507,
"z": 0.0722469910979271
},
"rotation": {
"x": -0.928327202796936,
"y": 0.13445810973644257,
"z": 0.1272566169500351,
"w": -0.3232197165489197
}
}
},
{
"joint": "PinkyTip",
"pose": {
"position": {
"x": 0.03135494887828827,
"y": -0.04178089275956154,
"z": 0.06164591759443283
},
"rotation": {
"x": -0.928327202796936,
"y": 0.13445810973644257,
"z": 0.1272566169500351,
"w": -0.3232197165489197
}
}
}
]
}
\ No newline at end of file
{
"items": [
{
"joint": "None",
"pose": {
"position": {
"x": -0.01725071482360363,
"y": -0.08121182024478913,
"z": -0.47676876187324526
},
"rotation": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
}
}
},
{
"joint": "Wrist",
"pose": {
"position": {
"x": 0.08615099638700485,
"y": -0.024168234318494798,
"z": 0.034818120300769809
},
"rotation": {
"x": -0.24332590401172639,
"y": 0.6052875518798828,
"z": 0.5141062140464783,
"w": -0.5566452741622925
}
}
},
{
"joint": "Palm",
"pose": {
"position": {
"x": 0.03520287200808525,
"y": -0.010816145688295365,
"z": 0.04648737236857414
},
"rotation": {
"x": -0.24332590401172639,
"y": 0.6052875518798828,
"z": 0.5141062140464783,
"w": -0.5566452741622925
}
}
},
{
"joint": "ThumbMetacarpalJoint",
"pose": {
"position": {
"x": 0.06692907959222794,
"y": -0.0030839829705655576,
"z": 0.020349422469735147
},
"rotation": {
"x": 0.39406728744506838,
"y": 0.7213952541351318,
"z": 0.33115363121032717,
"w": -0.46385547518730166
}
}
},
{
"joint": "ThumbProximalJoint",
"pose": {
"position": {
"x": 0.048644911497831348,
"y": 0.034663256257772449,
"z": 0.004639927297830582
},
"rotation": {
"x": 0.34302714467048647,
"y": 0.719179630279541,
"z": 0.2980014383792877,
"w": -0.5261238217353821
}
}
},
{
"joint": "ThumbDistalJoint",
"pose": {
"position": {
"x": 0.030924495309591295,
"y": 0.05998371168971062,
"z": -0.004000300541520119
},
"rotation": {
"x": 0.4403221607208252,
"y": 0.6942930817604065,
"z": 0.3865111470222473,
"w": -0.4186002314090729
}
}
},
{
"joint": "ThumbTip",
"pose": {
"position": {
"x": 0.02607334591448307,
"y": 0.07819978147745133,
"z": -0.011070644482970238
},
"rotation": {
"x": 0.4403221607208252,
"y": 0.6942930817604065,
"z": 0.3865111470222473,
"w": -0.4186002314090729
}
}
},
{
"joint": "IndexMetacarpal",
"pose": {
"position": {
"x": 0.06430374830961228,
"y": -0.01019766554236412,
"z": 0.02929815649986267
},
"rotation": {
"x": -0.22792501747608186,
"y": 0.6316274404525757,
"z": 0.5866482257843018,
"w": -0.45270389318466189
}
}
},
{
"joint": "IndexKnuckle",
"pose": {
"position": {
"x": 0.011573880910873413,
"y": 0.02339656837284565,
"z": 0.03546718880534172
},
"rotation": {
"x": 0.3942926526069641,
"y": -0.7424762845039368,
"z": -0.21414896845817567,
"w": 0.49741214513778689
}
}
},
{
"joint": "IndexMiddleJoint",
"pose": {
"position": {
"x": -0.021892068907618524,
"y": 0.020658958703279496,
"z": 0.020219745114445688
},
"rotation": {
"x": 0.5834210515022278,
"y": -0.7061115503311157,
"z": 0.3634859323501587,
"w": 0.17027443647384644
}
}
},
{
"joint": "IndexDistalJoint",
"pose": {
"position": {
"x": -0.017463261261582376,
"y": 0.00348295527510345,
"z": 0.0038637774996459486
},
"rotation": {
"x": 0.6371655464172363,
"y": -0.4360961318016052,
"z": 0.6206539869308472,
"w": -0.13840782642364503
}
}
},
{
"joint": "IndexTip",
"pose": {
"position": {
"x": -0.001938387518748641,
"y": -0.0027357139624655248,
"z": 0.0005815188633278012
},
"rotation": {
"x": 0.6371655464172363,
"y": -0.4360961318016052,
"z": 0.6206539869308472,
"w": -0.13840782642364503
}
}
},
{
"joint": "MiddleMetacarpal",
"pose": {
"position": {
"x": 0.06397924572229386,
"y": -0.016921602189540864,
"z": 0.03521520271897316
},
"rotation": {
"x": -0.16760338842868806,
"y": 0.5928976535797119,
"z": 0.5015624761581421,
"w": -0.6073026657104492
}
}
},
{
"joint": "MiddleKnuckle",
"pose": {
"position": {
"x": 0.01083554606884718,
"y": 0.006482137367129326,
"z": 0.049619730561971667
},
"rotation": {
"x": 0.5027921199798584,
"y": -0.7059369087219238,
"z": -0.16476257145404817,
"w": 0.4708792269229889
}
}
},
{
"joint": "MiddleMiddleJoint",
"pose": {
"position": {
"x": -0.025254713371396066,
"y": -0.003984889946877956,
"z": 0.02779259905219078
},
"rotation": {
"x": 0.6809582710266113,
"y": -0.6233372688293457,
"z": 0.3824990391731262,
"w": -0.039771441370248798
}
}
},
{
"joint": "MiddleDistalJoint",
"pose": {
"position": {
"x": -0.00917090568691492,
"y": -0.015904264524579049,
"z": 0.007921875454485417
},
"rotation": {
"x": 0.6229440569877625,
"y": -0.2391648292541504,
"z": 0.642637312412262,
"w": -0.37781840562820437
}
}
},
{
"joint": "MiddleTip",
"pose": {
"position": {
"x": 0.008252275176346302,
"y": -0.013008372858166695,
"z": 0.009888304397463799
},
"rotation": {
"x": 0.6229440569877625,
"y": -0.2391648292541504,
"z": 0.642637312412262,
"w": -0.37781840562820437
}
}
},
{
"joint": "RingMetacarpal",
"pose": {
"position": {
"x": 0.06303475052118302,
"y": -0.02612213045358658,
"z": 0.04269380867481232
},
"rotation": {
"x": -0.18103565275669099,
"y": 0.5941647887229919,
"z": 0.39771339297294619,
"w": -0.6752913594245911
}
}
},
{
"joint": "RingKnuckle",
"pose": {
"position": {
"x": 0.010207276791334153,
"y": -0.013390008360147477,
"z": 0.055441394448280337
},
"rotation": {
"x": 0.5632884502410889,
"y": -0.6713510751724243,
"z": -0.15870888531208039,
"w": 0.45477786660194399
}
}
},
{
"joint": "RingMiddleJoint",
"pose": {
"position": {
"x": -0.01994304731488228,
"y": -0.024818312376737596,
"z": 0.03496982902288437
},
"rotation": {
"x": 0.7331446409225464,
"y": -0.5462665557861328,
"z": 0.3692132830619812,
"w": -0.16697438061237336
}
}
},
{
"joint": "RingDistalJoint",
"pose": {
"position": {
"x": -0.0031065356452018024,
"y": -0.028507214039564134,
"z": 0.019337791949510576
},
"rotation": {
"x": 0.6351615786552429,
"y": -0.23133434355258943,
"z": 0.5935887098312378,
"w": -0.43731656670570376
}
}
},
{
"joint": "RingTip",
"pose": {
"position": {
"x": 0.015546157956123352,
"y": -0.023027585819363595,
"z": 0.021024812012910844
},
"rotation": {
"x": 0.6351615786552429,
"y": -0.23133434355258943,
"z": 0.5935887098312378,
"w": -0.43731656670570376
}
}
},
{
"joint": "PinkyMetacarpal",
"pose": {
"position": {
"x": 0.06254640221595764,
"y": -0.034929849207401279,
"z": 0.04593820124864578
},
"rotation": {
"x": -0.19249169528484345,
"y": 0.581859290599823,
"z": 0.2601516842842102,
"w": -0.7461285591125488
}
}
},
{
"joint": "PinkyKnuckle",
"pose": {
"position": {
"x": 0.009921858087182045,
"y": -0.03408779203891754,
"z": 0.05945640057325363
},
"rotation": {
"x": 0.6286200881004334,
"y": -0.6190594434738159,
"z": -0.18423764407634736,
"w": 0.43321672081947329
}
}
},
{
"joint": "PinkyMiddleJoint",
"pose": {
"position": {
"x": -0.007876850664615631,
"y": -0.041423700749874118,
"z": 0.04655241593718529
},
"rotation": {
"x": 0.7744045257568359,
"y": -0.5470465421676636,
"z": 0.2698802649974823,
"w": -0.1682688444852829
}
}
},
{
"joint": "PinkyDistalJoint",
"pose": {
"position": {
"x": 0.0036155348643660547,
"y": -0.042087383568286899,
"z": 0.03132062032818794
},
"rotation": {
"x": 0.7368069291114807,
"y": -0.19751593470573426,
"z": 0.4435950815677643,
"w": -0.47120407223701479
}
}
},
{
"joint": "PinkyTip",
"pose": {
"position": {
"x": 0.016652610152959825,
"y": -0.034032851457595828,
"z": 0.02879030816257
},
"rotation": {
"x": 0.7368069291114807,
"y": -0.19751593470573426,
"z": 0.4435950815677643,
"w": -0.47120407223701479
}
}
}
]
}
\ No newline at end of file
{
"items": [
{
"joint": "None",
"pose": {
"position": {
"x": 0.0021753902547061445,
"y": -0.13046418130397798,
"z": -0.45588064193725588
},
"rotation": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
}
}
},
{
"joint": "Wrist",
"pose": {
"position": {
"x": 0.07915662229061127,
"y": -0.13887012004852296,
"z": -0.010340530425310135
},
"rotation": {
"x": -0.5914298295974731,
"y": -0.2676140367984772,
"z": -0.06283169984817505,
"w": 0.7577439546585083
}
}
},
{
"joint": "Palm",
"pose": {
"position": {
"x": 0.06830108910799027,
"y": -0.09366560727357865,
"z": -0.0000256318598985672
},
"rotation": {
"x": -0.5914298295974731,
"y": -0.2676140367984772,
"z": -0.06283169984817505,
"w": 0.7577439546585083
}
}
},
{
"joint": "ThumbMetacarpalJoint",
"pose": {
"position": {
"x": 0.05787024274468422,
"y": -0.12883375585079194,
"z": -0.005382232367992401
},
"rotation": {
"x": 0.4801919758319855,
"y": -0.04491055756807327,
"z": -0.7443504333496094,
"w": -0.4627794027328491
}
}
},
{
"joint": "ThumbProximalJoint",
"pose": {
"position": {
"x": 0.030012525618076326,
"y": -0.10770050436258316,
"z": 0.016813457012176515
},
"rotation": {
"x": 0.312323659658432,
"y": -0.2742984890937805,
"z": -0.6935320496559143,
"w": -0.5894817113876343
}
}
},
{
"joint": "ThumbDistalJoint",
"pose": {
"position": {
"x": 0.026396021246910096,
"y": -0.08305369317531586,
"z": 0.03835996612906456
},
"rotation": {
"x": 0.26157766580581667,
"y": -0.3302468955516815,
"z": -0.6686716675758362,
"w": -0.6136223673820496
}
}
},
{
"joint": "ThumbTip",
"pose": {
"position": {
"x": 0.027343440800905229,
"y": -0.07000578194856644,
"z": 0.04939644783735275
},
"rotation": {
"x": 0.26157766580581667,
"y": -0.3302468955516815,
"z": -0.6686716675758362,
"w": -0.6136223673820496
}
}
},
{
"joint": "IndexMetacarpal",
"pose": {
"position": {
"x": 0.06611358374357224,
"y": -0.12426556646823883,
"z": -0.0055283233523368839
},
"rotation": {
"x": -0.5613270998001099,
"y": -0.42208683490753176,
"z": -0.06766947358846665,
"w": 0.7086432576179504
}
}
},
{
"joint": "IndexKnuckle",
"pose": {
"position": {
"x": 0.034438081085681918,
"y": -0.0725482851266861,
"z": -0.004708992317318916
},
"rotation": {
"x": -0.6286489963531494,
"y": -0.2787279188632965,
"z": 0.040076885372400287,
"w": 0.7249277830123901
}
}
},
{
"joint": "IndexMiddleJoint",
"pose": {
"position": {
"x": 0.015563697554171086,
"y": -0.03562714159488678,
"z": -0.0024565430358052255
},
"rotation": {
"x": -0.6645650863647461,
"y": -0.2075067013502121,
"z": 0.10458821058273316,
"w": 0.7102522253990173
}
}
},
{
"joint": "IndexDistalJoint",
"pose": {
"position": {
"x": 0.005756473168730736,
"y": -0.015270628966391087,
"z": -0.0017626225017011166
},
"rotation": {
"x": -0.6223592162132263,
"y": -0.24349386990070344,
"z": 0.01842544600367546,
"w": 0.7439839839935303
}
}
},
{
"joint": "IndexTip",
"pose": {
"position": {
"x": 0.00011674128472805023,
"y": -0.0018588211387395859,
"z": -0.00020025699632242322
},
"rotation": {
"x": -0.6223592162132263,
"y": -0.24349386990070344,
"z": 0.01842544600367546,
"w": 0.7439839839935303
}
}
},
{
"joint": "MiddleMetacarpal",
"pose": {
"position": {
"x": 0.07268297672271729,
"y": -0.12254584580659867,
"z": -0.004201311618089676
},
"rotation": {
"x": -0.6534333825111389,
"y": -0.22906279563903809,
"z": -0.018352244049310685,
"w": 0.7212615013122559
}
}
},
{
"joint": "MiddleKnuckle",
"pose": {
"position": {
"x": 0.054447855800390246,
"y": -0.06595612317323685,
"z": -0.0017550308257341385
},
"rotation": {
"x": -0.5899049043655396,
"y": -0.16088859736919404,
"z": -0.018363818526268007,
"w": 0.7910826206207275
}
}
},
{
"joint": "MiddleMiddleJoint",
"pose": {
"position": {
"x": 0.04355549067258835,
"y": -0.022029317915439607,
"z": 0.010043984279036522
},
"rotation": {
"x": -0.6020974516868591,
"y": -0.14070262014865876,
"z": -0.036361001431941989,
"w": 0.7852000594139099
}
}
},
{
"joint": "MiddleDistalJoint",
"pose": {
"position": {
"x": 0.03923114016652107,
"y": 0.0012873951345682145,
"z": 0.015791211277246476
},
"rotation": {
"x": -0.5366969108581543,
"y": -0.17153941094875337,
"z": -0.09987709671258927,
"w": 0.8206644058227539
}
}
},
{
"joint": "MiddleTip",
"pose": {
"position": {
"x": 0.03647539019584656,
"y": 0.015714645385742189,
"z": 0.021557386964559556
},
"rotation": {
"x": -0.5366969108581543,
"y": -0.17153941094875337,
"z": -0.09987709671258927,
"w": 0.8206644058227539
}
}
},
{
"joint": "RingMetacarpal",
"pose": {
"position": {
"x": 0.08137646317481995,
"y": -0.11985518038272858,
"z": -0.00190657377243042
},
"rotation": {
"x": -0.6267969012260437,
"y": -0.10518965870141983,
"z": 0.02498382329940796,
"w": 0.7716453075408936
}
}
},
{
"joint": "RingKnuckle",
"pose": {
"position": {
"x": 0.07067620009183884,
"y": -0.06669728457927704,
"z": 0.008708799257874489
},
"rotation": {
"x": 0.40646883845329287,
"y": 0.1807955503463745,
"z": 0.030094729736447336,
"w": -0.8951042294502258
}
}
},
{
"joint": "RingMiddleJoint",
"pose": {
"position": {
"x": 0.060088954865932468,
"y": -0.04056686535477638,
"z": 0.03008754923939705
},
"rotation": {
"x": -0.2107616662979126,
"y": 0.18913404643535615,
"z": -0.04620787873864174,
"w": -0.9580028653144836
}
}
},
{
"joint": "RingDistalJoint",
"pose": {
"position": {
"x": 0.0528024360537529,
"y": -0.0495174415409565,
"z": 0.047927625477313998
},
"rotation": {
"x": -0.449715256690979,
"y": 0.15903393924236298,
"z": -0.020673276856541635,
"w": -0.8789007067680359
}
}
},
{
"joint": "RingTip",
"pose": {
"position": {
"x": 0.048170287162065509,
"y": -0.06364263594150543,
"z": 0.05758979544043541
},
"rotation": {
"x": -0.449715256690979,
"y": 0.15903393924236298,
"z": -0.020673276856541635,
"w": -0.8789007067680359
}
}
},
{
"joint": "PinkyMetacarpal",
"pose": {
"position": {
"x": 0.08909709751605988,
"y": -0.11985252797603607,
"z": 0.001964922994375229
},
"rotation": {
"x": -0.5780324339866638,
"y": -0.0013396204449236394,
"z": 0.06318691372871399,
"w": 0.8135625720024109
}
}
},
{
"joint": "PinkyKnuckle",
"pose": {
"position": {
"x": 0.0851951465010643,
"y": -0.07107751816511154,
"z": 0.019172409549355508
},
"rotation": {
"x": 0.31776368618011477,
"y": 0.2502634525299072,
"z": 0.05463750660419464,
"w": -0.9129235744476318
}
}
},
{
"joint": "PinkyMiddleJoint",
"pose": {
"position": {
"x": 0.07433749735355377,
"y": -0.055455759167671207,
"z": 0.03647337108850479
},
"rotation": {
"x": -0.17528946697711945,
"y": 0.2344343513250351,
"z": 0.019245747476816179,
"w": -0.9560556411743164
}
}
},
{
"joint": "PinkyDistalJoint",
"pose": {
"position": {
"x": 0.06645255535840988,
"y": -0.06111001968383789,
"z": 0.050835996866226199
},
"rotation": {
"x": -0.4488738477230072,
"y": 0.26990553736686709,
"z": 0.08396486192941666,
"w": -0.8479632139205933
}
}
},
{
"joint": "PinkyTip",
"pose": {
"position": {
"x": 0.05911727994680405,
"y": -0.07095448672771454,
"z": 0.05705229192972183
},
"rotation": {
"x": -0.4488738477230072,
"y": 0.26990553736686709,
"z": 0.08396486192941666,
"w": -0.8479632139205933
}
}
}
]
}
\ No newline at end of file
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
[assembly: System.Reflection.AssemblyVersion("2.5.0.0")]
[assembly: System.Reflection.AssemblyFileVersion("2.5.0.0")]
[assembly: System.Reflection.AssemblyProduct("Microsoft® Mixed Reality Toolkit aipmragent_work")]
[assembly: System.Reflection.AssemblyCopyright("Copyright © Microsoft Corporation")]
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using Microsoft.MixedReality.Toolkit.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Microsoft.MixedReality.Toolkit.Input
{
/// <summary>
/// Base class for services that create simulated input devices.
/// </summary>
public abstract class BaseInputSimulationService : BaseInputDeviceManager
{
/// <summary>
/// Dictionary to capture all active controllers detected
/// </summary>
private readonly Dictionary<Handedness, BaseController> trackedControllers = new Dictionary<Handedness, BaseController>();
/// <summary>
/// Active controllers
/// </summary>
private IMixedRealityController[] activeControllers = System.Array.Empty<IMixedRealityController>();
/// <inheritdoc />
public override IMixedRealityController[] GetActiveControllers()
{
return activeControllers;
}
#region BaseInputDeviceManager Implementation
/// <summary>
/// Constructor.
/// </summary>
/// <param name="registrar">The <see cref="IMixedRealityServiceRegistrar"/> instance that loaded the data provider.</param>
/// <param name="inputSystem">The <see cref="Microsoft.MixedReality.Toolkit.Input.IMixedRealityInputSystem"/> instance that receives data from this provider.</param>
/// <param name="name">Friendly name of the service.</param>
/// <param name="priority">Service priority. Used to determine order of instantiation.</param>
/// <param name="profile">The service's configuration profile.</param>
[System.Obsolete("This constructor is obsolete (registrar parameter is no longer required) and will be removed in a future version of the Microsoft Mixed Reality Toolkit.")]
protected BaseInputSimulationService(
IMixedRealityServiceRegistrar registrar,
IMixedRealityInputSystem inputSystem,
string name,
uint priority,
BaseMixedRealityProfile profile) : this(inputSystem, name, priority, profile)
{
Registrar = registrar;
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="inputSystem">The <see cref="Microsoft.MixedReality.Toolkit.Input.IMixedRealityInputSystem"/> instance that receives data from this provider.</param>
/// <param name="name">Friendly name of the service.</param>
/// <param name="priority">Service priority. Used to determine order of instantiation.</param>
/// <param name="profile">The service's configuration profile.</param>
protected BaseInputSimulationService(
IMixedRealityInputSystem inputSystem,
string name,
uint priority,
BaseMixedRealityProfile profile) : base(inputSystem, name, priority, profile)
{ }
#endregion BaseInputDeviceManager Implementation
// Register input sources for controllers based on controller data
protected void UpdateControllerDevice(ControllerSimulationMode simulationMode, Handedness handedness, object controllerData)
{
if (controllerData != null)
{
if(controllerData is SimulatedHandData handData && handData.IsTracked)
{
SimulatedHand hand = GetOrAddControllerDevice(handedness, simulationMode) as SimulatedHand;
hand.UpdateState(handData);
return;
}
else if (controllerData is SimulatedMotionControllerData motionControllerData && motionControllerData.IsTracked)
{
SimulatedMotionController motionController = GetOrAddControllerDevice(handedness, simulationMode) as SimulatedMotionController;
motionController.UpdateState(motionControllerData);
return;
}
}
RemoveControllerDevice(handedness);
}
public BaseController GetControllerDevice(Handedness handedness)
{
if (trackedControllers.TryGetValue(handedness, out BaseController controller))
{
return controller;
}
return null;
}
protected BaseController GetOrAddControllerDevice(Handedness handedness, ControllerSimulationMode simulationMode)
{
var controller = GetControllerDevice(handedness);
if (controller != null)
{
if (controller is SimulatedHand hand && hand.SimulationMode == simulationMode)
{
return controller;
}
else if (controller is SimulatedMotionController && simulationMode == ControllerSimulationMode.MotionController)
{
return controller;
}
else
{
// Remove and recreate controller device if simulation mode doesn't match
RemoveControllerDevice(handedness);
}
}
DebugUtilities.LogVerboseFormat("GetOrAddControllerDevice: Adding a new simulated controller of handedness {0} and simulation mode {1}", handedness, simulationMode);
System.Type controllerType = null;
SupportedControllerType st;
IMixedRealityInputSource inputSource;
switch (simulationMode)
{
case ControllerSimulationMode.HandGestures:
st = SupportedControllerType.GGVHand;
inputSource = Service?.RequestNewGenericInputSource($"{handedness} Hand", RequestPointers(st, handedness), InputSourceType.Hand);
controller = new SimulatedGestureHand(TrackingState.Tracked, handedness, inputSource);
controllerType = typeof(SimulatedGestureHand);
break;
case ControllerSimulationMode.ArticulatedHand:
st = SupportedControllerType.ArticulatedHand;
inputSource = Service?.RequestNewGenericInputSource($"{handedness} Hand", RequestPointers(st, handedness), InputSourceType.Hand);
controller = new SimulatedArticulatedHand(TrackingState.Tracked, handedness, inputSource);
controllerType = typeof(SimulatedArticulatedHand);
break;
case ControllerSimulationMode.MotionController:
st = SupportedControllerType.WindowsMixedReality;
inputSource = Service?.RequestNewGenericInputSource($"{handedness} MotionController", RequestPointers(st, handedness), InputSourceType.Controller);
controller = new SimulatedMotionController(TrackingState.Tracked, handedness, inputSource);
controllerType = typeof(SimulatedMotionController);
break;
default:
controller = null;
break;
}
if (controller == null || !controller.Enabled)
{
// Controller failed to be setup correctly.
Debug.LogError($"Failed to create {controllerType} controller");
// Return null so we don't raise the source detected.
return null;
}
for (int i = 0; i < controller.InputSource?.Pointers?.Length; i++)
{
controller.InputSource.Pointers[i].Controller = controller;
}
Service?.RaiseSourceDetected(controller.InputSource, controller);
trackedControllers.Add(handedness, controller);
UpdateActiveControllers();
return controller;
}
protected void RemoveControllerDevice(Handedness handedness)
{
var controller = GetControllerDevice(handedness);
if (controller != null)
{
DebugUtilities.LogVerboseFormat("RemoveHandDevice: Removing simulated controller of handedness", handedness);
Service?.RaiseSourceLost(controller.InputSource, controller);
RecyclePointers(controller.InputSource);
trackedControllers.Remove(handedness);
UpdateActiveControllers();
}
}
protected void RemoveAllControllerDevices()
{
foreach (var controller in trackedControllers.Values)
{
Service?.RaiseSourceLost(controller.InputSource, controller);
RecyclePointers(controller.InputSource);
}
trackedControllers.Clear();
UpdateActiveControllers();
}
private void UpdateActiveControllers()
{
activeControllers = trackedControllers.Values.ToArray<IMixedRealityController>();
}
#region Obsolete Methods
// Register input sources for hands based on hand data
[Obsolete("Use UpdateControllerDevice instead.")]
protected void UpdateHandDevice(ControllerSimulationMode simulationMode, Handedness handedness, SimulatedHandData handData)
{
UpdateControllerDevice(simulationMode, handedness, handData);
}
[Obsolete("Use GetControllerDevice instead.")]
public SimulatedHand GetHandDevice(Handedness handedness)
{
return GetControllerDevice(handedness) as SimulatedHand;
}
[Obsolete("Use GetOrAddControllerDevice instead.")]
protected SimulatedHand GetOrAddHandDevice(Handedness handedness, ControllerSimulationMode simulationMode)
{
return GetOrAddControllerDevice(handedness, simulationMode) as SimulatedHand;
}
[Obsolete("Use RemoveControllerDevice instead.")]
protected void RemoveHandDevice(Handedness handedness)
{
RemoveControllerDevice(handedness);
}
[Obsolete("Use RemoveAllControllerDevices instead.")]
protected void RemoveAllHandDevices()
{
RemoveAllControllerDevices();
}
#endregion
}
}
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
[assembly: System.Reflection.AssemblyVersion("2.5.0.0")]
[assembly: System.Reflection.AssemblyFileVersion("2.5.0.0")]
[assembly: System.Reflection.AssemblyProduct("Microsoft® Mixed Reality Toolkit aipmragent_work")]
[assembly: System.Reflection.AssemblyCopyright("Copyright © Microsoft Corporation")]
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using Microsoft.MixedReality.Toolkit.Utilities;
using System;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace Microsoft.MixedReality.Toolkit.Input
{
/// <summary>
/// Tools for simulating and recording input as well as playing back input animation in the Unity editor.
/// </summary>
public class InputSimulationWindow : EditorWindow
{
private InputAnimation Animation
{
get { return PlaybackService?.Animation; }
set { if (PlaybackService != null) PlaybackService.Animation = value; }
}
private string loadedFilePath = "";
private IInputSimulationService simulationService = null;
private IInputSimulationService SimulationService
{
get
{
if (simulationService == null)
{
simulationService = CoreServices.GetInputSystemDataProvider<IInputSimulationService>();
}
return simulationService;
}
}
private IMixedRealityInputRecordingService recordingService = null;
private IMixedRealityInputRecordingService RecordingService
{
get
{
if (recordingService == null)
{
recordingService = CoreServices.GetInputSystemDataProvider<IMixedRealityInputRecordingService>();
}
return recordingService;
}
}
private IMixedRealityInputPlaybackService playbackService = null;
private IMixedRealityInputPlaybackService PlaybackService
{
get
{
if (playbackService == null)
{
playbackService = CoreServices.GetInputSystemDataProvider<IMixedRealityInputPlaybackService>();
}
return playbackService;
}
}
public enum ToolMode
{
/// <summary>
/// Record input animation and store in the asset.
/// </summary>
Record,
/// <summary>
/// Play back input animation as simulated input.
/// </summary>
Playback,
}
public ToolMode Mode { get; private set; } = ToolMode.Record;
/// Icon textures
private Texture2D iconPlay = null;
private Texture2D iconPause = null;
private Texture2D iconRecord = null;
private Texture2D iconRecordActive = null;
private Texture2D iconStepFwd = null;
private Texture2D iconJumpBack = null;
private Texture2D iconJumpFwd = null;
[MenuItem("Mixed Reality Toolkit/Utilities/Input Simulation")]
private static void ShowWindow()
{
InputSimulationWindow window = GetWindow<InputSimulationWindow>();
window.titleContent = new GUIContent("Input Simulation");
window.Show();
}
private void OnGUI()
{
LoadIcons();
if (!Application.isPlaying)
{
EditorGUILayout.HelpBox("Input simulation is only available in play mode", MessageType.Info);
return;
}
DrawSimulationGUI();
EditorGUILayout.Separator();
string[] modeStrings = Enum.GetNames(typeof(ToolMode));
Mode = (ToolMode)GUILayout.SelectionGrid((int)Mode, modeStrings, modeStrings.Length);
switch (Mode)
{
case ToolMode.Record:
DrawRecordingGUI();
break;
case ToolMode.Playback:
DrawPlaybackGUI();
break;
}
// XXX Reloading the scene is currently not supported,
// due to the life cycle of the MRTK "instance" object (see #4530).
// Enable the button below once scene reloading is supported!
#if false
using (new GUIEnabledWrapper(Application.isPlaying))
{
bool reloadScene = GUILayout.Button("Reload Scene");
if (reloadScene)
{
Scene activeScene = SceneManager.GetActiveScene();
if (activeScene.IsValid())
{
SceneManager.LoadScene(activeScene.name);
return;
}
}
}
#endif
}
private void DrawSimulationGUI()
{
if (SimulationService == null)
{
EditorGUILayout.HelpBox("No input simulation service found", MessageType.Info);
return;
}
DrawHeadGUI();
DrawHandsGUI();
}
private void DrawHeadGUI()
{
if (!CameraCache.Main)
{
return;
}
using (new GUILayout.VerticalScope(EditorStyles.helpBox))
{
GUILayout.Label($"Head:");
Transform headTransform = CameraCache.Main.transform;
Vector3 newPosition = EditorGUILayout.Vector3Field("Position", headTransform.position);
Vector3 newRotation = DrawRotationGUI("Rotation", headTransform.rotation.eulerAngles);
bool resetHand = GUILayout.Button("Reset");
if (newPosition != headTransform.position)
{
headTransform.position = newPosition;
}
if (newRotation != headTransform.rotation.eulerAngles)
{
headTransform.rotation = Quaternion.Euler(newRotation);
}
if (resetHand)
{
headTransform.position = Vector3.zero;
headTransform.rotation = Quaternion.identity;
}
}
}
private void DrawHandsGUI()
{
ControllerSimulationMode newHandSimMode = (ControllerSimulationMode)EditorGUILayout.EnumPopup("Hand Simulation Mode", SimulationService.ControllerSimulationMode);
if (newHandSimMode != SimulationService.ControllerSimulationMode)
{
SimulationService.ControllerSimulationMode = newHandSimMode;
}
using (new GUILayout.HorizontalScope())
{
DrawHandGUI(
"Left",
SimulationService.IsAlwaysVisibleControllerLeft, v => SimulationService.IsAlwaysVisibleControllerLeft = v,
SimulationService.ControllerPositionLeft, v => SimulationService.ControllerPositionLeft = v,
SimulationService.ControllerRotationLeft, v => SimulationService.ControllerRotationLeft = v,
SimulationService.ResetControllerLeft);
DrawHandGUI(
"Right",
SimulationService.IsAlwaysVisibleControllerRight, v => SimulationService.IsAlwaysVisibleControllerRight = v,
SimulationService.ControllerPositionRight, v => SimulationService.ControllerPositionRight = v,
SimulationService.ControllerRotationRight, v => SimulationService.ControllerRotationRight = v,
SimulationService.ResetControllerRight);
}
}
private void DrawHandGUI(string name,
bool isAlwaysVisible, Action<bool> setAlwaysVisible,
Vector3 position, Action<Vector3> setPosition,
Vector3 rotation, Action<Vector3> setRotation,
Action reset)
{
using (new GUILayout.VerticalScope(EditorStyles.helpBox))
{
GUILayout.Label($"{name} Hand:");
bool newIsAlwaysVisible = EditorGUILayout.Toggle("Always Visible", isAlwaysVisible);
Vector3 newPosition = EditorGUILayout.Vector3Field("Position", position);
Vector3 newRotation = DrawRotationGUI("Rotation", rotation);
bool resetHand = GUILayout.Button("Reset");
if (newIsAlwaysVisible != isAlwaysVisible)
{
setAlwaysVisible(newIsAlwaysVisible);
}
if (newPosition != position)
{
setPosition(newPosition);
}
if (newRotation != rotation)
{
setRotation(newRotation);
}
if (resetHand)
{
reset();
}
}
}
private void DrawRecordingGUI()
{
if (RecordingService == null)
{
EditorGUILayout.HelpBox("No input recording service found", MessageType.Info);
return;
}
using (new GUILayout.HorizontalScope())
{
bool newUseTimeLimit = GUILayout.Toggle(RecordingService.UseBufferTimeLimit, "Use buffer time limit");
if (newUseTimeLimit != RecordingService.UseBufferTimeLimit)
{
RecordingService.UseBufferTimeLimit = newUseTimeLimit;
}
using (new EditorGUI.DisabledGroupScope(!RecordingService.UseBufferTimeLimit))
{
float newTimeLimit = EditorGUILayout.FloatField(RecordingService.RecordingBufferTimeLimit);
if (newTimeLimit != RecordingService.RecordingBufferTimeLimit)
{
RecordingService.RecordingBufferTimeLimit = newTimeLimit;
}
}
}
bool wasRecording = RecordingService.IsRecording;
var recordButtonContent = wasRecording
? new GUIContent(iconRecordActive, "Stop recording input animation")
: new GUIContent(iconRecord, "Record new input animation");
bool record = GUILayout.Toggle(wasRecording, recordButtonContent, "Button");
if (record != wasRecording)
{
if (record)
{
RecordingService.StartRecording();
}
else
{
RecordingService.StopRecording();
SaveAnimation(true);
}
}
DrawAnimationInfo();
}
private void DrawPlaybackGUI()
{
DrawAnimationInfo();
using (new GUILayout.HorizontalScope())
{
if (GUILayout.Button("Load ..."))
{
string filepath = EditorUtility.OpenFilePanel(
"Select input animation file",
"",
InputAnimationSerializationUtils.Extension);
LoadAnimation(filepath);
}
}
using (new EditorGUI.DisabledGroupScope(PlaybackService == null))
{
bool wasPlaying = PlaybackService.IsPlaying;
bool play, stepFwd, jumpBack, jumpFwd;
using (new GUILayout.HorizontalScope())
{
jumpBack = GUILayout.Button(new GUIContent(iconJumpBack, "Jump to the start of the input animation"), "Button");
var playButtonContent = wasPlaying
? new GUIContent(iconPause, "Stop playing input animation")
: new GUIContent(iconPlay, "Play back input animation");
play = GUILayout.Toggle(wasPlaying, playButtonContent, "Button");
stepFwd = GUILayout.Button(new GUIContent(iconStepFwd, "Step forward one frame"), "Button");
jumpFwd = GUILayout.Button(new GUIContent(iconJumpFwd, "Jump to the end of the input animation"), "Button");
}
float time = PlaybackService.LocalTime;
float duration = (Animation != null ? Animation.Duration : 0.0f);
float newTimeField = EditorGUILayout.FloatField("Current time", time);
float newTimeSlider = GUILayout.HorizontalSlider(time, 0.0f, duration);
if (play != wasPlaying)
{
if (play)
{
PlaybackService.Play();
}
else
{
PlaybackService.Pause();
}
}
if (jumpBack)
{
PlaybackService.LocalTime = 0.0f;
}
if (jumpFwd)
{
PlaybackService.LocalTime = duration;
}
if (stepFwd)
{
PlaybackService.LocalTime += Time.deltaTime;
}
if (newTimeField != time)
{
PlaybackService.LocalTime = newTimeField;
}
if (newTimeSlider != time)
{
PlaybackService.LocalTime = newTimeSlider;
}
// Repaint while playing to update the timeline
if (PlaybackService.IsPlaying)
{
Repaint();
}
}
}
private void DrawAnimationInfo()
{
using (new GUILayout.VerticalScope(EditorStyles.helpBox))
{
GUILayout.Label("Animation Info:", EditorStyles.boldLabel);
if (Animation != null)
{
GUILayout.Label($"File Path: {loadedFilePath}");
GUILayout.Label($"Duration: {Animation.Duration} seconds");
}
else
{
GUILayout.Label("No animation loaded");
}
}
}
private Vector3 DrawRotationGUI(string label, Vector3 rotation)
{
Vector3 newRotation = EditorGUILayout.Vector3Field(label, rotation);
return newRotation;
}
private void SaveAnimation(bool loadAfterExport)
{
string outputPath;
if (loadedFilePath.Length > 0)
{
string loadedDirectory = Path.GetDirectoryName(loadedFilePath);
outputPath = EditorUtility.SaveFilePanel(
"Select output path",
loadedDirectory,
InputAnimationSerializationUtils.GetOutputFilename(),
InputAnimationSerializationUtils.Extension);
}
else
{
outputPath = EditorUtility.SaveFilePanelInProject(
"Select output path",
InputAnimationSerializationUtils.GetOutputFilename(),
InputAnimationSerializationUtils.Extension,
"Enter filename for exporting input animation");
}
if (outputPath.Length > 0)
{
string filename = Path.GetFileName(outputPath);
string directory = Path.GetDirectoryName(outputPath);
string result = RecordingService.SaveInputAnimation(filename, directory);
RecordingService.DiscardRecordedInput();
if (loadAfterExport)
{
LoadAnimation(result);
}
}
}
private void LoadAnimation(string filepath)
{
if (PlaybackService.LoadInputAnimation(filepath))
{
loadedFilePath = filepath;
}
else
{
loadedFilePath = "";
}
}
private void LoadIcons()
{
// MRTK_TimelinePlay.png
LoadTexture(ref iconPlay, "474f3f21b48daea4f8617806305769ff");
// MRTK_TimelinePause.png
LoadTexture(ref iconPause, "1bfd4df7e86b18640b9fa1af5713bfb9");
// MRTK_TimelineRecord.png
LoadTexture(ref iconRecord, "c079cf55f13c1dc4db7d09053a51a40d");
// MRTK_TimelineRecordActive.png
LoadTexture(ref iconRecordActive, "6752387ee2181ee4fbef5cc74691b6ac");
// MRTK_TimelineStepFwd.png
LoadTexture(ref iconStepFwd, "230b98155638e544892c123d8d674737");
// MRTK_TimelineJumpFwd.png
LoadTexture(ref iconJumpFwd, "3afb597cbd6ec44439ea7b8ce92d957a");
// MRTK_TimelineJumpBack.png
LoadTexture(ref iconJumpBack, "a5d8e80a54741dc459e4f116e1d477f2");
}
private static void LoadTexture(ref Texture2D tex, string fileGuid)
{
if (tex == null)
{
tex = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(fileGuid));
}
}
}
}
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using Microsoft.MixedReality.Toolkit.Utilities.Editor;
using UnityEditor;
using UnityEngine;
using System;
namespace Microsoft.MixedReality.Toolkit.Input
{
/// <summary>
/// Inspector for KeyBindings.
/// This shows a simple dropdown list for selecting a binding, as well as a button for binding keys by pressing them.
/// </summary>
[CustomPropertyDrawer(typeof(KeyBinding))]
public class KeyBindingInspector : PropertyDrawer
{
// Draw the property inside the given rect
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty bindingType = property.FindPropertyRelative("bindingType");
SerializedProperty code = property.FindPropertyRelative("code");
// Using BeginProperty / EndProperty on the parent property means that
// prefab override logic works on the entire property.
EditorGUI.BeginProperty(position, label, property);
// Draw label
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
Rect autoBindPosition = new Rect(position.x + position.width - 20.0f, position.y, 20.0f, position.height);
Rect codePosition = new Rect(position.x, position.y, position.width - 22.0f, position.height);
// Don't make child fields be indented
var indent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
// Show the traditional long dropdown list for selecting a key binding.
if (KeyBinding.KeyBindingToEnumMap.TryGetValue(Tuple.Create((KeyBinding.KeyType)bindingType.intValue, code.intValue), out int index))
{
int newIndex = EditorGUI.Popup(codePosition, index, KeyBinding.AllCodeNames);
if (newIndex != index)
{
if (KeyBinding.EnumToKeyBindingMap.TryGetValue(newIndex, out var kb))
{
bindingType.intValue = (int)kb.Item1;
code.intValue = kb.Item2;
}
}
}
// Show a popup for binding by pressing a key or mouse button.
// Note that this method does not work for shift keys (Unity event limitation)
if (GUI.Button(autoBindPosition, ""))
{
KeyBindingPopupWindow.Show(property);
}
// Set indent back to what it was
EditorGUI.indentLevel = indent;
EditorGUI.EndProperty();
property.serializedObject.ApplyModifiedProperties();
}
}
/// <summary>
/// Utility window that listens to input events to set a key binding.
/// Pressing a key or mouse button will define the binding and then immediately close the popup.
/// </summary>
/// <remarks>
/// The shift keys don't raise input events on their own, so this popup does not work for shift keys.
/// These have to be bound by selecting from the traditional dropdown list.
/// </remarks>
public class KeyBindingPopupWindow : EditorWindow
{
private static KeyBindingPopupWindow window;
private SerializedProperty keyBindingProp;
private SerializedProperty bindingTypeProp;
private SerializedProperty codeProp;
/// <summary>
/// Create a new popup.
/// </summary>
public static void Show(SerializedProperty keyBinding)
{
if (window != null)
{
window.Close();
}
window = null;
window = CreateInstance<KeyBindingPopupWindow>();
window.titleContent = new GUIContent($"Key Binding : {keyBinding.name}");
window.keyBindingProp = keyBinding;
window.bindingTypeProp = keyBinding.FindPropertyRelative("bindingType");
window.codeProp = keyBinding.FindPropertyRelative("code");
var windowSize = new Vector2(256f, 128f);
window.maxSize = windowSize;
window.minSize = windowSize;
window.CenterOnMainWin();
window.ShowUtility();
}
private void OnGUI()
{
Event evt = Event.current;
switch (evt.type)
{
case EventType.KeyUp:
ApplyKeyCode(evt.keyCode);
break;
case EventType.MouseUp:
ApplyMouseButton(evt.button);
break;
}
}
// Set the binding based on a keyboard key
private void ApplyKeyCode(KeyCode keyCode)
{
bindingTypeProp.intValue = (int)KeyBinding.KeyType.Key;
codeProp.intValue = (int)keyCode;
keyBindingProp.serializedObject.ApplyModifiedProperties();
Close();
}
// Set the binding based on a mouse button
private void ApplyMouseButton(int button)
{
bindingTypeProp.intValue = (int)KeyBinding.KeyType.Mouse;
codeProp.intValue = button;
keyBindingProp.serializedObject.ApplyModifiedProperties();
Close();
}
}
}
{
"name": "Microsoft.MixedReality.Toolkit.Services.InputSimulation.Editor",
"references": [
"Microsoft.MixedReality.Toolkit",
"Microsoft.MixedReality.Toolkit.Editor.Inspectors",
"Microsoft.MixedReality.Toolkit.Editor.Utilities",
"Microsoft.MixedReality.Toolkit.Services.InputAnimation",
"Microsoft.MixedReality.Toolkit.Services.InputSystem",
"Microsoft.MixedReality.Toolkit.Services.InputSimulation"
],
"optionalUnityReferences": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment