Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. using System;
  2. using UnityEngine;
  3. #if LIH_PRESENT
  4. using UnityEngine.Experimental.XR.Interaction;
  5. #endif
  6.  
  7. namespace UnityEngine.XR.Interaction.Toolkit
  8. {
  9.     /// <summary>
  10.     /// XRController MonoBehaviour that interprets InputSystem events into
  11.     /// XR Interaction Interactor position, rotation and interaction states.
  12.     /// </summary>
  13.     [DisallowMultipleComponent, AddComponentMenu("XR/XR Controller")]
  14.     public class XRController : MonoBehaviour
  15.     {
  16.         /// <summary>
  17.         /// The update type being used by the tracked pose driver
  18.         /// </summary>
  19.         public enum UpdateType
  20.         {
  21.             /// <summary>
  22.             /// Sample input at both update, and directly before rendering. For smooth head pose tracking,
  23.             /// we recommend using this value as it will provide the lowest input latency for the device.
  24.             /// This is the default value for the UpdateType option
  25.             /// </summary>
  26.             UpdateAndBeforeRender,
  27.             /// <summary>
  28.             /// Only sample input during the update phase of the frame.
  29.             /// </summary>
  30.             Update,
  31.             /// <summary>
  32.             /// Only sample input directly before rendering
  33.             /// </summary>
  34.             BeforeRender,
  35.         }
  36.         [Header("Tracking Configuration")]
  37.                
  38.         [SerializeField]
  39.         [Tooltip("The time within the frame that the XRController will sample input.")]
  40.         UpdateType m_UpdateTrackingType = UpdateType.UpdateAndBeforeRender;
  41.         /// <summary>
  42.         /// The update type being used by the tracked pose driver
  43.         /// </summary>
  44.         public UpdateType updateTrackingType
  45.         {
  46.             get { return m_UpdateTrackingType; }
  47.             set { m_UpdateTrackingType = value; }
  48.         }
  49.  
  50.         bool m_EnableInputTracking = true;
  51.         /// <summary>Gets or sets if input is enabled for this controller.</summary>
  52.         public bool enableInputTracking
  53.         {
  54.             get { return m_EnableInputTracking; }
  55.             set { m_EnableInputTracking = value; }
  56.         }
  57.  
  58.      
  59.         [Header("Configuration")]
  60.        
  61.         [SerializeField, Tooltip("Used to disable an input state changing in the interactor. useful for swapping to a different interactor on the same object")]
  62.         bool m_EnableInputActions = true;
  63.         public bool enableInputActions { get { return m_EnableInputActions; } set { m_EnableInputActions = value; } }
  64.  
  65. #if LIH_PRESENT
  66.         [SerializeField, Tooltip("Pose provider used to provide tracking data separate from the XR Node")]
  67.         BasePoseProvider m_PoseProvider;
  68.         public BasePoseProvider poseProvider { get { return m_PoseProvider; } set { m_PoseProvider = value; } }
  69. #endif
  70.  
  71.         [SerializeField]
  72.         [Tooltip("Gets or sets the XRNode for this controller.")]
  73.         XRNode m_ControllerNode;
  74.         /// <summary>Gets or sets the XRNode for this controller.</summary>
  75.         public XRNode controllerNode { get { return m_ControllerNode; } set { m_ControllerNode = value; } }
  76.        
  77.         [SerializeField]
  78.         [Tooltip("The input usage that triggers a select, activate or uiInteraction action")]
  79.         InputHelpers.Button m_SelectUsage = InputHelpers.Button.Grip;
  80.         /// <summary>Gets or sets the usage to use for detecting selection.</summary>
  81.         public InputHelpers.Button selectUsage { get { return m_SelectUsage; } set { m_SelectUsage = value; } }
  82.  
  83.         [SerializeField]
  84.         [Tooltip("Gets or sets the usage to use for detecting activation.")]
  85.         InputHelpers.Button m_ActivateUsage = InputHelpers.Button.Trigger;
  86.         /// <summary>Gets or sets the usage to use for detecting activation.</summary>
  87.         public InputHelpers.Button activateUsage { get { return m_ActivateUsage; } set { m_ActivateUsage = value; } }
  88.  
  89.         [SerializeField]
  90.         [Tooltip("Gets or sets the usage to use for detecting a UI press.")]
  91.         InputHelpers.Button m_UIPressUsage = InputHelpers.Button.Trigger;
  92.         /// <summary>Gets or sets the usage to use for detecting a UI press.</summary>
  93.         public InputHelpers.Button uiPressUsage { get { return m_UIPressUsage; } set { m_UIPressUsage = value; } }
  94.  
  95.         [SerializeField]
  96.         [Tooltip("Gets or sets the the amount the axis needs to be pressed to trigger an interaction event.")]
  97.         float m_AxisToPressThreshold = 0.1f;
  98.         /// <summary>Gets or sets the the amount the axis needs to be pressed to trigger an interaction event.</summary>
  99.         public float axisToPressThreshold { get { return m_AxisToPressThreshold; } set { m_AxisToPressThreshold = value; } }
  100.  
  101.         [Header("Model")]
  102.  
  103.         [SerializeField]
  104.         [Tooltip("Gets or sets the model prefab to show for this controller.")]
  105.         Transform m_ModelPrefab;
  106.         /// <summary>Gets or sets the model prefab to show for this controller.</summary>
  107.         public Transform modelPrefab { get { return m_ModelPrefab; } set { m_ModelPrefab = value; } }
  108.  
  109.         [SerializeField]
  110.         [Tooltip("Gets or sets the model transform that is used as the parent for the controller model.")]
  111.         Transform m_ModelTransform;
  112.         /// <summary>Gets or sets the model transform that is used as the parent for the controller model.
  113.         /// Note: setting this will not automatically destroy the previous model transform object.
  114.         /// </summary>
  115.         public Transform modelTransform { get { return m_ModelTransform; } }
  116.  
  117.         [SerializeField]
  118.         [Tooltip("Gets or sets whether this model animates in response to interaction events.")]
  119.         bool m_AnimateModel;
  120.         /// <summary>Gets or sets whether this model animates in response to interaction events.</summary>
  121.         public bool animateModel { get { return m_AnimateModel; } set { m_AnimateModel = value; } }
  122.  
  123.         [SerializeField]
  124.         [Tooltip("Gets or sets the animation transition to enable when selecting.")]
  125.         string m_ModelSelectTransition;
  126.         /// <summary>Gets or sets the animation transition to enable when selecting.</summary>
  127.         public string modelSelectTransition { get { return m_ModelSelectTransition; } set { m_ModelSelectTransition = value; } }
  128.  
  129.         [SerializeField]
  130.         [Tooltip("Gets or sets the animation transition to enable when de-selecting.")]
  131.         string m_ModelDeSelectTransition;
  132.         /// <summary>Gets or sets the animation transition to enable when de-selecting.</summary>
  133.         public string modelDeSelectTransition { get { return m_ModelDeSelectTransition; } set { m_ModelDeSelectTransition = value; } }
  134.  
  135.         /// <summary>
  136.         /// InteractionState type to hold current state for a given interaction.
  137.         /// </summary>
  138.         internal struct InteractionState
  139.         {
  140.             /// <summary>This field is true if it is is currently on.</summary>
  141.             public bool active;
  142.             /// <summary>This field is true if the interaction state was activated this frame.</summary>
  143.             public bool activatedThisFrame;
  144.             /// <summary>This field is true if the interaction state was de-activated this frame.</summary>
  145.             public bool deActivatedThisFrame;
  146.         }
  147.  
  148.         internal enum InteractionTypes { select, activate, uiPress };
  149.         InteractionState m_SelectInteractionState;
  150.         InteractionState m_ActivateInteractionState;
  151.         InteractionState m_UIPressInteractionState;
  152.  
  153.         /// <summary>Gets the current select interaction state.</summary>
  154.         internal InteractionState selectInteractionState { get { return m_SelectInteractionState; } }
  155.         /// <summary>Gets the current activate interaction state.</summary>
  156.         internal InteractionState activateInteractionState { get { return m_ActivateInteractionState; } }
  157.         /// <summary>Gets the current ui press interaction state.</summary>
  158.         internal InteractionState uiPressInteractionState { get { return m_UIPressInteractionState; } }
  159.  
  160. ////MODIFIED BY TONY!
  161.         /// <summary>Gets the InputDevice being used to read data from.</summary>
  162.         public InputDeviceWrapper inputDevice
  163.         {
  164.             get
  165.             {
  166.                 return m_InputDevice.isValid ? m_InputDevice : (m_InputDevice = new InputDeviceWrapper(controllerNode));
  167.             }
  168.         }
  169.         private InputDeviceWrapper m_InputDevice;
  170.  
  171.         // Flag to indicate that setup should be (re)performed on Update.
  172.         bool m_PerformSetup = true;
  173.  
  174.         GameObject m_ModelGO;
  175.         bool m_HideControllerModel = false;
  176.  
  177.         /// <summary>Gets or sets whether the controller model should be hidden.</summary>
  178.         public bool hideControllerModel
  179.         {
  180.             get { return m_HideControllerModel; }
  181.             set
  182.             {
  183.                 m_HideControllerModel = value;
  184.                 if (m_ModelGO)
  185.                     m_ModelGO.SetActive(!m_HideControllerModel);
  186.             }
  187.         }
  188.  
  189.         protected virtual void OnEnable()
  190.         {
  191.             Application.onBeforeRender += OnBeforeRender;
  192.         }
  193.  
  194.         protected virtual void OnDisable()
  195.         {
  196.             Application.onBeforeRender -= OnBeforeRender;
  197.         }
  198.  
  199.         protected virtual void OnBeforeRender()
  200.         {
  201.             if (enableInputTracking &&
  202.                (m_UpdateTrackingType == UpdateType.BeforeRender ||
  203.                 m_UpdateTrackingType == UpdateType.UpdateAndBeforeRender))
  204.             {
  205.                 UpdateTrackingInput();
  206.             }
  207.         }
  208.  
  209.         protected virtual void Awake()
  210.         {
  211.             // create empty model transform if none specified
  212.             if (m_ModelTransform == null)
  213.             {
  214.                 var modelGO = new GameObject(string.Format("[{0}] Model", gameObject.name));
  215.                 if (modelGO != null)
  216.                 {
  217.                     m_ModelTransform = modelGO.transform;
  218.                     m_ModelTransform.SetParent(transform);
  219.                     modelGO.transform.localPosition = Vector3.zero;
  220.                     modelGO.transform.localRotation = Quaternion.identity;
  221.                 }
  222.             }
  223.         }
  224.  
  225.         void PerformSetup()
  226.         {
  227.             SetupModel();
  228.         }
  229.  
  230.         void SetupModel()
  231.         {
  232.             if (m_ModelGO)
  233.                 Destroy(m_ModelGO);
  234.             var model = m_ModelPrefab;
  235.             if (model != null)
  236.             {
  237.                 m_ModelGO = Instantiate(model).gameObject;
  238.                 m_ModelGO.transform.parent = m_ModelTransform;
  239.                 m_ModelGO.transform.localPosition = new Vector3(0f, 0f, 0f);
  240.                 m_ModelGO.transform.localRotation = Quaternion.identity;
  241.                 m_ModelGO.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
  242.                 m_ModelGO.transform.gameObject.SetActive(true);
  243.             }
  244.         }
  245.  
  246.         bool ShouldUpdateTrackingInput()
  247.         {
  248.             return enableInputTracking &&
  249.                 (m_UpdateTrackingType == UpdateType.Update ||
  250.                 m_UpdateTrackingType == UpdateType.UpdateAndBeforeRender);
  251.         }
  252.  
  253.         void Update()
  254.         {
  255.             if (m_PerformSetup)
  256.             {
  257.                 PerformSetup();
  258.                 m_PerformSetup = false;
  259.             }
  260.  
  261.             if ( enableInputTracking &&
  262.                 (m_UpdateTrackingType == UpdateType.Update ||
  263.                 m_UpdateTrackingType == UpdateType.UpdateAndBeforeRender))
  264.             {
  265.                 UpdateTrackingInput();
  266.  
  267.             }
  268.  
  269.             if (enableInputActions)
  270.             {
  271.                 UpdateInput();
  272.             }
  273.         }
  274.  
  275.         protected void UpdateTrackingInput()
  276.         {                      
  277.             Vector3 devicePosition = new Vector3();
  278.             Quaternion deviceRotation = new Quaternion();
  279.  
  280. #if LIH_PRESENT_V1API
  281.             if (m_PoseProvider != null)
  282.             {
  283.                 Pose poseProviderPose = new Pose();
  284.                 if(m_PoseProvider.TryGetPoseFromProvider(out poseProviderPose))
  285.                 {
  286.                     transform.localPosition = poseProviderPose.position;
  287.                     transform.localRotation = poseProviderPose.rotation;
  288.                 }
  289.             }
  290.             else
  291. #elif LIH_PRESENT_V2API
  292.             if (m_PoseProvider != null)
  293.             {
  294.                 Pose poseProviderPose = new Pose();
  295.                 var retFlags = m_PoseProvider.GetPoseFromProvider(out poseProviderPose);
  296.                 if ((retFlags & SpatialTracking.PoseDataFlags.Position) > 0)
  297.                 {
  298.                     transform.localPosition = poseProviderPose.position;
  299.                 }
  300.                 if ((retFlags & SpatialTracking.PoseDataFlags.Rotation) > 0)
  301.                 {
  302.                     transform.localRotation = poseProviderPose.rotation;
  303.                 }
  304.             }            
  305.             else
  306. #endif
  307.             {
  308.                 if (inputDevice.TryGetFeatureValue(CommonUsages.devicePosition, out devicePosition))
  309.                     transform.localPosition = devicePosition;
  310.  
  311.                 if (inputDevice.TryGetFeatureValue(CommonUsages.deviceRotation, out deviceRotation))
  312.                     transform.localRotation = deviceRotation;
  313.             }
  314.         }
  315.  
  316.         void UpdateInput()
  317.         {
  318.             // clear state for selection, activation and press state dependent on this frame
  319.             m_SelectInteractionState.activatedThisFrame = m_SelectInteractionState.deActivatedThisFrame = false;
  320.             m_ActivateInteractionState.activatedThisFrame = m_ActivateInteractionState.deActivatedThisFrame = false;
  321.             m_UIPressInteractionState.activatedThisFrame = m_UIPressInteractionState.deActivatedThisFrame = false;
  322.  
  323.             HandleInteractionAction(controllerNode, m_SelectUsage, ref m_SelectInteractionState);
  324.             HandleInteractionAction(controllerNode, m_ActivateUsage, ref m_ActivateInteractionState);
  325.             HandleInteractionAction(controllerNode, m_UIPressUsage, ref m_UIPressInteractionState);
  326.  
  327.             UpdateControllerModelAnimation();
  328.         }
  329.  
  330.         void HandleInteractionAction(XRNode node, InputHelpers.Button button, ref InteractionState interactionState)
  331.         {
  332.             bool pressed = false;
  333.             inputDevice.IsPressed(button, out pressed, m_AxisToPressThreshold);
  334.                
  335.             if (pressed)
  336.             {
  337.                 if (!interactionState.active)
  338.                 {
  339.                     interactionState.activatedThisFrame = true;
  340.                     interactionState.active = true;
  341.                 }
  342.             }
  343.             else
  344.             {
  345.                 if (interactionState.active)
  346.                 {
  347.                     interactionState.deActivatedThisFrame = true;
  348.                     interactionState.active = false;
  349.                 }
  350.             }
  351.         }
  352.  
  353.         // Override the XRController's current interaction state (used for interaction state playback)
  354.         internal void UpdateInteractionType(InteractionTypes interactionStateType, bool isInteractionStateOn)
  355.         {
  356.             switch (interactionStateType)
  357.             {
  358.                 case InteractionTypes.select:
  359.                     UpdateInteractionState(ref m_SelectInteractionState, isInteractionStateOn);
  360.                     break;
  361.                 case InteractionTypes.activate:
  362.                     UpdateInteractionState(ref m_ActivateInteractionState, isInteractionStateOn);
  363.                     break;
  364.                 case InteractionTypes.uiPress:
  365.                     UpdateInteractionState(ref m_UIPressInteractionState, isInteractionStateOn);
  366.                     break;
  367.             }
  368.         }
  369.  
  370.         static void UpdateInteractionState(ref InteractionState interactionState, bool isInteractionStateOn)
  371.         {
  372.             bool previousActive = interactionState.active;
  373.             interactionState.active = isInteractionStateOn;
  374.  
  375.             if (interactionState.active && !previousActive)
  376.                 interactionState.activatedThisFrame = true;
  377.             else if (!interactionState.active && previousActive)
  378.                 interactionState.deActivatedThisFrame = true;
  379.         }
  380.  
  381.         // Override the XRController's controller model's animation (if the prefab contains an animator)
  382.         internal void UpdateControllerModelAnimation()
  383.         {
  384.             if (m_ModelGO && m_AnimateModel)
  385.             {
  386.                 Animator animator = m_ModelGO.GetComponent<Animator>();
  387.                 if (animator)
  388.                 {
  389.                     if (m_SelectInteractionState.activatedThisFrame)
  390.                         animator.SetTrigger(modelSelectTransition);
  391.                     else if (m_SelectInteractionState.deActivatedThisFrame)
  392.                         animator.SetTrigger(modelDeSelectTransition);
  393.                 }
  394.             }
  395.         }
  396.  
  397.         // Override the XRController's current position and rotation (used for interaction state playback)
  398.         internal void UpdateControllerPose(Vector3 position, Quaternion rotation)
  399.         {
  400.             transform.localPosition = position;
  401.             transform.localRotation = rotation;
  402.         }
  403.  
  404.         /// <summary>Play a haptic impulse on the controller if one is available</summary>
  405.         /// <param name="amplitude">Amplitude (from 0.0 to 1.0) to play impulse at.</param>
  406.         /// <param name="duration">Duration (in seconds) to play haptic impulse.</param>
  407.         public bool SendHapticImpulse(float amplitude, float duration)
  408.         {
  409.             HapticCapabilities capabilities;
  410.             if (inputDevice.TryGetHapticCapabilities(out capabilities) &&
  411.                 capabilities.supportsImpulse)
  412.             {
  413.                 return inputDevice.SendHapticImpulse(0, amplitude, duration);
  414.             }
  415.             return false;
  416.         }
  417.     }
  418. }
  419.