Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Assets/Scenes/EVRC.unity
Original file line number Diff line number Diff line change
Expand Up @@ -3683,6 +3683,9 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
actionsController: {fileID: 1840785751}
hapticAction:
actionPath: /actions/default/out/Haptic
needsReinit: 0
--- !u!1 &750486503
GameObject:
m_ObjectHideFlags: 0
Expand Down
3 changes: 3 additions & 0 deletions Assets/Scripts/ActionsController/IBindingsController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace EVRC
{
using Hand = ActionsController.Hand;
using TrackpadInterval = ActionsController.TrackpadInterval;

public enum BindingsHintCategory
Expand All @@ -17,5 +18,7 @@ public interface IBindingsController
bool CanShowBindings();
void ShowBindings(BindingsHintCategory hintCategory);
void EditBindings();
IHaptics GetHapticsForHand(Hand hand);

}
}
8 changes: 8 additions & 0 deletions Assets/Scripts/ActionsController/IHaptics.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace EVRC
{
public interface IHaptics
{
void ThrottleDetent();
}
}

11 changes: 11 additions & 0 deletions Assets/Scripts/ActionsController/IHaptics.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions Assets/Scripts/ActionsControllerBindingsLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,20 @@ public void EditBindings()
Debug.LogWarning("Bindings Controller not available");
}
}

public IHaptics GetHapticsForHand(Hand hand)
{
var controller = CurrentController;
if (controller != null)
{
return CurrentController.GetHapticsForHand(hand);
}
else
{
Debug.LogWarning("Bindings Controller not available");
return null;
}
}

}
}
7 changes: 7 additions & 0 deletions Assets/Scripts/ActionsController_SteamVRInputBindings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public class ActionsController_SteamVRInputBindings : MonoBehaviour, IBindingsCo
{
public ActionsController actionsController;

public SteamVR_Action_Vibration hapticAction;

private Dictionary<SteamVR_Action_Boolean, InputAction> booleanActionMap = new Dictionary<SteamVR_Action_Boolean, InputAction>();
private Dictionary<SteamVR_Action_Vector2, InputAction> vector2ActionMap = new Dictionary<SteamVR_Action_Vector2, InputAction>();
private Dictionary<SteamVR_Action_Boolean, InputAction> trackpadSlideTouchActionMap = new Dictionary<SteamVR_Action_Boolean, InputAction>();
Expand Down Expand Up @@ -489,5 +491,10 @@ public void EditBindings()
{
SteamVR_Input.OpenBindingUI();
}

public IHaptics GetHapticsForHand(Hand hand)
{
return new SteamVRHaptics(hapticAction, hand);
}
}
}
23 changes: 23 additions & 0 deletions Assets/Scripts/SteamVRHaptics.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Valve.VR;

namespace EVRC
{
using Hand = ActionsController.Hand;

public class SteamVRHaptics : IHaptics
{
SteamVR_Action_Vibration hapticAction;
SteamVR_Input_Sources inputSource;

public SteamVRHaptics(SteamVR_Action_Vibration hapticAction, Hand hand)
{
this.hapticAction = hapticAction;
inputSource = ActionsController_SteamVRInputBindings.GetInputSourceForHand(hand);
}

public void ThrottleDetent()
{
hapticAction.Execute(0, 0.15f, 10, 0.15f, inputSource);
}
}
}
11 changes: 11 additions & 0 deletions Assets/Scripts/SteamVRHaptics.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

140 changes: 134 additions & 6 deletions Assets/Scripts/VirtualThrottle.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
using System;
using UnityEngine;
using UnityEngine;

namespace EVRC
{
enum ThrottleState
{
Forward,
ForwardIdleDetent,
Idle,
ReverseIdleDetent,
Reverse,
}

/**
* A virtual 1-axis movable throttle that outputs to vJoy when grabbed
*/
Expand All @@ -21,6 +29,7 @@ public class VirtualThrottle : MonoBehaviour, IGrabable, IHighlightable
private bool highlighted = false;
private ControllerInteractionPoint attachedInteractionPoint;
private Transform attachPoint;
private ThrottleState state = ThrottleState.Idle;

public GrabMode GetGrabMode()
{
Expand Down Expand Up @@ -93,6 +102,13 @@ public void Ungrabbed(ControllerInteractionPoint interactionPoint)
{
buttons.Ungrabbed();
}

var throttle = handle.localPosition.z / magnitudeLength;
if (Mathf.Abs(throttle) < output.throttleDeadzonePercentage)
{
handle.localPosition = Vector3.zero;
state = ThrottleState.Idle;
}
}
}

Expand Down Expand Up @@ -142,10 +158,19 @@ void LateUpdate()

var t = attachPoint;
handle.position = t.position;
handle.localPosition = new Vector3(
0,
0,
Mathf.Clamp(handle.localPosition.z, -magnitudeLength, magnitudeLength));

var localMagnitude = Mathf.Clamp(handle.localPosition.z, -magnitudeLength, magnitudeLength);
var throttle = localMagnitude / magnitudeLength;
if (Mathf.Abs(throttle) < detentSize)
{
MoveThrottleToIdleDetent();
}
else
{
handle.localPosition = new Vector3(0, 0, localMagnitude);
}

CheckStateChange(throttle);
}

void Update()
Expand All @@ -156,5 +181,108 @@ void Update()
var throttle = handle.localPosition.z / magnitudeLength;
output.SetThrottle(throttle);
}

private float detentSize
{
get
{
return output.throttleDeadzonePercentage / 100f;
}
}

private float reverseDetentSize
{
get
{
return 3 * detentSize;
}
}


private void CheckStateChange(float throttle)
{
switch (state)
{
case ThrottleState.Forward:
if (throttle < detentSize)
{
state = ThrottleState.ForwardIdleDetent;
EmitHapticDetent();
}
break;

case ThrottleState.ForwardIdleDetent:
if (throttle < -reverseDetentSize)
{
state = ThrottleState.Reverse;
EmitHapticDetent();
}
else if (throttle > detentSize)
{
state = ThrottleState.Forward;
EmitHapticDetent();
}
else
{
MoveThrottleToIdleDetent();
}
break;

case ThrottleState.Idle:
if (throttle > detentSize)
{
state = ThrottleState.Forward;
EmitHapticDetent();
}
else if (throttle < -detentSize)
{
state = ThrottleState.Reverse;
EmitHapticDetent();
}
else
{
MoveThrottleToIdleDetent();
}
break;

case ThrottleState.ReverseIdleDetent:
if (throttle > reverseDetentSize)
{
state = ThrottleState.Forward;
EmitHapticDetent();
}
else if (throttle < -detentSize)
{
state = ThrottleState.Reverse;
EmitHapticDetent();
}
else
{
MoveThrottleToIdleDetent();
}
break;

case ThrottleState.Reverse:
if (throttle > -detentSize)
{
state = ThrottleState.ReverseIdleDetent;
EmitHapticDetent();
}
break;
}
}

private void MoveThrottleToIdleDetent()
{
handle.localPosition = Vector3.zero;
}

private void EmitHapticDetent()
{
var attachment = attachedInteractionPoint;
var haptics = ActionsControllerBindingsLoader.CurrentBindingsController
.GetHapticsForHand(attachment.Hand);
haptics.ThrottleDetent();
}
}
}