Files
2020-05-02 19:29:40 -07:00

234 lines
9.7 KiB
C#

/************************************************************************************
Copyright : Copyright 2017-Present Oculus VR, LLC. All Rights reserved.
Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
you may not use the Oculus VR Rift SDK except in compliance with the License,
which is provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
You may obtain a copy of the License at
http://www.oculusvr.com/licenses/LICENSE-3.2
Unless required by applicable law or agreed to in writing, the Oculus VR SDK
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************************/
using System.Collections.Specialized;
using System.Runtime.InteropServices;
using UnityEngine;
namespace ControllerSelection
{
public class OVRInputHelpers
{
public enum HandFilter
{
None = 0,
Left = 1,
Right = 2,
Both = Left | Right
}
/// <summary>
/// Indicates whether hand started pinching in this frame
/// </summary>
/// <param name="activeController"></param>
/// <param name="finger"></param>
/// <returns></returns>
public static bool IsFingerStartPinching(OVRInput.Controller activeController, OVRHand.HandFinger finger)
{
bool isLeftHand = (activeController & OVRInput.Controller.LHand) == OVRInput.Controller.LHand;
var curPinch = isLeftHand ? HandsManager.Instance.GetLeftPinchMode(finger) : HandsManager.Instance.GetRightPinchMode(finger);
var lastPinch = isLeftHand ? HandsManager.Instance.GetLastLeftPinchMode(finger) : HandsManager.Instance.GetLastRightPinchMode(finger);
return (lastPinch == HandsManager.PinchMode.NotPinched && curPinch == HandsManager.PinchMode.Pinched);
}
/// <summary>
/// Indicates whether hand stopped pinching in this frame
/// </summary>
/// <param name="activeController"></param>
/// <param name="finger"></param>
/// <returns></returns>
public static bool IsFingerStopPinching(OVRInput.Controller activeController, OVRHand.HandFinger finger)
{
bool isLeftHand = (activeController & OVRInput.Controller.LHand) == OVRInput.Controller.LHand;
var curPinch = isLeftHand ? HandsManager.Instance.GetLeftPinchMode(finger) : HandsManager.Instance.GetRightPinchMode(finger);
var lastPinch = isLeftHand ? HandsManager.Instance.GetLastLeftPinchMode(finger) : HandsManager.Instance.GetLastRightPinchMode(finger);
return (lastPinch == HandsManager.PinchMode.Pinched && curPinch == HandsManager.PinchMode.NotPinched);
}
/// <summary>
/// Indicates whether hand is pinching
/// </summary>
/// <param name="activeController"></param>
/// <param name="finger"></param>
/// <returns></returns>
public static bool IsFingerPinching(OVRInput.Controller activeController, OVRHand.HandFinger finger)
{
bool isLeftHand = (activeController & OVRInput.Controller.LHand) == OVRInput.Controller.LHand;
var curPinch = isLeftHand ? HandsManager.Instance.GetLeftPinchMode(finger) : HandsManager.Instance.GetRightPinchMode(finger);
return (curPinch == HandsManager.PinchMode.Pinched);
}
/// <summary>
/// Returns hand orientation
/// </summary>
/// <param name="factiveController"></param>
/// <param name="orientation"></param>
/// <param name="position"></param>
/// <returns></returns>
public static bool GetHandOrientation(OVRInput.Controller activeController, out Quaternion orientation, out Vector3 position)
{
orientation = default(Quaternion);
position = default(Vector3);
if ((activeController & OVRInput.Controller.Hands) == OVRInput.Controller.None)
{
return false;
}
if (!HandsManager.Instance || !HandsManager.Instance.IsInitialized())
{
return false;
}
var hand = (activeController & OVRInput.Controller.RHand) == OVRInput.Controller.RHand ? HandsManager.Instance.RightHand : HandsManager.Instance.LeftHand;
var isReliable = hand.IsTracked && hand.HandConfidence == OVRHand.TrackingConfidence.High;
if (!isReliable || !hand.IsPointerPoseValid)
{
return false;
}
var pointer = hand.PointerPose;
orientation = pointer.rotation;
position = pointer.position;
return true;
}
// Given a controller and tracking space, return the ray that controller uses.
// Will fall back to center eye or camera on Gear if no controller is present.
public static bool GetSelectionRay(OVRInput.Controller activeController, Transform trackingSpace, out Ray ray)
{
ray = default(Ray);
if (trackingSpace != null && activeController != OVRInput.Controller.None)
{
Quaternion orientation = default(Quaternion);
Vector3 localStartPoint = default(Vector3);
if ((activeController & OVRInput.Controller.Hands) != OVRInput.Controller.None)
{
if (!GetHandOrientation(activeController, out orientation, out localStartPoint))
{
return false;
}
}
else
{
orientation = OVRInput.GetLocalControllerRotation(activeController);
localStartPoint = OVRInput.GetLocalControllerPosition(activeController);
}
Matrix4x4 localToWorld = trackingSpace.localToWorldMatrix;
Vector3 worldStartPoint = localToWorld.MultiplyPoint(localStartPoint);
Vector3 worldOrientation = localToWorld.MultiplyVector(orientation * Vector3.forward);
ray = new Ray(worldStartPoint, worldOrientation);
return true;
}
return false;
}
// Search the scene to find a tracking space. This method can be expensive! Try to avoid it if possible.
public static Transform FindTrackingSpace() {
// There should be an OVRManager in the scene
if (OVRManager.instance != null) {
Transform trackingSpace = OVRManager.instance.transform.Find("TrackingSpace");
if (trackingSpace != null) {
return trackingSpace;
}
}
Debug.LogWarning("OVRManager is not in scene, finding tracking space is going to be expensive!");
// Look for any CameraRig objects
OVRCameraRig[] cameraRigs = UnityEngine.Object.FindObjectsOfType(typeof(OVRCameraRig)) as OVRCameraRig[];
foreach (OVRCameraRig cameraRig in cameraRigs) {
if (cameraRig.gameObject.activeSelf) {
Transform trackingSpace = cameraRig.transform.Find("TrackingSpace");
if (trackingSpace != null) {
return trackingSpace;
}
}
}
// Last resort, look for a tracking space
GameObject trackingSpaceGO = UnityEngine.GameObject.Find("TrackingSpace");
if (trackingSpaceGO != null) {
return trackingSpaceGO.transform;
}
// Guess it doesn't exist
return null;
}
/// <summary>
/// Returns connected controllers
/// </summary>
/// <param name="filter"></param>
/// <returns></returns>
public static OVRInput.Controller GetConnectedControllers(HandFilter filter = HandFilter.Both)
{
OVRInput.Controller controller = OVRInput.GetConnectedControllers();
if (((filter & HandFilter.Right) == HandFilter.Right) && (controller & OVRInput.Controller.RTouch) == OVRInput.Controller.RTouch)
{
return OVRInput.Controller.RTouch;
}
if (((filter & HandFilter.Left) == HandFilter.Left) && (controller & OVRInput.Controller.LTouch) == OVRInput.Controller.LTouch)
{
return OVRInput.Controller.LTouch;
}
if (((filter & HandFilter.Right) == HandFilter.Right) && (controller & OVRInput.Controller.RTrackedRemote) == OVRInput.Controller.RTrackedRemote)
{
return OVRInput.Controller.RTrackedRemote;
}
if (((filter & HandFilter.Left) == HandFilter.Left) && (controller & OVRInput.Controller.LTrackedRemote) == OVRInput.Controller.LTrackedRemote)
{
return OVRInput.Controller.LTrackedRemote;
}
controller = OVRInput.Controller.None;
if (OVRPlugin.GetHandTrackingEnabled())
{
if ((filter & HandFilter.Both) == HandFilter.Both)
{
return OVRInput.Controller.Hands;
}
else if ((filter & HandFilter.Right) == HandFilter.Right)
{
return OVRInput.Controller.RHand;
}
else
{
return OVRInput.Controller.LHand;
}
}
return OVRInput.Controller.None;
}
}
}