Initialer Upload neues Unity-Projekt
This commit is contained in:
236
Assets/Oculus/VR/Scripts/OVREyeGaze.cs
Normal file
236
Assets/Oculus/VR/Scripts/OVREyeGaze.cs
Normal file
@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus 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
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus 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;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// This class updates the transform of the GameObject to point toward an eye direction.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See <see cref="OVRPlugin.EyeGazeState"/> structure for list of eye state parameters.
|
||||
/// </remarks>
|
||||
[HelpURL("https://developer.oculus.com/reference/unity/latest/class_o_v_r_eye_gaze")]
|
||||
public class OVREyeGaze : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// True if eye tracking is enabled, otherwise false.
|
||||
/// </summary>
|
||||
public bool EyeTrackingEnabled => OVRPlugin.eyeTrackingEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// GameObject will automatically change position and rotate according to the selected eye.
|
||||
/// </summary>
|
||||
public EyeId Eye;
|
||||
|
||||
/// <summary>
|
||||
/// A confidence value ranging from 0..1 indicating the reliability of the eye tracking data.
|
||||
/// </summary>
|
||||
public float Confidence { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// GameObject will not change if detected eye state confidence is below this threshold.
|
||||
/// </summary>
|
||||
[Range(0f, 1f)]
|
||||
public float ConfidenceThreshold = 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// GameObject will automatically change position.
|
||||
/// </summary>
|
||||
public bool ApplyPosition = true;
|
||||
|
||||
/// <summary>
|
||||
/// GameObject will automatically rotate.
|
||||
/// </summary>
|
||||
public bool ApplyRotation = true;
|
||||
|
||||
private OVRPlugin.EyeGazesState _currentEyeGazesState;
|
||||
|
||||
/// <summary>
|
||||
/// Reference frame for eye. If it's null, then world reference frame will be used.
|
||||
/// </summary>
|
||||
[Tooltip("Reference frame for eye. " +
|
||||
"Reference frame should be set in the forward direction of the eye. It is there to calculate the initial offset of the eye GameObject. " +
|
||||
"If it's null, then world reference frame will be used.")]
|
||||
public Transform ReferenceFrame;
|
||||
|
||||
/// <summary>
|
||||
/// HeadSpace: Track eye relative to head space.
|
||||
/// WorldSpace: Track eye in world space.
|
||||
/// TrackingSpace: Track eye relative to OVRCameraRig.
|
||||
/// </summary>
|
||||
[Tooltip(
|
||||
"HeadSpace: Tracking mode will convert the eye pose from tracking space to local space " +
|
||||
"which is relative to the VR camera rig. For example, we can use this setting to correctly " +
|
||||
"show the eye movement of a character which is facing in another direction than the source.\n" +
|
||||
"WorldSpace: Tracking mode will convert the eye pose from tracking space to world space.\n" +
|
||||
"TrackingSpace: Track eye is relative to OVRCameraRig. This is raw pose information from VR tracking space.")]
|
||||
public EyeTrackingMode TrackingMode;
|
||||
|
||||
private Quaternion _initialRotationOffset;
|
||||
private Transform _viewTransform;
|
||||
|
||||
private const OVRPermissionsRequester.Permission EyeTrackingPermission =
|
||||
OVRPermissionsRequester.Permission.EyeTracking;
|
||||
|
||||
private Action<string> _onPermissionGranted;
|
||||
private static int _trackingInstanceCount;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_onPermissionGranted = OnPermissionGranted;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
PrepareHeadDirection();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_trackingInstanceCount++;
|
||||
|
||||
if (!StartEyeTracking())
|
||||
{
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPermissionGranted(string permissionId)
|
||||
{
|
||||
if (permissionId == OVRPermissionsRequester.GetPermissionId(EyeTrackingPermission))
|
||||
{
|
||||
OVRPermissionsRequester.PermissionGranted -= _onPermissionGranted;
|
||||
enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool StartEyeTracking()
|
||||
{
|
||||
if (!OVRPermissionsRequester.IsPermissionGranted(EyeTrackingPermission))
|
||||
{
|
||||
OVRPermissionsRequester.PermissionGranted -= _onPermissionGranted;
|
||||
OVRPermissionsRequester.PermissionGranted += _onPermissionGranted;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!OVRPlugin.StartEyeTracking())
|
||||
{
|
||||
Debug.LogWarning($"[{nameof(OVREyeGaze)}] Failed to start eye tracking.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (--_trackingInstanceCount == 0)
|
||||
{
|
||||
OVRPlugin.StopEyeTracking();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
OVRPermissionsRequester.PermissionGranted -= _onPermissionGranted;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!OVRPlugin.GetEyeGazesState(OVRPlugin.Step.Render, -1, ref _currentEyeGazesState))
|
||||
return;
|
||||
|
||||
var eyeGaze = _currentEyeGazesState.EyeGazes[(int)Eye];
|
||||
|
||||
if (!eyeGaze.IsValid)
|
||||
return;
|
||||
|
||||
Confidence = eyeGaze.Confidence;
|
||||
if (Confidence < ConfidenceThreshold)
|
||||
return;
|
||||
|
||||
var pose = eyeGaze.Pose.ToOVRPose();
|
||||
switch (TrackingMode)
|
||||
{
|
||||
case EyeTrackingMode.HeadSpace:
|
||||
pose = pose.ToHeadSpacePose();
|
||||
break;
|
||||
case EyeTrackingMode.WorldSpace:
|
||||
pose = pose.ToWorldSpacePose(Camera.main);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ApplyPosition)
|
||||
{
|
||||
transform.position = pose.position;
|
||||
}
|
||||
|
||||
if (ApplyRotation)
|
||||
{
|
||||
transform.rotation = CalculateEyeRotation(pose.orientation);
|
||||
}
|
||||
}
|
||||
|
||||
private Quaternion CalculateEyeRotation(Quaternion eyeRotation)
|
||||
{
|
||||
var eyeRotationWorldSpace = _viewTransform.rotation * eyeRotation;
|
||||
var lookDirection = eyeRotationWorldSpace * Vector3.forward;
|
||||
var targetRotation = Quaternion.LookRotation(lookDirection, _viewTransform.up);
|
||||
|
||||
return targetRotation * _initialRotationOffset;
|
||||
}
|
||||
|
||||
private void PrepareHeadDirection()
|
||||
{
|
||||
string transformName = "HeadLookAtDirection";
|
||||
|
||||
_viewTransform = new GameObject(transformName).transform;
|
||||
|
||||
if (ReferenceFrame)
|
||||
{
|
||||
_viewTransform.SetPositionAndRotation(ReferenceFrame.position, ReferenceFrame.rotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
_viewTransform.SetPositionAndRotation(transform.position, Quaternion.identity);
|
||||
}
|
||||
|
||||
_viewTransform.parent = transform.parent;
|
||||
_initialRotationOffset = Quaternion.Inverse(_viewTransform.rotation) * transform.rotation;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// List of eyes
|
||||
/// </summary>
|
||||
public enum EyeId
|
||||
{
|
||||
Left = OVRPlugin.Eye.Left,
|
||||
Right = OVRPlugin.Eye.Right
|
||||
}
|
||||
|
||||
public enum EyeTrackingMode
|
||||
{
|
||||
HeadSpace,
|
||||
WorldSpace,
|
||||
TrackingSpace
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user