| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420 |
- /*******************************************************************************
- Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
- NOTICE:All information contained herein is, and remains the property of
- PICO Technology Co., Ltd. The intellectual and technical concepts
- contained herein are proprietary to PICO Technology Co., Ltd. and may be
- covered by patents, patents in process, and are protected by trade secret or
- copyright law. Dissemination of this information or reproduction of this
- material is strictly forbidden unless prior written permission is obtained from
- PICO Technology Co., Ltd.
- *******************************************************************************/
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.XR;
- namespace Unity.XR.PXR
- {
- public class PXR_EyeTracking
- {
- /// <summary>
- /// Gets the PosMatrix of the head.
- /// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
- /// </summary>
- /// <param name="matrix">A Matrix4x4 value returned by the result.</param>
- /// <returns>
- /// * `true`: success
- /// * `false`: failure
- /// </returns>
- public static bool GetHeadPosMatrix(out Matrix4x4 matrix)
- {
- matrix = Matrix4x4.identity;
- if (!PXR_Manager.Instance.eyeTracking)
- return false;
- if (!GetEyeTrackingDevice(out InputDevice device))
- return false;
- Vector3 headPos = Vector3.zero;
- if (!device.TryGetFeatureValue(CommonUsages.devicePosition, out headPos))
- {
- Debug.LogError("PXRLog Failed at GetHeadPosMatrix Pos");
- return false;
- }
- Quaternion headRot = Quaternion.identity;
- if (!device.TryGetFeatureValue(CommonUsages.deviceRotation, out headRot))
- {
- Debug.LogError("PXRLog Failed at GetHeadPosMatrix Rot");
- return false;
- }
- matrix = Matrix4x4.TRS(headPos, headRot, Vector3.one);
- return true;
- }
- static InputDevice curDevice;
- /// <summary>
- /// Gets the input device for eye tracking data.
- /// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
- /// </summary>
- /// <param name="device">The input device returned by the result.</param>
- /// <returns>
- /// * `true`: success
- /// * `false`: failure
- /// </returns>
- static bool GetEyeTrackingDevice(out InputDevice device)
- {
- if (curDevice!= null&& curDevice.isValid)
- {
- device = curDevice;
- return true;
- }
- device = default;
- if (!PXR_Manager.Instance.eyeTracking)
- return false;
- List<InputDevice> devices = new List<InputDevice>();
- InputDevices.GetDevicesWithCharacteristics(InputDeviceCharacteristics.EyeTracking | InputDeviceCharacteristics.HeadMounted, devices);
- if (devices.Count == 0)
- {
- Debug.LogError("PXRLog Failed at GetEyeTrackingDevice devices.Count");
- return false;
- }
- device = devices[0];
- curDevice = device;
- if (!device.isValid)
- {
- Debug.LogError("PXRLog Failed at GetEyeTrackingDevice device.isValid");
- }
- return device.isValid;
- }
- /// <summary>
- /// Gets the position of the center of the eyes in the Unity camera coordinate system (unit: meter).
- /// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
- /// </summary>
- /// <param name="point">Returns a vector3 value which is divided by 1000.
- /// To get the original value, multiply the returned value by 1000. Unit: millimeter.
- /// </param>
- /// <returns>
- /// * `true`: success
- /// * `false`: failure
- /// </returns>
- public static bool GetCombineEyeGazePoint(out Vector3 point)
- {
- point = Vector3.zero;
- if (!PXR_Manager.Instance.eyeTracking)
- return false;
- if (!GetEyeTrackingDevice(out InputDevice device))
- return false;
- if (!device.TryGetFeatureValue(PXR_Usages.combineEyePoint, out point))
- {
- Debug.Log("PXRLog Failed at GetCombineEyeGazePoint point");
- return false;
- }
- return true;
- }
- /// <summary>
- /// Gets the direction of binocular combined gaze in the Unity camera coordinate system.
- /// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
- /// </summary>
- /// <param name="vector">Returns a vector3 value which is divided by 1000.
- /// To get the original value, multiply the returned value by 1000. Unit: millimeter.
- /// </param>
- /// <returns>
- /// * `true`: success
- /// * `false`: failure
- /// </returns>
- public static bool GetCombineEyeGazeVector(out Vector3 vector)
- {
- vector = Vector3.zero;
- if (!PXR_Manager.Instance.eyeTracking)
- return false;
- if (!GetEyeTrackingDevice(out InputDevice device))
- return false;
- if (!device.TryGetFeatureValue(PXR_Usages.combineEyeVector, out vector))
- {
- Debug.LogError("PXRLog Failed at GetCombineEyeGazeVector vector");
- return false;
- }
- return true;
- }
- /// <summary>
- /// Gets the openness/closeness of the left eye.
- /// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
- /// </summary>
- /// <param name="openness">A float value returned by the result. The value ranges from `0.0` to `1.0`. `0.0` incicates completely closed, `1.0` indicates completely open.</param>
- /// <returns>
- /// * `true`: success
- /// * `false`: failure
- /// </returns>
- public static bool GetLeftEyeGazeOpenness(out float openness)
- {
- openness = 0;
- if (!PXR_Manager.Instance.eyeTracking)
- return false;
- if (!GetEyeTrackingDevice(out InputDevice device))
- return false;
- if (!device.TryGetFeatureValue(PXR_Usages.leftEyeOpenness, out openness))
- {
- Debug.LogError("PXRLog Failed at GetLeftEyeGazeOpenness openness");
- return false;
- }
- return true;
- }
- /// <summary>
- /// Gets the openness/closeness of the right eye.
- /// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
- /// </summary>
- /// <param name="openness">A float value returned by the result. The value ranges from `0.0` to `1.0`. `0.0` indicates completely closed, `1.0` indicates completely open.</param>
- /// <returns>
- /// * `true`: success
- /// * `false`: failure
- /// </returns>
- public static bool GetRightEyeGazeOpenness(out float openness)
- {
- openness = 0;
- if (!PXR_Manager.Instance.eyeTracking)
- return false;
- if (!GetEyeTrackingDevice(out InputDevice device))
- return false;
- if (!device.TryGetFeatureValue(PXR_Usages.rightEyeOpenness, out openness))
- {
- Debug.LogError("PXRLog Failed at GetRightEyeGazeOpenness openness");
- return false;
- }
- return true;
- }
- /// <summary>
- /// Gets whether the data of the current left eye is available.
- /// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
- /// </summary>
- /// <param name="status">An int value returned by the result. Below are the EyePoseStatus enumerations:
- /// * `GazePointValid` = (1 << 0),
- /// * `GazeVectorValid` = (1 << 1),
- /// * `EyeOpennessValid` = (1 << 2),
- /// * `EyePupilDilationValid` = (1 << 3),
- /// * `EyePositionGuideValid` = (1 << 4),
- /// * `EyePupilPositionValid` = (1 << 5),
- /// * `EyeConvergenceDistanceValid` = (1 << 6),
- /// * `EyeGazePointValid` = (1 << 7),
- /// * `EyeGazeVectorValid` = (1 << 8),
- /// * `PupilDistanceValid` = (1 << 9),
- /// * `ConvergenceDistanceValid` = (1 << 10),
- /// * `PupilDiameterValid` = (1 << 11),
- /// </param>
- /// <returns>
- /// * `true`: success
- /// * `false`: failure
- /// </returns>
- public static bool GetLeftEyePoseStatus(out uint status)
- {
- status = 0;
- if (!PXR_Manager.Instance.eyeTracking)
- return false;
- if (!GetEyeTrackingDevice(out InputDevice device))
- return false;
- if (!device.TryGetFeatureValue(PXR_Usages.leftEyePoseStatus, out status))
- {
- Debug.LogError("PXRLog Failed at GetLeftEyePoseStatus status");
- return false;
- }
- return true;
- }
- /// <summary>
- /// Gets whether the data of the current right eye is available.
- /// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
- /// </summary>
- /// <param name="status">An int value returned by the result:
- /// * `0`: not available
- /// * `1`: available
- /// </param>
- /// <returns>
- /// * `true`: success
- /// * `false`: failure
- /// </returns>
- public static bool GetRightEyePoseStatus(out uint status)
- {
- status = 0;
- if (!PXR_Manager.Instance.eyeTracking)
- return false;
- if (!GetEyeTrackingDevice(out InputDevice device))
- return false;
- if (!device.TryGetFeatureValue(PXR_Usages.rightEyePoseStatus, out status))
- {
- Debug.LogError("PXRLog Failed at GetRightEyePoseStatus status");
- return false;
- }
- return true;
- }
- /// <summary>
- /// Gets whether the data of the combined eye is available.
- /// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
- /// </summary>
- /// <param name="status">An int value returned by the result:
- /// `0`: not available
- /// `1`: available
- /// </param>
- /// <returns>
- /// * `true`: success
- /// * `false`: failure
- /// </returns>
- public static bool GetCombinedEyePoseStatus(out uint status)
- {
- status = 0;
- if (!PXR_Manager.Instance.eyeTracking)
- return false;
- if (!GetEyeTrackingDevice(out InputDevice device))
- return false;
- if (!device.TryGetFeatureValue(PXR_Usages.combinedEyePoseStatus, out status))
- {
- Debug.LogError("PXRLog Failed at GetCombinedEyePoseStatus status");
- return false;
- }
- return true;
- }
- /// <summary>
- /// Gets the coordinate of the left eye's inner eye corner in the image coordinate system, where the top left corner is (0,0) and the bottom right corner is (1,1).
- /// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
- /// </summary>
- /// <param name="position">A vector3 value returned by the result.</param>
- /// <returns>
- /// * `true`: success
- /// * `false`: failure
- /// </returns>
- public static bool GetLeftEyePositionGuide(out Vector3 position)
- {
- position = Vector3.zero;
- if (!PXR_Manager.Instance.eyeTracking)
- return false;
- if (!GetEyeTrackingDevice(out InputDevice device))
- return false;
- if (!device.TryGetFeatureValue(PXR_Usages.leftEyePositionGuide, out position))
- {
- Debug.LogError("PXRLog Failed at GetLeftEyePositionGuide pos");
- return false;
- }
- return true;
- }
- /// <summary>
- /// Gets the coordinate of the right eye's inner eye corner in the image coordinate system, where the top left corner is (0,0) and the bottom right corner is (1,1).
- /// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
- /// </summary>
- /// <param name="position">A vector3 value returned by the result.</param>
- /// <returns>
- /// * `true`: success
- /// * `false`: failure
- /// </returns>
- public static bool GetRightEyePositionGuide(out Vector3 position)
- {
- position = Vector3.zero;
- if (!PXR_Manager.Instance.eyeTracking)
- return false;
- if (!GetEyeTrackingDevice(out InputDevice device))
- return false;
- if (!device.TryGetFeatureValue(PXR_Usages.rightEyePositionGuide, out position))
- {
- Debug.LogError("PXRLog Failed at GetRightEyePositionGuide pos");
- return false;
- }
- return true;
- }
- /// <summary>
- /// Gets the direction of binocular combined gaze in the View coordinate system (i.e., OpenXR right-handed coordinate system).
- /// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
- /// </summary>
- /// <param name="direction">A vector3 value returned by the result.</param>
- /// <returns>
- /// * `true`: success
- /// * `false`: failure
- /// </returns>
- public static bool GetFoveatedGazeDirection(out Vector3 direction)
- {
- direction = Vector3.zero;
- if (!PXR_Manager.Instance.eyeTracking)
- return false;
- if (!GetEyeTrackingDevice(out InputDevice device))
- return false;
- if (!device.TryGetFeatureValue(PXR_Usages.foveatedGazeDirection, out direction))
- {
- Debug.LogError("PXRLog Failed at GetFoveatedGazeDirection direction");
- return false;
- }
- return true;
- }
- /// <summary>
- /// Gets whether the current foveated gaze tracking data is available.
- /// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
- /// </summary>
- /// <param name="status">An int value returned by the result:
- /// * `0`: not available
- /// * `1`: available
- /// </param>
- /// <returns>
- /// * `true`: success
- /// * `false`: failure
- /// </returns>
- public static bool GetFoveatedGazeTrackingState(out uint state)
- {
- state = 0;
- if (!PXR_Manager.Instance.eyeTracking)
- return false;
- if (!GetEyeTrackingDevice(out InputDevice device))
- return false;
- if (!device.TryGetFeatureValue(PXR_Usages.foveatedGazeTrackingState, out state))
- {
- Debug.LogError("PXRLog Failed at GetFoveatedGazeTrackingState state");
- return false;
- }
- return true;
- }
- }
- }
|