88 lines
3.3 KiB
C#
88 lines
3.3 KiB
C#
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
|
|
#pragma warning disable CS0618 // Suppress deprecation warnings
|
|
|
|
using UnityEngine;
|
|
|
|
namespace Microsoft.MixedReality.OpenXR
|
|
{
|
|
/// <summary>
|
|
/// Handles articulation of the animatable parts of a controller model.
|
|
/// </summary>
|
|
public class ControllerModelArticulator : MonoBehaviour
|
|
{
|
|
private ControllerModel m_controllerModel = null;
|
|
private ulong m_modelKey = 0;
|
|
private Transform[] m_animationNodes = null;
|
|
private Pose[] m_poses = null;
|
|
|
|
private bool IsArticulating => m_controllerModel != null && m_modelKey != 0;
|
|
|
|
/// <summary>
|
|
/// Tries to start active articulation of this controller model.
|
|
/// </summary>
|
|
/// <param name="controllerModel">The reference to the controller model this component represents. See <see cref="ControllerModel.Left"/> and <see cref="ControllerModel.Right"/>.</param>
|
|
/// <param name="modelKey">The model key corresponding to the loaded controller model. See <see cref="ControllerModel.TryGetControllerModelKey(out ulong)"/>.</param>
|
|
/// <returns>True if the controller model supports part articulation and articulation was actively started.</returns>
|
|
public bool TryStartArticulating(ControllerModel controllerModel, ulong modelKey)
|
|
{
|
|
if (controllerModel.TryGetControllerModelProperties(modelKey, transform, out m_animationNodes))
|
|
{
|
|
m_controllerModel = controllerModel;
|
|
m_modelKey = modelKey;
|
|
// For updating the node poses in Update. This needs to be the same length as the number of nodes.
|
|
if (m_poses == null || m_poses.Length != m_animationNodes.Length)
|
|
{
|
|
m_poses = new Pose[m_animationNodes.Length];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Disable the built-in, auto-playing glTF animations in the Quest model.
|
|
Animation[] animations = GetComponentsInChildren<Animation>();
|
|
foreach (Animation animation in animations)
|
|
{
|
|
animation.enabled = false;
|
|
}
|
|
}
|
|
|
|
return IsArticulating;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stops any active articulation of this controller model.
|
|
/// </summary>
|
|
public void StopArticulating()
|
|
{
|
|
m_controllerModel = null;
|
|
m_modelKey = 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// The MonoBehaviour Update() callback.
|
|
/// </summary>
|
|
protected void Update()
|
|
{
|
|
if (IsArticulating
|
|
&& m_poses != null
|
|
&& m_animationNodes != null
|
|
&& m_controllerModel.TryGetControllerModelState(m_modelKey, m_poses))
|
|
{
|
|
for (int i = 0; i < m_poses.Length; i++)
|
|
{
|
|
Transform node = m_animationNodes[i];
|
|
Pose pose = m_poses[i];
|
|
|
|
#if UNITY_2021_3_11_OR_NEWER
|
|
node.SetLocalPositionAndRotation(pose.position, pose.rotation);
|
|
#else
|
|
node.localPosition = pose.position;
|
|
node.localRotation = pose.rotation;
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|