summaryrefslogtreecommitdiff
path: root/Assets/Samples/XR Hands/1.6.0/HandVisualizer/Scripts/HandProcessor.cs
diff options
context:
space:
mode:
authorpryazha <pryadeiniv@mail.ru>2025-07-02 08:46:23 -0700
committerpryazha <pryadeiniv@mail.ru>2025-07-02 08:46:23 -0700
commit8263edd59284aba390aca011d25b79efecef4c48 (patch)
tree6346e2afaaabd32156601cafaf20d4ee813befaf /Assets/Samples/XR Hands/1.6.0/HandVisualizer/Scripts/HandProcessor.cs
Diffstat (limited to 'Assets/Samples/XR Hands/1.6.0/HandVisualizer/Scripts/HandProcessor.cs')
-rw-r--r--Assets/Samples/XR Hands/1.6.0/HandVisualizer/Scripts/HandProcessor.cs171
1 files changed, 171 insertions, 0 deletions
diff --git a/Assets/Samples/XR Hands/1.6.0/HandVisualizer/Scripts/HandProcessor.cs b/Assets/Samples/XR Hands/1.6.0/HandVisualizer/Scripts/HandProcessor.cs
new file mode 100644
index 0000000..3c575bc
--- /dev/null
+++ b/Assets/Samples/XR Hands/1.6.0/HandVisualizer/Scripts/HandProcessor.cs
@@ -0,0 +1,171 @@
+using System.Collections.Generic;
+using UnityEngine.XR.Hands.Processing;
+
+namespace UnityEngine.XR.Hands.Samples.VisualizerSample
+{
+ /// <summary>
+ /// Example hand processor that applies transformations on the root poses to
+ /// modify the hands skeleton. Note it is possible to modify the bones
+ /// directly for more advanced use cases that are not shown here.
+ /// </summary>
+ public class HandProcessor : MonoBehaviour, IXRHandProcessor
+ {
+ /// <inheritdoc />
+ public int callbackOrder => 0;
+
+ /// <summary>
+ /// The mode to use for the sample processor.
+ /// </summary>
+ public enum ProcessorExampleMode
+ {
+ /// <summary>
+ /// No processing is applied.
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// Smooths the hand root pose of the left and right hands with interpolated positions
+ /// </summary>
+ Smoothing,
+
+ /// <summary>
+ /// Inverts the left and right hands.
+ /// </summary>
+ Invert
+ }
+
+ // Variables used for smoothing hand movements.
+ bool m_FirstFrame = false;
+ Vector3 m_LastLeftHandPosition;
+ Vector3 m_LastRightHandPosition;
+ Pose m_LeftHandPose = Pose.identity;
+ Pose m_RightHandPose = Pose.identity;
+
+ [SerializeField]
+ [Tooltip("The mode to use for the sample processor.")]
+ ProcessorExampleMode m_ProcessorExampleMode = ProcessorExampleMode.Smoothing;
+ ProcessorExampleMode m_LastProcessorExampleMode = ProcessorExampleMode.None;
+
+ /// <summary>
+ /// The <see cref="ProcessorExampleMode"/> to use for the sample processor.
+ /// </summary>
+ public ProcessorExampleMode processorExampleMode
+ {
+ get => m_ProcessorExampleMode;
+ set => m_ProcessorExampleMode = value;
+ }
+
+ // Smoothing factors for the left and right hands.
+ [Header("Smoothing parameters")]
+ [SerializeField]
+ [Tooltip("The smoothing factor to use when smoothing the root of the left hand in the sample processor. Use 0 for no smoothing.")]
+ float m_LeftHandSmoothingFactor = 16f;
+
+ [SerializeField]
+ [Tooltip("The smoothing factor to use when smoothing the root of the right hand in the sample processor. Use 0 for no smoothing.")]
+ float m_RightHandSmoothingFactor = 16f;
+
+ /// <inheritdoc />
+ public void ProcessJoints(XRHandSubsystem subsystem, XRHandSubsystem.UpdateSuccessFlags successFlags, XRHandSubsystem.UpdateType updateType)
+ {
+ switch (m_ProcessorExampleMode)
+ {
+ case ProcessorExampleMode.Smoothing:
+ SmoothHandsExample(subsystem, successFlags, updateType, m_LastProcessorExampleMode != m_ProcessorExampleMode);
+ break;
+
+ case ProcessorExampleMode.Invert:
+ InvertHandsExample(subsystem, successFlags, updateType);
+ break;
+ }
+
+ m_LastProcessorExampleMode = m_ProcessorExampleMode;
+ }
+
+ // Smooths the hand movements of an XRHandSubsystem by updating the root
+ // pose of the left and right hands with interpolated positions.
+ void SmoothHandsExample(XRHandSubsystem subsystem, XRHandSubsystem.UpdateSuccessFlags successFlags, XRHandSubsystem.UpdateType updateType, bool modeChanged)
+ {
+ var leftHand = subsystem.leftHand;
+ var rightHand = subsystem.rightHand;
+
+ if (leftHand.isTracked && m_LeftHandSmoothingFactor > 0)
+ {
+ var leftPose = leftHand.rootPose;
+ var currentLeftHandPosition = leftPose.position;
+ if (!m_FirstFrame && !modeChanged)
+ {
+ float tweenAmt = Time.deltaTime * m_LeftHandSmoothingFactor;
+ currentLeftHandPosition = Vector3.Lerp(m_LastLeftHandPosition, currentLeftHandPosition, tweenAmt);
+ m_LeftHandPose.position = currentLeftHandPosition;
+ m_LeftHandPose.rotation = leftPose.rotation;
+
+ leftHand.SetRootPose(m_LeftHandPose);
+ subsystem.SetCorrespondingHand(leftHand);
+ }
+ m_LastLeftHandPosition = currentLeftHandPosition;
+ }
+
+ if (rightHand.isTracked && m_RightHandSmoothingFactor > 0)
+ {
+ var rightPose = rightHand.rootPose;
+ var currentRightHandPosition = rightPose.position;
+ if (!m_FirstFrame && !modeChanged)
+ {
+ float tweenAmt = Time.deltaTime * m_RightHandSmoothingFactor;
+ currentRightHandPosition = Vector3.Lerp(m_LastRightHandPosition, currentRightHandPosition, tweenAmt);
+ m_RightHandPose.position = currentRightHandPosition;
+ m_RightHandPose.rotation = rightPose.rotation;
+
+ rightHand.SetRootPose(m_RightHandPose);
+ subsystem.SetCorrespondingHand(rightHand);
+ }
+ m_LastRightHandPosition = currentRightHandPosition;
+ }
+ }
+
+ // Call this from process joints to try inverting the user's hands.
+ void InvertHandsExample(XRHandSubsystem subsystem, XRHandSubsystem.UpdateSuccessFlags successFlags, XRHandSubsystem.UpdateType updateType)
+ {
+ var leftHand = subsystem.leftHand;
+ var leftHandPose = leftHand.rootPose;
+
+ var rightHand = subsystem.rightHand;
+ var rightHandPose = rightHand.rootPose;
+
+ if (leftHand.isTracked)
+ {
+ leftHand.SetRootPose(rightHandPose);
+ subsystem.SetCorrespondingHand(leftHand);
+
+ rightHand.SetRootPose(leftHandPose);
+ subsystem.SetCorrespondingHand(rightHand);
+ }
+ }
+
+ void Update()
+ {
+ if (m_Subsystem != null)
+ return;
+
+ SubsystemManager.GetSubsystems(s_SubsystemsReuse);
+ if (s_SubsystemsReuse.Count == 0)
+ return;
+
+ m_Subsystem = s_SubsystemsReuse[0];
+ m_Subsystem.RegisterProcessor(this);
+ }
+
+ void OnDisable()
+ {
+ if (m_Subsystem != null)
+ {
+ m_Subsystem.UnregisterProcessor(this);
+ m_Subsystem = null;
+ }
+ }
+
+ XRHandSubsystem m_Subsystem;
+ static List<XRHandSubsystem> s_SubsystemsReuse = new List<XRHandSubsystem>();
+ }
+}