Add ultimate xr
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32f22795408987f42bb073e358835363
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrHpReverbG2Input.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
using UltimateXR.Devices.Integrations.Microsoft;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.HP
|
||||
{
|
||||
/// <summary>
|
||||
/// HP Reverb G2 Input.
|
||||
/// </summary>
|
||||
public class UxrHpReverbG2Input : UxrWindowsMixedRealityInput
|
||||
{
|
||||
#region Public Overrides UxrWindowsMixedRealityInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return "HP Reverb G2 Controller";
|
||||
yield return "HP Reverb G2 Controller OpenXR";
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick |
|
||||
UxrControllerElements.Joystick2 |
|
||||
UxrControllerElements.Grip |
|
||||
UxrControllerElements.Trigger |
|
||||
UxrControllerElements.Button1 |
|
||||
UxrControllerElements.Button2 |
|
||||
UxrControllerElements.Menu |
|
||||
UxrControllerElements.DPad);
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd7aa825077847641b535866ae4258b9
|
||||
timeCreated: 1499677449
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrHpReverbG2Tracking.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Devices.Integrations.Microsoft;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.HP
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking component for HP Reverb G2.
|
||||
/// </summary>
|
||||
public class UxrHpReverbG2Tracking : UxrWindowsMixedRealityTracking
|
||||
{
|
||||
#region Public Overrides UxrWindowsMixedRealityTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrHpReverbG2Input);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85e5b3a94d5599c4982fe887142e1201
|
||||
timeCreated: 1499842642
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7ef432f4a08f6348b5b1e4e3ca778e4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,63 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrHtcViveCosmosInput.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
using UltimateXR.Devices.Integrations.SteamVR;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.HTC
|
||||
{
|
||||
/// <summary>
|
||||
/// HTC Vive Cosmos controllers input using SteamVR.
|
||||
/// </summary>
|
||||
public class UxrHtcViveCosmosInput : UxrSteamVRControllerInput
|
||||
{
|
||||
#region Public Overrides UxrSteamVRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get { yield return ControllerNameHtcViveCosmos; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool MainJoystickIsTouchpad => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick | // Joystick
|
||||
UxrControllerElements.Grip | // Grip
|
||||
UxrControllerElements.Bumper | // Bumper
|
||||
UxrControllerElements.Trigger | // Trigger
|
||||
UxrControllerElements.Button1 | // Button A/X
|
||||
UxrControllerElements.Button2 | // Button B/Y
|
||||
UxrControllerElements.DPad); // Joystick
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
|
||||
{
|
||||
return UxrControllerInputCapabilities.HapticImpulses;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Types & Data
|
||||
|
||||
private const string ControllerNameHtcViveCosmos = "vive_cosmos_controller";
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aeb548548ec3cdb489de559527782aee
|
||||
timeCreated: 1499677449
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrHtcViveCosmosTracking.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Devices.Integrations.SteamVR;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.HTC
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking for HTC Vive Cosmos controllers using SteamVR SDK.
|
||||
/// </summary>
|
||||
public class UxrHtcViveCosmosTracking : UxrSteamVRControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrControllerTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrHtcViveCosmosInput);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7aaab42f00bf7ad4bb5388a08c575a4d
|
||||
timeCreated: 1499842642
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,85 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrHtcViveFocus3Input.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.HTC
|
||||
{
|
||||
/// <summary>
|
||||
/// HTC Vive Focus 3 controller input using WaveXR SDK's UnityXR support.
|
||||
/// </summary>
|
||||
public class UxrHtcViveFocus3Input : UxrUnityXRControllerInput
|
||||
{
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SDK dependency: Wave XR.
|
||||
/// </summary>
|
||||
public override string SDKDependency => UxrConstants.SdkWaveXR;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsHandednessSupported => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool MainJoystickIsTouchpad => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick |
|
||||
UxrControllerElements.Grip |
|
||||
UxrControllerElements.Trigger |
|
||||
UxrControllerElements.Button1 |
|
||||
UxrControllerElements.Button2 |
|
||||
UxrControllerElements.Menu |
|
||||
UxrControllerElements.DPad);
|
||||
|
||||
if (handSide == UxrHandSide.Right)
|
||||
{
|
||||
// Remove menu button from right controller, which is reserved.
|
||||
validElements = validElements & ~(uint)UxrControllerElements.Menu;
|
||||
}
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrUnityXRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return "WVR_CR_Left_001";
|
||||
yield return "WVR_CR_Right_001";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Overrides UxrUnityXRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateInput()
|
||||
{
|
||||
base.UpdateInput();
|
||||
|
||||
// To avoid grip requiring to press the whole button, we use the analog value and a threshold
|
||||
|
||||
float gripThreshold = 0.7f;
|
||||
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Grip, GetInput1D(UxrHandSide.Left, UxrInput1D.Grip) > gripThreshold);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Grip, GetInput1D(UxrHandSide.Right, UxrInput1D.Grip) > gripThreshold);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99f34313b313be54fa63910a496c06a7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrHtcViveFocus3Tracking.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Core;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.HTC
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking for HTC Vive Focus 3 controllers using WaveXR SDK's UnityXR support.
|
||||
/// </summary>
|
||||
public class UxrHtcViveFocus3Tracking : UxrUnityXRControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrControllerTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrHtcViveFocus3Input);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrTrackingDevice
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string SDKDependency => UxrConstants.SdkWaveXR;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 74d5790b838df3441b94784597d32e7a
|
||||
timeCreated: 1499842642
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,78 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrHtcViveInput.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
using UltimateXR.Devices.Integrations.SteamVR;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.HTC
|
||||
{
|
||||
/// <summary>
|
||||
/// HTC Vive controllers input using SteamVR.
|
||||
/// </summary>
|
||||
public class UxrHtcViveInput : UxrSteamVRControllerInput
|
||||
{
|
||||
#region Public Overrides UxrSteamVRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return "controller_vive";
|
||||
yield return "Vive. Controller MV";
|
||||
yield return "Vive. Controller Pro MV";
|
||||
yield return "VIVE Controller MV";
|
||||
yield return "VIVE Controller Pro MV";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override float GetInput1D(UxrHandSide handSide, UxrInput1D input1D, bool getIgnoredInput = false)
|
||||
{
|
||||
// Since Vive controllers don't have an analog grip button, make sure the analog
|
||||
// grip functionality is supported.
|
||||
if (input1D == UxrInput1D.Grip)
|
||||
{
|
||||
return GetButtonsPress(handSide, UxrInputButtons.Grip, getIgnoredInput) ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool MainJoystickIsTouchpad => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick | // Joystick
|
||||
UxrControllerElements.Grip | // Grip
|
||||
UxrControllerElements.Trigger | // Trigger
|
||||
UxrControllerElements.Button1 | // Button A,
|
||||
UxrControllerElements.Button2 |
|
||||
UxrControllerElements.Menu |
|
||||
UxrControllerElements.DPad); // Joystick
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
|
||||
{
|
||||
return UxrControllerInputCapabilities.HapticImpulses;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ab26074711a00449bb89e018281422d
|
||||
timeCreated: 1499677449
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrHtcViveTracking.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Devices.Integrations.SteamVR;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.HTC
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking for HTC Vive controllers using SteamVR SDK.
|
||||
/// </summary>
|
||||
public class UxrHtcViveTracking : UxrSteamVRControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrControllerTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrHtcViveInput);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f9f613010cce8f0408243773fe913d9f
|
||||
timeCreated: 1499842642
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 570a4a7e3a0905c42a29df863535996b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,126 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrMagicLeap2Input.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.MagicLeap
|
||||
{
|
||||
/// <summary>
|
||||
/// Magic Leap 2 controller input using Magic Leap SDK.
|
||||
/// </summary>
|
||||
public class UxrMagicLeap2Input : UxrUnityXRControllerInput
|
||||
{
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SDK dependency: Magic Leap 2.
|
||||
/// </summary>
|
||||
public override string SDKDependency => UxrConstants.SdkMagicLeap;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsHandednessSupported => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool MainJoystickIsTouchpad => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick |
|
||||
UxrControllerElements.Trigger |
|
||||
UxrControllerElements.Grip |
|
||||
UxrControllerElements.Bumper |
|
||||
UxrControllerElements.Menu |
|
||||
UxrControllerElements.DPad);
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrUnityXRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get { yield return "MagicLeap Controller"; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Trigger Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnDeviceConnected(UxrDeviceConnectEventArgs e)
|
||||
{
|
||||
base.OnDeviceConnected(e);
|
||||
|
||||
#if ULTIMATEXR_USE_MAGICLEAP_SDK
|
||||
if (e.IsConnected)
|
||||
{
|
||||
_mlInputs = new MagicLeapInputs();
|
||||
_mlInputs.Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_mlInputs != null)
|
||||
{
|
||||
_mlInputs.Dispose();
|
||||
_mlInputs = null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Overrides UxrUnityXRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateInput()
|
||||
{
|
||||
base.UpdateInput();
|
||||
|
||||
// Propagate touchpad touch to press, since only touch is signaled by the API
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick, GetButtonsTouch(UxrHandSide.Left, UxrInputButtons.Joystick));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Joystick, GetButtonsTouch(UxrHandSide.Right, UxrInputButtons.Joystick));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool HasButtonContactOther(UxrHandSide handSide, UxrInputButtons button, ButtonContact buttonContact)
|
||||
{
|
||||
#if ULTIMATEXR_USE_MAGICLEAP_SDK
|
||||
if (button == UxrInputButtons.Bumper)
|
||||
{
|
||||
return _mlInputs.Controller.Bumper.IsPressed();
|
||||
}
|
||||
|
||||
// To allow quick integration with UltimateXR manipulation, and since the ML2 doesn't have a grip button, we map
|
||||
// the bumper to the grip too.
|
||||
|
||||
if (button == UxrInputButtons.Grip)
|
||||
{
|
||||
return _mlInputs.Controller.Bumper.IsPressed();
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Types & Data
|
||||
|
||||
#if ULTIMATEXR_USE_MAGICLEAP_SDK
|
||||
private MagicLeapInputs _mlInputs;
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3110ba3566d315a41af6c0e8535ee19b
|
||||
timeCreated: 1499677449
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrMagicLeap2Tracking.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Core;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.MagicLeap
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking for Magic Leap 2 devices using the Magic Leap SDK.
|
||||
/// </summary>
|
||||
public class UxrMagicLeap2Tracking : UxrUnityXRControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrControllerTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrMagicLeap2Input);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrTrackingDevice
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsMixedRealityDevice => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string SDKDependency => UxrConstants.SdkMagicLeap;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 207d5725f18c1eb4eaba95a17cdf1794
|
||||
timeCreated: 1499842642
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc2e3b5030e4f874b8db7909c4b35781
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrMetaHandTracking.FlipMode.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace UltimateXR.Devices.Integrations.Meta
|
||||
{
|
||||
public partial class UxrMetaHandTracking
|
||||
{
|
||||
#region Private Types & Data
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates the different ways to retrieve an Oculus SDK Quaternion.
|
||||
/// </summary>
|
||||
private enum FlipMode
|
||||
{
|
||||
None,
|
||||
FlipX,
|
||||
FlipZ
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42cd7d7680024864810a8c3cf3a42dbc
|
||||
timeCreated: 1654777476
|
||||
@@ -0,0 +1,266 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrMetaHandTracking.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using UltimateXR.Core;
|
||||
#if ULTIMATEXR_USE_OCULUS_SDK
|
||||
using UltimateXR.Avatar.Rig;
|
||||
using UltimateXR.Core.Math;
|
||||
using UltimateXR.Extensions.Unity.Math;
|
||||
using UnityEngine;
|
||||
#endif
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Meta
|
||||
{
|
||||
/// <summary>
|
||||
/// Hand tracking for Meta devices.
|
||||
/// </summary>
|
||||
public partial class UxrMetaHandTracking : UxrHandTracking
|
||||
{
|
||||
#region Public Overrides UxrTrackingDevice
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string SDKDependency => UxrConstants.SdkOculus;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrHandTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsLeftHandAvailable
|
||||
{
|
||||
get
|
||||
{
|
||||
#if ULTIMATEXR_USE_OCULUS_SDK
|
||||
if (OVRPlugin.GetHandState(OVRPlugin.Step.Render, OVRPlugin.Hand.HandLeft, ref _leftHandState))
|
||||
{
|
||||
_isLeftHandAvailable = _leftHandState.Status.HasFlag(OVRPlugin.HandStatus.HandTracked);
|
||||
}
|
||||
else
|
||||
{
|
||||
_isLeftHandAvailable = false;
|
||||
}
|
||||
return _isLeftHandAvailable;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsRightHandAvailable
|
||||
{
|
||||
get
|
||||
{
|
||||
#if ULTIMATEXR_USE_OCULUS_SDK
|
||||
if (OVRPlugin.GetHandState(OVRPlugin.Step.Render, OVRPlugin.Hand.HandRight, ref _rightHandState))
|
||||
{
|
||||
_isRightHandAvailable = _rightHandState.Status.HasFlag(OVRPlugin.HandStatus.HandTracked);
|
||||
}
|
||||
else
|
||||
{
|
||||
_isRightHandAvailable = false;
|
||||
}
|
||||
return _isRightHandAvailable;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unity
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes to events so that the component can be enabled or disabled based on the presence of hand tracking.
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
#if ULTIMATEXR_USE_OCULUS_SDK
|
||||
// Initialize axis system
|
||||
|
||||
if (Avatar != null && Avatar.LeftHand.HasFullHandData())
|
||||
{
|
||||
_leftHandOculusRotation = Quaternion.LookRotation(Vector3.right, -Vector3.up);
|
||||
_leftFingerOculusRotation = Quaternion.LookRotation(-Vector3.right, -Vector3.up);
|
||||
}
|
||||
|
||||
if (Avatar != null && Avatar.RightHand.HasFullHandData())
|
||||
{
|
||||
_rightHandOculusRotation = Quaternion.LookRotation(Vector3.right, Vector3.up);
|
||||
_rightFingerOculusRotation = Quaternion.LookRotation(Vector3.right, Vector3.up);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Overrides UxrTrackingDevice
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateSensors()
|
||||
{
|
||||
#if ULTIMATEXR_USE_OCULUS_SDK
|
||||
_isLeftHandAvailable = OVRPlugin.GetHandState(OVRPlugin.Step.Render, OVRPlugin.Hand.HandLeft, ref _leftHandState);
|
||||
_isRightHandAvailable = OVRPlugin.GetHandState(OVRPlugin.Step.Render, OVRPlugin.Hand.HandRight, ref _rightHandState);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateAvatar()
|
||||
{
|
||||
#if ULTIMATEXR_USE_OCULUS_SDK
|
||||
|
||||
Transform wristLeft = Avatar.LeftHandBone;
|
||||
Transform wristRight = Avatar.RightHandBone;
|
||||
|
||||
if (_isLeftHandAvailable && wristLeft != null)
|
||||
{
|
||||
if (UseCalibration)
|
||||
{
|
||||
SetCalibrationPose(UxrHandSide.Left);
|
||||
}
|
||||
|
||||
UxrAvatarArmInfo leftArmInfo = Avatar.AvatarRigInfo.GetArmInfo(UxrHandSide.Left);
|
||||
UxrUniversalLocalAxes leftHandParentAxes = wristLeft.parent == Avatar.AvatarRig.LeftArm.Forearm ? leftArmInfo.ForearmUniversalLocalAxes : leftArmInfo.HandUniversalLocalAxes;
|
||||
|
||||
Vector3 sensorLeftPos = Avatar.transform.TransformPoint(_leftHandState.RootPose.Position.FromFlippedZVector3f());
|
||||
Quaternion sensorLeftRot = Avatar.transform.rotation * ToCorrectCoordinateSystem(_leftHandState.RootPose.Orientation, FlipMode.FlipZ, _leftHandOculusRotation, leftHandParentAxes, leftArmInfo.HandUniversalLocalAxes);
|
||||
|
||||
wristLeft.position = sensorLeftPos;
|
||||
wristLeft.rotation = sensorLeftRot;
|
||||
|
||||
UpdateFinger(UxrHandSide.Left, Avatar.LeftHand.Index, OVRPlugin.BoneId.Hand_Index1, 3, _leftFingerOculusRotation, leftArmInfo.HandUniversalLocalAxes, leftArmInfo.FingerUniversalLocalAxes);
|
||||
UpdateFinger(UxrHandSide.Left, Avatar.LeftHand.Middle, OVRPlugin.BoneId.Hand_Middle1, 3, _leftFingerOculusRotation, leftArmInfo.HandUniversalLocalAxes, leftArmInfo.FingerUniversalLocalAxes);
|
||||
UpdateFinger(UxrHandSide.Left, Avatar.LeftHand.Ring, OVRPlugin.BoneId.Hand_Ring1, 3, _leftFingerOculusRotation, leftArmInfo.HandUniversalLocalAxes, leftArmInfo.FingerUniversalLocalAxes);
|
||||
UpdateFinger(UxrHandSide.Left, Avatar.LeftHand.Little, OVRPlugin.BoneId.Hand_Pinky0, 4, _leftFingerOculusRotation, leftArmInfo.HandUniversalLocalAxes, leftArmInfo.FingerUniversalLocalAxes);
|
||||
UpdateFinger(UxrHandSide.Left, Avatar.LeftHand.Thumb, OVRPlugin.BoneId.Hand_Thumb0, 4, _leftFingerOculusRotation, leftArmInfo.HandUniversalLocalAxes, leftArmInfo.FingerUniversalLocalAxes);
|
||||
}
|
||||
|
||||
if (_isRightHandAvailable && wristRight != null)
|
||||
{
|
||||
if (UseCalibration)
|
||||
{
|
||||
SetCalibrationPose(UxrHandSide.Right);
|
||||
}
|
||||
|
||||
UxrAvatarArmInfo rightArmInfo = Avatar.AvatarRigInfo.GetArmInfo(UxrHandSide.Right);
|
||||
UxrUniversalLocalAxes rightHandParentAxes = wristRight.parent == Avatar.AvatarRig.RightArm.Forearm ? rightArmInfo.ForearmUniversalLocalAxes : rightArmInfo.HandUniversalLocalAxes;
|
||||
|
||||
Vector3 sensorRightPos = Avatar.transform.TransformPoint(_rightHandState.RootPose.Position.FromFlippedZVector3f());
|
||||
Quaternion sensorRightRot = Avatar.transform.rotation * ToCorrectCoordinateSystem(_rightHandState.RootPose.Orientation, FlipMode.FlipZ, _rightHandOculusRotation, rightHandParentAxes, rightArmInfo.HandUniversalLocalAxes);
|
||||
|
||||
wristRight.position = sensorRightPos;
|
||||
wristRight.rotation = sensorRightRot;
|
||||
|
||||
UpdateFinger(UxrHandSide.Right, Avatar.RightHand.Index, OVRPlugin.BoneId.Hand_Index1, 3, _rightFingerOculusRotation, rightArmInfo.HandUniversalLocalAxes, rightArmInfo.FingerUniversalLocalAxes);
|
||||
UpdateFinger(UxrHandSide.Right, Avatar.RightHand.Middle, OVRPlugin.BoneId.Hand_Middle1, 3, _rightFingerOculusRotation, rightArmInfo.HandUniversalLocalAxes, rightArmInfo.FingerUniversalLocalAxes);
|
||||
UpdateFinger(UxrHandSide.Right, Avatar.RightHand.Ring, OVRPlugin.BoneId.Hand_Ring1, 3, _rightFingerOculusRotation, rightArmInfo.HandUniversalLocalAxes, rightArmInfo.FingerUniversalLocalAxes);
|
||||
UpdateFinger(UxrHandSide.Right, Avatar.RightHand.Little, OVRPlugin.BoneId.Hand_Pinky1, 3, _rightFingerOculusRotation, rightArmInfo.HandUniversalLocalAxes, rightArmInfo.FingerUniversalLocalAxes);
|
||||
UpdateFinger(UxrHandSide.Right, Avatar.RightHand.Thumb, OVRPlugin.BoneId.Hand_Thumb0, 4, _rightFingerOculusRotation, rightArmInfo.HandUniversalLocalAxes, rightArmInfo.FingerUniversalLocalAxes);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#if ULTIMATEXR_USE_OCULUS_SDK
|
||||
|
||||
/// <summary>
|
||||
/// Updates a finger using tracking information.
|
||||
/// </summary>
|
||||
/// <param name="handSide">Which hand the finger belongs to</param>
|
||||
/// <param name="avatarFinger">The avatar finger to update</param>
|
||||
/// <param name="baseBoneId">The oculus bone base id</param>
|
||||
/// <param name="boneCount">The number of bones to update, usually 2, 3 or 4</param>
|
||||
/// <param name="fingerOculusRotation">Oculus finger coordinate system</param>
|
||||
/// <param name="wristUniversalLocalAxes">Avatar wrist coordinate system</param>
|
||||
/// <param name="fingerUniversalLocalAxes">Avatar finger coordinate system</param>
|
||||
private void UpdateFinger(UxrHandSide handSide, UxrAvatarFinger avatarFinger, OVRPlugin.BoneId baseBoneId, int boneCount, Quaternion fingerOculusRotation, UxrUniversalLocalAxes wristUniversalLocalAxes, UxrUniversalLocalAxes fingerUniversalLocalAxes)
|
||||
{
|
||||
int baseIndex = (int)baseBoneId;
|
||||
|
||||
OVRPlugin.HandState handState = handSide == UxrHandSide.Left ? _leftHandState : _rightHandState;
|
||||
FlipMode flipMode = handSide == UxrHandSide.Left ? FlipMode.FlipX : FlipMode.FlipZ;
|
||||
|
||||
if (boneCount > 3)
|
||||
{
|
||||
if (avatarFinger.Metacarpal != null)
|
||||
{
|
||||
avatarFinger.Metacarpal.localRotation = ToCorrectCoordinateSystem(handState.BoneRotations[baseIndex], flipMode, fingerOculusRotation, wristUniversalLocalAxes, fingerUniversalLocalAxes);
|
||||
ApplyBoneCalibration(avatarFinger.Metacarpal);
|
||||
}
|
||||
|
||||
baseIndex++;
|
||||
}
|
||||
|
||||
if (boneCount > 2)
|
||||
{
|
||||
avatarFinger.Proximal.localRotation = ToCorrectCoordinateSystem(handState.BoneRotations[baseIndex], flipMode, fingerOculusRotation, avatarFinger.Metacarpal == null ? wristUniversalLocalAxes : fingerUniversalLocalAxes, fingerUniversalLocalAxes);
|
||||
ApplyBoneCalibration(avatarFinger.Proximal);
|
||||
|
||||
baseIndex++;
|
||||
}
|
||||
|
||||
avatarFinger.Intermediate.localRotation = ToCorrectCoordinateSystem(handState.BoneRotations[baseIndex], flipMode, fingerOculusRotation, fingerUniversalLocalAxes, fingerUniversalLocalAxes);
|
||||
avatarFinger.Distal.localRotation = ToCorrectCoordinateSystem(handState.BoneRotations[baseIndex + 1], flipMode, fingerOculusRotation, fingerUniversalLocalAxes, fingerUniversalLocalAxes);
|
||||
|
||||
ApplyBoneCalibration(avatarFinger.Intermediate);
|
||||
ApplyBoneCalibration(avatarFinger.Distal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a rotation from the Oculus SDK coordinate system to the avatar coordinate system.
|
||||
/// </summary>
|
||||
/// <param name="oculusRotation">Oculus rotation to convert</param>
|
||||
/// <param name="flipRotation">How to process the rotation</param>
|
||||
/// <param name="oculusAxes">
|
||||
/// Information that converts from the "universal" coordinate system to the coordinate
|
||||
/// system used by the parent's node.
|
||||
/// </param>
|
||||
/// <param name="parentUniversalLocalAxes"></param>
|
||||
/// <param name="universalLocalAxes">
|
||||
/// Information that converts from the "universal" coordinate system to the coordinate
|
||||
/// system used by the node.
|
||||
/// </param>
|
||||
/// <returns>Rotation in the avatar coordinate system</returns>
|
||||
private Quaternion ToCorrectCoordinateSystem(OVRPlugin.Quatf oculusRotation, FlipMode flipRotation, Quaternion oculusAxes, UxrUniversalLocalAxes parentUniversalLocalAxes, UxrUniversalLocalAxes universalLocalAxes)
|
||||
{
|
||||
Quaternion rotation = oculusRotation.FromQuatf();
|
||||
|
||||
switch (flipRotation)
|
||||
{
|
||||
case FlipMode.FlipX:
|
||||
rotation = oculusRotation.FromFlippedXQuatf();
|
||||
break;
|
||||
|
||||
case FlipMode.FlipZ:
|
||||
rotation = oculusRotation.FromFlippedZQuatf();
|
||||
break;
|
||||
}
|
||||
|
||||
Quaternion finalRotation = Quaternion.Inverse(parentUniversalLocalAxes.UniversalToActualAxesRotation) * universalLocalAxes.UniversalToActualAxesRotation * rotation * Quaternion.Inverse(oculusAxes) * universalLocalAxes.UniversalToActualAxesRotation;
|
||||
return finalRotation.IsValid() ? finalRotation : Quaternion.identity;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if ULTIMATEXR_USE_OCULUS_SDK
|
||||
|
||||
private bool _isLeftHandAvailable;
|
||||
private bool _isRightHandAvailable;
|
||||
private OVRPlugin.HandState _leftHandState;
|
||||
private OVRPlugin.HandState _rightHandState;
|
||||
private Quaternion _leftHandOculusRotation;
|
||||
private Quaternion _rightHandOculusRotation;
|
||||
private Quaternion _leftFingerOculusRotation;
|
||||
private Quaternion _rightFingerOculusRotation;
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d33e531453e48da93053497271b4abd
|
||||
timeCreated: 1654764133
|
||||
@@ -0,0 +1,72 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrMetaTouchQuest2Input.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Meta
|
||||
{
|
||||
/// <summary>
|
||||
/// Oculus Touch controller input using Oculus SDK.
|
||||
/// </summary>
|
||||
public class UxrMetaTouchQuest2Input : UxrUnityXRControllerInput
|
||||
{
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SDK dependency: Oculus SDK.
|
||||
/// </summary>
|
||||
public override string SDKDependency => UxrConstants.SdkOculus;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsHandednessSupported => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool MainJoystickIsTouchpad => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick |
|
||||
UxrControllerElements.Grip |
|
||||
UxrControllerElements.Trigger |
|
||||
UxrControllerElements.ThumbCapSense |
|
||||
UxrControllerElements.Button1 |
|
||||
UxrControllerElements.Button2 |
|
||||
UxrControllerElements.Menu |
|
||||
UxrControllerElements.DPad);
|
||||
|
||||
if (handSide == UxrHandSide.Right)
|
||||
{
|
||||
// Remove menu button from right controller, which is reserved.
|
||||
validElements = validElements & ~(uint)UxrControllerElements.Menu;
|
||||
}
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrUnityXRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get
|
||||
{
|
||||
if (UxrTrackingDevice.HeadsetDeviceName is "Oculus Quest2")
|
||||
{
|
||||
yield return "Oculus Touch Controller - Left";
|
||||
yield return "Oculus Touch Controller - Right";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ff66b86132a55f4a9f6efea46da64bb
|
||||
timeCreated: 1499677449
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,65 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrMetaTouchQuest2InputSteamVR.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
using UltimateXR.Devices.Integrations.SteamVR;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Meta
|
||||
{
|
||||
/// <summary>
|
||||
/// Oculus Touch controllers input using SteamVR.
|
||||
/// </summary>
|
||||
public class UxrMetaTouchQuest2InputSteamVR : UxrSteamVRControllerInput
|
||||
{
|
||||
#region Public Overrides UxrSteamVRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return "Oculus Quest2 (Left Controller)";
|
||||
yield return "Oculus Quest2 (Right Controller)";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool MainJoystickIsTouchpad => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick | // Joystick
|
||||
UxrControllerElements.Grip | // Grip
|
||||
UxrControllerElements.Trigger | // Trigger
|
||||
UxrControllerElements.Button1 | // Button A
|
||||
UxrControllerElements.Button2 | // Button B
|
||||
UxrControllerElements.DPad);
|
||||
|
||||
if (handSide == UxrHandSide.Left)
|
||||
{
|
||||
validElements |= (uint)UxrControllerElements.Menu;
|
||||
}
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
|
||||
{
|
||||
return UxrControllerInputCapabilities.HapticImpulses;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e34315eb5a4f11d41ade48a0c1a86715
|
||||
timeCreated: 1499677449
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrMetaTouchQuest2Tracking.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Core;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Meta
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking for Oculus Touch devices using the Oculus SDK.
|
||||
/// </summary>
|
||||
public class UxrMetaTouchQuest2Tracking : UxrUnityXRControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrControllerTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrMetaTouchQuest2Input);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrTrackingDevice
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string SDKDependency => UxrConstants.SdkOculus;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 793d8fce02a8c7a42a9414fb6f5d3dc1
|
||||
timeCreated: 1499842642
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrMetaTouchQuest2TrackingSteamVR.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Devices.Integrations.SteamVR;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Meta
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking for Oculus Touch controllers using SteamVR SDK.
|
||||
/// </summary>
|
||||
public class UxrMetaTouchQuest2TrackingSteamVR : UxrSteamVRControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrControllerTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrMetaTouchQuest2InputSteamVR);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 813e0bb28152bed4ea5c634099e04934
|
||||
timeCreated: 1624443263
|
||||
@@ -0,0 +1,72 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrMetaTouchQuest3Input.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Meta
|
||||
{
|
||||
/// <summary>
|
||||
/// Oculus Touch controller input using Oculus SDK.
|
||||
/// </summary>
|
||||
public class UxrMetaTouchQuest3Input : UxrUnityXRControllerInput
|
||||
{
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SDK dependency: Oculus SDK.
|
||||
/// </summary>
|
||||
public override string SDKDependency => UxrConstants.SdkOculus;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsHandednessSupported => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool MainJoystickIsTouchpad => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick |
|
||||
UxrControllerElements.Grip |
|
||||
UxrControllerElements.Trigger |
|
||||
UxrControllerElements.ThumbCapSense |
|
||||
UxrControllerElements.Button1 |
|
||||
UxrControllerElements.Button2 |
|
||||
UxrControllerElements.Menu |
|
||||
UxrControllerElements.DPad);
|
||||
|
||||
if (handSide == UxrHandSide.Right)
|
||||
{
|
||||
// Remove menu button from right controller, which is reserved.
|
||||
validElements = validElements & ~(uint)UxrControllerElements.Menu;
|
||||
}
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrUnityXRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get
|
||||
{
|
||||
if (UxrTrackingDevice.HeadsetDeviceName is "Oculus Quest3" or "Meta Quest 3" or "Oculus Headset2")
|
||||
{
|
||||
yield return "Oculus Touch Controller - Left";
|
||||
yield return "Oculus Touch Controller - Right";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd07cb58266720f478deb9264c45c614
|
||||
timeCreated: 1499677449
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,67 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrMetaTouchQuest3InputSteamVR.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
using UltimateXR.Devices.Integrations.SteamVR;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Meta
|
||||
{
|
||||
/// <summary>
|
||||
/// Oculus Touch controllers input using SteamVR.
|
||||
/// </summary>
|
||||
public class UxrMetaTouchQuest3InputSteamVR : UxrSteamVRControllerInput
|
||||
{
|
||||
#region Public Overrides UxrSteamVRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return "Oculus Quest3 (Left Controller)";
|
||||
yield return "Oculus Quest3 (Right Controller)";
|
||||
yield return "Meta Quest 3 (Left Controller)";
|
||||
yield return "Meta Quest 3 (Right Controller)";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool MainJoystickIsTouchpad => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick | // Joystick
|
||||
UxrControllerElements.Grip | // Grip
|
||||
UxrControllerElements.Trigger | // Trigger
|
||||
UxrControllerElements.Button1 | // Button A
|
||||
UxrControllerElements.Button2 | // Button B
|
||||
UxrControllerElements.DPad);
|
||||
|
||||
if (handSide == UxrHandSide.Left)
|
||||
{
|
||||
validElements |= (uint)UxrControllerElements.Menu;
|
||||
}
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
|
||||
{
|
||||
return UxrControllerInputCapabilities.HapticImpulses;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0acc555071f36c4fb74251d9a25c5ae
|
||||
timeCreated: 1499677449
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrMetaTouchQuest3Tracking.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Core;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Meta
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking for Oculus Touch devices using the Oculus SDK.
|
||||
/// </summary>
|
||||
public class UxrMetaTouchQuest3Tracking : UxrUnityXRControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrControllerTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrMetaTouchQuest3Input);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrTrackingDevice
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string SDKDependency => UxrConstants.SdkOculus;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6cc855f608e72a745b7a79e8ca93ba67
|
||||
timeCreated: 1499842642
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrMetaTouchQuest3TrackingSteamVR.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Devices.Integrations.SteamVR;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Meta
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking for Oculus Touch controllers using SteamVR SDK.
|
||||
/// </summary>
|
||||
public class UxrMetaTouchQuest3TrackingSteamVR : UxrSteamVRControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrControllerTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrMetaTouchQuest3InputSteamVR);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07ea441b9add1fd4fb72713dd14725cb
|
||||
timeCreated: 1624443263
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30f0aa17591f44647ac57e3b104cc1dc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrWindowsMixedRealityInput.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Microsoft
|
||||
{
|
||||
/// <summary>
|
||||
/// Windows Mixed Reality input using Unity XR.
|
||||
/// </summary>
|
||||
public class UxrWindowsMixedRealityInput : UxrUnityXRControllerInput
|
||||
{
|
||||
#region Inspector Properties/Serialized Fields
|
||||
|
||||
[Header("Windows Mixed Reality:")] [SerializeField] private float _joystickDeadZone = 0.15f;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <summary>
|
||||
/// Requires WMR SDK using OpenXR.
|
||||
/// </summary>
|
||||
public override string SDKDependency => UxrConstants.SdkWindowsMixedReality;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsHandednessSupported => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override float JoystickDeadZone => _joystickDeadZone;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick |
|
||||
UxrControllerElements.Joystick2 |
|
||||
UxrControllerElements.Grip |
|
||||
UxrControllerElements.Trigger |
|
||||
UxrControllerElements.Menu |
|
||||
UxrControllerElements.DPad);
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrUnityXRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return "Windows MR Controller";
|
||||
yield return "Windows MR Controller OpenXR";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e6fba2dada135740a5cc23e3c44ab6b
|
||||
timeCreated: 1499677449
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrWindowsMixedRealityTracking.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Core;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Microsoft
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking component for devices based on Windows Mixed Reality.
|
||||
/// </summary>
|
||||
public class UxrWindowsMixedRealityTracking : UxrUnityXRControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrControllerTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrWindowsMixedRealityInput);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrTrackingDevice
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string SDKDependency => UxrConstants.SdkWindowsMixedReality;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e44a53324016f44da8b9fb0183ace63
|
||||
timeCreated: 1499842642
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e1369784c4dde144b2b46e73bd11505
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,72 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrOculusTouchRiftInput.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Oculus
|
||||
{
|
||||
/// <summary>
|
||||
/// Oculus Touch controller input using Oculus SDK.
|
||||
/// </summary>
|
||||
public class UxrOculusTouchRiftInput : UxrUnityXRControllerInput
|
||||
{
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SDK dependency: Oculus SDK.
|
||||
/// </summary>
|
||||
public override string SDKDependency => UxrConstants.SdkOculus;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsHandednessSupported => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool MainJoystickIsTouchpad => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick |
|
||||
UxrControllerElements.Grip |
|
||||
UxrControllerElements.Trigger |
|
||||
UxrControllerElements.ThumbCapSense |
|
||||
UxrControllerElements.Button1 |
|
||||
UxrControllerElements.Button2 |
|
||||
UxrControllerElements.Menu |
|
||||
UxrControllerElements.DPad);
|
||||
|
||||
if (handSide == UxrHandSide.Right)
|
||||
{
|
||||
// Remove menu button from right controller, which is reserved.
|
||||
validElements = validElements & ~(uint)UxrControllerElements.Menu;
|
||||
}
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrUnityXRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get
|
||||
{
|
||||
if (UxrTrackingDevice.HeadsetDeviceName == "Oculus Rift CV1")
|
||||
{
|
||||
yield return "Oculus Touch Controller - Left";
|
||||
yield return "Oculus Touch Controller - Right";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e00e8773baf4604392a82350eee8671
|
||||
timeCreated: 1499677449
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,66 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrOculusTouchRiftInputSteamVR.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
using UltimateXR.Devices.Integrations.SteamVR;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Oculus
|
||||
{
|
||||
/// <summary>
|
||||
/// Oculus Touch controllers input using SteamVR.
|
||||
/// </summary>
|
||||
public class UxrOculusTouchRiftInputSteamVR : UxrSteamVRControllerInput
|
||||
{
|
||||
#region Public Overrides UxrSteamVRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return "Oculus Rift CV1 (Left Controller)";
|
||||
yield return "Oculus Rift CV1 (Right Controller)";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool MainJoystickIsTouchpad => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick | // Joystick
|
||||
UxrControllerElements.Grip | // Grip
|
||||
UxrControllerElements.Trigger | // Trigger
|
||||
UxrControllerElements.Button1 | // Button A
|
||||
UxrControllerElements.Button2 | // Button B
|
||||
UxrControllerElements.DPad);
|
||||
|
||||
if (handSide == UxrHandSide.Left)
|
||||
{
|
||||
validElements |= (uint)UxrControllerElements.Menu;
|
||||
}
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
|
||||
{
|
||||
return UxrControllerInputCapabilities.HapticImpulses;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e41f3824310273441b1a66dc33fc3bc6
|
||||
timeCreated: 1499677449
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,72 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrOculusTouchRiftSQuestInput.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Oculus
|
||||
{
|
||||
/// <summary>
|
||||
/// Oculus Touch controller input using Oculus SDK.
|
||||
/// </summary>
|
||||
public class UxrOculusTouchRiftSQuestInput : UxrUnityXRControllerInput
|
||||
{
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SDK dependency: Oculus SDK.
|
||||
/// </summary>
|
||||
public override string SDKDependency => UxrConstants.SdkOculus;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsHandednessSupported => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool MainJoystickIsTouchpad => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick |
|
||||
UxrControllerElements.Grip |
|
||||
UxrControllerElements.Trigger |
|
||||
UxrControllerElements.ThumbCapSense |
|
||||
UxrControllerElements.Button1 |
|
||||
UxrControllerElements.Button2 |
|
||||
UxrControllerElements.Menu |
|
||||
UxrControllerElements.DPad);
|
||||
|
||||
if (handSide == UxrHandSide.Right)
|
||||
{
|
||||
// Remove menu button from right controller, which is reserved.
|
||||
validElements = validElements & ~(uint)UxrControllerElements.Menu;
|
||||
}
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrUnityXRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get
|
||||
{
|
||||
if (UxrTrackingDevice.HeadsetDeviceName is "Oculus Rift S" or "Oculus Quest")
|
||||
{
|
||||
yield return "Oculus Touch Controller - Left";
|
||||
yield return "Oculus Touch Controller - Right";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c97b7d15f1e96f445a4e33190f9a5020
|
||||
timeCreated: 1499677449
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,67 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrOculusTouchRiftSQuestInputSteamVR.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
using UltimateXR.Devices.Integrations.SteamVR;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Oculus
|
||||
{
|
||||
/// <summary>
|
||||
/// Oculus Touch controllers input using SteamVR.
|
||||
/// </summary>
|
||||
public class UxrOculusTouchRiftSQuestInputSteamVR : UxrSteamVRControllerInput
|
||||
{
|
||||
#region Public Overrides UxrSteamVRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return "Oculus Quest (Left Controller)";
|
||||
yield return "Oculus Quest (Right Controller)";
|
||||
yield return "Oculus Rift S (Left Controller)";
|
||||
yield return "Oculus Rift S (Right Controller)";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool MainJoystickIsTouchpad => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick | // Joystick
|
||||
UxrControllerElements.Grip | // Grip
|
||||
UxrControllerElements.Trigger | // Trigger
|
||||
UxrControllerElements.Button1 | // Button A
|
||||
UxrControllerElements.Button2 | // Button B
|
||||
UxrControllerElements.DPad);
|
||||
|
||||
if (handSide == UxrHandSide.Left)
|
||||
{
|
||||
validElements |= (uint)UxrControllerElements.Menu;
|
||||
}
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
|
||||
{
|
||||
return UxrControllerInputCapabilities.HapticImpulses;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46ee2d04c77b0bd4383d6231da50d980
|
||||
timeCreated: 1499677449
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrOculusTouchRiftSQuestTracking.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Core;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Oculus
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking for Oculus Touch devices using the Oculus SDK.
|
||||
/// </summary>
|
||||
public class UxrOculusTouchRiftSQuestTracking : UxrUnityXRControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrControllerTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrOculusTouchRiftSQuestInput);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrTrackingDevice
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string SDKDependency => UxrConstants.SdkOculus;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d9733f867143cc499549d95ef911b9b
|
||||
timeCreated: 1499842642
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrOculusTouchRiftSQuestTrackingSteamVR.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Devices.Integrations.SteamVR;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Oculus
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking for Oculus Touch controllers using SteamVR SDK.
|
||||
/// </summary>
|
||||
public class UxrOculusTouchRiftSQuestTrackingSteamVR : UxrSteamVRControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrControllerTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrOculusTouchRiftSQuestInputSteamVR);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6d431e33dfaa8a49b2c2572cdf2c202
|
||||
timeCreated: 1624443263
|
||||
@@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrOculusTouchRiftTracking.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Core;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Oculus
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking for Oculus Touch devices using the Oculus SDK.
|
||||
/// </summary>
|
||||
public class UxrOculusTouchRiftTracking : UxrUnityXRControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrControllerTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrOculusTouchRiftInput);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrTrackingDevice
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string SDKDependency => UxrConstants.SdkOculus;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c997e1e44845a44599cad72e2f63768
|
||||
timeCreated: 1499842642
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrOculusTouchRiftTrackingSteamVR.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Devices.Integrations.SteamVR;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Oculus
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking for Oculus Touch controllers using SteamVR SDK.
|
||||
/// </summary>
|
||||
public class UxrOculusTouchRiftTrackingSteamVR : UxrSteamVRControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrControllerTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrOculusTouchRiftInputSteamVR);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9f2ab5b48994c7b933178d3fea37f60
|
||||
timeCreated: 1624443263
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 836a0efbc8d36a546be3937cb7d41b41
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,67 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrPicoNeo3Input.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Pico
|
||||
{
|
||||
/// <summary>
|
||||
/// Pico Neo 3 controller input using PicoXR SDK.
|
||||
/// </summary>
|
||||
public class UxrPicoNeo3Input : UxrUnityXRControllerInput
|
||||
{
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SDK dependency: PicoXR.
|
||||
/// </summary>
|
||||
public override string SDKDependency => UxrConstants.SdkPicoXR;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsHandednessSupported => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool MainJoystickIsTouchpad => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick |
|
||||
UxrControllerElements.Grip |
|
||||
UxrControllerElements.Trigger |
|
||||
UxrControllerElements.Button1 |
|
||||
UxrControllerElements.Button2 |
|
||||
UxrControllerElements.Menu |
|
||||
UxrControllerElements.Back |
|
||||
UxrControllerElements.DPad);
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrUnityXRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return "PicoXR Controller-Left";
|
||||
yield return "PicoXR Controller-Right";
|
||||
yield return "PICO Controller-Left";
|
||||
yield return "PICO Controller-Right";
|
||||
yield return "PICO Live Preview Controller-Left";
|
||||
yield return "PICO Live Preview Controller-Right";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0343e6207db6ea84a9a8d40c5170d7f3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrPicoNeo3Tracking.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Core;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Pico
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking for Pico Neo 3 devices using the PicoXR SDK.
|
||||
/// </summary>
|
||||
public class UxrPicoNeo3Tracking : UxrUnityXRControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrControllerTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrPicoNeo3Input);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrTrackingDevice
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string SDKDependency => UxrConstants.SdkPicoXR + "";
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91427e7abc5228c44af202060dafa3af
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d71f258a02cff25498b3607eb0dcc4e8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrSteamVRConstants.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace UltimateXR.Devices.Integrations.SteamVR
|
||||
{
|
||||
/// <summary>
|
||||
/// SteamVR constants needed across our framework. At runtime and also for editor classes.
|
||||
/// </summary>
|
||||
public static class UxrSteamVRConstants
|
||||
{
|
||||
#region Public Types & Data
|
||||
|
||||
public const string ActionSetName = "ultimatexr";
|
||||
public const string ActionNameHandSkeletonLeft = "hand_left_skeleton";
|
||||
public const string ActionNameHandSkeletonRight = "hand_right_skeleton";
|
||||
public const string ActionNameHandHaptics = "hand_haptics";
|
||||
public const string BindingInputClick = "click";
|
||||
public const string BindingInputTouch = "touch";
|
||||
public const string BindingVarBool = "boolean";
|
||||
public const string BindingVarVector1 = "vector1";
|
||||
public const string BindingVarVector2 = "vector2";
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b308562c7bd4762ba25e88f5f3a5aa4
|
||||
timeCreated: 1623420066
|
||||
@@ -0,0 +1,658 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrSteamVRControllerInput.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Avatar.Controllers;
|
||||
using UltimateXR.Core;
|
||||
using UltimateXR.Haptics;
|
||||
using UnityEngine;
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Valve.VR;
|
||||
using UltimateXR.Avatar.Rig;
|
||||
using UltimateXR.Core.Settings;
|
||||
using UltimateXR.Manipulation;
|
||||
#endif
|
||||
|
||||
#pragma warning disable 414 // Disable warnings due to unused values
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.SteamVR
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for all SteamVR input devices.
|
||||
/// Provides common input handling thanks to using the actions exported by the
|
||||
/// SteamVRActionsExporter.
|
||||
/// Child classes will require some overrides and minimal input handling if necessary.
|
||||
/// </summary>
|
||||
public abstract class UxrSteamVRControllerInput : UxrControllerInput
|
||||
{
|
||||
#region Inspector Properties/Serialized Fields
|
||||
|
||||
// These will be shown only in custom inspectors for controllers that use them (f.e. index controllers).
|
||||
[SerializeField] [HideInInspector] private string _openHandPoseName;
|
||||
[SerializeField] [HideInInspector] private float _indexCurlAmount = 60.0f;
|
||||
[SerializeField] [HideInInspector] private float _middleCurlAmount = 60.0f;
|
||||
[SerializeField] [HideInInspector] private float _ringCurlAmount = 60.0f;
|
||||
[SerializeField] [HideInInspector] private float _littleCurlAmount = 60.0f;
|
||||
[SerializeField] [HideInInspector] private float _thumbCurlAmount = 60.0f;
|
||||
[SerializeField] [HideInInspector] private float _thumbSpreadAmount = 30.0f;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Types & Data
|
||||
|
||||
/// <summary>
|
||||
/// Gets list of controller names that the component can handle.
|
||||
/// </summary>
|
||||
public abstract IEnumerable<string> ControllerNames { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets if the class will use hand skeletons.
|
||||
/// </summary>
|
||||
public virtual bool UsesHandSkeletons => false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsHandednessSupported => true;
|
||||
|
||||
/// <summary>
|
||||
/// SteamVR child classes will require SteamVR SDK to access functionality.
|
||||
/// </summary>
|
||||
public override string SDKDependency => UxrConstants.SdkSteamVR;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsControllerEnabled(UxrHandSide handSide)
|
||||
{
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
if (s_controllerList.TryGetValue(GetType().Name, out List<int> controllerIndices))
|
||||
{
|
||||
return controllerIndices.Contains(handSide == UxrHandSide.Left
|
||||
? (int)OpenVR.System.GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole.LeftHand)
|
||||
: (int)OpenVR.System.GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole.RightHand));
|
||||
}
|
||||
|
||||
return false;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override float GetInput1D(UxrHandSide handSide, UxrInput1D input1D, bool getIgnoredInput = false)
|
||||
{
|
||||
if (ShouldIgnoreInput(handSide, getIgnoredInput))
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
SteamVR_Input_Sources source = handSide == UxrHandSide.Left ? SteamVR_Input_Sources.LeftHand : SteamVR_Input_Sources.RightHand;
|
||||
|
||||
if (_actionsInput1D.TryGetValue(input1D, out SteamVR_Action_Single action))
|
||||
{
|
||||
return action[source].axis;
|
||||
}
|
||||
|
||||
#endif
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Vector2 GetInput2D(UxrHandSide handSide, UxrInput2D input2D, bool getIgnoredInput = false)
|
||||
{
|
||||
if (ShouldIgnoreInput(handSide, getIgnoredInput))
|
||||
{
|
||||
return Vector2.zero;
|
||||
}
|
||||
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
SteamVR_Input_Sources source = handSide == UxrHandSide.Left ? SteamVR_Input_Sources.LeftHand : SteamVR_Input_Sources.RightHand;
|
||||
|
||||
if (_actionsInput2D.TryGetValue(input2D, out SteamVR_Action_Vector2 action))
|
||||
{
|
||||
return FilterTwoAxesDeadZone(action[source].axis, JoystickDeadZone);
|
||||
}
|
||||
|
||||
#endif
|
||||
return Vector2.zero;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void SendHapticFeedback(UxrHandSide handSide, UxrHapticClip hapticClip)
|
||||
{
|
||||
if (hapticClip.FallbackClipType != UxrHapticClipType.None)
|
||||
{
|
||||
SendHapticFeedback(handSide, hapticClip.FallbackClipType, hapticClip.FallbackAmplitude, hapticClip.FallbackDurationSeconds, hapticClip.HapticMode);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void SendHapticFeedback(UxrHandSide handSide,
|
||||
float frequency,
|
||||
float amplitude,
|
||||
float durationSeconds,
|
||||
UxrHapticMode hapticMode = UxrHapticMode.Mix)
|
||||
{
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
SteamVR_Input_Sources source = handSide == UxrHandSide.Left ? SteamVR_Input_Sources.LeftHand : SteamVR_Input_Sources.RightHand;
|
||||
_handHapticsAction.Execute(0.0f, durationSeconds, frequency, amplitude, source);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void StopHapticFeedback(UxrHandSide handSide)
|
||||
{
|
||||
// TODO. Doesn't seem to be supported.
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unity
|
||||
|
||||
/// <summary>
|
||||
/// Takes care of registering the component in the global list of SteamVR input components.
|
||||
/// Builds the action list to access input and starts listening for device connections.
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
// Build actions
|
||||
BuildActionObjects();
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
// Listen to device connected events
|
||||
SteamVR_Events.DeviceConnected.Remove(OnDeviceConnected);
|
||||
SteamVR_Events.DeviceConnected.Listen(OnDeviceConnected);
|
||||
}
|
||||
|
||||
_awakeFinished = true;
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
// Disabled by default at the beginning, unless we already these controllers registered.
|
||||
// If we already have the controllers registered it is due to an Awake() when loading a new scene.
|
||||
enabled = s_controllerList.TryGetValue(InputClassName, out List<int> controllerIndices) && controllerIndices.Count > 0;
|
||||
RaiseConnectOnStart = enabled;
|
||||
|
||||
if (!s_initializedSteamVR)
|
||||
{
|
||||
global::Valve.VR.SteamVR.Initialize();
|
||||
SteamVR_Input.GetActionSet(UxrSteamVRConstants.ActionSetName).Activate();
|
||||
s_initializedSteamVR = true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
enabled = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the component is disabled. In the case the component was using skeletal
|
||||
/// input, the hand will be driven by the Avatar Animator back again.
|
||||
/// </summary>
|
||||
protected override void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
|
||||
if (UsesHandSkeletons)
|
||||
{
|
||||
if (!_awakeFinished || !UxrManager.Instance || !Avatar || !Avatar.AvatarController)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UxrStandardAvatarController standardAvatarController = Avatar.AvatarController as UxrStandardAvatarController;
|
||||
|
||||
if (standardAvatarController == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(_openHandPoseName))
|
||||
{
|
||||
standardAvatarController.LeftHandDefaultPoseNameOverride = null;
|
||||
standardAvatarController.RightHandDefaultPoseNameOverride = null;
|
||||
standardAvatarController.LeftHandGrabPoseNameOverride = null;
|
||||
standardAvatarController.RightHandGrabPoseNameOverride = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes SteamVR if necessary and activates the UltimateXR action set.
|
||||
/// Will initialize skeleton functionality if necessary.
|
||||
/// </summary>
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
if (UsesHandSkeletons)
|
||||
{
|
||||
_handSkeletonActionLeft.SetSkeletalTransformSpace(EVRSkeletalTransformSpace.Model);
|
||||
_handSkeletonActionRight.SetSkeletalTransformSpace(EVRSkeletalTransformSpace.Model);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the component has skeleton capabilities, the hand bones will be updated here.
|
||||
/// </summary>
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (Avatar == null)
|
||||
{
|
||||
}
|
||||
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
// Update using skeleton if necessary
|
||||
if (UsesHandSkeletons)
|
||||
{
|
||||
UxrStandardAvatarController avatarControllerStandard = Avatar.AvatarController as UxrStandardAvatarController;
|
||||
UxrAvatarRig avatarRig = Avatar.AvatarRig;
|
||||
|
||||
if (avatarControllerStandard == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float curlIndex = _handSkeletonActionLeft.fingerCurls[SteamVR_Skeleton_FingerIndexes.index] * _indexCurlAmount;
|
||||
float curlMiddle = _handSkeletonActionLeft.fingerCurls[SteamVR_Skeleton_FingerIndexes.middle] * _middleCurlAmount;
|
||||
float curlRing = _handSkeletonActionLeft.fingerCurls[SteamVR_Skeleton_FingerIndexes.ring] * _ringCurlAmount;
|
||||
float curlLittle = _handSkeletonActionLeft.fingerCurls[SteamVR_Skeleton_FingerIndexes.pinky] * _littleCurlAmount;
|
||||
float curlThumb = _handSkeletonActionLeft.fingerCurls[SteamVR_Skeleton_FingerIndexes.thumb] * _thumbCurlAmount;
|
||||
float splayThumb = _handSkeletonActionLeft.fingerSplays[SteamVR_Skeleton_FingerIndexes.thumb] * _thumbSpreadAmount;
|
||||
|
||||
if (!UxrGrabManager.Instance.IsHandGrabbing(Avatar, UxrHandSide.Left) && !avatarControllerStandard.IsLeftHandInsideFingerPointingVolume)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_openHandPoseName))
|
||||
{
|
||||
avatarControllerStandard.LeftHandDefaultPoseNameOverride = _openHandPoseName;
|
||||
avatarControllerStandard.LeftHandGrabPoseNameOverride = _openHandPoseName;
|
||||
Avatar.SetCurrentHandPoseImmediately(UxrHandSide.Left, _openHandPoseName);
|
||||
|
||||
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Left, Avatar.LeftHand.Index, curlIndex, curlIndex, curlIndex);
|
||||
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Left, Avatar.LeftHand.Middle, curlMiddle, curlMiddle, curlMiddle);
|
||||
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Left, Avatar.LeftHand.Ring, curlRing, curlRing, curlRing);
|
||||
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Left, Avatar.LeftHand.Little, curlLittle, curlLittle, curlLittle);
|
||||
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Left, Avatar.LeftHand.Thumb, curlThumb * 0.1f, curlThumb * 0.3f, curlThumb * 1.0f, splayThumb);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_openHandPoseName))
|
||||
{
|
||||
avatarControllerStandard.LeftHandDefaultPoseNameOverride = null;
|
||||
}
|
||||
}
|
||||
|
||||
curlIndex = _handSkeletonActionRight.fingerCurls[SteamVR_Skeleton_FingerIndexes.index] * _indexCurlAmount;
|
||||
curlMiddle = _handSkeletonActionRight.fingerCurls[SteamVR_Skeleton_FingerIndexes.middle] * _middleCurlAmount;
|
||||
curlRing = _handSkeletonActionRight.fingerCurls[SteamVR_Skeleton_FingerIndexes.ring] * _ringCurlAmount;
|
||||
curlLittle = _handSkeletonActionRight.fingerCurls[SteamVR_Skeleton_FingerIndexes.pinky] * _littleCurlAmount;
|
||||
curlThumb = _handSkeletonActionRight.fingerCurls[SteamVR_Skeleton_FingerIndexes.thumb] * _thumbCurlAmount;
|
||||
splayThumb = _handSkeletonActionRight.fingerSplays[SteamVR_Skeleton_FingerIndexes.thumb] * _thumbSpreadAmount;
|
||||
|
||||
if (!UxrGrabManager.Instance.IsHandGrabbing(Avatar, UxrHandSide.Right) && !avatarControllerStandard.IsRightHandInsideFingerPointingVolume)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_openHandPoseName))
|
||||
{
|
||||
avatarControllerStandard.RightHandDefaultPoseNameOverride = _openHandPoseName;
|
||||
avatarControllerStandard.RightHandGrabPoseNameOverride = _openHandPoseName;
|
||||
Avatar.SetCurrentHandPoseImmediately(UxrHandSide.Right, _openHandPoseName);
|
||||
|
||||
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Right, Avatar.RightHand.Index, curlIndex, curlIndex, curlIndex);
|
||||
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Right, Avatar.RightHand.Middle, curlMiddle, curlMiddle, curlMiddle);
|
||||
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Right, Avatar.RightHand.Ring, curlRing, curlRing, curlRing);
|
||||
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Right, Avatar.RightHand.Little, curlLittle, curlLittle, curlLittle);
|
||||
UxrAvatarRig.CurlFinger(Avatar, UxrHandSide.Right, Avatar.RightHand.Thumb, curlThumb * 0.1f, curlThumb * 0.3f, curlThumb * 1.0f, splayThumb);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_openHandPoseName))
|
||||
{
|
||||
avatarControllerStandard.RightHandDefaultPoseNameOverride = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Overrides UxrControllerInput
|
||||
|
||||
/// <summary>
|
||||
/// Updates the complete input state using our common SteamVR actions. This allows to use the same interface
|
||||
/// for all controllers and enables the implementation of new devices with minimal effort.
|
||||
/// </summary>
|
||||
protected override void UpdateInput()
|
||||
{
|
||||
base.UpdateInput();
|
||||
|
||||
// Get joystick values
|
||||
Vector2 leftJoystickValue = GetInput2D(UxrHandSide.Left, UxrInput2D.Joystick);
|
||||
Vector2 rightJoystickValue = GetInput2D(UxrHandSide.Right, UxrInput2D.Joystick);
|
||||
Vector2 leftJoystick2Value = GetInput2D(UxrHandSide.Left, UxrInput2D.Joystick2);
|
||||
Vector2 rightJoystick2Value = GetInput2D(UxrHandSide.Right, UxrInput2D.Joystick2);
|
||||
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
var system = OpenVR.System;
|
||||
|
||||
if (system == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update buttons
|
||||
foreach (UxrInputButtons button in Enum.GetValues(typeof(UxrInputButtons)))
|
||||
{
|
||||
if (button != UxrInputButtons.None && button != UxrInputButtons.Any && button != UxrInputButtons.Everything)
|
||||
{
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, button, _actionsButtonClick[button][SteamVR_Input_Sources.LeftHand].state);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, button, _actionsButtonClick[button][SteamVR_Input_Sources.RightHand].state);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, button, _actionsButtonTouch[button][SteamVR_Input_Sources.LeftHand].state);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, button, _actionsButtonTouch[button][SteamVR_Input_Sources.RightHand].state);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// These ones are mainly for teleporting functionality when we don't get touch values out of joysticks:
|
||||
if (leftJoystickValue != Vector2.zero && leftJoystickValue.magnitude > AnalogAsDPadThreshold)
|
||||
{
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Joystick, true);
|
||||
}
|
||||
|
||||
if (rightJoystickValue != Vector2.zero && rightJoystickValue.magnitude > AnalogAsDPadThreshold)
|
||||
{
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Joystick, true);
|
||||
}
|
||||
|
||||
// Same for joystick2 just in case
|
||||
if (leftJoystick2Value != Vector2.zero && leftJoystick2Value.magnitude > AnalogAsDPadThreshold)
|
||||
{
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Joystick2, true);
|
||||
}
|
||||
|
||||
if (rightJoystick2Value != Vector2.zero && rightJoystick2Value.magnitude > AnalogAsDPadThreshold)
|
||||
{
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Joystick2, true);
|
||||
}
|
||||
|
||||
// Update joystick/DPad direction buttons using joystick analog value and pressed state
|
||||
uint leftDirectionFlags = GetButtonFlags(MainJoystickIsTouchpad ? ButtonFlags.PressFlagsLeft : ButtonFlags.TouchFlagsLeft);
|
||||
|
||||
if (leftJoystickValue != Vector2.zero && leftJoystickValue.magnitude > AnalogAsDPadThreshold && (leftDirectionFlags & (int)UxrInputButtons.Joystick) != 0)
|
||||
{
|
||||
float leftJoystickAngle = Input2DToAngle(leftJoystickValue);
|
||||
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadLeft, IsInput2dDPadLeft(leftJoystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadRight, IsInput2dDPadRight(leftJoystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadUp, IsInput2dDPadUp(leftJoystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadDown, IsInput2dDPadDown(leftJoystickAngle));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadLeft, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadRight, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadUp, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadDown, false);
|
||||
}
|
||||
|
||||
uint leftButtonPressFlags = GetButtonFlags(ButtonFlags.PressFlagsLeft);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickLeft, (leftButtonPressFlags & (uint)UxrInputButtons.DPadLeft) != 0);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickRight, (leftButtonPressFlags & (uint)UxrInputButtons.DPadRight) != 0);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickUp, (leftButtonPressFlags & (uint)UxrInputButtons.DPadUp) != 0);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickDown, (leftButtonPressFlags & (uint)UxrInputButtons.DPadDown) != 0);
|
||||
|
||||
uint rightDirectionFlags = GetButtonFlags(MainJoystickIsTouchpad ? ButtonFlags.PressFlagsRight : ButtonFlags.TouchFlagsRight);
|
||||
|
||||
if (rightJoystickValue != Vector2.zero && rightJoystickValue.magnitude > AnalogAsDPadThreshold && (rightDirectionFlags & (int)UxrInputButtons.Joystick) != 0)
|
||||
{
|
||||
float rightJoystickAngle = Input2DToAngle(rightJoystickValue);
|
||||
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadLeft, IsInput2dDPadLeft(rightJoystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadRight, IsInput2dDPadRight(rightJoystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadUp, IsInput2dDPadUp(rightJoystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadDown, IsInput2dDPadDown(rightJoystickAngle));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadLeft, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadRight, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadUp, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadDown, false);
|
||||
}
|
||||
|
||||
uint rightButtonPressFlags = GetButtonFlags(ButtonFlags.PressFlagsRight);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickLeft, (rightButtonPressFlags & (uint)UxrInputButtons.DPadLeft) != 0);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickRight, (rightButtonPressFlags & (uint)UxrInputButtons.DPadRight) != 0);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickUp, (rightButtonPressFlags & (uint)UxrInputButtons.DPadUp) != 0);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickDown, (rightButtonPressFlags & (uint)UxrInputButtons.DPadDown) != 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Types & Data
|
||||
|
||||
private string InputClassName => GetType().Name;
|
||||
|
||||
// Global data
|
||||
private static readonly Dictionary<string, List<int>> s_controllerList = new Dictionary<string, List<int>>();
|
||||
private static bool s_initializedSteamVR;
|
||||
|
||||
// Local data
|
||||
private bool _awakeFinished;
|
||||
|
||||
#endregion
|
||||
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
|
||||
/// <summary>
|
||||
/// Given a controller name, gets a list of controller names using the Virtual Desktop controller naming convention.
|
||||
/// </summary>
|
||||
/// <param name="controllerName">Controller name to get the virtual desktop controller names for</param>
|
||||
/// <returns>List of virtual desktop controller names</returns>
|
||||
private static IEnumerable<string> GetVirtualDesktopWrappedControllerNames(string controllerName)
|
||||
{
|
||||
yield return $"OpenVR Controller({controllerName}) - Left";
|
||||
yield return $"OpenVR Controller({controllerName}) - Right";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a SteamVR device is connected
|
||||
/// </summary>
|
||||
/// <param name="index">Device index</param>
|
||||
/// <param name="connected">True if connected, false if disconnected</param>
|
||||
private static void OnDeviceConnected(int index, bool connected)
|
||||
{
|
||||
if (OpenVR.System == null)
|
||||
{
|
||||
if (UxrGlobalSettings.Instance.LogLevelDevices >= UxrLogLevel.Errors)
|
||||
{
|
||||
Debug.LogError($"{UxrConstants.DevicesModule} {nameof(UxrSteamVRControllerInput)}::{nameof(OnDeviceConnected)}: OpenVR.System is null");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (OpenVR.System.GetTrackedDeviceClass((uint)index) != ETrackedDeviceClass.Controller)
|
||||
{
|
||||
// Ignore devices that aren't controllers
|
||||
return;
|
||||
}
|
||||
|
||||
var renderModelName = new StringBuilder(ModelNameMaxLength);
|
||||
var error = ETrackedPropertyError.TrackedProp_Success;
|
||||
|
||||
OpenVR.System.GetStringTrackedDeviceProperty((uint)index, ETrackedDeviceProperty.Prop_ModelNumber_String, renderModelName, ModelNameMaxLength, ref error);
|
||||
|
||||
string modelNameString = renderModelName.ToString();
|
||||
|
||||
if (UxrGlobalSettings.Instance.LogLevelDevices >= UxrLogLevel.Relevant)
|
||||
{
|
||||
Debug.Log($"{UxrConstants.DevicesModule} {nameof(UxrSteamVRControllerInput)}::{nameof(OnDeviceConnected)}: connected={connected}, model={modelNameString}");
|
||||
}
|
||||
|
||||
IEnumerable<UxrSteamVRControllerInput> inputsSteamVR = AllComponents.Where(i => i is UxrSteamVRControllerInput).Cast<UxrSteamVRControllerInput>();
|
||||
|
||||
UxrSteamVRControllerInput inputSteamVR = inputsSteamVR.FirstOrDefault(i =>
|
||||
i.ControllerNames.Any(n => string.Equals(n, modelNameString)) || i.ControllerNames.SelectMany(GetVirtualDesktopWrappedControllerNames).Any(n => string.Equals(n, modelNameString)));
|
||||
|
||||
if (inputSteamVR != null)
|
||||
{
|
||||
// Model is one of the registered SteamVR inputs and needs to be processed
|
||||
if (UxrGlobalSettings.Instance.LogLevelDevices >= UxrLogLevel.Relevant)
|
||||
{
|
||||
Debug.Log($"{UxrConstants.DevicesModule} {nameof(UxrSteamVRControllerInput)}::{nameof(OnDeviceConnected)}: Device name {modelNameString} was registered by {inputSteamVR.InputClassName} and is being processed!");
|
||||
}
|
||||
|
||||
if (!s_controllerList.TryGetValue(inputSteamVR.InputClassName, out List<int> controllerIndices))
|
||||
{
|
||||
controllerIndices = new List<int>();
|
||||
s_controllerList.Add(inputSteamVR.InputClassName, controllerIndices);
|
||||
}
|
||||
|
||||
if (connected)
|
||||
{
|
||||
// Connected
|
||||
controllerIndices.Add(index);
|
||||
|
||||
if (inputSteamVR.enabled == false)
|
||||
{
|
||||
// First controller: Notify device is connected since we consider the device the whole setup
|
||||
inputSteamVR.enabled = true;
|
||||
inputSteamVR.OnDeviceConnected(new UxrDeviceConnectEventArgs(true));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disconnected
|
||||
controllerIndices.Remove(index);
|
||||
|
||||
if (controllerIndices.Count == 0)
|
||||
{
|
||||
// Last controller disconnected: Notify device is disconnected.
|
||||
inputSteamVR.enabled = false;
|
||||
inputSteamVR.OnDeviceConnected(new UxrDeviceConnectEventArgs(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UxrGlobalSettings.Instance.LogLevelDevices >= UxrLogLevel.Relevant)
|
||||
{
|
||||
Debug.Log($"{UxrConstants.DevicesModule} {nameof(UxrSteamVRControllerInput)}::{nameof(OnDeviceConnected)}: Device is not recognized as input by any of {inputsSteamVR.Count()} components");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the action bound to the given button and input type.
|
||||
/// </summary>
|
||||
/// <param name="button">Button to look for</param>
|
||||
/// <param name="inputType">Type of input to handle. Use <see cref="UxrSteamVRConstants" />.</param>
|
||||
/// <returns>
|
||||
/// Action bound to the given button and input type. If the button doesn't exist
|
||||
/// in the current controller it will return a fake action showing no input
|
||||
/// </returns>
|
||||
private static SteamVR_Action_Boolean GetButtonAction(UxrInputButtons button, string inputType)
|
||||
{
|
||||
return SteamVR_Input.GetAction<SteamVR_Action_Boolean>(UxrSteamVRConstants.ActionSetName, $"{button.ToString().ToLower()}_{inputType}_{UxrSteamVRConstants.BindingVarBool}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the action bound to the given <see cref="UxrInput1D" />.
|
||||
/// </summary>
|
||||
/// <param name="input1D">Element to look for</param>
|
||||
/// <returns>
|
||||
/// Action bound to the given 1D input. If the element doesn't exist in the current controller it will return a
|
||||
/// fake action showing no input
|
||||
/// </returns>
|
||||
private static SteamVR_Action_Single GetInput1DAction(UxrInput1D input1D)
|
||||
{
|
||||
return SteamVR_Input.GetAction<SteamVR_Action_Single>(UxrSteamVRConstants.ActionSetName, $"{input1D.ToString().ToLower()}_{UxrSteamVRConstants.BindingVarVector1}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the action bound to the given <see cref="UxrInput2D" />.
|
||||
/// </summary>
|
||||
/// <param name="input2D">Element to look for</param>
|
||||
/// <returns>
|
||||
/// Action bound to the given 2D input. If the element doesn't exist in the current controller it will return a fake
|
||||
/// action showing no input
|
||||
/// </returns>
|
||||
private static SteamVR_Action_Vector2 GetInput2DAction(UxrInput2D input2D)
|
||||
{
|
||||
return SteamVR_Input.GetAction<SteamVR_Action_Vector2>(UxrSteamVRConstants.ActionSetName, $"{input2D.ToString().ToLower()}_{UxrSteamVRConstants.BindingVarVector2}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds all action objects needed to check for input using SteamVR.
|
||||
/// We use enumeration of all elements inside an Enum to build our action list and,
|
||||
/// thanks to the functionality of SteamVR, when an action doesn't exist it will
|
||||
/// generate a fake action showing no input.
|
||||
/// </summary>
|
||||
private void BuildActionObjects()
|
||||
{
|
||||
// Buttons
|
||||
foreach (UxrInputButtons button in Enum.GetValues(typeof(UxrInputButtons)))
|
||||
{
|
||||
if (button != UxrInputButtons.None && button != UxrInputButtons.Any && button != UxrInputButtons.Everything)
|
||||
{
|
||||
_actionsButtonClick.Add(button, GetButtonAction(button, UxrSteamVRConstants.BindingInputClick));
|
||||
_actionsButtonTouch.Add(button, GetButtonAction(button, UxrSteamVRConstants.BindingInputTouch));
|
||||
}
|
||||
}
|
||||
|
||||
// UxrInput1D
|
||||
foreach (UxrInput1D input1D in Enum.GetValues(typeof(UxrInput1D)))
|
||||
{
|
||||
if (input1D != UxrInput1D.None)
|
||||
{
|
||||
_actionsInput1D.Add(input1D, GetInput1DAction(input1D));
|
||||
}
|
||||
}
|
||||
|
||||
// UxrInput2D
|
||||
foreach (UxrInput2D input2D in Enum.GetValues(typeof(UxrInput2D)))
|
||||
{
|
||||
if (input2D != UxrInput2D.None)
|
||||
{
|
||||
_actionsInput2D.Add(input2D, GetInput2DAction(input2D));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
private const int ModelNameMaxLength = 256;
|
||||
|
||||
private readonly Dictionary<UxrInputButtons, SteamVR_Action_Boolean> _actionsButtonClick = new Dictionary<UxrInputButtons, SteamVR_Action_Boolean>();
|
||||
private readonly Dictionary<UxrInputButtons, SteamVR_Action_Boolean> _actionsButtonTouch = new Dictionary<UxrInputButtons, SteamVR_Action_Boolean>();
|
||||
private readonly Dictionary<UxrInput1D, SteamVR_Action_Single> _actionsInput1D = new Dictionary<UxrInput1D, SteamVR_Action_Single>();
|
||||
private readonly Dictionary<UxrInput2D, SteamVR_Action_Vector2> _actionsInput2D = new Dictionary<UxrInput2D, SteamVR_Action_Vector2>();
|
||||
|
||||
private readonly SteamVR_Action_Skeleton _handSkeletonActionLeft = SteamVR_Input.GetAction<SteamVR_Action_Skeleton>(UxrSteamVRConstants.ActionSetName, UxrSteamVRConstants.ActionNameHandSkeletonLeft);
|
||||
private readonly SteamVR_Action_Skeleton _handSkeletonActionRight = SteamVR_Input.GetAction<SteamVR_Action_Skeleton>(UxrSteamVRConstants.ActionSetName, UxrSteamVRConstants.ActionNameHandSkeletonRight);
|
||||
private readonly SteamVR_Action_Vibration _handHapticsAction = SteamVR_Input.GetAction<SteamVR_Action_Vibration>(UxrSteamVRConstants.ActionSetName, UxrSteamVRConstants.ActionNameHandHaptics);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore 414 // Restore warnings due to unused values
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e95eafbdf5bd474e8b9b19b85ed37f2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,103 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrSteamVRControllerTracking.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using UltimateXR.Core;
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
using Valve.VR;
|
||||
#endif
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.SteamVR
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for tracking devices that use SteamVR.
|
||||
/// </summary>
|
||||
public abstract class UxrSteamVRControllerTracking : UxrControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrTrackingDevice
|
||||
|
||||
/// <summary>
|
||||
/// Gets SDK dependency. SteamVR tracking devices require SteamVR SDK installed.
|
||||
/// </summary>
|
||||
public override string SDKDependency => UxrConstants.SdkSteamVR;
|
||||
|
||||
#endregion
|
||||
|
||||
#region MonoBehaviour
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes to SteamVR pose update events
|
||||
/// </summary>
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
global::Valve.VR.SteamVR.Initialize();
|
||||
|
||||
if (global::Valve.VR.SteamVR.initializedState is global::Valve.VR.SteamVR.InitializedStates.Initializing or global::Valve.VR.SteamVR.InitializedStates.InitializeSuccess)
|
||||
{
|
||||
if (poseAction != null)
|
||||
{
|
||||
poseAction[SteamVR_Input_Sources.LeftHand].onUpdate += PoseAction_OnUpdate;
|
||||
poseAction[SteamVR_Input_Sources.RightHand].onUpdate += PoseAction_OnUpdate;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes from SteamVR pose update events
|
||||
/// </summary>
|
||||
protected override void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
if (global::Valve.VR.SteamVR.initializedState is global::Valve.VR.SteamVR.InitializedStates.Initializing or global::Valve.VR.SteamVR.InitializedStates.InitializeSuccess)
|
||||
{
|
||||
if (poseAction != null)
|
||||
{
|
||||
poseAction[SteamVR_Input_Sources.LeftHand].onUpdate -= PoseAction_OnUpdate;
|
||||
poseAction[SteamVR_Input_Sources.RightHand].onUpdate -= PoseAction_OnUpdate;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handling Methods
|
||||
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
/// <summary>
|
||||
/// Handles the pose action update
|
||||
/// </summary>
|
||||
/// <param name="fromAction">The action that triggered the event</param>
|
||||
/// <param name="fromSource">The source that was updated</param>
|
||||
private void PoseAction_OnUpdate(SteamVR_Action_Pose fromAction, SteamVR_Input_Sources fromSource)
|
||||
{
|
||||
if (fromSource == SteamVR_Input_Sources.LeftHand)
|
||||
{
|
||||
UpdateSensor(UxrHandSide.Left, poseAction[fromSource].localPosition, poseAction[fromSource].localRotation);
|
||||
}
|
||||
else if (fromSource == SteamVR_Input_Sources.RightHand)
|
||||
{
|
||||
UpdateSensor(UxrHandSide.Right, poseAction[fromSource].localPosition, poseAction[fromSource].localRotation);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private types & Data
|
||||
|
||||
#if ULTIMATEXR_USE_STEAMVR_SDK
|
||||
private readonly SteamVR_Action_Pose poseAction = SteamVR_Input.GetAction<SteamVR_Action_Pose>("Pose");
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ada8ee64cca041b7bab08de0867749c2
|
||||
timeCreated: 1624002590
|
||||
@@ -0,0 +1,64 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrDummyControllerInput.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using UltimateXR.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Dummy input class that is used when there is no active input component in the avatar.
|
||||
/// It has the advantage of avoiding to check for null input component and it doesn't generate any type of input
|
||||
/// events.
|
||||
/// </summary>
|
||||
public class UxrDummyControllerInput : UxrControllerInput
|
||||
{
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string LeftControllerName => "Dummy Left";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string RightControllerName => "Dummy Right";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsHandednessSupported => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsControllerEnabled(UxrHandSide handSide)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElement)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override float GetInput1D(UxrHandSide handSide, UxrInput1D input1D, bool getIgnoredInput = false)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Vector2 GetInput2D(UxrHandSide handSide, UxrInput2D input2D, bool getIgnoredInput = false)
|
||||
{
|
||||
return Vector2.zero;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69f904c3378e5b644ab8bb4cf3257be6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,310 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrGamepadInput.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using UltimateXR.Core;
|
||||
using UnityEngine;
|
||||
#if ULTIMATEXR_USE_UNITYINPUTSYSTEM_SDK
|
||||
using UnityEngine.InputSystem;
|
||||
#endif
|
||||
|
||||
namespace UltimateXR.Devices.Integrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Standard X-box like gamepad input.
|
||||
/// </summary>
|
||||
public class UxrGamepadInput : UxrControllerInput
|
||||
{
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string SDKDependency => UxrConstants.SdkUnityInputSystem;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Single;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsHandednessSupported => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsControllerEnabled(UxrHandSide handSide)
|
||||
{
|
||||
#if ULTIMATEXR_USE_UNITYINPUTSYSTEM_SDK
|
||||
return Gamepad.current != null;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick | // Left thumbstick
|
||||
UxrControllerElements.Joystick2 | // Right thumbstick
|
||||
UxrControllerElements.Trigger | // Left index trigger
|
||||
UxrControllerElements.Trigger2 | // Right index trigger
|
||||
UxrControllerElements.Button1 | // Button 1
|
||||
UxrControllerElements.Button2 | // Button 2
|
||||
UxrControllerElements.Button3 | // Button 3
|
||||
UxrControllerElements.Button4 | // Button 4
|
||||
UxrControllerElements.Bumper | // Left shoulder button
|
||||
UxrControllerElements.Bumper2 | // Right shoulder button
|
||||
UxrControllerElements.Back | // Left system button
|
||||
UxrControllerElements.Menu | // Right system button
|
||||
UxrControllerElements.DPad); // Digital pad
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
|
||||
{
|
||||
return UxrControllerInputCapabilities.HapticImpulses;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override float GetInput1D(UxrHandSide handSide, UxrInput1D input1D, bool getIgnoredInput = false)
|
||||
{
|
||||
if (ShouldIgnoreInput(handSide, getIgnoredInput))
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
#if ULTIMATEXR_USE_UNITYINPUTSYSTEM_SDK
|
||||
switch (input1D)
|
||||
{
|
||||
case UxrInput1D.Trigger: return Gamepad.current.leftTrigger.ReadValue();
|
||||
|
||||
case UxrInput1D.Trigger2: return Gamepad.current.rightTrigger.ReadValue();
|
||||
}
|
||||
#endif
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Vector2 GetInput2D(UxrHandSide handSide, UxrInput2D input2D, bool getIgnoredInput = false)
|
||||
{
|
||||
if (ShouldIgnoreInput(handSide, getIgnoredInput))
|
||||
{
|
||||
return Vector2.zero;
|
||||
}
|
||||
|
||||
#if ULTIMATEXR_USE_UNITYINPUTSYSTEM_SDK
|
||||
switch (input2D)
|
||||
{
|
||||
case UxrInput2D.Joystick: return Gamepad.current.leftStick.ReadValue();
|
||||
|
||||
case UxrInput2D.Joystick2: return Gamepad.current.rightStick.ReadValue();
|
||||
}
|
||||
#else
|
||||
switch (input2D)
|
||||
{
|
||||
case UxrInput2D.Joystick: return new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
|
||||
|
||||
case UxrInput2D.Joystick2: return Vector2.zero;
|
||||
}
|
||||
#endif
|
||||
return Vector2.zero;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unity
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes to device events.
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
#if ULTIMATEXR_USE_UNITYINPUTSYSTEM_SDK
|
||||
InputSystem.onDeviceChange += InputSystem_DeviceChanged;
|
||||
enabled = _gamepad != null;
|
||||
#else
|
||||
enabled = false;
|
||||
#endif
|
||||
RaiseConnectOnStart = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes from device events.
|
||||
/// </summary>
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
|
||||
#if ULTIMATEXR_USE_UNITYINPUTSYSTEM_SDK
|
||||
InputSystem.onDeviceChange -= InputSystem_DeviceChanged;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handling Methods
|
||||
|
||||
#if ULTIMATEXR_USE_UNITYINPUTSYSTEM_SDK
|
||||
|
||||
/// <summary>
|
||||
/// Handles the <see cref="InputSystem.onDeviceChange" /> event.
|
||||
/// </summary>
|
||||
/// <param name="device">Device changed</param>
|
||||
/// <param name="deviceChange">The change</param>
|
||||
private void InputSystem_DeviceChanged(InputDevice device, InputDeviceChange deviceChange)
|
||||
{
|
||||
if (enabled == false && Gamepad.current != null)
|
||||
{
|
||||
// If component is disabled and gamepad is available, act as connect
|
||||
enabled = true;
|
||||
_gamepad = Gamepad.current;
|
||||
OnDeviceConnected(new UxrDeviceConnectEventArgs(true));
|
||||
}
|
||||
else if (enabled && Gamepad.current == null)
|
||||
{
|
||||
// If component is enabled and gamepad is unavailable, act as disconnect
|
||||
enabled = false;
|
||||
_gamepad = null;
|
||||
OnDeviceConnected(new UxrDeviceConnectEventArgs(false));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Overrides UxrControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateInput()
|
||||
{
|
||||
base.UpdateInput();
|
||||
|
||||
#if ULTIMATEXR_USE_UNITYINPUTSYSTEM_SDK
|
||||
if (Gamepad.current == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float leftJoystickAngle = Input2DToAngle(Gamepad.current.leftStick.ReadValue());
|
||||
float rightJoystickAngle = Input2DToAngle(Gamepad.current.rightStick.ReadValue());
|
||||
|
||||
// For single devices where there is no handedness, IUxrControllerInputUpdater.UpdateInput() expects the left button flags to be updated
|
||||
// and it will take care of copying them to the right so that both hands return the same input.
|
||||
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickLeft, IsInput2dDPadLeft(leftJoystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickRight, IsInput2dDPadRight(leftJoystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickUp, IsInput2dDPadUp(leftJoystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickDown, IsInput2dDPadDown(leftJoystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick2Left, IsInput2dDPadLeft(rightJoystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick2Right, IsInput2dDPadRight(rightJoystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick2Up, IsInput2dDPadUp(rightJoystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick2Down, IsInput2dDPadDown(rightJoystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Trigger, Gamepad.current.leftTrigger.ReadValue() > AnalogAsDPadThreshold);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Trigger2, Gamepad.current.rightTrigger.ReadValue() > AnalogAsDPadThreshold);
|
||||
#else
|
||||
Vector2 leftJoystick = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
|
||||
|
||||
if (leftJoystick != Vector2.zero && leftJoystick.magnitude > AnalogAsDPadThreshold)
|
||||
{
|
||||
float joystickAngle = Input2DToAngle(leftJoystick);
|
||||
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickLeft, IsInput2dDPadLeft(joystickAngle));
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickRight, IsInput2dDPadRight(joystickAngle));
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickUp, IsInput2dDPadUp(joystickAngle));
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickDown, IsInput2dDPadDown(joystickAngle));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickLeft, false);
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickRight, false);
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickUp, false);
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickDown, false);
|
||||
}
|
||||
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick2Left, false);
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick2Right, false);
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick2Up, false);
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick2Down, false);
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Trigger, false);
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Trigger2, false);
|
||||
#endif
|
||||
|
||||
#if ULTIMATEXR_USE_UNITYINPUTSYSTEM_SDK
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick, Gamepad.current.leftStickButton.ReadValue() > AnalogAsDPadThreshold);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick2, Gamepad.current.rightStickButton.ReadValue() > AnalogAsDPadThreshold);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Bumper, Gamepad.current.leftShoulder.ReadValue() > AnalogAsDPadThreshold);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Bumper2, Gamepad.current.rightShoulder.ReadValue() > AnalogAsDPadThreshold);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button1, Gamepad.current.buttonSouth.ReadValue() > AnalogAsDPadThreshold);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button2, Gamepad.current.buttonEast.ReadValue() > AnalogAsDPadThreshold);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button3, Gamepad.current.buttonWest.ReadValue() > AnalogAsDPadThreshold);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button4, Gamepad.current.buttonNorth.ReadValue() > AnalogAsDPadThreshold);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Back, Gamepad.current.selectButton.ReadValue() > AnalogAsDPadThreshold);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Menu, Gamepad.current.startButton.ReadValue() > AnalogAsDPadThreshold);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadLeft, Gamepad.current.dpad.left.ReadValue() > AnalogAsDPadThreshold);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadRight, Gamepad.current.dpad.right.ReadValue() > AnalogAsDPadThreshold);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadUp, Gamepad.current.dpad.up.ReadValue() > AnalogAsDPadThreshold);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadDown, Gamepad.current.dpad.down.ReadValue() > AnalogAsDPadThreshold);
|
||||
|
||||
#elif UNITY_STANDALONE_OSX
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick, Input.GetKey(KeyCode.JoystickButton11));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick2, Input.GetKey(KeyCode.JoystickButton12));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Bumper, Input.GetKey(KeyCode.JoystickButton13));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Bumper2, Input.GetKey(KeyCode.JoystickButton14));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button1, Input.GetKey(KeyCode.JoystickButton16));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button2, Input.GetKey(KeyCode.JoystickButton17));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button3, Input.GetKey(KeyCode.JoystickButton18));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button4, Input.GetKey(KeyCode.JoystickButton19));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Menu, Input.GetKey(KeyCode.JoystickButton9));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadLeft, Input.GetKey(KeyCode.JoystickButton7));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadRight, Input.GetKey(KeyCode.JoystickButton8));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadUp, Input.GetKey(KeyCode.JoystickButton5));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadDown, Input.GetKey(KeyCode.JoystickButton6));
|
||||
|
||||
#elif UNITY_STANDALONE_LINUX
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick, Input.GetKey(KeyCode.JoystickButton9));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick2, Input.GetKey(KeyCode.JoystickButton10));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Bumper, Input.GetKey(KeyCode.JoystickButton4));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Bumper2, Input.GetKey(KeyCode.JoystickButton5));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button1, Input.GetKey(KeyCode.JoystickButton0));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button2, Input.GetKey(KeyCode.JoystickButton1));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button3, Input.GetKey(KeyCode.JoystickButton2));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button4, Input.GetKey(KeyCode.JoystickButton3));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Menu, Input.GetKey(KeyCode.JoystickButton7));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadLeft, Input.GetKey(KeyCode.JoystickButton11));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadRight, Input.GetKey(KeyCode.JoystickButton12));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadUp, Input.GetKey(KeyCode.JoystickButton13));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadDown, Input.GetKey(KeyCode.JoystickButton14)));
|
||||
|
||||
#else
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick, Input.GetKey(KeyCode.JoystickButton8));
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick2, Input.GetKey(KeyCode.JoystickButton9));
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Bumper, Input.GetKey(KeyCode.JoystickButton4));
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Bumper2, Input.GetKey(KeyCode.JoystickButton5));
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button1, Input.GetKey(KeyCode.JoystickButton0));
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button2, Input.GetKey(KeyCode.JoystickButton1));
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button3, Input.GetKey(KeyCode.JoystickButton2));
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button4, Input.GetKey(KeyCode.JoystickButton3));
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Back, Input.GetKey(KeyCode.JoystickButton6));
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Menu, Input.GetKey(KeyCode.JoystickButton7));
|
||||
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadLeft, false);
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadRight, false);
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadUp, false);
|
||||
this.SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadDown, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Types & Data
|
||||
|
||||
#if ULTIMATEXR_USE_UNITYINPUTSYSTEM_SDK
|
||||
private Gamepad _gamepad;
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1cf3f2ab4b560be4e90fce9b1ca24f10
|
||||
timeCreated: 1499677449
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrUnityXRControllerInput.ButtonContact.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace UltimateXR.Devices.Integrations
|
||||
{
|
||||
public abstract partial class UxrUnityXRControllerInput
|
||||
{
|
||||
#region Private Types & Data
|
||||
|
||||
/// <summary>
|
||||
/// Types of button contact.
|
||||
/// </summary>
|
||||
protected enum ButtonContact
|
||||
{
|
||||
/// <summary>
|
||||
/// Button press.
|
||||
/// </summary>
|
||||
Press,
|
||||
|
||||
/// <summary>
|
||||
/// Button contact without pressing.
|
||||
/// </summary>
|
||||
Touch
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4bfa0e7c496b4585957a85feaa88b564
|
||||
timeCreated: 1643734934
|
||||
@@ -0,0 +1,946 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrUnityXRControllerInput.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UltimateXR.Core;
|
||||
using UltimateXR.Core.Settings;
|
||||
using UltimateXR.Haptics;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR;
|
||||
#if ULTIMATEXR_UNITY_XR_OCULUS
|
||||
using Unity.XR.Oculus;
|
||||
#endif
|
||||
|
||||
namespace UltimateXR.Devices.Integrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic base class for left-right input devices that can be handled through the new
|
||||
/// generic Unity XR input interface. Before, we had to manually support each SDK individually.
|
||||
/// </summary>
|
||||
public abstract partial class UxrUnityXRControllerInput : UxrControllerInput
|
||||
{
|
||||
#region Public Types & Data
|
||||
|
||||
/// <summary>
|
||||
/// Gets list of controller names that the component can handle
|
||||
/// </summary>
|
||||
public abstract IEnumerable<string> ControllerNames { get; }
|
||||
|
||||
/// <summary>
|
||||
/// We use this when we are implementing new controllers that we don't know the name of, in order to
|
||||
/// show the controller names in the UxrDebugControllerPanel.
|
||||
/// Returning true will register the controllers in <see cref="InputDevices_DeviceConnected" /> no
|
||||
/// matter which input device gets connected. Then using the UxrDebugControllerPanel we can see which
|
||||
/// devices got connected.
|
||||
/// This is mostly useful for untethered devices that cannot be tested directly in Unity.
|
||||
/// </summary>
|
||||
public virtual bool ForceUseAlways => false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string LeftControllerName => _deviceLeft.isValid ? _deviceLeft.name : string.Empty;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string RightControllerName => _deviceRight.isValid ? _deviceRight.name : string.Empty;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsControllerEnabled(UxrHandSide handSide)
|
||||
{
|
||||
return GetInputDevice(handSide).isValid;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override float GetInput1D(UxrHandSide handSide, UxrInput1D input1D, bool getIgnoredInput = false)
|
||||
{
|
||||
if (ShouldIgnoreInput(handSide, getIgnoredInput))
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
InputDevice inputDevice = GetInputDevice(handSide);
|
||||
|
||||
if (inputDevice.isValid)
|
||||
{
|
||||
float value;
|
||||
|
||||
switch (input1D)
|
||||
{
|
||||
case UxrInput1D.Grip:
|
||||
|
||||
if (inputDevice.TryGetFeatureValue(CommonUsages.grip, out value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case UxrInput1D.Trigger:
|
||||
|
||||
if (inputDevice.TryGetFeatureValue(CommonUsages.trigger, out value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case UxrInput1D.Trigger2: break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Vector2 GetInput2D(UxrHandSide handSide, UxrInput2D input2D, bool getIgnoredInput = false)
|
||||
{
|
||||
if (ShouldIgnoreInput(handSide, getIgnoredInput))
|
||||
{
|
||||
return Vector2.zero;
|
||||
}
|
||||
|
||||
InputDevice inputDevice = GetInputDevice(handSide);
|
||||
|
||||
if (inputDevice.isValid)
|
||||
{
|
||||
Vector2 value;
|
||||
|
||||
switch (input2D)
|
||||
{
|
||||
case UxrInput2D.Joystick:
|
||||
|
||||
if (inputDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out value))
|
||||
{
|
||||
return FilterTwoAxesDeadZone(value, JoystickDeadZone);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case UxrInput2D.Joystick2:
|
||||
|
||||
if (inputDevice.TryGetFeatureValue(CommonUsages.secondary2DAxis, out value))
|
||||
{
|
||||
return FilterTwoAxesDeadZone(value, JoystickDeadZone);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Vector2.zero;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
|
||||
{
|
||||
UxrControllerInputCapabilities capabilities = 0;
|
||||
|
||||
InputDevice inputDevice = GetInputDevice(handSide);
|
||||
|
||||
if (!inputDevice.isValid)
|
||||
{
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
if (inputDevice.TryGetHapticCapabilities(out HapticCapabilities hapticCapabilities))
|
||||
{
|
||||
if (hapticCapabilities.supportsBuffer)
|
||||
{
|
||||
capabilities |= UxrControllerInputCapabilities.HapticClips;
|
||||
}
|
||||
|
||||
if (hapticCapabilities.supportsImpulse)
|
||||
{
|
||||
capabilities |= UxrControllerInputCapabilities.HapticImpulses;
|
||||
}
|
||||
}
|
||||
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void SendHapticFeedback(UxrHandSide handSide, UxrHapticClip hapticClip)
|
||||
{
|
||||
InputDevice inputDevice = GetInputDevice(handSide);
|
||||
|
||||
if (!inputDevice.isValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (hapticClip == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inputDevice.TryGetHapticCapabilities(out HapticCapabilities hapticCapabilities))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (hapticClip.Clip == null || !hapticCapabilities.supportsBuffer)
|
||||
{
|
||||
SendHapticFeedback(handSide,
|
||||
hapticClip.FallbackClipType,
|
||||
hapticClip.FallbackAmplitude,
|
||||
hapticClip.FallbackDurationSeconds,
|
||||
hapticClip.HapticMode);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create haptics clip from audio
|
||||
byte[] hapticBuffer = CreateHapticBufferFromAudioClip(inputDevice, hapticClip.Clip);
|
||||
|
||||
if (hapticBuffer == null)
|
||||
{
|
||||
SendHapticFeedback(handSide,
|
||||
hapticClip.FallbackClipType,
|
||||
hapticClip.FallbackAmplitude,
|
||||
hapticClip.FallbackDurationSeconds,
|
||||
hapticClip.HapticMode);
|
||||
return;
|
||||
}
|
||||
|
||||
// Readjust amplitude?
|
||||
if (Mathf.Approximately(hapticClip.ClipAmplitude, 1.0f) == false)
|
||||
{
|
||||
for (int i = 0; i < hapticBuffer.Length; ++i)
|
||||
{
|
||||
hapticBuffer[i] = (byte)Mathf.Clamp(Mathf.RoundToInt(hapticBuffer[i] * hapticClip.ClipAmplitude), 0, 255);
|
||||
}
|
||||
}
|
||||
|
||||
// Send using replace or mix
|
||||
uint channel = 0;
|
||||
|
||||
if (hapticClip.HapticMode == UxrHapticMode.Mix && hapticCapabilities.numChannels > 0)
|
||||
{
|
||||
if (handSide == UxrHandSide.Left)
|
||||
{
|
||||
_leftHapticChannel = (_leftHapticChannel + 1) % hapticCapabilities.numChannels;
|
||||
channel = _leftHapticChannel;
|
||||
}
|
||||
else
|
||||
{
|
||||
_rightHapticChannel = (_rightHapticChannel + 1) % hapticCapabilities.numChannels;
|
||||
channel = _rightHapticChannel;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
inputDevice.StopHaptics();
|
||||
|
||||
_leftHapticChannel = 0;
|
||||
_rightHapticChannel = 0;
|
||||
}
|
||||
|
||||
inputDevice.SendHapticBuffer(channel, hapticBuffer);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void SendHapticFeedback(UxrHandSide handSide,
|
||||
float frequency,
|
||||
float amplitude,
|
||||
float durationSeconds,
|
||||
UxrHapticMode hapticMode = UxrHapticMode.Mix)
|
||||
{
|
||||
InputDevice inputDevice = GetInputDevice(handSide);
|
||||
|
||||
if (!inputDevice.isValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inputDevice.TryGetHapticCapabilities(out HapticCapabilities hapticCapabilities))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup using replace or mix
|
||||
uint channel = 0;
|
||||
|
||||
if (hapticMode == UxrHapticMode.Mix && hapticCapabilities.numChannels > 0)
|
||||
{
|
||||
if (handSide == UxrHandSide.Left)
|
||||
{
|
||||
_leftHapticChannel = (_leftHapticChannel + 1) % hapticCapabilities.numChannels;
|
||||
channel = _leftHapticChannel;
|
||||
}
|
||||
else
|
||||
{
|
||||
_rightHapticChannel = (_rightHapticChannel + 1) % hapticCapabilities.numChannels;
|
||||
channel = _rightHapticChannel;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
inputDevice.StopHaptics();
|
||||
|
||||
_leftHapticChannel = 0;
|
||||
_rightHapticChannel = 0;
|
||||
}
|
||||
|
||||
// Send
|
||||
if (hapticCapabilities.supportsBuffer)
|
||||
{
|
||||
byte[] samples = new byte[(int)(hapticCapabilities.bufferFrequencyHz * durationSeconds)];
|
||||
int steps = frequency > 0.0f ? Mathf.RoundToInt(hapticCapabilities.bufferFrequencyHz / frequency) : -1;
|
||||
byte sample = (byte)Mathf.Clamp(amplitude * 255.0f, 0, 255.0f);
|
||||
|
||||
for (int i = 0; i < samples.Length; ++i)
|
||||
{
|
||||
if (steps < 2)
|
||||
{
|
||||
samples[i] = sample;
|
||||
}
|
||||
else
|
||||
{
|
||||
samples[i] = i % steps == 0 ? sample : (byte)0;
|
||||
}
|
||||
}
|
||||
|
||||
inputDevice.SendHapticBuffer(channel, samples);
|
||||
}
|
||||
else if (hapticCapabilities.supportsImpulse)
|
||||
{
|
||||
inputDevice.SendHapticImpulse(channel, amplitude, durationSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void StopHapticFeedback(UxrHandSide handSide)
|
||||
{
|
||||
InputDevice inputDevice = GetInputDevice(handSide);
|
||||
|
||||
if (!inputDevice.isValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
inputDevice.StopHaptics();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unity
|
||||
|
||||
/// <summary>
|
||||
/// Initializes variables and subscribes to events.
|
||||
/// If the controllers were already initialized, enables the component. Otherwise it begins disabled until devices are
|
||||
/// connected.
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
_leftHapticChannel = 0;
|
||||
_rightHapticChannel = 0;
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
InputDevices.deviceConnected += InputDevices_DeviceConnected;
|
||||
InputDevices.deviceDisconnected += InputDevices_DeviceDisconnected;
|
||||
|
||||
// Check if the device is already connected. This may happen if a new scene was loaded, because
|
||||
// the connection events were already triggered and processed. We should have them registered in
|
||||
// our static fields.
|
||||
_deviceLeft = s_activeInputDevices.FirstOrDefault(d => ControllerNames.Any(n => string.Equals(d.name, n)) && IsLeftController(d));
|
||||
_deviceRight = s_activeInputDevices.FirstOrDefault(d => ControllerNames.Any(n => string.Equals(d.name, n)) && IsRightController(d));
|
||||
|
||||
List<InputDevice> devices = new List<InputDevice>();
|
||||
InputDevices.GetDevices(devices);
|
||||
|
||||
if (!_deviceLeft.isValid)
|
||||
{
|
||||
_deviceLeft = devices.FirstOrDefault(d => ControllerNames.Any(n => string.Equals(d.name, n)) && IsLeftController(d));
|
||||
}
|
||||
|
||||
if (!_deviceRight.isValid)
|
||||
{
|
||||
_deviceRight = devices.FirstOrDefault(d => ControllerNames.Any(n => string.Equals(d.name, n)) && IsRightController(d));
|
||||
}
|
||||
|
||||
enabled = _deviceLeft.isValid || _deviceRight.isValid;
|
||||
RaiseConnectOnStart = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes from device events.
|
||||
/// </summary>
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
|
||||
InputDevices.deviceConnected -= InputDevices_DeviceConnected;
|
||||
InputDevices.deviceDisconnected -= InputDevices_DeviceDisconnected;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handling Methods
|
||||
|
||||
/// <summary>
|
||||
/// Event called when a device is connected. Check for compatible devices.
|
||||
/// </summary>
|
||||
/// <param name="inputDevice">The device that was connected</param>
|
||||
private void InputDevices_DeviceConnected(InputDevice inputDevice)
|
||||
{
|
||||
// Check if device is compatible with component
|
||||
if (ForceUseAlways || ControllerNames.Any(n => string.Equals(n, inputDevice.name)))
|
||||
{
|
||||
// Found compatible device. Look for features.
|
||||
List<InputFeatureUsage> listFeatures = new List<InputFeatureUsage>();
|
||||
|
||||
bool isController = false;
|
||||
|
||||
// Check for controllers and side
|
||||
if (IsLeftController(inputDevice))
|
||||
{
|
||||
// Left controller
|
||||
|
||||
if (UxrGlobalSettings.Instance.LogLevelDevices >= UxrLogLevel.Relevant)
|
||||
{
|
||||
Debug.Log($"{UxrConstants.DevicesModule} {InputClassName}::{nameof(InputDevices_DeviceConnected)}: Device name {inputDevice.name} was registered by {InputClassName} and is being processed as left controller. InputDevice.isValid={inputDevice.isValid}");
|
||||
}
|
||||
|
||||
_deviceLeft = inputDevice;
|
||||
isController = true;
|
||||
}
|
||||
else if (IsRightController(inputDevice))
|
||||
{
|
||||
// Right controller
|
||||
|
||||
if (UxrGlobalSettings.Instance.LogLevelDevices >= UxrLogLevel.Relevant)
|
||||
{
|
||||
Debug.Log($"{UxrConstants.DevicesModule} {InputClassName}::{nameof(InputDevices_DeviceConnected)}: Device name {inputDevice.name} was registered by {InputClassName} and is being processed as right controller. InputDevice.isValid={inputDevice.isValid}");
|
||||
}
|
||||
|
||||
_deviceRight = inputDevice;
|
||||
isController = true;
|
||||
}
|
||||
|
||||
if (isController)
|
||||
{
|
||||
// Register active device
|
||||
s_activeInputDevices.Add(inputDevice);
|
||||
|
||||
if (!enabled)
|
||||
{
|
||||
// Component is disabled. Enable it and send Connected event.
|
||||
enabled = true;
|
||||
OnDeviceConnected(new UxrDeviceConnectEventArgs(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for controllers and side
|
||||
if (IsLeftController(inputDevice))
|
||||
{
|
||||
// Left controller
|
||||
|
||||
if (UxrGlobalSettings.Instance.LogLevelDevices >= UxrLogLevel.Relevant)
|
||||
{
|
||||
Debug.Log($"{UxrConstants.DevicesModule} {InputClassName}::{nameof(InputDevices_DeviceConnected)}: Left device connected unknown: {inputDevice.name}. InputDevice.isValid={inputDevice.isValid}");
|
||||
}
|
||||
}
|
||||
else if (IsRightController(inputDevice))
|
||||
{
|
||||
// Right controller
|
||||
|
||||
if (UxrGlobalSettings.Instance.LogLevelDevices >= UxrLogLevel.Relevant)
|
||||
{
|
||||
Debug.Log($"{UxrConstants.DevicesModule} {InputClassName}::{nameof(InputDevices_DeviceConnected)}: Right device connected unknown: {inputDevice.name}. InputDevice.isValid={inputDevice.isValid}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event called when a device is disconnected. We use it to update our internal lists.
|
||||
/// </summary>
|
||||
/// <param name="inputDevice">The device that was disconnected</param>
|
||||
private void InputDevices_DeviceDisconnected(InputDevice inputDevice)
|
||||
{
|
||||
// Check if device is compatible with component
|
||||
if (ForceUseAlways || ControllerNames.Any(n => string.Equals(n, inputDevice.name)))
|
||||
{
|
||||
if (string.Equals(inputDevice.serialNumber, _deviceLeft.serialNumber) || string.Equals(inputDevice.serialNumber, _deviceRight.serialNumber))
|
||||
{
|
||||
if (UxrGlobalSettings.Instance.LogLevelDevices >= UxrLogLevel.Relevant)
|
||||
{
|
||||
Debug.Log($"{UxrConstants.DevicesModule} {InputClassName}::{nameof(InputDevices_DeviceDisconnected)}: Device name {inputDevice.name} was registered by {InputClassName} and is being disconnected. InputDevice.isValid={inputDevice.isValid}");
|
||||
}
|
||||
}
|
||||
|
||||
// Unregister device
|
||||
s_activeInputDevices.RemoveAll(i => string.Equals(i.name, inputDevice.name));
|
||||
|
||||
// If last device was disconnected, disable component. Component will be re-enabled using connection event.
|
||||
if (enabled && !_deviceLeft.isValid && !_deviceRight.isValid)
|
||||
{
|
||||
enabled = false;
|
||||
OnDeviceConnected(new UxrDeviceConnectEventArgs(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Overrides UxrControllerInput
|
||||
|
||||
/// <summary>
|
||||
/// Updates the input state. This should not be called by the user since it is called by the framework already.
|
||||
/// </summary>
|
||||
protected override void UpdateInput()
|
||||
{
|
||||
base.UpdateInput();
|
||||
|
||||
bool buttonPressTriggerLeft = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Trigger, ButtonContact.Press);
|
||||
bool buttonPressTriggerRight = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Trigger, ButtonContact.Press);
|
||||
bool buttonPressTrigger2Left = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Trigger2, ButtonContact.Press);
|
||||
bool buttonPressTrigger2Right = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Trigger2, ButtonContact.Press);
|
||||
bool buttonPressJoystickLeft = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Joystick, ButtonContact.Press);
|
||||
bool buttonPressJoystickRight = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Joystick, ButtonContact.Press);
|
||||
bool buttonPressJoystick2Left = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Joystick2, ButtonContact.Press);
|
||||
bool buttonPressJoystick2Right = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Joystick2, ButtonContact.Press);
|
||||
bool buttonPressButton1Left = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Button1, ButtonContact.Press);
|
||||
bool buttonPressButton1Right = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Button1, ButtonContact.Press);
|
||||
bool buttonPressButton2Left = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Button2, ButtonContact.Press);
|
||||
bool buttonPressButton2Right = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Button2, ButtonContact.Press);
|
||||
bool buttonPressButton3Left = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Button3, ButtonContact.Press);
|
||||
bool buttonPressButton3Right = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Button3, ButtonContact.Press);
|
||||
bool buttonPressButton4Left = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Button4, ButtonContact.Press);
|
||||
bool buttonPressButton4Right = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Button4, ButtonContact.Press);
|
||||
bool buttonPressBumperLeft = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Bumper, ButtonContact.Press);
|
||||
bool buttonPressBumperRight = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Bumper, ButtonContact.Press);
|
||||
bool buttonPressBumper2Left = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Bumper2, ButtonContact.Press);
|
||||
bool buttonPressBumper2Right = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Bumper2, ButtonContact.Press);
|
||||
bool buttonPressMenuLeft = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Menu, ButtonContact.Press);
|
||||
bool buttonPressMenuRight = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Menu, ButtonContact.Press);
|
||||
bool buttonPressGripLeft = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Grip, ButtonContact.Press);
|
||||
bool buttonPressGripRight = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Grip, ButtonContact.Press);
|
||||
bool buttonPressThumbCapSenseLeft = HasButtonContact(UxrHandSide.Left, UxrInputButtons.ThumbCapSense, ButtonContact.Press);
|
||||
bool buttonPressThumbCapSenseRight = HasButtonContact(UxrHandSide.Right, UxrInputButtons.ThumbCapSense, ButtonContact.Press);
|
||||
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Trigger, buttonPressTriggerLeft);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Trigger, buttonPressTriggerRight);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Trigger2, buttonPressTrigger2Left);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Trigger2, buttonPressTrigger2Right);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick, buttonPressJoystickLeft);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Joystick, buttonPressJoystickRight);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick2, buttonPressJoystick2Left);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Joystick2, buttonPressJoystick2Right);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button1, buttonPressButton1Left);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Button1, buttonPressButton1Right);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button2, buttonPressButton2Left);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Button2, buttonPressButton2Right);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button3, buttonPressButton3Left);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Button3, buttonPressButton3Right);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Button4, buttonPressButton4Left);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Button4, buttonPressButton4Right);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Bumper, buttonPressBumperLeft);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Bumper, buttonPressBumperRight);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Bumper2, buttonPressBumper2Left);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Bumper2, buttonPressBumper2Right);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Menu, buttonPressMenuLeft);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Menu, buttonPressMenuRight);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Grip, buttonPressGripLeft);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Grip, buttonPressGripRight);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.ThumbCapSense, buttonPressThumbCapSenseLeft);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.ThumbCapSense, buttonPressThumbCapSenseRight);
|
||||
|
||||
bool buttonTouchTriggerLeft = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Trigger, ButtonContact.Touch);
|
||||
bool buttonTouchTriggerRight = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Trigger, ButtonContact.Touch);
|
||||
bool buttonTouchTrigger2Left = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Trigger2, ButtonContact.Touch);
|
||||
bool buttonTouchTrigger2Right = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Trigger2, ButtonContact.Touch);
|
||||
bool buttonTouchJoystickLeft = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Joystick, ButtonContact.Touch);
|
||||
bool buttonTouchJoystickRight = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Joystick, ButtonContact.Touch);
|
||||
bool buttonTouchJoystick2Left = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Joystick2, ButtonContact.Touch);
|
||||
bool buttonTouchJoystick2Right = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Joystick2, ButtonContact.Touch);
|
||||
bool buttonTouchButton1Left = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Button1, ButtonContact.Touch);
|
||||
bool buttonTouchButton1Right = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Button1, ButtonContact.Touch);
|
||||
bool buttonTouchButton2Left = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Button2, ButtonContact.Touch);
|
||||
bool buttonTouchButton2Right = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Button2, ButtonContact.Touch);
|
||||
bool buttonTouchButton3Left = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Button3, ButtonContact.Touch);
|
||||
bool buttonTouchButton3Right = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Button3, ButtonContact.Touch);
|
||||
bool buttonTouchButton4Left = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Button4, ButtonContact.Touch);
|
||||
bool buttonTouchButton4Right = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Button4, ButtonContact.Touch);
|
||||
bool buttonTouchBumperLeft = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Bumper, ButtonContact.Touch);
|
||||
bool buttonTouchBumperRight = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Bumper, ButtonContact.Touch);
|
||||
bool buttonTouchBumper2Left = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Bumper2, ButtonContact.Touch);
|
||||
bool buttonTouchBumper2Right = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Bumper2, ButtonContact.Touch);
|
||||
bool buttonTouchMenuLeft = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Menu, ButtonContact.Touch);
|
||||
bool buttonTouchMenuRight = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Menu, ButtonContact.Touch);
|
||||
bool buttonTouchGripLeft = HasButtonContact(UxrHandSide.Left, UxrInputButtons.Grip, ButtonContact.Touch);
|
||||
bool buttonTouchGripRight = HasButtonContact(UxrHandSide.Right, UxrInputButtons.Grip, ButtonContact.Touch);
|
||||
bool buttonTouchThumbCapSenseLeft = HasButtonContact(UxrHandSide.Left, UxrInputButtons.ThumbCapSense, ButtonContact.Touch);
|
||||
bool buttonTouchThumbCapSenseRight = HasButtonContact(UxrHandSide.Right, UxrInputButtons.ThumbCapSense, ButtonContact.Touch);
|
||||
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Trigger, buttonTouchTriggerLeft);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Trigger, buttonTouchTriggerRight);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Trigger2, buttonTouchTrigger2Left);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Trigger2, buttonTouchTrigger2Right);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Joystick, buttonTouchJoystickLeft);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Joystick, buttonTouchJoystickRight);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Joystick2, buttonTouchJoystick2Left);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Joystick2, buttonTouchJoystick2Right);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Button1, buttonTouchButton1Left);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Button1, buttonTouchButton1Right);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Button2, buttonTouchButton2Left);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Button2, buttonTouchButton2Right);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Button3, buttonTouchButton3Left);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Button3, buttonTouchButton3Right);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Button4, buttonTouchButton4Left);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Button4, buttonTouchButton4Right);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Bumper, buttonTouchBumperLeft);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Bumper, buttonTouchBumperRight);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Bumper2, buttonTouchBumper2Left);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Bumper2, buttonTouchBumper2Right);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Menu, buttonTouchMenuLeft);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Menu, buttonTouchMenuRight);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.Grip, buttonTouchGripLeft);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.Grip, buttonTouchGripRight);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsLeft, UxrInputButtons.ThumbCapSense, buttonTouchThumbCapSenseLeft);
|
||||
SetButtonFlags(ButtonFlags.TouchFlagsRight, UxrInputButtons.ThumbCapSense, buttonTouchThumbCapSenseRight);
|
||||
|
||||
Vector2 leftJoystick = GetInput2D(UxrHandSide.Left, UxrInput2D.Joystick, true);
|
||||
Vector2 leftDPad = leftJoystick; // Mapped to joystick by default
|
||||
|
||||
if (leftJoystick != Vector2.zero && leftJoystick.magnitude > AnalogAsDPadThreshold)
|
||||
{
|
||||
float joystickAngle = Input2DToAngle(leftJoystick);
|
||||
bool touchPadFix = !MainJoystickIsTouchpad || buttonPressJoystickLeft;
|
||||
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickLeft, touchPadFix && IsInput2dDPadLeft(joystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickRight, touchPadFix && IsInput2dDPadRight(joystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickUp, touchPadFix && IsInput2dDPadUp(joystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickDown, touchPadFix && IsInput2dDPadDown(joystickAngle));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickLeft, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickRight, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickUp, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.JoystickDown, false);
|
||||
}
|
||||
|
||||
if (leftDPad != Vector2.zero && leftDPad.magnitude > AnalogAsDPadThreshold)
|
||||
{
|
||||
float dPadAngle = Input2DToAngle(leftDPad);
|
||||
bool touchPadFix = !MainJoystickIsTouchpad || buttonPressJoystickLeft;
|
||||
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadLeft, touchPadFix && IsInput2dDPadLeft(dPadAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadRight, touchPadFix && IsInput2dDPadRight(dPadAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadUp, touchPadFix && IsInput2dDPadUp(dPadAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadDown, touchPadFix && IsInput2dDPadDown(dPadAngle));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadLeft, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadRight, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadUp, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.DPadDown, false);
|
||||
}
|
||||
|
||||
Vector2 rightJoystick = GetInput2D(UxrHandSide.Right, UxrInput2D.Joystick, true);
|
||||
Vector2 rightDPad = rightJoystick; // Mapped to joystick by default
|
||||
|
||||
if (rightJoystick != Vector2.zero && rightJoystick.magnitude > AnalogAsDPadThreshold)
|
||||
{
|
||||
float joystickAngle = Input2DToAngle(rightJoystick);
|
||||
bool touchPadFix = !MainJoystickIsTouchpad || buttonPressJoystickRight;
|
||||
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickLeft, touchPadFix && IsInput2dDPadLeft(joystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickRight, touchPadFix && IsInput2dDPadRight(joystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickUp, touchPadFix && IsInput2dDPadUp(joystickAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickDown, touchPadFix && IsInput2dDPadDown(joystickAngle));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickLeft, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickRight, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickUp, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.JoystickDown, false);
|
||||
}
|
||||
|
||||
if (rightDPad != Vector2.zero && rightDPad.magnitude > AnalogAsDPadThreshold)
|
||||
{
|
||||
float dPadAngle = Input2DToAngle(rightDPad);
|
||||
bool touchPadFix = !MainJoystickIsTouchpad || buttonPressJoystickRight;
|
||||
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadLeft, touchPadFix && IsInput2dDPadLeft(dPadAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadRight, touchPadFix && IsInput2dDPadRight(dPadAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadUp, touchPadFix && IsInput2dDPadUp(dPadAngle));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadDown, touchPadFix && IsInput2dDPadDown(dPadAngle));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadLeft, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadRight, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadUp, false);
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.DPadDown, false);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a non-standard button in a controller is currently being touched or pressed.
|
||||
/// </summary>
|
||||
/// <param name="handSide">Which controller side to check</param>
|
||||
/// <param name="button">Button to check</param>
|
||||
/// <param name="buttonContact">Type of contact to check for (touch or press)</param>
|
||||
/// <returns>Boolean telling whether the specified button has contact</returns>
|
||||
protected virtual bool HasButtonContactOther(UxrHandSide handSide, UxrInputButtons button, ButtonContact buttonContact)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the input device interface in Unity's input system for a given hand.
|
||||
/// Usually if it is a left+right setup it will give a list with a single entry but the system is very generic
|
||||
/// so it is prepared to handle different setups.
|
||||
/// Normally we get the list and just use the first entry if available.
|
||||
/// </summary>
|
||||
/// <param name="handSide">Hand to get the input devices for</param>
|
||||
/// <returns><see cref="InputDevice" /> representing the input device</returns>
|
||||
protected InputDevice GetInputDevice(UxrHandSide handSide)
|
||||
{
|
||||
return handSide == UxrHandSide.Left ? _deviceLeft : _deviceRight;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Using an audio file, creates a haptic samples buffer that can be sent for feedback.
|
||||
/// This code is based on the Oculus SDK (OVRHaptics.cs).
|
||||
/// </summary>
|
||||
/// <param name="inputDevice">Unity input device that will be the feedback target</param>
|
||||
/// <param name="audioClip">Audio clip whose audio sample will be used to create haptics</param>
|
||||
/// <returns>Buffer that can be sent to the device as haptic feedback</returns>
|
||||
protected byte[] CreateHapticBufferFromAudioClip(InputDevice inputDevice, AudioClip audioClip)
|
||||
{
|
||||
float[] audioData = new float[audioClip.samples * audioClip.channels];
|
||||
audioClip.GetData(audioData, 0);
|
||||
|
||||
if (!inputDevice.TryGetHapticCapabilities(out HapticCapabilities hapticCapabilities) || !hapticCapabilities.supportsBuffer)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (hapticCapabilities.bufferFrequencyHz == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
double stepSizePrecise = (audioClip.frequency + 1e-6) / hapticCapabilities.bufferFrequencyHz;
|
||||
|
||||
if (stepSizePrecise < 1.0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int stepSize = (int)stepSizePrecise;
|
||||
double stepSizeError = stepSizePrecise - stepSize;
|
||||
int length = audioData.Length;
|
||||
|
||||
double accumStepSizeError = 0.0f;
|
||||
byte[] samples = new byte[length];
|
||||
int i = 0;
|
||||
int s = 0;
|
||||
|
||||
while (i < length)
|
||||
{
|
||||
byte sample = (byte)(Mathf.Clamp01(Mathf.Abs(audioData[i])) * byte.MaxValue);
|
||||
|
||||
if (s < samples.Length)
|
||||
{
|
||||
samples[s] = sample;
|
||||
s++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
i += stepSize * audioClip.channels;
|
||||
accumStepSizeError += stepSizeError;
|
||||
if ((int)accumStepSizeError > 0)
|
||||
{
|
||||
i += (int)accumStepSizeError * audioClip.channels;
|
||||
accumStepSizeError = accumStepSizeError - (int)accumStepSizeError;
|
||||
}
|
||||
}
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets if the given input device is a left side VR controller
|
||||
/// </summary>
|
||||
/// <param name="inputDevice">Device to check</param>
|
||||
/// <returns>Whether the given input device is a left side VR controller</returns>
|
||||
private static bool IsLeftController(InputDevice inputDevice)
|
||||
{
|
||||
return inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Left);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets if the given input device is a right side VR controller
|
||||
/// </summary>
|
||||
/// <param name="inputDevice">Device to check</param>
|
||||
/// <returns>Whether the given input device is a right side VR controller</returns>
|
||||
private static bool IsRightController(InputDevice inputDevice)
|
||||
{
|
||||
return inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the given button in a controller is currently being touched or pressed.
|
||||
/// </summary>
|
||||
/// <param name="handSide">Which controller side to check</param>
|
||||
/// <param name="button">Button to check</param>
|
||||
/// <param name="buttonContact">Type of contact to check for (touch or press)</param>
|
||||
/// <returns>Boolean telling whether the specified button has contact</returns>
|
||||
private bool HasButtonContact(UxrHandSide handSide, UxrInputButtons button, ButtonContact buttonContact)
|
||||
{
|
||||
InputDevice inputDevice = GetInputDevice(handSide);
|
||||
if (!inputDevice.isValid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (button == UxrInputButtons.Joystick)
|
||||
{
|
||||
var featureUsage = buttonContact == ButtonContact.Press ? CommonUsages.primary2DAxisClick : CommonUsages.primary2DAxisTouch;
|
||||
if (inputDevice.TryGetFeatureValue(featureUsage, out bool value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
else if (button == UxrInputButtons.Joystick2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (button == UxrInputButtons.Trigger)
|
||||
{
|
||||
if (buttonContact == ButtonContact.Touch)
|
||||
{
|
||||
#if ULTIMATEXR_UNITY_XR_OCULUS
|
||||
if (inputDevice.TryGetFeatureValue(OculusUsages.indexTouch, out bool valueTouch))
|
||||
{
|
||||
return valueTouch;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (inputDevice.TryGetFeatureValue(CommonUsages.trigger, out float valueFloat))
|
||||
{
|
||||
// We try getting the float value first because in analog buttons like the oculus it will trigger too early with the bool version.
|
||||
return valueFloat > AnalogAsDPadThreshold;
|
||||
}
|
||||
|
||||
if (inputDevice.TryGetFeatureValue(CommonUsages.triggerButton, out bool value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
else if (button == UxrInputButtons.Trigger2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (button == UxrInputButtons.Grip)
|
||||
{
|
||||
if (inputDevice.TryGetFeatureValue(CommonUsages.gripButton, out bool value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
else if (button == UxrInputButtons.Button1)
|
||||
{
|
||||
var featureUsage = buttonContact == ButtonContact.Press ? CommonUsages.primaryButton : CommonUsages.primaryTouch;
|
||||
if (inputDevice.TryGetFeatureValue(featureUsage, out bool value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
else if (button == UxrInputButtons.Button2)
|
||||
{
|
||||
var featureUsage = buttonContact == ButtonContact.Press ? CommonUsages.secondaryButton : CommonUsages.secondaryTouch;
|
||||
if (inputDevice.TryGetFeatureValue(featureUsage, out bool value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
else if (button == UxrInputButtons.Menu)
|
||||
{
|
||||
if (inputDevice.TryGetFeatureValue(CommonUsages.menuButton, out bool value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
else if (button == UxrInputButtons.ThumbCapSense)
|
||||
{
|
||||
if (buttonContact == ButtonContact.Press)
|
||||
{
|
||||
#if ULTIMATEXR_UNITY_XR_OCULUS
|
||||
if (inputDevice.TryGetFeatureValue(OculusUsages.thumbrest, out bool value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (buttonContact == ButtonContact.Touch)
|
||||
{
|
||||
#if ULTIMATEXR_UNITY_XR_OCULUS
|
||||
if (inputDevice.TryGetFeatureValue(OculusUsages.thumbTouch, out bool value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (button == UxrInputButtons.IndexCapSense)
|
||||
{
|
||||
}
|
||||
else if (button == UxrInputButtons.MiddleCapSense)
|
||||
{
|
||||
}
|
||||
else if (button == UxrInputButtons.RingCapSense)
|
||||
{
|
||||
}
|
||||
else if (button == UxrInputButtons.LittleCapSense)
|
||||
{
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Types & Data
|
||||
|
||||
private string InputClassName => GetType().Name;
|
||||
|
||||
private static readonly List<InputDevice> s_activeInputDevices = new List<InputDevice>();
|
||||
|
||||
private InputDevice _deviceLeft;
|
||||
private InputDevice _deviceRight;
|
||||
private uint _leftHapticChannel;
|
||||
private uint _rightHapticChannel;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f85b57eaa39cce438201cb182d59147
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,67 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrUnityXRControllerTracking.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
using UltimateXR.Core.Settings;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for tracking devices based on OpenVR.
|
||||
/// </summary>
|
||||
public abstract class UxrUnityXRControllerTracking : UxrControllerTracking
|
||||
{
|
||||
#region Protected Overrides UxrTrackingDevice
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateSensors()
|
||||
{
|
||||
base.UpdateSensors();
|
||||
|
||||
if (Avatar.CameraComponent == null)
|
||||
{
|
||||
if (UxrGlobalSettings.Instance.LogLevelDevices >= UxrLogLevel.Warnings)
|
||||
{
|
||||
Debug.LogWarning($"{UxrConstants.DevicesModule}: No camera has been setup for this avatar");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
List<XRNodeState> nodeStates = new List<XRNodeState>();
|
||||
InputTracking.GetNodeStates(nodeStates);
|
||||
|
||||
foreach (XRNodeState nodeState in nodeStates)
|
||||
{
|
||||
if (nodeState.nodeType == XRNode.LeftHand)
|
||||
{
|
||||
Vector3 localAvatarLeftHandSensorPos = LocalAvatarLeftHandSensorPos;
|
||||
Quaternion localAvatarLeftHandSensorRot = LocalAvatarLeftHandSensorRot;
|
||||
|
||||
nodeState.TryGetRotation(out localAvatarLeftHandSensorRot);
|
||||
nodeState.TryGetPosition(out localAvatarLeftHandSensorPos);
|
||||
|
||||
UpdateSensor(UxrHandSide.Left, localAvatarLeftHandSensorPos, localAvatarLeftHandSensorRot);
|
||||
|
||||
}
|
||||
else if (nodeState.nodeType == XRNode.RightHand)
|
||||
{
|
||||
Vector3 localAvatarRightHandSensorPos = LocalAvatarRightHandSensorPos;
|
||||
Quaternion localAvatarRightHandSensorRot = LocalAvatarRightHandSensorRot;
|
||||
|
||||
nodeState.TryGetRotation(out localAvatarRightHandSensorRot);
|
||||
nodeState.TryGetPosition(out localAvatarRightHandSensorPos);
|
||||
|
||||
UpdateSensor(UxrHandSide.Right, localAvatarRightHandSensorPos, localAvatarRightHandSensorRot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e81ce09144eac54bb33e8bff7ddf811
|
||||
timeCreated: 1499842642
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f38dee19b883b1342bf0816189bd9ce0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,87 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrValveIndexInput.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Core;
|
||||
using UltimateXR.Devices.Integrations.SteamVR;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Valve
|
||||
{
|
||||
/// <summary>
|
||||
/// Valve index controllers. Also known as Knuckles.
|
||||
/// </summary>
|
||||
public class UxrValveIndexInput : UxrSteamVRControllerInput
|
||||
{
|
||||
#region Public Overrides UxrControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerSetupType SetupType => UxrControllerSetupType.Dual;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool MainJoystickIsTouchpad => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements)
|
||||
{
|
||||
uint validElements = (uint)(UxrControllerElements.Joystick | // Joystick
|
||||
UxrControllerElements.Joystick2 | // Trackpad
|
||||
UxrControllerElements.Grip | // Grip
|
||||
UxrControllerElements.Trigger | // Trigger
|
||||
UxrControllerElements.Button1 | // Button A
|
||||
UxrControllerElements.Button2 | // Button B
|
||||
UxrControllerElements.DPad); // Joystick
|
||||
|
||||
return (validElements & (uint)controllerElements) == (uint)controllerElements;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide)
|
||||
{
|
||||
return UxrControllerInputCapabilities.HapticImpulses | UxrControllerInputCapabilities.TrackedHandPose;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Overrides UxrSteamVRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<string> ControllerNames
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return "indexcontroller";
|
||||
yield return "Knuckles EV3.0 Left";
|
||||
yield return "Knuckles EV3.0 Right";
|
||||
yield return "Knuckles EV2.0 Left";
|
||||
yield return "Knuckles EV2.0 Right";
|
||||
yield return "Knuckles Left";
|
||||
yield return "Knuckles Right";
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool UsesHandSkeletons => true;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Overrides UxrSteamVRControllerInput
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateInput()
|
||||
{
|
||||
base.UpdateInput();
|
||||
|
||||
// Propagate touchpad touch to press, since only touch is signaled by the API
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Joystick2, GetButtonsTouch(UxrHandSide.Left, UxrInputButtons.Joystick2));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Joystick2, GetButtonsTouch(UxrHandSide.Right, UxrInputButtons.Joystick2));
|
||||
|
||||
// Propagate grip touch to press, since only touch is signaled by the API
|
||||
SetButtonFlags(ButtonFlags.PressFlagsLeft, UxrInputButtons.Grip, GetButtonsTouch(UxrHandSide.Left, UxrInputButtons.Grip));
|
||||
SetButtonFlags(ButtonFlags.PressFlagsRight, UxrInputButtons.Grip, GetButtonsTouch(UxrHandSide.Right, UxrInputButtons.Grip));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d38a842ac6135e64babe0def2b78c7f0
|
||||
timeCreated: 1499677449
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrValveIndexTracking.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System;
|
||||
using UltimateXR.Devices.Integrations.SteamVR;
|
||||
|
||||
namespace UltimateXR.Devices.Integrations.Valve
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracking component for Valve Index controllers, also known as Knuckles, using SteamVR.
|
||||
/// </summary>
|
||||
public class UxrValveIndexTracking : UxrSteamVRControllerTracking
|
||||
{
|
||||
#region Public Overrides UxrControllerTracking
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type RelatedControllerInputType => typeof(UxrValveIndexInput);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c210797670b3ccb4faa0d527c28face7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user