test
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
// ENABLE_VR is not defined on Game Core but the assembly is available with limited features when the XR module is enabled.
|
||||
#if UNITY_INPUT_SYSTEM_ENABLE_XR && (ENABLE_VR || UNITY_GAMECORE) || PACKAGE_DOCS_GENERATION
|
||||
namespace UnityEngine.InputSystem.XR.Haptics
|
||||
{
|
||||
public struct BufferedRumble
|
||||
{
|
||||
public HapticCapabilities capabilities { get; private set; }
|
||||
InputDevice device { get; set; }
|
||||
|
||||
public BufferedRumble(InputDevice device)
|
||||
{
|
||||
if (device == null)
|
||||
throw new System.ArgumentNullException(nameof(device));
|
||||
|
||||
this.device = device;
|
||||
|
||||
var command = GetHapticCapabilitiesCommand.Create();
|
||||
device.ExecuteCommand(ref command);
|
||||
capabilities = command.capabilities;
|
||||
}
|
||||
|
||||
public void EnqueueRumble(byte[] samples)
|
||||
{
|
||||
var command = SendBufferedHapticCommand.Create(samples);
|
||||
device.ExecuteCommand(ref command);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1e8cf3dc2c11ed47a2666fcf0d3a938
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,50 @@
|
||||
// ENABLE_VR is not defined on Game Core but the assembly is available with limited features when the XR module is enabled.
|
||||
#if UNITY_INPUT_SYSTEM_ENABLE_XR && (ENABLE_VR || UNITY_GAMECORE) || PACKAGE_DOCS_GENERATION
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine.InputSystem.LowLevel;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
|
||||
namespace UnityEngine.InputSystem.XR.Haptics
|
||||
{
|
||||
public struct HapticState
|
||||
{
|
||||
public HapticState(uint samplesQueued, uint samplesAvailable)
|
||||
{
|
||||
this.samplesQueued = samplesQueued;
|
||||
this.samplesAvailable = samplesAvailable;
|
||||
}
|
||||
|
||||
public uint samplesQueued { get; private set; }
|
||||
public uint samplesAvailable { get; private set; }
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||
public struct GetCurrentHapticStateCommand : IInputDeviceCommandInfo
|
||||
{
|
||||
static FourCC Type => new FourCC('X', 'H', 'S', '0');
|
||||
|
||||
const int kSize = InputDeviceCommand.kBaseCommandSize + (sizeof(uint) * 2);
|
||||
|
||||
public FourCC typeStatic => Type;
|
||||
|
||||
[FieldOffset(0)]
|
||||
InputDeviceCommand baseCommand;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize)]
|
||||
public uint samplesQueued;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + sizeof(int))]
|
||||
public uint samplesAvailable;
|
||||
|
||||
public HapticState currentState => new HapticState(samplesQueued, samplesAvailable);
|
||||
|
||||
public static GetCurrentHapticStateCommand Create()
|
||||
{
|
||||
return new GetCurrentHapticStateCommand
|
||||
{
|
||||
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0049e966b9953774fa3d07808a5555a9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,159 @@
|
||||
// ENABLE_VR is not defined on Game Core but the assembly is available with limited features when the XR module is enabled.
|
||||
#if UNITY_INPUT_SYSTEM_ENABLE_XR && (ENABLE_VR || UNITY_GAMECORE) || PACKAGE_DOCS_GENERATION
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine.InputSystem.LowLevel;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
|
||||
namespace UnityEngine.InputSystem.XR.Haptics
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the haptic capabilities of a specific device.
|
||||
/// </summary>
|
||||
public struct HapticCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes and returns an instance of <see cref="HapticCapabilities"/>.
|
||||
/// </summary>
|
||||
/// <param name="numChannels">The number of haptic channels available on this device.</param>
|
||||
/// <param name="supportsImpulse">This device supports sending a haptic impulse.</param>
|
||||
/// <param name="supportsBuffer">This device supports sending a haptic buffer.</param>
|
||||
/// <param name="frequencyHz">The buffer frequency the device operates at in Hertz.</param>
|
||||
/// <param name="maxBufferSize">The max amount of buffer data that can be stored by the device.</param>
|
||||
/// <param name="optimalBufferSize">The optimal size of a device's buffer, taking into account frequency and latency.</param>
|
||||
public HapticCapabilities(uint numChannels, bool supportsImpulse, bool supportsBuffer, uint frequencyHz, uint maxBufferSize, uint optimalBufferSize)
|
||||
{
|
||||
this.numChannels = numChannels;
|
||||
this.supportsImpulse = supportsImpulse;
|
||||
this.supportsBuffer = supportsBuffer;
|
||||
this.frequencyHz = frequencyHz;
|
||||
this.maxBufferSize = maxBufferSize;
|
||||
this.optimalBufferSize = optimalBufferSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deprecated. Use <see cref="HapticCapabilities(uint, bool, bool, uint, uint, uint)"/> instead.
|
||||
/// This constructor did not match the native haptic capabilities struct and was missing properties.
|
||||
/// </summary>
|
||||
/// <param name="numChannels">The number of haptic channels available on this device.</param>
|
||||
/// <param name="frequencyHz">The buffer frequency the device operates at in Hertz.</param>
|
||||
/// <param name="maxBufferSize">The max amount of buffer data that can be stored by the device.</param>
|
||||
public HapticCapabilities(uint numChannels, uint frequencyHz, uint maxBufferSize)
|
||||
: this(numChannels, false, false, frequencyHz, maxBufferSize, 0U)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of haptic channels available on this device.
|
||||
/// </summary>
|
||||
public uint numChannels { get; }
|
||||
|
||||
/// <summary>
|
||||
/// This device supports sending a haptic impulse.
|
||||
/// </summary>
|
||||
/// <seealso cref="SendHapticImpulseCommand"/>
|
||||
public bool supportsImpulse { get; }
|
||||
|
||||
/// <summary>
|
||||
/// This device supports sending a haptic buffer.
|
||||
/// </summary>
|
||||
/// <seealso cref="SendBufferedHapticCommand"/>
|
||||
public bool supportsBuffer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The buffer frequency the device operates at in Hertz. This impacts how fast the device consumes buffered haptic data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This value is greater than 0 if <see cref="supportsBuffer"/> is <see langword="true"/>, and 0 otherwise.
|
||||
/// </remarks>
|
||||
public uint frequencyHz { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The max amount of buffer data that can be stored by the device.
|
||||
/// </summary>
|
||||
public uint maxBufferSize { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The optimal size of a device's buffer, taking into account frequency and latency.
|
||||
/// </summary>
|
||||
public uint optimalBufferSize { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Input device command struct for retrieving the haptic capabilities of a device.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||
public struct GetHapticCapabilitiesCommand : IInputDeviceCommandInfo
|
||||
{
|
||||
static FourCC Type => new FourCC('X', 'H', 'C', '0');
|
||||
|
||||
// 20 bytes of data from uint(4) + bool(1) + bool(1) + padding + uint(4) + uint(4) + uint(4)
|
||||
const int kSize = InputDeviceCommand.kBaseCommandSize + 20;
|
||||
|
||||
/// <inheritdoc />
|
||||
public FourCC typeStatic => Type;
|
||||
|
||||
[FieldOffset(0)]
|
||||
InputDeviceCommand baseCommand;
|
||||
|
||||
/// <summary>
|
||||
/// The number of haptic channels available on this device.
|
||||
/// </summary>
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize)]
|
||||
public uint numChannels;
|
||||
|
||||
/// <summary>
|
||||
/// This device supports sending a haptic impulse.
|
||||
/// </summary>
|
||||
/// <seealso cref="SendHapticImpulseCommand"/>
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + 4)]
|
||||
public bool supportsImpulse;
|
||||
|
||||
/// <summary>
|
||||
/// This device supports sending a haptic buffer.
|
||||
/// </summary>
|
||||
/// <seealso cref="SendBufferedHapticCommand"/>
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + 5)]
|
||||
public bool supportsBuffer;
|
||||
|
||||
/// <summary>
|
||||
/// The buffer frequency the device operates at in Hertz. This impacts how fast the device consumes buffered haptic data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This value is greater than 0 if <see cref="supportsBuffer"/> is <see langword="true"/>, and 0 otherwise.
|
||||
/// </remarks>
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + 8)]
|
||||
public uint frequencyHz;
|
||||
|
||||
/// <summary>
|
||||
/// The max amount of buffer data that can be stored by the device.
|
||||
/// </summary>
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + 12)]
|
||||
public uint maxBufferSize;
|
||||
|
||||
/// <summary>
|
||||
/// The optimal size of a device's buffer, taking into account frequency and latency.
|
||||
/// </summary>
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + 16)]
|
||||
public uint optimalBufferSize;
|
||||
|
||||
/// <summary>
|
||||
/// The haptic capabilities of the device, populated after this command is executed.
|
||||
/// </summary>
|
||||
public HapticCapabilities capabilities => new HapticCapabilities(numChannels, supportsImpulse, supportsBuffer, frequencyHz, maxBufferSize, optimalBufferSize);
|
||||
|
||||
/// <summary>
|
||||
/// Creates and returns a new initialized input device command struct for retrieving
|
||||
/// the haptic capabilities of a device when executed.
|
||||
/// </summary>
|
||||
/// <returns>Returns a new command struct with the data header initialized, making it ready to execute.</returns>
|
||||
/// <seealso cref="InputDevice.ExecuteCommand{TCommand}(ref TCommand)"/>
|
||||
public static GetHapticCapabilitiesCommand Create()
|
||||
{
|
||||
return new GetHapticCapabilitiesCommand
|
||||
{
|
||||
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ade21199e79d394ab34f4e6887f1c09
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,56 @@
|
||||
// ENABLE_VR is not defined on Game Core but the assembly is available with limited features when the XR module is enabled.
|
||||
#if UNITY_INPUT_SYSTEM_ENABLE_XR && (ENABLE_VR || UNITY_GAMECORE) || PACKAGE_DOCS_GENERATION
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine.InputSystem.LowLevel;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
|
||||
namespace UnityEngine.InputSystem.XR.Haptics
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||
public unsafe struct SendBufferedHapticCommand : IInputDeviceCommandInfo
|
||||
{
|
||||
static FourCC Type => new FourCC('X', 'H', 'U', '0');
|
||||
|
||||
private const int kMaxHapticBufferSize = 1024;
|
||||
private const int kSize = InputDeviceCommand.kBaseCommandSize + (sizeof(int) * 2) + (kMaxHapticBufferSize * sizeof(byte));
|
||||
|
||||
public FourCC typeStatic => Type;
|
||||
|
||||
[FieldOffset(0)]
|
||||
private InputDeviceCommand baseCommand;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize)]
|
||||
private int channel;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + sizeof(int))]
|
||||
private int bufferSize;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + (sizeof(int) * 2))]
|
||||
private fixed byte buffer[kMaxHapticBufferSize];
|
||||
|
||||
public static SendBufferedHapticCommand Create(byte[] rumbleBuffer)
|
||||
{
|
||||
if (rumbleBuffer == null)
|
||||
throw new System.ArgumentNullException(nameof(rumbleBuffer));
|
||||
|
||||
var rumbleBufferSize = Mathf.Min(kMaxHapticBufferSize, rumbleBuffer.Length);
|
||||
var newCommand = new SendBufferedHapticCommand
|
||||
{
|
||||
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||
bufferSize = rumbleBufferSize
|
||||
};
|
||||
|
||||
//TODO TOMB: There must be a more effective, bulk copy operation for fixed buffers than this.
|
||||
//Replace if found.
|
||||
var commandPtr = &newCommand;
|
||||
fixed(byte* src = rumbleBuffer)
|
||||
{
|
||||
for (int cpyIndex = 0; cpyIndex < rumbleBufferSize; cpyIndex++)
|
||||
commandPtr->buffer[cpyIndex] = src[cpyIndex];
|
||||
}
|
||||
|
||||
return newCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e553fed0b97be3349aff36916eb6fefc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,53 @@
|
||||
// ENABLE_VR is not defined on Game Core but the assembly is available with limited features when the XR module is enabled.
|
||||
#if UNITY_INPUT_SYSTEM_ENABLE_XR && (ENABLE_VR || UNITY_GAMECORE) || PACKAGE_DOCS_GENERATION
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine.InputSystem.LowLevel;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
|
||||
namespace UnityEngine.InputSystem.XR.Haptics
|
||||
{
|
||||
/// <summary>
|
||||
/// A device command sent to a device to set it's motor rumble amplitude for a set duration.
|
||||
/// </summary>
|
||||
/// <remarks>This is directly used by the <see cref="XRControllerWithRumble"/> class. For clearer details of using this command, see that class.</remarks>
|
||||
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||
public struct SendHapticImpulseCommand : IInputDeviceCommandInfo
|
||||
{
|
||||
static FourCC Type => new FourCC('X', 'H', 'I', '0');
|
||||
|
||||
private const int kSize = InputDeviceCommand.kBaseCommandSize + sizeof(int) + (sizeof(float) * 2);
|
||||
|
||||
[FieldOffset(0)]
|
||||
InputDeviceCommand baseCommand;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize)]
|
||||
private int channel;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + sizeof(int))]
|
||||
private float amplitude;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + sizeof(int) + (sizeof(float)))]
|
||||
private float duration;
|
||||
|
||||
public FourCC typeStatic => Type;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a device command that can then be sent to a specific device.
|
||||
/// </summary>
|
||||
/// <param name="motorChannel">The desired motor you want to rumble</param>
|
||||
/// <param name="motorAmplitude">The desired motor amplitude that should be within a [0-1] range.</param>
|
||||
/// <param name="motorDuration">The desired duration of the impulse in seconds.</param>
|
||||
/// <returns>The command that should be sent to the device via <c>InputDevice.ExecuteCommand</c>.</returns>
|
||||
public static SendHapticImpulseCommand Create(int motorChannel, float motorAmplitude, float motorDuration)
|
||||
{
|
||||
return new SendHapticImpulseCommand
|
||||
{
|
||||
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||
channel = motorChannel,
|
||||
amplitude = motorAmplitude,
|
||||
duration = motorDuration
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f84d6a1bd34ea6428fa1db0e9f459cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user