test
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using UnityEngine.InputSystem.LowLevel;
|
||||
|
||||
////REVIEW: should we keep an explicit playback status? ATM calling ResumeHaptics() will re-issue last set motor speed regardless of pause state
|
||||
|
||||
namespace UnityEngine.InputSystem.Haptics
|
||||
{
|
||||
/// <summary>
|
||||
/// Common implementation of dual motor rumbling.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This struct is meant for use in devices that implement <see cref="IDualMotorRumble"/>.
|
||||
/// </remarks>
|
||||
internal struct DualMotorRumble
|
||||
{
|
||||
/// <summary>
|
||||
/// Normalized [0..1] speed of the low-frequency (usually left) motor.
|
||||
/// </summary>
|
||||
/// <value>Speed of left motor.</value>
|
||||
public float lowFrequencyMotorSpeed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Normalized [0..1] speed of the high-frequency (usually right) motor.
|
||||
/// </summary>
|
||||
/// <value>Speed of right motor.</value>
|
||||
public float highFrequencyMotorSpeed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether either of the motors is currently set to non-zero speeds.
|
||||
/// </summary>
|
||||
/// <value>True if the motors are currently turned on.</value>
|
||||
/// <remarks>
|
||||
/// Does not take pausing into account, i.e. <see cref="lowFrequencyMotorSpeed"/> and/or
|
||||
/// <see cref="highFrequencyMotorSpeed"/> may be non-zero but haptics on the device
|
||||
/// may actually be paused with <see cref="PauseHaptics"/>.
|
||||
/// </remarks>
|
||||
public bool isRumbling =>
|
||||
!Mathf.Approximately(lowFrequencyMotorSpeed, 0f)
|
||||
|| !Mathf.Approximately(highFrequencyMotorSpeed, 0f);
|
||||
|
||||
/// <summary>
|
||||
/// Reset motor speeds to zero but retain current values for <see cref="lowFrequencyMotorSpeed"/>
|
||||
/// and <see cref="highFrequencyMotorSpeed"/>.
|
||||
/// </summary>
|
||||
/// <param name="device">Device to send command to.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="device"/> is null.</exception>
|
||||
public void PauseHaptics(InputDevice device)
|
||||
{
|
||||
if (device == null)
|
||||
throw new ArgumentNullException("device");
|
||||
|
||||
if (!isRumbling)
|
||||
return;
|
||||
|
||||
var command = DualMotorRumbleCommand.Create(0f, 0f);
|
||||
device.ExecuteCommand(ref command);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resume haptics by setting motor speeds to the current values of <see cref="lowFrequencyMotorSpeed"/>
|
||||
/// and <see cref="highFrequencyMotorSpeed"/>.
|
||||
/// </summary>
|
||||
/// <param name="device">Device to send command to.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="device"/> is null.</exception>
|
||||
public void ResumeHaptics(InputDevice device)
|
||||
{
|
||||
if (device == null)
|
||||
throw new ArgumentNullException("device");
|
||||
|
||||
if (!isRumbling)
|
||||
return;
|
||||
|
||||
SetMotorSpeeds(device, lowFrequencyMotorSpeed, highFrequencyMotorSpeed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset haptics by setting both <see cref="lowFrequencyMotorSpeed"/> and <see cref="highFrequencyMotorSpeed"/>
|
||||
/// to zero.
|
||||
/// </summary>
|
||||
/// <param name="device">Device to send command to.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="device"/> is null.</exception>
|
||||
public void ResetHaptics(InputDevice device)
|
||||
{
|
||||
if (device == null)
|
||||
throw new ArgumentNullException("device");
|
||||
|
||||
if (!isRumbling)
|
||||
return;
|
||||
|
||||
SetMotorSpeeds(device, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the speed of the low-frequency (usually left) and high-frequency (usually right) motor
|
||||
/// on <paramref name="device"/>. Updates <see cref="lowFrequencyMotorSpeed"/> and
|
||||
/// <see cref="highFrequencyMotorSpeed"/>.
|
||||
/// </summary>
|
||||
/// <param name="device">Device to send command to.</param>
|
||||
/// <param name="lowFrequency">Speed of the low-frequency (left) motor. Normalized [0..1] value
|
||||
/// with 1 indicating maximum speed and 0 indicating the motor is turned off. Will automatically
|
||||
/// be clamped into range.</param>
|
||||
/// <param name="highFrequency">Speed of the high-frequency (right) motor. Normalized [0..1] value
|
||||
/// with 1 indicating maximum speed and 0 indicating the motor is turned off. Will automatically
|
||||
/// be clamped into range.</param>
|
||||
/// <remarks>
|
||||
/// Sends <see cref="DualMotorRumbleCommand"/> to <paramref name="device"/>.
|
||||
/// </remarks>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="device"/> is null.</exception>
|
||||
public void SetMotorSpeeds(InputDevice device, float lowFrequency, float highFrequency)
|
||||
{
|
||||
if (device == null)
|
||||
throw new ArgumentNullException("device");
|
||||
|
||||
lowFrequencyMotorSpeed = Mathf.Clamp(lowFrequency, 0.0f, 1.0f);
|
||||
highFrequencyMotorSpeed = Mathf.Clamp(highFrequency, 0.0f, 1.0f);
|
||||
|
||||
var command = DualMotorRumbleCommand.Create(lowFrequencyMotorSpeed, highFrequencyMotorSpeed);
|
||||
device.ExecuteCommand(ref command);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4a1c749d40b4bf985d6b32d7db339bb
|
||||
timeCreated: 1517012194
|
@@ -0,0 +1,37 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
|
||||
namespace UnityEngine.InputSystem.LowLevel
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||
internal struct DualMotorRumbleCommand : IInputDeviceCommandInfo
|
||||
{
|
||||
public static FourCC Type { get { return new FourCC('R', 'M', 'B', 'L'); } }
|
||||
|
||||
internal const int kSize = InputDeviceCommand.kBaseCommandSize + sizeof(float) * 2;
|
||||
|
||||
[FieldOffset(0)]
|
||||
public InputDeviceCommand baseCommand;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize)]
|
||||
public float lowFrequencyMotorSpeed;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + 4)]
|
||||
public float highFrequencyMotorSpeed;
|
||||
|
||||
public FourCC typeStatic
|
||||
{
|
||||
get { return Type; }
|
||||
}
|
||||
|
||||
public static DualMotorRumbleCommand Create(float lowFrequency, float highFrequency)
|
||||
{
|
||||
return new DualMotorRumbleCommand
|
||||
{
|
||||
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||
lowFrequencyMotorSpeed = lowFrequency,
|
||||
highFrequencyMotorSpeed = highFrequency
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee46ea662a1d4d2397d0b3a45baf67ef
|
||||
timeCreated: 1517015642
|
@@ -0,0 +1,30 @@
|
||||
namespace UnityEngine.InputSystem.Haptics
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple haptics interface that allows to control two motors individually.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Dual-motor control is most common on gamepads (see <see cref="Gamepad"/>) such as
|
||||
/// Xbox and PlayStation controllers.
|
||||
/// </remarks>
|
||||
public interface IDualMotorRumble : IHaptics
|
||||
{
|
||||
/// <summary>
|
||||
/// Set the motor speeds of the low-frequency (usually on the left) and high-frequency
|
||||
/// (usually on the right) motors.
|
||||
/// </summary>
|
||||
/// <param name="lowFrequency">Speed of the low-frequency (left) motor. Normalized [0..1] value
|
||||
/// with 1 indicating maximum speed and 0 indicating the motor is turned off. Will automatically
|
||||
/// be clamped into range.</param>
|
||||
/// <param name="highFrequency">Speed of the high-frequency (right) motor. Normalized [0..1] value
|
||||
/// with 1 indicating maximum speed and 0 indicating the motor is turned off. Will automatically
|
||||
/// be clamped into range.</param>
|
||||
/// <remarks>
|
||||
/// Note that hardware will put limits on the level of control you have over the motors.
|
||||
/// Rumbling the motors at maximum speed for an extended period of time may cause them to turn
|
||||
/// off for some time to prevent overheating. Also, how quickly the motors react and how often
|
||||
/// the speed can be updated will depend on the hardware and drivers.
|
||||
/// </remarks>
|
||||
void SetMotorSpeeds(float lowFrequency, float highFrequency);
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6982a6ffcdbf47a6aa68fd4418622395
|
||||
timeCreated: 1516644451
|
@@ -0,0 +1,81 @@
|
||||
////REVIEW: Devices usually will automatically shut down haptics if they haven't received a haptics command in some time.
|
||||
//// How should we deal with that? Should haptics automatically refresh themselves periodically while they are set?
|
||||
|
||||
////REVIEW: Do we need a mute in addition to a pause?
|
||||
|
||||
namespace UnityEngine.InputSystem.Haptics
|
||||
{
|
||||
/// <summary>
|
||||
/// Base interface for haptics on input devices.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// To support haptics, an <see cref="InputDevice"/> has to implement one or more
|
||||
/// haptics interfaces.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// class MyDevice : InputDevice, IDualMotorRumble
|
||||
/// {
|
||||
/// private DualMotorRumble m_Rumble;
|
||||
///
|
||||
/// public void SetMotorSpeeds(float lowFrequency, float highFrequency)
|
||||
/// {
|
||||
/// m_Rumble.SetMotorSpeeds(lowFrequency, highFrequency);
|
||||
/// }
|
||||
///
|
||||
/// public void PauseHaptics()
|
||||
/// {
|
||||
/// m_Rumble.PauseHaptics();
|
||||
/// }
|
||||
///
|
||||
/// public void ResumeHaptics()
|
||||
/// {
|
||||
/// m_Rumble.ResumeHaptics();
|
||||
/// }
|
||||
///
|
||||
/// public void ResetHaptics()
|
||||
/// {
|
||||
/// m_Rumble.ResetHaptics();
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso cref="InputSystem.PauseHaptics"/>
|
||||
/// <seealso cref="InputSystem.ResumeHaptics"/>
|
||||
/// <seealso cref="InputSystem.ResetHaptics"/>
|
||||
public interface IHaptics
|
||||
{
|
||||
/// <summary>
|
||||
/// Pause haptics playback on the device.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This should preserve current playback settings (such as motor speed levels
|
||||
/// or effect playback positions) but shut down feedback effects on the device.
|
||||
///
|
||||
/// If proper resumption of effects is not possible, playback should be stopped
|
||||
/// and <see cref="ResumeHaptics"/> is allowed to be a no-operation.
|
||||
///
|
||||
/// Note that haptics playback states are not required to survive domain reloads
|
||||
/// in the editor.
|
||||
/// </remarks>
|
||||
/// <seealso cref="ResumeHaptics"/>
|
||||
void PauseHaptics();
|
||||
|
||||
/// <summary>
|
||||
/// Resume haptics playback on the device.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Should be called after calling <see cref="PauseHaptics"/>. Otherwise does
|
||||
/// nothing.
|
||||
/// </remarks>
|
||||
void ResumeHaptics();
|
||||
|
||||
/// <summary>
|
||||
/// Reset haptics playback on the device to its default state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This will turn off all haptics effects that may be playing on the device.
|
||||
/// </remarks>
|
||||
void ResetHaptics();
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 179e4e4b8003406d97463b101f15eb8b
|
||||
timeCreated: 1516752847
|
Reference in New Issue
Block a user