Init
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
#if !PICO_OPENXR_SDK
|
||||
/*******************************************************************************
|
||||
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;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
public class PXR_Boundary
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the boundary as visible or invisible. Note: The setting defined in this function can be overridden by system settings (e.g., proximity trigger) or user settings (e.g., disabling the boundary system).
|
||||
/// </summary>
|
||||
/// <param name="value">Whether to set the boundary as visible or invisble:
|
||||
/// - `true`: visible
|
||||
/// - `false`: invisible</param>
|
||||
public static void SetVisible(bool value)
|
||||
{
|
||||
PXR_Plugin.Boundary.UPxr_SetBoundaryVisiable(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the boundary is visible.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// - `true`: visible
|
||||
/// - `false`: invisible</returns>
|
||||
public static bool GetVisible()
|
||||
{
|
||||
return PXR_Plugin.Boundary.UPxr_GetBoundaryVisiable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the boundary is configured. Boundary-related functions are available for use only if the boundary is configured.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// - `true`: configured
|
||||
/// - `false`: not configured</returns>
|
||||
public static bool GetConfigured()
|
||||
{
|
||||
return PXR_Plugin.Boundary.UPxr_GetBoundaryConfigured();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the boundary is enabled.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// - `true`: enabled
|
||||
/// - `false`: not enabled</returns>
|
||||
public static bool GetEnabled()
|
||||
{
|
||||
return PXR_Plugin.Boundary.UPxr_GetBoundaryEnabled();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a tracked node (Left hand, Right hand, Head) will trigger the boundary.
|
||||
/// </summary>
|
||||
/// <param name="node">The node to track: HandLeft-left controller; HandRight-right controller; Head-HMD.</param>
|
||||
/// <param name="boundaryType">The boundary type: `OuterBoundary`-boundary (custom boundary or in-site fast boundary); `PlayArea`-the maximum rectangle in the custom boundary (no such a rectangle in the in-site fast boundary).</param>
|
||||
/// <returns>
|
||||
/// A struct that contains the following details:
|
||||
/// - `IsTriggering`: bool, whether the boundary is triggered;
|
||||
/// - `ClosestDistance`: float, the minimum distance between the tracked node and the boundary;
|
||||
/// - `ClosestPoint`: vector3, the closest point between the tracked node and the boundary;
|
||||
/// - `ClosestPointNormal`: vector3, the normal line of the closest point;
|
||||
/// - `valid`: bool, whether the result returned is valid.
|
||||
/// </returns>
|
||||
public static PxrBoundaryTriggerInfo TestNode(BoundaryTrackingNode node, BoundaryType boundaryType)
|
||||
{
|
||||
return PXR_Plugin.Boundary.UPxr_TestNodeIsInBoundary(node, boundaryType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a tracked point will trigger the boundary.
|
||||
/// </summary>
|
||||
/// <param name="point">The coordinate of the point.</param>
|
||||
/// <param name="boundaryType">The boundary type: `OuterBoundary`-boundary (custom boundary or in-site fast boundary); `PlayArea`-customize the maximum rectangle in the custom boundary (no such rectangle for in-site fast boundary).</param>
|
||||
/// <returns>
|
||||
/// A struct that contains the following details:
|
||||
/// - `IsTriggering`: bool, whether the boundary is triggered;
|
||||
/// - `ClosestDistance`: float, the minimum distance between the tracked node and the boundary;
|
||||
/// - `ClosestPoint`: vector3, the closest point between the tracked node and the boundary;
|
||||
/// - `ClosestPointNormal`: vector3, the normal line of the closest point;
|
||||
/// - `valid`: bool, whether the result returned is valid.
|
||||
/// </returns>
|
||||
public static PxrBoundaryTriggerInfo TestPoint(PxrVector3f point, BoundaryType boundaryType)
|
||||
{
|
||||
return PXR_Plugin.Boundary.UPxr_TestPointIsInBoundary(point, boundaryType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of boundary points.
|
||||
/// </summary>
|
||||
/// <param name="boundaryType">The boundary type:
|
||||
/// - `OuterBoundary`: custom boundary or in-site fast boundary.
|
||||
/// - `PlayArea`: customize the maximum rectangle in the custom boundary (no such rectangle for in-site fast boundary).</param>
|
||||
/// <returns>A collection of boundary points.
|
||||
/// - If you pass `OuterBoundary`, the actual calibrated vertex array of the boundary will be returned.
|
||||
/// - If you pass `PlayArea`, the boundary points array of the maximum rectangle within the calibrated play area will be returned. The boundary points array is calculated by the algorithm.
|
||||
/// For stationary boundary, passing `PlayArea` returns nothing.
|
||||
/// </returns>
|
||||
public static Vector3[] GetGeometry(BoundaryType boundaryType)
|
||||
{
|
||||
return PXR_Plugin.Boundary.UPxr_GetBoundaryGeometry(boundaryType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the play area for the custom boundary.
|
||||
/// </summary>
|
||||
/// <param name="boundaryType">You can only pass `PlayArea` (customize the maximum rectangle in the custom boundary). **Note**: There is no such rectangle for stationary boundary.</param>
|
||||
/// <returns>The lengths of the X and Z axis of the maximum rectangle within the custom calibrated play area. The lengths are calculated by the algorithm. The length of the Y axis is always 1.
|
||||
/// If the current user calibrates the stationary boundary, (0,1,0) will be returned.
|
||||
/// </returns>
|
||||
public static Vector3 GetDimensions(BoundaryType boundaryType)
|
||||
{
|
||||
return PXR_Plugin.Boundary.UPxr_GetBoundaryDimensions(boundaryType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the camera image of the device and use it as the environmental background. Before calling this function, make sure you have set the clear flags of the camera to solid color and have set the background color of the camera to 0 for the alpha channel.
|
||||
/// @note If the app is paused, this function will cease. Therefore, you need to call this function again after the app has been resumed.
|
||||
/// </summary>
|
||||
/// <param name="value">Whether to enable SeeThrough: `true`-enable; `false`-do not enable.</param>
|
||||
/// <see cref="PXR_Manager.EnableVideoSeeThrough"/> is preferred over this method.
|
||||
[Obsolete("Deprecated.Please use PXR_Manager.EnableVideoSeeThrough instead", true)]
|
||||
public static void EnableSeeThroughManual(bool value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current status of seethrough tracking.
|
||||
/// </summary>
|
||||
/// <returns>Returns `PxrTrackingState`. Below are the enumerations:
|
||||
/// * `LostNoReason`: no reason
|
||||
/// * `LostCamera`: camera calibration data error
|
||||
/// * `LostHighLight`: environment lighting too bright
|
||||
/// * `LostLowLight`: environment lighting too dark
|
||||
/// * `LostLowFeatureCount`: few environmental features
|
||||
/// * `LostReLocation`: relocation in progress
|
||||
/// * `LostInitialization`: initialization in progress
|
||||
/// * `LostNoCamera`: camera data error
|
||||
/// * `LostNoIMU`: IMU data error
|
||||
/// * `LostIMUJitter`: IMU data jitter
|
||||
/// * `LostUnknown`: unknown error
|
||||
/// </returns>
|
||||
[Obsolete("SeeThroughTracking State is not supported.", true)]
|
||||
public static PxrTrackingState GetSeeThroughTrackingState() {
|
||||
return PxrTrackingState.LostUnknown;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// disable or enable boundary
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public static void SetGuardianSystemDisable(bool value)
|
||||
{
|
||||
PXR_Plugin.Boundary.UPxr_SetGuardianSystemDisable(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses the global pose.
|
||||
/// </summary>
|
||||
/// <param name="value">Specifies whether to use the global pose.
|
||||
/// * `true`: use
|
||||
/// * `false`: do not use
|
||||
/// </param>
|
||||
[Obsolete("Global Pose is not supported.", true)]
|
||||
public static void UseGlobalPose(bool value)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 617aa04623edd024a9298a3b21656d4c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,863 @@
|
||||
/*******************************************************************************
|
||||
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;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.XR;
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
public class PXR_CompositionLayer : MonoBehaviour, IComparable<PXR_CompositionLayer>
|
||||
{
|
||||
private const string TAG = "[PXR_CompositionLayer]";
|
||||
public static List<PXR_CompositionLayer> Instances = new List<PXR_CompositionLayer>();
|
||||
|
||||
public static int overlayID = 0;
|
||||
[NonSerialized]
|
||||
public int overlayIndex;
|
||||
public int layerDepth;
|
||||
public int imageIndex = 0;
|
||||
public OverlayType overlayType = OverlayType.Overlay;
|
||||
public OverlayShape overlayShape = OverlayShape.Quad;
|
||||
public TextureType textureType = TextureType.ExternalSurface;
|
||||
public Transform overlayTransform;
|
||||
public Camera xrRig;
|
||||
|
||||
public Texture[] layerTextures = new Texture[2] { null, null };
|
||||
|
||||
public bool useTextureAlphaBlending = true;
|
||||
public bool usePremultipliedAlpha = false;
|
||||
public bool isDynamic = false;
|
||||
public int[] overlayTextureIds = new int[2];
|
||||
public Matrix4x4[] mvMatrixs = new Matrix4x4[2];
|
||||
public Vector3[] modelScales = new Vector3[2];
|
||||
public Quaternion[] modelRotations = new Quaternion[2];
|
||||
public Vector3[] modelTranslations = new Vector3[2];
|
||||
public Quaternion[] cameraRotations = new Quaternion[2];
|
||||
public Vector3[] cameraTranslations = new Vector3[2];
|
||||
public Camera[] overlayEyeCamera = new Camera[2];
|
||||
|
||||
public bool overrideColorScaleAndOffset = false;
|
||||
public Vector4 colorScale = Vector4.one;
|
||||
public Vector4 colorOffset = Vector4.zero;
|
||||
|
||||
// Eac
|
||||
public Vector3 offsetPosLeft = Vector3.zero;
|
||||
public Vector3 offsetPosRight = Vector3.zero;
|
||||
public Vector4 offsetRotLeft = new Vector4(0, 0, 0, 1);
|
||||
public Vector4 offsetRotRight = new Vector4(0, 0, 0, 1);
|
||||
public EACModelType eacModelType = EACModelType.Eac360;
|
||||
public float overlapFactor = 1.0f;
|
||||
public ulong timestamp = 0;
|
||||
|
||||
private Vector4 overlayLayerColorScaleDefault = Vector4.one;
|
||||
private Vector4 overlayLayerColorOffsetDefault = Vector4.zero;
|
||||
|
||||
public bool isExternalAndroidSurface = false;
|
||||
public bool isExternalAndroidSurfaceDRM = false;
|
||||
public Surface3DType externalAndroidSurface3DType = Surface3DType.Single;
|
||||
|
||||
#region Blurred Quad
|
||||
public BlurredQuadMode blurredQuadMode = BlurredQuadMode.SmallWindow;
|
||||
|
||||
public float blurredQuadScale = 0.5f;
|
||||
public float blurredQuadShift = 0.01f;
|
||||
public float blurredQuadFOV = 61.05f;
|
||||
public float blurredQuadIPD = 0.064f;
|
||||
#endregion
|
||||
|
||||
public IntPtr externalAndroidSurfaceObject = IntPtr.Zero;
|
||||
public delegate void ExternalAndroidSurfaceObjectCreated();
|
||||
public ExternalAndroidSurfaceObjectCreated externalAndroidSurfaceObjectCreated = null;
|
||||
|
||||
// 360
|
||||
public float radius = 0; // >0
|
||||
|
||||
// ImageRect
|
||||
public bool useImageRect = false;
|
||||
public TextureRect textureRect = TextureRect.StereoScopic;
|
||||
public DestinationRect destinationRect = DestinationRect.Default;
|
||||
public Rect srcRectLeft = new Rect(0, 0, 1, 1);
|
||||
public Rect srcRectRight = new Rect(0, 0, 1, 1);
|
||||
public Rect dstRectLeft = new Rect(0, 0, 1, 1);
|
||||
public Rect dstRectRight = new Rect(0, 0, 1, 1);
|
||||
|
||||
public PxrRecti imageRectLeft;
|
||||
public PxrRecti imageRectRight;
|
||||
|
||||
// LayerBlend
|
||||
public bool useLayerBlend = false;
|
||||
public PxrBlendFactor srcColor = PxrBlendFactor.PxrBlendFactorOne;
|
||||
public PxrBlendFactor dstColor = PxrBlendFactor.PxrBlendFactorOne;
|
||||
public PxrBlendFactor srcAlpha = PxrBlendFactor.PxrBlendFactorOne;
|
||||
public PxrBlendFactor dstAlpha = PxrBlendFactor.PxrBlendFactorOne;
|
||||
public float[] colorMatrix = new float[18] {
|
||||
1,0,0, // left
|
||||
0,1,0,
|
||||
0,0,1,
|
||||
1,0,0, // right
|
||||
0,1,0,
|
||||
0,0,1,
|
||||
};
|
||||
|
||||
public bool isClones = false;
|
||||
public bool isClonesToNew = false;
|
||||
|
||||
public bool enableSubmitLayer = true;
|
||||
public PXR_CompositionLayer originalOverLay;
|
||||
public IntPtr layerSubmitPtr = IntPtr.Zero;
|
||||
|
||||
[HideInInspector]
|
||||
public SuperSamplingMode supersamplingMode = SuperSamplingMode.None;
|
||||
[HideInInspector]
|
||||
public SuperSamplingEnhance supersamplingEnhance = SuperSamplingEnhance.None;
|
||||
|
||||
[HideInInspector]
|
||||
public SharpeningMode sharpeningMode = SharpeningMode.None;
|
||||
[HideInInspector]
|
||||
public SharpeningEnhance sharpeningEnhance = SharpeningEnhance.None;
|
||||
//Super Resolution
|
||||
public bool superResolution;
|
||||
public bool normalSupersampling;
|
||||
public bool qualitySupersampling;
|
||||
public bool fixedFoveatedSupersampling;
|
||||
public bool normalSharpening;
|
||||
public bool qualitySharpening;
|
||||
public bool fixedFoveatedSharpening;
|
||||
public bool selfAdaptiveSharpening;
|
||||
|
||||
|
||||
private bool toCreateSwapChain = false;
|
||||
private bool toCopyRT = false;
|
||||
private bool copiedRT = false;
|
||||
private int eyeCount = 2;
|
||||
private UInt32 imageCounts = 0;
|
||||
private PxrLayerParam overlayParam = new PxrLayerParam();
|
||||
private struct NativeTexture
|
||||
{
|
||||
public Texture[] textures;
|
||||
};
|
||||
private NativeTexture[] nativeTextures;
|
||||
private static Material cubeM;
|
||||
private IntPtr leftPtr = IntPtr.Zero;
|
||||
private IntPtr rightPtr = IntPtr.Zero;
|
||||
private static Material textureM;
|
||||
|
||||
public HDRFlags hdr = HDRFlags.None;
|
||||
|
||||
public int CompareTo(PXR_CompositionLayer other)
|
||||
{
|
||||
return layerDepth.CompareTo(other.layerDepth);
|
||||
}
|
||||
|
||||
protected void Awake()
|
||||
{
|
||||
xrRig = Camera.main;
|
||||
Instances.Add(this);
|
||||
if (null == xrRig.gameObject.GetComponent<PXR_CompositionLayerManager>())
|
||||
{
|
||||
xrRig.gameObject.AddComponent<PXR_CompositionLayerManager>();
|
||||
}
|
||||
|
||||
overlayEyeCamera[0] = xrRig;
|
||||
overlayEyeCamera[1] = xrRig;
|
||||
|
||||
overlayTransform = GetComponent<Transform>();
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
if (overlayTransform != null)
|
||||
{
|
||||
MeshRenderer render = overlayTransform.GetComponent<MeshRenderer>();
|
||||
if (render != null)
|
||||
{
|
||||
render.enabled = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!isClones)
|
||||
{
|
||||
InitializeBuffer();
|
||||
}
|
||||
|
||||
PXR_Plugin.Sensor.UPxr_HMDUpdateSwitch(false);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (isClones)
|
||||
{
|
||||
InitializeBuffer();
|
||||
}
|
||||
|
||||
if (PXR_Manager.Instance == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Camera[] cam = PXR_Manager.Instance.GetEyeCamera();
|
||||
if (cam[0] != null && cam[0].enabled)
|
||||
{
|
||||
RefreshCamera(cam[0], cam[0]);
|
||||
}
|
||||
else if (cam[1] != null && cam[2] != null)
|
||||
{
|
||||
RefreshCamera(cam[1], cam[2]);
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshCamera(Camera leftCamera, Camera rightCamera)
|
||||
{
|
||||
overlayEyeCamera[0] = leftCamera;
|
||||
overlayEyeCamera[1] = rightCamera;
|
||||
}
|
||||
|
||||
private void InitializeBuffer()
|
||||
{
|
||||
if (!isExternalAndroidSurface && !isClones)
|
||||
{
|
||||
if (null == layerTextures[0] && null == layerTextures[1])
|
||||
{
|
||||
PLog.e(TAG, " The left and right images are all empty!");
|
||||
return;
|
||||
}
|
||||
else if (null == layerTextures[0] && null != layerTextures[1])
|
||||
{
|
||||
layerTextures[0] = layerTextures[1];
|
||||
}
|
||||
else if (null != layerTextures[0] && null == layerTextures[1])
|
||||
{
|
||||
layerTextures[1] = layerTextures[0];
|
||||
}
|
||||
overlayParam.width = (uint)layerTextures[1].width;
|
||||
overlayParam.height = (uint)layerTextures[1].height;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayParam.width = 1024;
|
||||
overlayParam.height = 1024;
|
||||
}
|
||||
|
||||
overlayID++;
|
||||
overlayIndex = overlayID;
|
||||
overlayParam.layerId = overlayIndex;
|
||||
overlayParam.layerShape = overlayShape == 0 ? OverlayShape.Quad : overlayShape;
|
||||
overlayParam.layerType = overlayType;
|
||||
overlayParam.arraySize = 1;
|
||||
overlayParam.mipmapCount = 1;
|
||||
overlayParam.sampleCount = 1;
|
||||
overlayParam.layerFlags = 0;
|
||||
|
||||
if (OverlayShape.Cubemap == overlayShape)
|
||||
{
|
||||
overlayParam.faceCount = 6;
|
||||
if (cubeM == null)
|
||||
cubeM = new Material(Shader.Find("PXR_SDK/PXR_CubemapBlit"));
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayParam.faceCount = 1;
|
||||
if (textureM == null)
|
||||
textureM = new Material(Shader.Find("PXR_SDK/PXR_Texture2DBlit"));
|
||||
}
|
||||
|
||||
if (GraphicsDeviceType.Vulkan == SystemInfo.graphicsDeviceType)
|
||||
{
|
||||
if (ColorSpace.Linear == QualitySettings.activeColorSpace)
|
||||
{
|
||||
overlayParam.format = (UInt64)ColorForamt.VK_FORMAT_R8G8B8A8_SRGB;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayParam.format = (UInt64)ColorForamt.VK_FORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
if (OverlayShape.Cubemap == overlayShape)
|
||||
{
|
||||
cubeM.SetFloat("_Gamma", 2.2f);
|
||||
}
|
||||
else
|
||||
{
|
||||
textureM.SetFloat("_Gamma", 2.2f);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayParam.format = (UInt64)ColorForamt.GL_SRGB8_ALPHA8;
|
||||
}
|
||||
|
||||
if (isClones)
|
||||
{
|
||||
if (null != originalOverLay)
|
||||
{
|
||||
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlagSharedImagesBetweenLayers;
|
||||
leftPtr = Marshal.AllocHGlobal(Marshal.SizeOf(originalOverLay.overlayIndex));
|
||||
rightPtr = Marshal.AllocHGlobal(Marshal.SizeOf(originalOverLay.overlayIndex));
|
||||
Marshal.WriteInt64(leftPtr, originalOverLay.overlayIndex);
|
||||
Marshal.WriteInt64(rightPtr, originalOverLay.overlayIndex);
|
||||
overlayParam.leftExternalImages = leftPtr;
|
||||
overlayParam.rightExternalImages = rightPtr;
|
||||
isExternalAndroidSurface = originalOverLay.isExternalAndroidSurface;
|
||||
isDynamic = originalOverLay.isDynamic;
|
||||
overlayParam.width = (UInt32)Mathf.Min(overlayParam.width, originalOverLay.overlayParam.width);
|
||||
overlayParam.height = (UInt32)Mathf.Min(overlayParam.height, originalOverLay.overlayParam.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
PLog.e(TAG, "In clone state, originalOverLay cannot be empty!");
|
||||
}
|
||||
}
|
||||
|
||||
if (isExternalAndroidSurface)
|
||||
{
|
||||
if (isExternalAndroidSurfaceDRM)
|
||||
{
|
||||
overlayParam.layerFlags |= (UInt32)(PxrLayerCreateFlags.PxrLayerFlagAndroidSurface | PxrLayerCreateFlags.PxrLayerFlagProtectedContent);
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlagAndroidSurface;
|
||||
}
|
||||
|
||||
if (Surface3DType.LeftRight == externalAndroidSurface3DType)
|
||||
{
|
||||
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlag3DLeftRightSurface;
|
||||
}
|
||||
else if (Surface3DType.TopBottom == externalAndroidSurface3DType)
|
||||
{
|
||||
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlag3DTopBottomSurface;
|
||||
}
|
||||
|
||||
overlayParam.layerLayout = LayerLayout.Mono;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isDynamic)
|
||||
{
|
||||
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlagStaticImage;
|
||||
}
|
||||
|
||||
if ((layerTextures[0] != null && layerTextures[1] != null && layerTextures[0] == layerTextures[1]) || null == layerTextures[1])
|
||||
{
|
||||
eyeCount = 1;
|
||||
overlayParam.layerLayout = LayerLayout.Mono;
|
||||
}
|
||||
else
|
||||
{
|
||||
eyeCount = 2;
|
||||
overlayParam.layerLayout = LayerLayout.Stereo;
|
||||
}
|
||||
|
||||
toCreateSwapChain = true;
|
||||
}
|
||||
|
||||
PLog.i(TAG, $"UPxr_CreateLayer() overlayParam.layerId={overlayParam.layerId}, layerShape={overlayParam.layerShape}, layerType={overlayParam.layerType}, width={overlayParam.width}, height={overlayParam.height}, layerFlags={overlayParam.layerFlags}, format={overlayParam.format}, layerLayout={overlayParam.layerLayout}.");
|
||||
PXR_Plugin.Render.UPxr_CreateLayerParam(overlayParam);
|
||||
}
|
||||
|
||||
public void CreateExternalSurface(PXR_CompositionLayer overlayInstance)
|
||||
{
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
if (IntPtr.Zero != overlayInstance.externalAndroidSurfaceObject)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PXR_Plugin.Render.UPxr_GetLayerAndroidSurface(overlayInstance.overlayIndex, 0, ref overlayInstance.externalAndroidSurfaceObject);
|
||||
PLog.i(TAG, string.Format("CreateExternalSurface: Overlay Type:{0}, LayerDepth:{1}, SurfaceObject:{2}", overlayInstance.overlayType, overlayInstance.overlayIndex, overlayInstance.externalAndroidSurfaceObject));
|
||||
|
||||
if (IntPtr.Zero == overlayInstance.externalAndroidSurfaceObject || null == overlayInstance.externalAndroidSurfaceObjectCreated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
overlayInstance.externalAndroidSurfaceObjectCreated();
|
||||
#endif
|
||||
}
|
||||
|
||||
public void UpdateCoords()
|
||||
{
|
||||
if (null == overlayTransform || !overlayTransform.gameObject.activeSelf || null == overlayEyeCamera[0] || null == overlayEyeCamera[1])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < mvMatrixs.Length; i++)
|
||||
{
|
||||
mvMatrixs[i] = overlayEyeCamera[i].worldToCameraMatrix * overlayTransform.localToWorldMatrix;
|
||||
if (overlayTransform is RectTransform uiTransform)
|
||||
{
|
||||
var rect = uiTransform.rect;
|
||||
var lossyScale = overlayTransform.lossyScale;
|
||||
modelScales[i] = new Vector3(rect.width * lossyScale.x,
|
||||
rect.height * lossyScale.y, 1);
|
||||
modelTranslations[i] = uiTransform.TransformPoint(rect.center);
|
||||
}
|
||||
else
|
||||
{
|
||||
modelScales[i] = overlayTransform.lossyScale;
|
||||
modelTranslations[i] = overlayTransform.position;
|
||||
}
|
||||
modelRotations[i] = overlayTransform.rotation;
|
||||
cameraRotations[i] = overlayEyeCamera[i].transform.rotation;
|
||||
cameraTranslations[i] = overlayEyeCamera[i].transform.position;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CreateTexture()
|
||||
{
|
||||
if (!toCreateSwapChain)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null == nativeTextures)
|
||||
nativeTextures = new NativeTexture[eyeCount];
|
||||
|
||||
for (int i = 0; i < eyeCount; i++)
|
||||
{
|
||||
int ret = PXR_Plugin.Render.UPxr_GetLayerImageCount(overlayIndex, (EyeType)i, ref imageCounts);
|
||||
if (ret != 0 || imageCounts < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null == nativeTextures[i].textures)
|
||||
{
|
||||
nativeTextures[i].textures = new Texture[imageCounts];
|
||||
}
|
||||
|
||||
for (int j = 0; j < imageCounts; j++)
|
||||
{
|
||||
IntPtr ptr = IntPtr.Zero;
|
||||
PXR_Plugin.Render.UPxr_GetLayerImagePtr(overlayIndex, (EyeType)i, j, ref ptr);
|
||||
|
||||
if (IntPtr.Zero == ptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Texture texture;
|
||||
if (OverlayShape.Cubemap == overlayShape)
|
||||
{
|
||||
texture = Cubemap.CreateExternalTexture((int)overlayParam.width, TextureFormat.RGBA32, false, ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
texture = Texture2D.CreateExternalTexture((int)overlayParam.width, (int)overlayParam.height, TextureFormat.RGBA32, false, true, ptr);
|
||||
}
|
||||
|
||||
if (null == texture)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
nativeTextures[i].textures[j] = texture;
|
||||
}
|
||||
}
|
||||
|
||||
toCreateSwapChain = false;
|
||||
toCopyRT = true;
|
||||
copiedRT = false;
|
||||
|
||||
FreePtr();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CopyRT()
|
||||
{
|
||||
if (isClones)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!toCopyRT)
|
||||
{
|
||||
return copiedRT;
|
||||
}
|
||||
|
||||
if (!isDynamic && copiedRT)
|
||||
{
|
||||
return copiedRT;
|
||||
}
|
||||
|
||||
if (null == nativeTextures)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (enableSubmitLayer)
|
||||
{
|
||||
PXR_Plugin.Render.UPxr_GetLayerNextImageIndexByRender(overlayIndex, ref imageIndex);
|
||||
}
|
||||
for (int i = 0; i < eyeCount; i++)
|
||||
{
|
||||
Texture nativeTexture = nativeTextures[i].textures[imageIndex];
|
||||
|
||||
if (null == nativeTexture || null == layerTextures[i])
|
||||
continue;
|
||||
|
||||
RenderTexture texture = layerTextures[i] as RenderTexture;
|
||||
|
||||
if (OverlayShape.Cubemap == overlayShape && null == layerTextures[i] as Cubemap)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int f = 0; f < (int)overlayParam.faceCount; f++)
|
||||
{
|
||||
if (QualitySettings.activeColorSpace == ColorSpace.Gamma && texture != null && texture.format == RenderTextureFormat.ARGB32)
|
||||
{
|
||||
Graphics.CopyTexture(layerTextures[i], f, 0, nativeTexture, f, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderTextureDescriptor rtDes = new RenderTextureDescriptor((int)overlayParam.width, (int)overlayParam.height, RenderTextureFormat.ARGB32, 0);
|
||||
rtDes.msaaSamples = (int)overlayParam.sampleCount;
|
||||
rtDes.useMipMap = true;
|
||||
rtDes.autoGenerateMips = false;
|
||||
rtDes.sRGB = true;
|
||||
|
||||
RenderTexture renderTexture = RenderTexture.GetTemporary(rtDes);
|
||||
|
||||
if (!renderTexture.IsCreated())
|
||||
{
|
||||
renderTexture.Create();
|
||||
}
|
||||
renderTexture.DiscardContents();
|
||||
|
||||
if (OverlayShape.Cubemap == overlayShape)
|
||||
{
|
||||
cubeM.SetInt("_d", f);
|
||||
Graphics.Blit(layerTextures[i], renderTexture, cubeM);
|
||||
}
|
||||
else
|
||||
{
|
||||
textureM.mainTexture = texture;
|
||||
textureM.SetPass(0);
|
||||
textureM.SetInt("_premultiply", usePremultipliedAlpha ? 1 : 0);
|
||||
Graphics.Blit(layerTextures[i], renderTexture, textureM);
|
||||
}
|
||||
Graphics.CopyTexture(renderTexture, 0, 0, nativeTexture, f, 0);
|
||||
RenderTexture.ReleaseTemporary(renderTexture);
|
||||
}
|
||||
}
|
||||
copiedRT = true;
|
||||
}
|
||||
|
||||
return copiedRT;
|
||||
}
|
||||
|
||||
public void SetTexture(Texture texture, bool dynamic)
|
||||
{
|
||||
if (isExternalAndroidSurface)
|
||||
{
|
||||
PLog.w(TAG, "Not support setTexture !");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isClones)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (PXR_CompositionLayer overlay in PXR_CompositionLayer.Instances)
|
||||
{
|
||||
if (overlay.isClones && null != overlay.originalOverLay && overlay.originalOverLay.overlayIndex == overlayIndex)
|
||||
{
|
||||
overlay.DestroyLayer();
|
||||
overlay.isClonesToNew = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toCopyRT = false;
|
||||
PXR_Plugin.Render.UPxr_DestroyLayerByRender(overlayIndex);
|
||||
ClearTexture();
|
||||
for (int i = 0; i < layerTextures.Length; i++)
|
||||
{
|
||||
layerTextures[i] = texture;
|
||||
}
|
||||
|
||||
isDynamic = dynamic;
|
||||
InitializeBuffer();
|
||||
|
||||
if (!isClones)
|
||||
{
|
||||
foreach (PXR_CompositionLayer overlay in PXR_CompositionLayer.Instances)
|
||||
{
|
||||
if (overlay.isClones && overlay.isClonesToNew)
|
||||
{
|
||||
overlay.originalOverLay = this;
|
||||
overlay.InitializeBuffer();
|
||||
overlay.isClonesToNew = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FreePtr()
|
||||
{
|
||||
if (leftPtr != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(leftPtr);
|
||||
leftPtr = IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (rightPtr != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(rightPtr);
|
||||
rightPtr = IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (layerSubmitPtr != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(layerSubmitPtr);
|
||||
layerSubmitPtr = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDestroy()
|
||||
{
|
||||
DestroyLayer();
|
||||
Instances.Remove(this);
|
||||
}
|
||||
|
||||
public void DestroyLayer()
|
||||
{
|
||||
if (isExternalAndroidSurface)
|
||||
{
|
||||
PXR_Plugin.Render.UPxr_DestroyLayerByRender(overlayIndex);
|
||||
externalAndroidSurfaceObject = IntPtr.Zero;
|
||||
ClearTexture();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isClones)
|
||||
{
|
||||
List<PXR_CompositionLayer> toDestroyClones = new List<PXR_CompositionLayer>();
|
||||
foreach (PXR_CompositionLayer overlay in Instances)
|
||||
{
|
||||
if (overlay.isClones && null != overlay.originalOverLay && overlay.originalOverLay.overlayIndex == overlayIndex)
|
||||
{
|
||||
toDestroyClones.Add(overlay);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (PXR_CompositionLayer overLay in toDestroyClones)
|
||||
{
|
||||
PXR_Plugin.Render.UPxr_DestroyLayerByRender(overLay.overlayIndex);
|
||||
ClearTexture();
|
||||
}
|
||||
|
||||
PXR_Plugin.Render.UPxr_DestroyLayerByRender(overlayIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (null != originalOverLay && Instances.Contains(originalOverLay))
|
||||
{
|
||||
PXR_Plugin.Render.UPxr_DestroyLayerByRender(overlayIndex);
|
||||
}
|
||||
}
|
||||
ClearTexture();
|
||||
}
|
||||
|
||||
private void ClearTexture()
|
||||
{
|
||||
FreePtr();
|
||||
|
||||
if (isExternalAndroidSurface || null == nativeTextures || isClones)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < eyeCount; i++)
|
||||
{
|
||||
if (null == nativeTextures[i].textures)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 0; j < imageCounts; j++)
|
||||
DestroyImmediate(nativeTextures[i].textures[j]);
|
||||
}
|
||||
|
||||
nativeTextures = null;
|
||||
}
|
||||
|
||||
public void SetLayerColorScaleAndOffset(Vector4 scale, Vector4 offset)
|
||||
{
|
||||
colorScale = scale;
|
||||
colorOffset = offset;
|
||||
}
|
||||
|
||||
public void SetEACOffsetPosAndRot(Vector3 leftPos, Vector3 rightPos, Vector4 leftRot, Vector4 rightRot)
|
||||
{
|
||||
offsetPosLeft = leftPos;
|
||||
offsetPosRight = rightPos;
|
||||
offsetRotLeft = leftRot;
|
||||
offsetRotRight = rightRot;
|
||||
}
|
||||
|
||||
public void SetEACFactor(float factor)
|
||||
{
|
||||
overlapFactor = factor;
|
||||
}
|
||||
|
||||
public Vector4 GetLayerColorScale()
|
||||
{
|
||||
if (!overrideColorScaleAndOffset)
|
||||
{
|
||||
return overlayLayerColorScaleDefault;
|
||||
}
|
||||
return colorScale;
|
||||
}
|
||||
|
||||
public Vector4 GetLayerColorOffset()
|
||||
{
|
||||
if (!overrideColorScaleAndOffset)
|
||||
{
|
||||
return overlayLayerColorOffsetDefault;
|
||||
}
|
||||
return colorOffset;
|
||||
}
|
||||
|
||||
public PxrRecti getPxrRectiLeft(bool left)
|
||||
{
|
||||
if (left)
|
||||
{
|
||||
imageRectLeft.x = (int)(overlayParam.width * srcRectLeft.x);
|
||||
imageRectLeft.y = (int)(overlayParam.height * srcRectLeft.y);
|
||||
imageRectLeft.width = (int)(overlayParam.width * Mathf.Min(srcRectLeft.width, 1 - srcRectLeft.x));
|
||||
imageRectLeft.height = (int)(overlayParam.height * Mathf.Min(srcRectLeft.height, 1 - srcRectLeft.y));
|
||||
return imageRectLeft;
|
||||
}
|
||||
else
|
||||
{
|
||||
imageRectRight.x = (int)(overlayParam.width * srcRectRight.x);
|
||||
imageRectRight.y = (int)(overlayParam.height * srcRectRight.y);
|
||||
imageRectRight.width = (int)(overlayParam.width * Mathf.Min(srcRectRight.width, 1 - srcRectRight.x));
|
||||
imageRectRight.height = (int)(overlayParam.height * Mathf.Min(srcRectRight.height, 1 - srcRectRight.y));
|
||||
return imageRectRight;
|
||||
}
|
||||
}
|
||||
|
||||
public UInt32 getHDRFlags()
|
||||
{
|
||||
UInt32 hdrFlags = 0;
|
||||
if (!isExternalAndroidSurface)
|
||||
{
|
||||
return hdrFlags;
|
||||
}
|
||||
switch (hdr)
|
||||
{
|
||||
case HDRFlags.HdrPQ:
|
||||
hdrFlags |= (UInt32)PxrLayerSubmitFlags.PxrLayerFlagColorSpaceHdrPQ;
|
||||
break;
|
||||
case HDRFlags.HdrHLG:
|
||||
hdrFlags |= (UInt32)PxrLayerSubmitFlags.PxrLayerFlagColorSpaceHdrHLG;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return hdrFlags;
|
||||
}
|
||||
|
||||
public enum HDRFlags
|
||||
{
|
||||
None,
|
||||
HdrPQ,
|
||||
HdrHLG,
|
||||
}
|
||||
|
||||
public enum OverlayShape
|
||||
{
|
||||
Quad = 1,
|
||||
Cylinder = 2,
|
||||
Equirect = 4,
|
||||
Cubemap = 5,
|
||||
Eac = 6,
|
||||
Fisheye = 7,
|
||||
BlurredQuad = 9
|
||||
}
|
||||
|
||||
public enum OverlayType
|
||||
{
|
||||
Overlay = 0,
|
||||
Underlay = 1
|
||||
}
|
||||
|
||||
public enum TextureType
|
||||
{
|
||||
ExternalSurface,
|
||||
DynamicTexture,
|
||||
StaticTexture
|
||||
}
|
||||
|
||||
public enum LayerLayout
|
||||
{
|
||||
Stereo = 0,
|
||||
DoubleWide = 1,
|
||||
Array = 2,
|
||||
Mono = 3
|
||||
}
|
||||
|
||||
public enum Surface3DType
|
||||
{
|
||||
Single = 0,
|
||||
LeftRight,
|
||||
TopBottom
|
||||
}
|
||||
|
||||
public enum TextureRect
|
||||
{
|
||||
MonoScopic,
|
||||
StereoScopic,
|
||||
Custom
|
||||
}
|
||||
|
||||
public enum DestinationRect
|
||||
{
|
||||
Default,
|
||||
Custom
|
||||
}
|
||||
|
||||
public enum EACModelType
|
||||
{
|
||||
Eac360 = 0,
|
||||
Eac360ViewPort = 1,
|
||||
Eac180 = 4,
|
||||
Eac180ViewPort = 5,
|
||||
}
|
||||
|
||||
public enum ColorForamt
|
||||
{
|
||||
VK_FORMAT_R8G8B8A8_UNORM = 37,
|
||||
VK_FORMAT_R8G8B8A8_SRGB = 43,
|
||||
GL_SRGB8_ALPHA8 = 0x8c43,
|
||||
GL_RGBA8 = 0x8058
|
||||
}
|
||||
|
||||
public enum BlurredQuadMode
|
||||
{
|
||||
SmallWindow,
|
||||
Immersion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 489ea5e3dbac76347bc630b826798270
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,428 @@
|
||||
#if !PICO_OPENXR_SDK
|
||||
/*******************************************************************************
|
||||
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. 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 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 position of the left eye in a coordinate system. The upper-right point of the sensor is taken as the origin (0, 0) and the lower-left point is taken as (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 position of the right eye in a coordinate system. The upper-right point of the sensor is taken as the origin (0, 0) and the lower-left point is taken as (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 foveated gaze direction (i.e., the central point of fixed foveated rendering).
|
||||
/// @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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 815321e0da90723458db60e729bdebde
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,93 @@
|
||||
#if !PICO_OPENXR_SDK
|
||||
/*******************************************************************************
|
||||
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;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
public class PXR_FoveationRendering
|
||||
{
|
||||
private static PXR_FoveationRendering instance = null;
|
||||
public static PXR_FoveationRendering Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = new PXR_FoveationRendering();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a foveated rendering level.
|
||||
/// </summary>
|
||||
/// <param name="level">Select a foveated rendering level:
|
||||
/// * `None`: disable foveated rendering
|
||||
/// * `Low`
|
||||
/// * `Med`
|
||||
/// * `High`
|
||||
/// * `TopHigh`
|
||||
/// </param>
|
||||
/// <param name="isETFR">
|
||||
/// Describe if the foveated rendering mode is eye tracked foveated rendering (ETFR):
|
||||
/// * `true`: ETFR
|
||||
/// * `false`: not ETFR
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool SetFoveationLevel(FoveationLevel level, bool isETFR)
|
||||
{
|
||||
if (isETFR)
|
||||
{
|
||||
return PXR_Plugin.Render.UPxr_SetEyeFoveationLevel(level);
|
||||
}
|
||||
else
|
||||
{
|
||||
return PXR_Plugin.Render.UPxr_SetFoveationLevel(level);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current foveated rendering level.
|
||||
/// </summary>
|
||||
/// <returns>The current foveated rendering level:
|
||||
/// * `None` (`-1`): foveated rendering disabled
|
||||
/// * `Low`
|
||||
/// * `Med`
|
||||
/// * `High`
|
||||
/// * `TopHigh`
|
||||
/// </returns>
|
||||
public static FoveationLevel GetFoveationLevel()
|
||||
{
|
||||
return PXR_Plugin.Render.UPxr_GetFoveationLevel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets foveated rendering parameters.
|
||||
/// </summary>
|
||||
/// <param name="foveationGainX">Set the reduction rate of peripheral pixels in the X-axis direction. Value range: [1.0, 10.0], the greater the value, the higher the reduction rate.</param>
|
||||
/// <param name="foveationGainY">Set the reduction rate of peripheral pixels in the Y-axis direction. Value range: [1.0, 10.0], the greater the value, the higher the reduction rate.</param>
|
||||
/// <param name="foveationArea">Set the range of foveated area whose resolution is not to be reduced. Value range: [0.0, 4.0], the higher the value, the bigger the high-quality central area.</param>
|
||||
/// <param name="foveationMinimum">Set the minimum pixel density. Recommended values: 1/32, 1/16, 1/8, 1/4, 1/2. The actual pixel density will be greater than or equal to the value set here.</param>
|
||||
[Obsolete("SetFoveationParameters is not supported.", true)]
|
||||
public static void SetFoveationParameters(float foveationGainX, float foveationGainY, float foveationArea, float foveationMinimum)
|
||||
{}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d0598bf64df1a34e9a5ec19775188d5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,119 @@
|
||||
#if !PICO_OPENXR_SDK
|
||||
/*******************************************************************************
|
||||
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;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
|
||||
#if PICO_LIVE_PREVIEW && UNITY_EDITOR
|
||||
using Unity.XR.PICO.LivePreview;
|
||||
#endif
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
public static class PXR_HandTracking
|
||||
{
|
||||
/// <summary>Gets whether hand tracking is enabled or disabled.</summary>
|
||||
/// <returns>
|
||||
/// * `true`: enabled
|
||||
/// * `false`: disabled
|
||||
/// </returns>
|
||||
///interface has been deprecated
|
||||
[Obsolete("interface has been deprecated", true)]
|
||||
public static bool GetSettingState()
|
||||
{
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Gets the current active input device.</summary>
|
||||
/// <returns>The current active input device:
|
||||
/// * `HeadActive`: HMD
|
||||
/// * `ControllerActive`: controllers
|
||||
/// * `HandTrackingActive`: hands
|
||||
/// </returns>
|
||||
public static ActiveInputDevice GetActiveInputDevice()
|
||||
{
|
||||
return PXR_Plugin.HandTracking.UPxr_GetHandTrackerActiveInputType();
|
||||
}
|
||||
|
||||
/// <summary>Gets the data about the pose of a specified hand, including the status of the ray and fingers, the strength of finger pinch and ray touch.</summary>
|
||||
/// <param name="hand">The hand to get data for:
|
||||
/// * `HandLeft`: left hand
|
||||
/// * `HandRight`: right hand
|
||||
/// </param>
|
||||
/// <param name="aimState">`HandAimState` contains the data about the poses of ray and fingers.
|
||||
/// If you use PICO hand prefabs without changing any of their default settings, you will get the following data:
|
||||
/// ```csharp
|
||||
/// public class PXR_Hand
|
||||
/// {
|
||||
/// // Whether the data is valid.
|
||||
/// public bool Computed { get; private set; }
|
||||
/// // The ray pose.
|
||||
/// public Posef RayPose { get; private set; }
|
||||
/// // Whether the ray was displayed.
|
||||
/// public bool RayValid { get; private set; }
|
||||
/// // Whether the ray pinched.
|
||||
/// public bool Pinch { get; private set; }
|
||||
/// // The strength of ray pinch.
|
||||
/// public float PinchStrength { get; private set; }
|
||||
/// ```
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool GetAimState(HandType hand, ref HandAimState aimState)
|
||||
{
|
||||
if (!PXR_ProjectSetting.GetProjectConfig().handTracking)
|
||||
return false;
|
||||
return PXR_Plugin.HandTracking.UPxr_GetHandTrackerAimState(hand, ref aimState);
|
||||
}
|
||||
|
||||
/// <summary>Gets the locations of joints for a specified hand.</summary>
|
||||
/// <param name="hand">The hand to get joint locations for:
|
||||
/// * `HandLeft`: left hand
|
||||
/// * `HandRight`: right hand
|
||||
/// </param>
|
||||
/// <param name="jointLocations">Contains data about the locations of the joints in the specified hand.</param>
|
||||
/// <returns>
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool GetJointLocations(HandType hand, ref HandJointLocations jointLocations)
|
||||
{
|
||||
if (!PXR_ProjectSetting.GetProjectConfig().handTracking)
|
||||
return false;
|
||||
return PXR_Plugin.HandTracking.UPxr_GetHandTrackerJointLocations(hand, ref jointLocations);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scaling ratio of the hand model.
|
||||
/// </summary>
|
||||
/// <param name="hand">Specifies the hand to get scaling ratio for:
|
||||
/// * `HandLeft`: left hand
|
||||
/// * `HandRight`: right hand
|
||||
/// </param>
|
||||
/// <param name="scale">Returns the scaling ratio for the specified hand.</param>
|
||||
/// <returns>
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool GetHandScale(HandType hand,ref float scale)
|
||||
{
|
||||
return PXR_Plugin.HandTracking.UPxr_GetHandScale((int)hand, ref scale);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6243041ddd1c214c84a8c5abef6c24a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,952 @@
|
||||
#if !PICO_OPENXR_SDK
|
||||
/*******************************************************************************
|
||||
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 LitJson;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR;
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
public static partial class PXR_Input
|
||||
{
|
||||
/// <summary>Gets the status of the specified controller.</summary>
|
||||
/// <param name="controller">Specifies the controller to get status for: `LeftController` or `RightController`.</param>
|
||||
/// <returns>The status of the specified controller:
|
||||
/// - `static`: the controller is static
|
||||
/// - `SixDof`: the controller is in 6DoF tracking mode
|
||||
/// - `ThreeDof`: the controller is in 3DoF tracking mode
|
||||
/// - `Sleep`: the controller remains static for a long time and is now in sleep mode
|
||||
/// - `CollidedIn3Dof`: the controller collided with something else during 3DoF tracking
|
||||
/// - `CollidedIn6Dof`: the controller collided with something else during 6DoF tracking
|
||||
/// </returns>
|
||||
public static ControllerStatus GetControllerStatus(Controller controller)
|
||||
{
|
||||
PxrControllerTracking pxrControllerTracking = new PxrControllerTracking();
|
||||
PXR_Plugin.Controller.UPxr_GetControllerTrackingState((uint)controller, PXR_Plugin.System.UPxr_GetPredictedDisplayTime(), ref pxrControllerTracking);
|
||||
return (ControllerStatus)pxrControllerTracking.localControllerPose.status;
|
||||
}
|
||||
|
||||
/// <summary>A callback that indicates the input source (hand poses/controllers) has changed.</summary>
|
||||
public static Action<ActiveInputDevice> InputDeviceChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current dominant controller.
|
||||
/// </summary>
|
||||
/// <returns>The current dominant controller: `LeftController`; `RightController`.</returns>
|
||||
[Obsolete("GetDominantHand is not supported", true)]
|
||||
public static Controller GetDominantHand()
|
||||
{
|
||||
return Controller.LeftController;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a controller as the dominant controller.
|
||||
/// </summary>
|
||||
/// <param name="controller">The controller to be set as the dominant controller: `0`-left controller; `1`-right controller.</param>
|
||||
[Obsolete("SetDominantHand is not supported", true)]
|
||||
public static void SetDominantHand(Controller controller)
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Sets controller vibration, including vibration amplitude and duration.
|
||||
/// @note The `SendHapticImpulse` method offered by UnityXR is also supported. Click [here](https://docs.unity3d.com/ScriptReference/XR.InputDevice.SendHapticImpulse.html) for more information.
|
||||
/// </summary>
|
||||
/// <param name="strength">Vibration amplitude. The valid value ranges from `0` to `1`. The greater the value, the stronger the vibration amplitude. To stop controller vibration, call this function again and set this parameter to `0`.</param>
|
||||
/// <param name="time">Vibration duration. The valid value ranges from `0` to `65535` ms.</param>
|
||||
/// <param name="controller">The controller to set vibration for:
|
||||
/// * `0`: left controller
|
||||
/// * `1`: right controller
|
||||
/// </param>
|
||||
[Obsolete("Please use SendHapticImpulse instead", true)]
|
||||
public static void SetControllerVibration(float strength, int time, Controller controller)
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the device model.
|
||||
/// </summary>
|
||||
/// <returns>The device model. Enumerations: `G2`, `Neo2`, `Neo3`, `NewController`, `PICO_4`.</returns>
|
||||
public static ControllerDevice GetControllerDeviceType()
|
||||
{
|
||||
return (ControllerDevice)PXR_Plugin.Controller.UPxr_GetControllerType();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the connection status for a specified controller.
|
||||
/// </summary>
|
||||
/// <param name="controller">The controller to get connection status for:
|
||||
/// * `0`: left controller
|
||||
/// * `1`: right controller
|
||||
/// </param>
|
||||
/// <returns>The connection status of the specified controller:
|
||||
/// * `true`: connected
|
||||
/// * `false`: not connected
|
||||
/// </returns>
|
||||
public static bool IsControllerConnected(Controller controller)
|
||||
{
|
||||
return PXR_Plugin.Controller.UPxr_IsControllerConnected(controller);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the offset of the controller's display position to its real position.
|
||||
/// </summary>
|
||||
/// <param name="hand">The controller to set an offset for:
|
||||
/// * `0`: left controller
|
||||
/// * `1`: right controller
|
||||
/// </param>
|
||||
/// <param name="offset">The offset (in meters).</param>
|
||||
public static void SetControllerOriginOffset(Controller controller, Vector3 offset)
|
||||
{
|
||||
PXR_Plugin.Controller.UPxr_SetControllerOriginOffset((int)controller, offset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the predicted orientation of a specified controller after a specified time.
|
||||
/// </summary>
|
||||
/// <param name="hand">The controller to get the predicted rotation for:
|
||||
/// * `0`: left controller
|
||||
/// * `1`: right controller
|
||||
/// </param>
|
||||
/// <param name="predictTime">The time for prediction (in milliseconds).</param>
|
||||
/// <returns>The predicted orientation.</returns>
|
||||
public static Quaternion GetControllerPredictRotation(Controller controller, double predictTime)
|
||||
{
|
||||
PxrControllerTracking pxrControllerTracking = new PxrControllerTracking();
|
||||
PXR_Plugin.Controller.UPxr_GetControllerTrackingState((uint)controller, predictTime, ref pxrControllerTracking);
|
||||
|
||||
return new Quaternion(
|
||||
pxrControllerTracking.localControllerPose.pose.orientation.x,
|
||||
pxrControllerTracking.localControllerPose.pose.orientation.y,
|
||||
pxrControllerTracking.localControllerPose.pose.orientation.z,
|
||||
pxrControllerTracking.localControllerPose.pose.orientation.w);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the predicted position of a specified controller after a specified time.
|
||||
/// </summary>
|
||||
/// <param name="hand">The controller to get the predicted position for:
|
||||
/// * `0`: left controller
|
||||
/// * `1`: right controller
|
||||
/// </param>
|
||||
/// <param name="predictTime">The time for prediction (in milliseconds).</param>
|
||||
/// <returns>The predicted position.</returns>
|
||||
public static Vector3 GetControllerPredictPosition(Controller controller, double predictTime)
|
||||
{
|
||||
PxrControllerTracking pxrControllerTracking = new PxrControllerTracking();
|
||||
PXR_Plugin.Controller.UPxr_GetControllerTrackingState((uint)controller, predictTime, ref pxrControllerTracking);
|
||||
|
||||
return new Vector3(
|
||||
pxrControllerTracking.localControllerPose.pose.position.x,
|
||||
pxrControllerTracking.localControllerPose.pose.position.y,
|
||||
pxrControllerTracking.localControllerPose.pose.position.z);
|
||||
}
|
||||
|
||||
/// @deprecated Use \ref SendHapticImpulse instead.
|
||||
/// <summary>
|
||||
/// Sets event-triggered vibration for a specified controller.
|
||||
/// </summary>
|
||||
/// <param name="hand">The controller to enable vibration for:
|
||||
/// * `0`: left controller
|
||||
/// * `1`: right controller
|
||||
/// </param>
|
||||
/// <param name="frequency">Vibration frequency, which ranges from `50` to `500` Hz.</param>
|
||||
/// <param name="strength">Vibration amplitude. Its valid value ranges from `0` to `1`. The higher the value, the stronger the vibration amplitude.</param>
|
||||
/// <param name="time">Vibration duration, which ranges from `0` to `65535` ms.</param>
|
||||
[Obsolete("Please use SendHapticImpulse instead", true)]
|
||||
public static int SetControllerVibrationEvent(UInt32 hand, int frequency, float strength, int time)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/// @deprecated Use \ref StopHapticBuffer(int sourceId, bool clearCache) instead.
|
||||
/// <summary>
|
||||
/// Stops audio-triggered vibration.
|
||||
/// </summary>
|
||||
/// <param name="id">A reserved parameter, set it to the source ID returned by `StartVibrateBySharem` or `SaveVibrateByCache` to stop the corresponding vibration,
|
||||
/// or set it to `0` to stop all vibrations.</param>
|
||||
[Obsolete("Please use StopHapticBuffer instead", true)]
|
||||
public static int StopControllerVCMotor(int sourceId)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// @deprecated Deprecated.
|
||||
/// <summary>
|
||||
/// Starts audio-triggered vibration for specified controller(s). The audio data come from an audio file.
|
||||
/// </summary>
|
||||
/// <param name="file">The path to the audio file.</param>
|
||||
/// <param name="vibrateType">The controller(s) to enable vibration for:
|
||||
/// * `0`: none
|
||||
/// * `1`: left controller
|
||||
/// * `2`: right controller
|
||||
/// * `3`: left and right controllers
|
||||
/// </param>
|
||||
[Obsolete("StartControllerVCMotor is not supported", true)]
|
||||
public static int StartControllerVCMotor(string file, VibrateType vibrateType)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// @deprecated Deprecated.
|
||||
/// <summary>
|
||||
/// Sets the amplitude for audio-triggered vibration. Support changing the vibration amplitude during audio playback.
|
||||
/// </summary>
|
||||
/// <param name="mode">Vibration amplitude level:
|
||||
/// * `0`: no vibration
|
||||
/// * `1`: standard amplitude
|
||||
/// * `2`: 2×standard amplitude
|
||||
/// * `3`: 3×standard amplitude
|
||||
/// * `4`: 4×standard amplitude
|
||||
/// @note "3×standard amplitude" and "4×standard amplitude" are NOT recommended as they will cause serious loss of vibration details.
|
||||
/// </param>
|
||||
[Obsolete("SetControllerAmp is not supported", true)]
|
||||
public static int SetControllerAmp(float mode)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// @deprecated Use \ref SendHapticBuffer(VibrateType vibrateType, AudioClip audioClip, ChannelFlip channelFlip, ref int sourceId, CacheType cacheType) instead.
|
||||
/// <summary>
|
||||
/// Starts audio-triggered vibration for specified controller(s). The audio data come from an audio clip passed to the Unity Engine.
|
||||
/// </summary>
|
||||
/// <param name="audioClip">The path to the audio clip.</param>
|
||||
/// <param name="vibrateType">The controller(s) to enable vibration for:
|
||||
/// * `0`: none
|
||||
/// * `1`: left controller
|
||||
/// * `2`: right controller
|
||||
/// * `3`: left and right controllers
|
||||
/// </param>
|
||||
/// <param nname="channelFlip">Whether to enable audio channel inversion:
|
||||
/// * `Yes`: enable
|
||||
/// * `No`: disable
|
||||
/// Once audio channel inversion is enabled, the left controller vibrates with the audio data from the right channel, and vice versa.
|
||||
/// </param>
|
||||
/// <param nname="sourceId">Returns the unique ID for controlling the corresponding vibration,
|
||||
/// which will be used in `StartVibrateByCache`, `ClearVibrateByCache` or `StopControllerVCMotor`.</param>
|
||||
[Obsolete("Please use SendHapticBuffer instead", true)]
|
||||
public static int StartVibrateBySharem(AudioClip audioClip, VibrateType vibrateType, ChannelFlip channelFlip, ref int sourceId)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use \ref SendHapticBuffer(VibrateType vibrateType, float[] pcmData, int buffersize, int frequency, int channelMask, ChannelFlip channelFlip, ref int sourceId, CacheType cacheType) instead.
|
||||
*/
|
||||
/// <summary>
|
||||
/// Starts audio-triggered vibration for specified controller(s). This function is the overloaded version.
|
||||
/// </summary>
|
||||
/// <param name="data">The PCM data.</param>
|
||||
/// <param name="vibrateType">The controller(s) to enable vibration for:
|
||||
/// * `0`: none
|
||||
/// * `1`: left controller
|
||||
/// * `2`: right controller
|
||||
/// * `3`: left and right controllers
|
||||
/// </param>
|
||||
/// <param name="buffersize">The length of PCM data. Formula: (audioClip.samples)×(audioClip.channels).</param>
|
||||
/// <param name="frequency">Audio sampling rate.</param>
|
||||
/// <param name="channelMask">The number of channels.</param>
|
||||
/// <param name="channelFlip">Whether to enable audio channel inversion:
|
||||
/// * `Yes`: enable
|
||||
/// * `No`: disable
|
||||
/// Once audio channel inversion is enabled, the left controller vibrates with the audio data from the right channel, and vice versa.
|
||||
/// </param>
|
||||
/// <param name="sourceId">Returns the unique ID for controlling the corresponding vibration,
|
||||
/// which will be used in `StartVibrateByCache`, `ClearVibrateByCache` or `StopControllerVCMotor`.</param>
|
||||
[Obsolete("Please use SendHapticBuffer instead", true)]
|
||||
public static int StartVibrateBySharem(float[] data, VibrateType vibrateType, int buffersize, int frequency, int channelMask, ChannelFlip channelFlip, ref int sourceId)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/// @deprecated Use \ref SendHapticBuffer(VibrateType vibrateType, AudioClip audioClip, ChannelFlip channelFlip, ref int sourceId, CacheType cacheType) instead.
|
||||
/// <summary>
|
||||
/// Caches audio-triggered vibration data for specified controller(s).
|
||||
/// @note The cached data can be extracted from the cache directory and then transmitted, which reduces resource consumption and improves service performance.
|
||||
/// </summary>
|
||||
/// <param name="audioClip">The path to the audio clip.</param>
|
||||
/// <param name="vibrateType">The controller(s) to cache data for:
|
||||
/// * `0`: none
|
||||
/// * `1`: left controller
|
||||
/// * `2`: right controller
|
||||
/// * `3`: left and right controllers</param>
|
||||
/// <param name="channelFlip">Whether to enable audio channel inversion:
|
||||
/// * `Yes`: enable
|
||||
/// * `No`: disable
|
||||
/// Once audio channel inversion is enabled, the left controller vibrates with the audio data from the right channel, and vice versa.
|
||||
/// </param>
|
||||
/// <param name="cacheConfig">Whether to keep the controller vibrating while caching audio-based vibration data:
|
||||
/// * `CacheAndVibrate`: cache and keep vibrating
|
||||
/// * `CacheNoVibrate`: cache and stop vibrating
|
||||
/// </param>
|
||||
/// <param name="sourceId">Returns the unique ID for controlling the corresponding vibration,
|
||||
/// which will be used in `StartVibrateByCache`, `ClearVibrateByCache` or `StopControllerVCMotor`.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `-1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Please use SendHapticBuffer instead", true)]
|
||||
public static int SaveVibrateByCache(AudioClip audioClip, VibrateType vibrateType, ChannelFlip channelFlip, CacheConfig cacheConfig, ref int sourceId)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// @deprecated Use \ref SendHapticBuffer(VibrateType vibrateType, float[] pcmData, int buffersize, int frequency, int channelMask, ChannelFlip channelFlip, ref int sourceId, CacheType cacheType)
|
||||
/// <summary>
|
||||
/// Caches audio-triggered vibration data for specified controller(s). This function is the overloaded version.
|
||||
/// @note The cached data can be extracted from the cache directory and then transmitted, which reduces resource consumption and improves service performance.
|
||||
/// </summary>
|
||||
/// <param name="data">The PCM data.</param>
|
||||
/// <param name="vibrateType">The controller(s) to cache data for:
|
||||
/// * `0`: none
|
||||
/// * `1`: left controller
|
||||
/// * `2`: right controller
|
||||
/// * `3`: left and right controllers
|
||||
/// </param>
|
||||
/// <param name="buffersize">The length of PCM data. Formula: (audioClip.samples)×(audioClip.channels)</param>
|
||||
/// <param name="frequency">Audio sampling rate.</param>
|
||||
/// <param name="channelMask">The number of channels.</param>
|
||||
/// <param name="channelFlip">Whether to enable audio channel inversion:
|
||||
/// * `Yes`: enable
|
||||
/// * `No`: disable
|
||||
/// Once audio channel inversion is enabled, the left controller vibrates with the audio data from the right channel, and vice versa.
|
||||
/// </param>
|
||||
/// <param name="cacheConfig">Whether to keep the controller vibrating while caching audio-based vibration data:
|
||||
/// * `CacheAndVibrate`: cache and keep vibrating
|
||||
/// * `CacheNoVibrate`: cache and stop vibrating
|
||||
/// </param>
|
||||
/// <param name="sourceId">Returns the unique ID for controlling the corresponding vibration,
|
||||
/// which will be used in `StartVibrateByCache`, `ClearVibrateByCache` or `StopControllerVCMotor`.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `-1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Please use SendHapticBuffer instead", true)]
|
||||
public static int SaveVibrateByCache(float[] data, VibrateType vibrateType, int buffersize, int frequency, int channelMask, ChannelFlip channelFlip, CacheConfig cacheConfig, ref int sourceId)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// @deprecated Use \ref StartHapticBuffer instead.
|
||||
/// <summary>
|
||||
/// Plays cached audio-triggered vibration data.
|
||||
/// </summary>
|
||||
/// <param name="sourceId">The source ID returned by `StartVibrateBySharem` or `SaveVibrateByCache`.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `-1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Please use StartHapticBuffer instead", true)]
|
||||
public static int StartVibrateByCache(int sourceId)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// @deprecated Use \ref StopHapticBuffer(clearCache) instead.
|
||||
/// <summary>
|
||||
/// Clears cached audio-triggered vibration data.
|
||||
/// </summary>
|
||||
/// <param name="sourceId">The source ID returned by `StartVibrateBySharem` or `SaveVibrateByCache`.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `-1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Please use StopHapticBuffer(clearCache) instead", true)]
|
||||
public static int ClearVibrateByCache(int sourceId)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int SetControllerEnableKey(bool isEnable, PxrControllerKeyMap Key)
|
||||
{
|
||||
return PXR_Plugin.Controller.UPxr_SetControllerEnableKey(isEnable, Key);
|
||||
}
|
||||
|
||||
/// @deprecated Use \ref SendHapticBuffer(VibrateType vibrateType, TextAsset phfText, ChannelFlip channelFlip, float amplitudeScale, ref int sourceId) instead.
|
||||
/// <summary>
|
||||
/// Starts PHF-triggered vibration for specified controller(s). PHF stands for PICO haptic file.
|
||||
/// </summary>
|
||||
/// <param name="phfText">The path to the PHF file.</param>
|
||||
/// <param name="sourceId">The source ID returned by `StartVibrateBySharem` or `SaveVibrateByCache`.</param>
|
||||
/// <param name="vibrateType">The controller(s) to enable vibration for:
|
||||
/// * `0`: none
|
||||
/// * `1`: left controller
|
||||
/// * `2`: right controller
|
||||
/// * `3`: left and right controllers
|
||||
/// </param>
|
||||
/// <param name="channelFlip">Whether to enable audio channel inversion:
|
||||
/// * `Yes`: enable
|
||||
/// * `No`: disable
|
||||
/// Once audio channel inversion is enabled, the left controller vibrates with the audio data from the right channel, and vice versa.</param>
|
||||
/// <param name="amp">The vibration gain, the valid value range from `0` to `2`:
|
||||
/// * `0`: no vibration
|
||||
/// * `1`: standard amplitude
|
||||
/// * `2`: 2×standard amplitude</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `-1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Please use SendHapticBuffer instead", true)]
|
||||
public static int StartVibrateByPHF(TextAsset phfText, ref int sourceId, VibrateType vibrateType, ChannelFlip channelFlip, float amp)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// @deprecated Use \ref PauseHapticBuffer instead.
|
||||
/// <summary>
|
||||
/// Pauses PHF-triggered vibration.
|
||||
/// </summary>
|
||||
/// <param name="sourceId">The source ID returned by `StartVibrateBySharem` or `SaveVibrateByCache`.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `-1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Please use PauseHapticBuffer instead", true)]
|
||||
public static int PauseVibrate(int sourceId)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// @deprecated Use \ref ResumeHapticBuffer instead.
|
||||
/// <summary>
|
||||
/// Resumes PHF-triggered vibration.
|
||||
/// </summary>
|
||||
/// <param name="sourceId">The source ID returned by `StartVibrateBySharem` or `SaveVibrateByCache`.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `-1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Please use ResumeHapticBuffer instead", true)]
|
||||
public static int ResumeVibrate(int sourceId)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// @deprecated Use \ref UpdateHapticBuffer instead.
|
||||
/// <summary>
|
||||
/// Dynamically updates PHF and AudioClip vibration data.
|
||||
/// </summary>
|
||||
/// <param name="sourceId">The source ID returned by `StartVibrateBySharem` or `SaveVibrateByCache`.</param>
|
||||
/// <param name="vibrateType">The controller(s) to update PHF and AudioClip vibration data for:
|
||||
/// * `0`: none
|
||||
/// * `1`: left controller
|
||||
/// * `2`: right controller
|
||||
/// * `3`: left and right controllers
|
||||
/// </param>
|
||||
/// <param name="channelFlip">Whether to enable audio channel inversion:
|
||||
/// * `Yes`: enable
|
||||
/// * `No`: disable
|
||||
/// Once audio channel inversion is enabled, the left controller vibrates with the audio data from the right channel, and vice versa.</param>
|
||||
/// <param name="amp">The vibration gain, the valid value range from `0` to `2`:
|
||||
/// * `0`: no vibration
|
||||
/// * `1`: standard amplitude
|
||||
/// * `2`: 2×standard amplitude</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `-1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Please use UpdateHapticBuffer instead", true)]
|
||||
public static int UpdateVibrateParams(int sourceId, VibrateType vibrateType, ChannelFlip channelFlip, float amp)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data about the poses of body joints.
|
||||
/// </summary>
|
||||
/// <param name="predictTime">Reserved parameter, pass `0`.</param>
|
||||
/// <param name="bodyTrackerResult">Contains the data about the poses of body joints, including position, action, and more.</param>
|
||||
[Obsolete("Please use GetBodyTrackingData instead", true)]
|
||||
public static int GetBodyTrackingPose(double predictTime, ref BodyTrackerResult bodyTrackerResult)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of PICO Motion Trackers currently connected and their IDs.
|
||||
/// </summary>
|
||||
/// <param name="state">The number and IDs of connected PICO Motion Trackers.</param>
|
||||
[Obsolete("Please use GetMotionTrackerConnectStateWithSN instead", true)]
|
||||
public static int GetMotionTrackerConnectStateWithID(ref PxrMotionTracker1ConnectState state)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the battery of a specified PICO Motion Traker.
|
||||
/// </summary>
|
||||
/// <param name="trackerId">The ID of the motion tracker to get battery for.</param>
|
||||
/// <param name="battery">The motion tracker's battery. Value range: [0,5]. The smaller the value, the lower the battery level.</param>
|
||||
[Obsolete("Please use GetMotionTrackerBatteryWithSN instead", true)]
|
||||
public static int GetMotionTrackerBattery(int trackerId, ref int battery)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the PICO Motion Tracker has completed calibration.
|
||||
/// </summary>
|
||||
/// <param name="calibrated">Indicates the calibration status:
|
||||
/// `0`: calibration uncompleted
|
||||
/// `1`: calibration completed
|
||||
/// </param>
|
||||
[Obsolete("Please use GetBodyTrackingState instead", true)]
|
||||
public static int GetMotionTrackerCalibState(ref int calibrated)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a body tracking mode for PICO Motion Tracker. If this API is not called, the mode defaults to leg tracking.
|
||||
/// @note If you want to set the mode to full-body tracking, you must call this API before calling `OpenMotionTrackerCalibrationAPP`.
|
||||
/// </summary>
|
||||
/// <param name="mode">Selects a body tracking mode from the following:
|
||||
/// * Motion Tracker 1.0 `0`: leg tracking, nodes numbered 0 to 15 in `BodyTrackerRole` enum will return data.
|
||||
/// * Motion Tracker 1.0 `1`: full-body tracking, nodes numbered 0 to 23 in `BodyTrackerRole` enum will return data.
|
||||
/// * Motion Tracker 2.0 `0`: full-body tracking, nodes numbered 0 to 23 in `BodyTrackerRole` enum will return data. Low latency.
|
||||
/// * Motion Tracker 2.0 `1`: full-body tracking, nodes numbered 0 to 23 in `BodyTrackerRole` enum will return data. High latency.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Please use StartBodyTracking instead", true)]
|
||||
public static int SetBodyTrackingMode(BodyTrackingMode mode)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets bone lengths for different parts of the avatar. The data will be sent to PICO'S algorithm to make the avatar's poses more accurate.
|
||||
/// </summary>
|
||||
/// <param name="boneLength">Sets the bone lengths for different parts of the avatar. See the `BodyTrackingBoneLength` for details.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Please use StartBodyTracking instead", true)]
|
||||
public static int SetBodyTrackingBoneLength(BodyTrackingBoneLength boneLength)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a haptic impulse to specified controller(s) to trigger vibration.
|
||||
/// @note To stop vibration, call this API again and set both `amplitude` and `duration` to `0`.
|
||||
/// </summary>
|
||||
/// <param name="vibrateType">The controller(s) to send the haptic impulse to:
|
||||
/// * `None`
|
||||
/// * `LeftController`
|
||||
/// * `RightController`
|
||||
/// * `BothController`
|
||||
/// </param>
|
||||
/// <param name="amplitude">Vibration amplitude, which ranges from `0` to `1`. The higher the value, the stronger the vibration amplitude.</param>
|
||||
/// <param name="duration">Vibration duration, which ranges from `0` to `65535` ms.</param>
|
||||
/// <param name="frequency">Vibration frequency, which ranges from `50` to `500` Hz.</param>
|
||||
public static void SendHapticImpulse(VibrateType vibrateType, float amplitude, int duration, int frequency = 150)
|
||||
{
|
||||
switch (vibrateType)
|
||||
{
|
||||
case VibrateType.None:
|
||||
break;
|
||||
case VibrateType.LeftController:
|
||||
PXR_Plugin.Controller.UPxr_SetControllerVibrationEvent(0, frequency, amplitude, duration);
|
||||
break;
|
||||
case VibrateType.RightController:
|
||||
PXR_Plugin.Controller.UPxr_SetControllerVibrationEvent(1, frequency, amplitude, duration);
|
||||
break;
|
||||
case VibrateType.BothController:
|
||||
PXR_Plugin.Controller.UPxr_SetControllerVibrationEvent(0, frequency, amplitude, duration);
|
||||
PXR_Plugin.Controller.UPxr_SetControllerVibrationEvent(1, frequency, amplitude, duration);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a buffer of haptic data to specified controller(s) to trigger vibration.
|
||||
/// </summary>
|
||||
/// <param name="vibrateType">The controller(s) to send the haptic data to:
|
||||
/// * `None`
|
||||
/// * `LeftController`
|
||||
/// * `RightController`
|
||||
/// * `BothController`
|
||||
/// </param>
|
||||
/// <param name="audioClip">The audio data pulled from the audio file stored in the AudioClip component is used as the haptic data.</param>
|
||||
/// <param name="channelFlip">Determines whether to enable audio channel inversion. Once enabled, the left controller vibrates with the audio data from the right channel, and vice versa.
|
||||
/// * `Yes`: enable
|
||||
/// * `No`: disable
|
||||
/// </param>
|
||||
/// <param name="sourceId">Returns the unique ID for controlling the corresponding buffered haptic,
|
||||
/// which will be used in `PauseHapticBuffer`, `ResumeHapticBuffer`, `UpdateHapticBuffer`, or `StopHapticBuffer`.</param>
|
||||
/// <param name="cacheType">Whether to keep the controller vibrating while caching haptic data:
|
||||
/// * `DontCache`: don't cache.
|
||||
/// * `CacheAndVibrate`: cache and keep vibrating.
|
||||
/// * `CacheNoVibrate`: cache and stop vibrating. Call `StartHapticBuffer` to start haptic after caching the data.
|
||||
/// @note If not defined, `DontCache` will be passed by default.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `1`: failure
|
||||
/// </returns>
|
||||
/**
|
||||
* \overload int SendHapticBuffer(VibrateType vibrateType, AudioClip audioClip, ChannelFlip channelFlip, ref int sourceId, CacheType cacheType)
|
||||
*/
|
||||
public static int SendHapticBuffer(VibrateType vibrateType, AudioClip audioClip, ChannelFlip channelFlip, ref int sourceId, CacheType cacheType = CacheType.DontCache)
|
||||
{
|
||||
if (audioClip == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
float[] data = new float[audioClip.samples * audioClip.channels];
|
||||
int buffersize = audioClip.samples * audioClip.channels;
|
||||
audioClip.GetData(data, 0);
|
||||
int sampleRate = audioClip.frequency;
|
||||
int channelMask = audioClip.channels;
|
||||
if (cacheType == CacheType.DontCache)
|
||||
{
|
||||
return PXR_Plugin.Controller.UPxr_StartVibrateBySharem(data, (int)vibrateType, buffersize, sampleRate, channelMask, 32, (int)channelFlip, ref sourceId);
|
||||
}
|
||||
else
|
||||
{
|
||||
return PXR_Plugin.Controller.UPxr_SaveVibrateByCache(data, (int)vibrateType, buffersize, sampleRate, channelMask, 32, (int)channelFlip, (int)cacheType, ref sourceId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a buffer of haptic data to specified controller(s) to trigger vibration.
|
||||
/// </summary>
|
||||
/// <param name="vibrateType">The controller(s) to send the haptic data to:
|
||||
/// * `None`
|
||||
/// * `LeftController`
|
||||
/// * `RightController`
|
||||
/// * `BothController`
|
||||
/// </param>
|
||||
/// <param name="pcmData">The PCM data is converted from the audio file stored in the AudioClip component in the Unity Engine.</param>
|
||||
/// <param name="buffersize">The length of PCM data. Calculation formula: (audioClip.samples)×(audioClip.channels). Sample refers to the data in each channel.</param>
|
||||
/// <param name="frequency">Sample rate. The higher the sample rate, the closer the recorded signal is to the original.</param>
|
||||
/// <param name="channelMask">The number of channels that play the haptic data.</param>
|
||||
/// <param name="channelFlip">Determines whether to enable audio channel inversion. Once enabled, the left controller vibrates with the audio data from the right channel, and vice versa.
|
||||
/// * `Yes`: enable
|
||||
/// * `No`: disable
|
||||
/// </param>
|
||||
/// <param name="sourceId">Returns the unique ID for controlling the corresponding buffered haptic,
|
||||
/// which will be used in `PauseHapticBuffer`, `ResumeHapticBuffer`, `UpdateHapticBuffer`, or `StopHapticBuffer`.</param>
|
||||
/// <param name="cacheType">Whether to keep the controller vibrating while caching haptic data:
|
||||
/// * `DontCache`: don't cache.
|
||||
/// * `CacheAndVibrate`: cache and keep vibrating.
|
||||
/// * `CacheNoVibrate`: cache and stop vibrating. Call `StartHapticBuffer` to start vibration after caching the data.
|
||||
/// @note If not defined, `DontCache` will be passed by default.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `-1`: failure
|
||||
/// </returns>
|
||||
/**
|
||||
* \overload int SendHapticBuffer(VibrateType vibrateType, float[] pcmData, int buffersize, int frequency, int channelMask, ChannelFlip channelFlip, ref int sourceId, CacheType cacheType)
|
||||
*/
|
||||
public static int SendHapticBuffer(VibrateType vibrateType, float[] pcmData, int buffersize, int frequency, int channelMask, ChannelFlip channelFlip, ref int sourceId, CacheType cacheType = CacheType.DontCache)
|
||||
{
|
||||
if (cacheType == CacheType.DontCache)
|
||||
{
|
||||
return PXR_Plugin.Controller.UPxr_StartVibrateBySharem(pcmData, (int)vibrateType, buffersize, frequency, channelMask, 32, (int)channelFlip, ref sourceId);
|
||||
}
|
||||
else
|
||||
{
|
||||
return PXR_Plugin.Controller.UPxr_SaveVibrateByCache(pcmData, (int)vibrateType, buffersize, frequency, channelMask, 32, (int)channelFlip, (int)cacheType, ref sourceId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a buffer of haptic data to specified controller(s) to trigger vibration.
|
||||
/// </summary>
|
||||
/// <param name="vibrateType">The controller(s) to send the haptic data to:
|
||||
/// * `None`
|
||||
/// * `LeftController`
|
||||
/// * `RightController`
|
||||
/// * `BothController`
|
||||
/// </param>
|
||||
/// <param name="phfText">The PHF file (.json) that contains haptic data.</param>
|
||||
/// <param name="channelFlip">Determines whether to enable audio channel inversion. Once enabled, the left controller vibrates with the audio data from the right channel, and vice versa.
|
||||
/// * `Yes`: enable
|
||||
/// * `No`: disable
|
||||
/// <param name="amplitudeScale">Vibration amplitude, the higher the amplitude, the stronger the haptic effect. The valid value range from `0` to `2`:
|
||||
/// * `0`: no vibration
|
||||
/// * `1`: standard amplitude
|
||||
/// * `2`: 2×standard amplitude
|
||||
/// </param>
|
||||
/// <param name="sourceId">Returns the unique ID for controlling the corresponding buffered haptic,
|
||||
/// which will be used in `PauseHapticBuffer`, `ResumeHapticBuffer`, `UpdateHapticBuffer`, or `StopHapticBuffer`.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `-1`: failure
|
||||
/// </returns>
|
||||
public static int SendHapticBuffer(VibrateType vibrateType, TextAsset phfText, ChannelFlip channelFlip, float amplitudeScale, ref int sourceId)
|
||||
{
|
||||
return PXR_Plugin.Controller.UPxr_StartVibrateByPHF(phfText.text, phfText.text.Length, ref sourceId, (int)vibrateType, (int)channelFlip, amplitudeScale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops a specified buffered haptic.
|
||||
/// </summary>
|
||||
/// <param name="sourceId">The source ID returned by `SendHapticBuffer`. Set it to the target source ID to stop a specific buffered haptic,
|
||||
/// or set it to `0` to stop all buffered haptics. If not defined, `0` will be passed to stop all buffered haptics by default.</param>
|
||||
/// <param name="clearCache">Determines whether to clear the cached data of the specified haptic.
|
||||
/// If not defined, `false` will be passed to keep the cached data by default.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `1`: failure
|
||||
/// </returns>
|
||||
public static int StopHapticBuffer(int sourceId = 0, bool clearCache = false)
|
||||
{
|
||||
if (clearCache)
|
||||
{
|
||||
PXR_Plugin.Controller.UPxr_ClearVibrateByCache(sourceId);
|
||||
}
|
||||
return PXR_Plugin.Controller.UPxr_StopControllerVCMotor(sourceId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pauses a specified buffered haptic.
|
||||
/// </summary>
|
||||
/// <param name="sourceId">The source ID returned by `SendHapticBuffer`.
|
||||
/// Set it to the target source ID to stop a specific buffered haptic.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `-1`: failure
|
||||
/// </returns>
|
||||
public static int PauseHapticBuffer(int sourceId)
|
||||
{
|
||||
return PXR_Plugin.Controller.UPxr_PauseVibrate(sourceId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resumes a paused buffered haptic.
|
||||
/// </summary>
|
||||
/// <param name="sourceId">The source ID returned by `SendHapticBuffer`.
|
||||
/// Set it to the target source ID to resume a specific buffered haptic.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `-1`: failure
|
||||
/// </returns>
|
||||
public static int ResumeHapticBuffer(int sourceId)
|
||||
{
|
||||
return PXR_Plugin.Controller.UPxr_ResumeVibrate(sourceId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a specified buffered haptic.
|
||||
/// @note If you pass `CacheNoVibrate` in `SendHapticBuffer`, call this API if you want to start haptic after caching the data.
|
||||
/// </summary>
|
||||
/// <param name="sourceId">The source ID returned by `SendHapticBuffer` when there is cached data for the haptic.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `-1`: failure
|
||||
/// </returns>
|
||||
public static int StartHapticBuffer(int sourceId)
|
||||
{
|
||||
return PXR_Plugin.Controller.UPxr_StartVibrateByCache(sourceId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the settings for a specified buffered haptic.
|
||||
/// </summary>
|
||||
/// <param name="sourceId">The source ID returned by `SendHapticBuffer`.
|
||||
/// Set it to the target source ID to update a specific buffered haptic.</param>
|
||||
/// <param name="vibrateType">The controller(s) that the vibration is applied to:
|
||||
/// * `None`
|
||||
/// * `LeftController`
|
||||
/// * `RightController`
|
||||
/// * `BothController`
|
||||
/// </param>
|
||||
/// <param name="channelFlip">Determines whether to enable audio channel inversion. Once enabled, the left controller vibrates with the audio data from the right channel, and vice versa.
|
||||
/// * `Yes`: enable
|
||||
/// * `No`: disable
|
||||
/// <param name="amplitudeScale">Vibration amplitude, the higher the amplitude, the stronger the haptic effect. The valid value range from `0` to `2`:
|
||||
/// * `0`: no vibration
|
||||
/// * `1`: standard amplitude
|
||||
/// * `2`: 2×standard amplitude
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `-1`: failure
|
||||
/// </returns>
|
||||
public static int UpdateHapticBuffer(int sourceId, VibrateType vibrateType, ChannelFlip channelFlip, float amplitudeScale)
|
||||
{
|
||||
return PXR_Plugin.Controller.UPxr_UpdateVibrateParams(sourceId, (int)vibrateType, (int)channelFlip, amplitudeScale);
|
||||
}
|
||||
|
||||
/// <summary>Creates a haptic stream.</summary>
|
||||
/// <param name="phfVersion">The version of the PICO haptic file (PHF) that the stream uses.</param>
|
||||
/// <param name="frameDurationMs">Interframe space, which is the amount of time in milliseconds existing between the transmissions of frames.</param>
|
||||
/// <param name="hapticInfo">The information about this haptic stream you create.</param>
|
||||
/// <param name="speed">The streaming speed.</param>
|
||||
/// <param name="id">Returns the ID of the stream.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("CreateHapticStream is not supported", true)]
|
||||
public static int CreateHapticStream(string phfVersion, UInt32 frameDurationMs, ref VibrateInfo hapticInfo, float speed, ref int id)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes haptic data to a specified stream.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the target stream.</param>
|
||||
/// <param name="frames">The data contained in the PICO haptic file (PHF).</param>
|
||||
/// <param name="numFrames">The number of frames.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("WriteHapticStream is not supported", true)]
|
||||
public static int WriteHapticStream(int id, ref PxrPhfParamsNum frames, UInt32 numFrames)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a transmission speed for a specified haptic stream.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the stream.</param>
|
||||
/// <param name="speed">The transmission speed to set for the stream.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("SetHapticStreamSpeed is not supported", true)]
|
||||
public static int SetHapticStreamSpeed(int id, float speed)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the transmission speed of a specified haptic stream.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the stream.</param>
|
||||
/// <param name="speed">Returns the stream's transmission speed.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("GetHapticStreamSpeed is not supported", true)]
|
||||
public static int GetHapticStreamSpeed(int id, ref float speed)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the No. of the frame that the controller currently plays.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the haptic stream that triggers the vibration.</param>
|
||||
/// <param name="frameSequence">Returns the current frame's sequence No.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("GetHapticStreamCurrentFrameSequence is not supported", true)]
|
||||
public static int GetHapticStreamCurrentFrameSequence(int id, ref UInt64 frameSequence)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts the transmission of a specified haptic stream.
|
||||
/// </summary>
|
||||
/// <param name="source_id">The ID of the haptic stream.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("StartHapticStream is not supported", true)]
|
||||
public static int StartHapticStream(int source_id)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops the transmission of a specified haptic stream.
|
||||
/// </summary>
|
||||
/// <param name="source_id">The ID of the haptic stream.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("StopHapticStream is not supported", true)]
|
||||
public static int StopHapticStream(int source_id)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a specified haptic stream.
|
||||
/// </summary>
|
||||
/// <param name="source_id">The ID of the stream.</param>
|
||||
/// <returns>
|
||||
/// * `0`: successGetMotionTrackerCalibState
|
||||
/// * `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("RemoveHapticStream is not supported", true)]
|
||||
public static int RemoveHapticStream(int source_id)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the haptic data in a specified PICO haptic file (PHF).
|
||||
/// </summary>
|
||||
/// <param name="phfText">The PICO haptic file (.json) to parse.</param>
|
||||
[Obsolete("AnalysisHapticStreamPHF is not supported", true)]
|
||||
public static PxrPhfFile AnalysisHapticStreamPHF(TextAsset phfText)
|
||||
{
|
||||
String str = phfText.text;
|
||||
return JsonMapper.ToObject<PxrPhfFile>(str);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recenters the controller on PICO G3.
|
||||
/// </summary>
|
||||
[Obsolete("ResetController is not supported", true)]
|
||||
public static void ResetController()
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Sets arm model parameters on PICO G3.
|
||||
/// </summary>
|
||||
/// <param name="gazetype">Gaze type, which is used to define the way of getting the HMD data.</param>
|
||||
/// <param name="armmodeltype">Arm model type</param>
|
||||
/// <param name="elbowHeight">The elbow's height, which changes the arm's length.Value range: (0.0f, 0.2f). The default value is 0.0f.</param>
|
||||
/// <param name="elbowDepth">The elbow's depth, which changes the arm's position.Value range: (0.0f, 0.2f). The default value is 0.0f.</param>
|
||||
/// <param name="pointerTiltAngle">The ray's tilt angle. Value range: (0.0f, 30.0f). The default value is 0.0f.</param>
|
||||
[Obsolete("SetArmModelParameters is not supported", true)]
|
||||
public static void SetArmModelParameters(PxrGazeType gazetype, PxrArmModelType armmodeltype, float elbowHeight, float elbowDepth, float pointerTiltAngle)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current user's dominant hand in the system on PICO G3.
|
||||
/// </summary>
|
||||
/// <param name="deviceID"></param>
|
||||
public static void GetControllerHandness(ref int deviceID)
|
||||
{
|
||||
PXR_Plugin.Controller.UPxr_GetControllerHandness(ref deviceID);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce57129cda8427d4eaacb7990f5f40de
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,95 @@
|
||||
#if !PICO_OPENXR_SDK
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.XR;
|
||||
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
[Serializable]
|
||||
public class PXR_LateLatching : MonoBehaviour
|
||||
{
|
||||
#if UNITY_2020_3_OR_NEWER
|
||||
private Camera m_LateLatchingCamera;
|
||||
|
||||
static XRDisplaySubsystem s_DisplaySubsystem = null;
|
||||
|
||||
static List<XRDisplaySubsystem> s_DisplaySubsystems = new List<XRDisplaySubsystem>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_LateLatchingCamera = GetComponent<Camera>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
|
||||
List<XRDisplaySubsystem> displaySubsystems = new List<XRDisplaySubsystem>();
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
SubsystemManager.GetSubsystems(displaySubsystems);
|
||||
#else
|
||||
SubsystemManager.GetInstances(displaySubsystems);
|
||||
#endif
|
||||
Debug.Log("PXR_U OnEnable() displaySubsystems.Count = " + displaySubsystems.Count);
|
||||
for (int i = 0; i < displaySubsystems.Count; i++)
|
||||
{
|
||||
s_DisplaySubsystem = displaySubsystems[i];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (s_DisplaySubsystem == null)
|
||||
{
|
||||
List<XRDisplaySubsystem> displaySubsystems = new List<XRDisplaySubsystem>();
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
SubsystemManager.GetSubsystems(displaySubsystems);
|
||||
#else
|
||||
SubsystemManager.GetInstances(displaySubsystems);
|
||||
#endif
|
||||
if (displaySubsystems.Count > 0)
|
||||
{
|
||||
s_DisplaySubsystem = displaySubsystems[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (null == s_DisplaySubsystem)
|
||||
return;
|
||||
|
||||
|
||||
s_DisplaySubsystem.MarkTransformLateLatched(m_LateLatchingCamera.transform, XRDisplaySubsystem.LateLatchNode.Head);
|
||||
|
||||
}
|
||||
|
||||
#if !UNITY_EDITOR && UNITY_2021_2_OR_NEWER
|
||||
private void OnPreRender()
|
||||
{
|
||||
s_DisplaySubsystem.BeginRecordingIfLateLatched(m_LateLatchingCamera);
|
||||
}
|
||||
|
||||
private void OnPostRender()
|
||||
{
|
||||
s_DisplaySubsystem.EndRecordingIfLateLatched(m_LateLatchingCamera);
|
||||
}
|
||||
#endif
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0d77cf58f760874892e934648a878f2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d6132037afd3fe4abfa4282efd18bd4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,762 @@
|
||||
/*******************************************************************************
|
||||
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;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
|
||||
|
||||
public class PXR_MotionTracking
|
||||
{
|
||||
#region Eye Tracking
|
||||
//Eye Tracking
|
||||
public const int PXR_EYE_TRACKING_API_VERSION = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Wants eye tracking service for the current app.
|
||||
/// </summary>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
[Obsolete("WantEyeTrackingService is not supported..", true)]
|
||||
public static int WantEyeTrackingService()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the current device supports eye tracking.
|
||||
/// </summary>
|
||||
/// <param name="supported">
|
||||
/// Returns a bool indicating whether eye tracking is supported:
|
||||
/// * `true`: supported
|
||||
/// * `false`: not supported
|
||||
/// </param>
|
||||
/// <param name="supportedModesCount">
|
||||
/// Returns the number of eye tracking modes supported by the current device.
|
||||
/// </param>
|
||||
/// <param name="supportedModes">
|
||||
/// Returns the eye tracking modes supported by the current device.
|
||||
/// </param>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
public static int GetEyeTrackingSupported(ref bool supported, ref int supportedModesCount, ref EyeTrackingMode[] supportedModes)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_GetEyeTrackingSupported(ref supported, ref supportedModesCount, ref supportedModes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts eye tracking.
|
||||
/// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
|
||||
/// </summary>
|
||||
/// <param name="startInfo">Passes the information for starting eye tracking.
|
||||
/// </param>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
public static int StartEyeTracking(ref EyeTrackingStartInfo startInfo)
|
||||
{
|
||||
startInfo.SetVersion(PXR_EYE_TRACKING_API_VERSION);
|
||||
return PXR_Plugin.MotionTracking.UPxr_StartEyeTracking1(ref startInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops eye tracking.
|
||||
/// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
|
||||
/// </summary>
|
||||
/// <param name="stopInfo">Passes the information for stopping eye tracking. Currently, you do not need to pass anything.</param>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
public static int StopEyeTracking(ref EyeTrackingStopInfo stopInfo)
|
||||
{
|
||||
stopInfo.SetVersion(PXR_EYE_TRACKING_API_VERSION);
|
||||
return PXR_Plugin.MotionTracking.UPxr_StopEyeTracking1(ref stopInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the state of eye tracking.
|
||||
/// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
|
||||
/// </summary>
|
||||
/// <param name="isTracking">Returns a bool that indicates whether eye tracking is working:
|
||||
/// * `true`: eye tracking is working
|
||||
/// * `false`: eye tracking has been stopped
|
||||
/// </param>
|
||||
/// <param name="state">Returns the eye tracking state information, including the eye tracking mode and eye tracking state code.</param>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
public static int GetEyeTrackingState(ref bool isTracking, ref EyeTrackingState state)
|
||||
{
|
||||
state.SetVersion(PXR_EYE_TRACKING_API_VERSION);
|
||||
return PXR_Plugin.MotionTracking.UPxr_GetEyeTrackingState(ref isTracking, ref state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets eye tracking data.
|
||||
/// @note Only supported by PICO Neo3 Pro Eye, PICO 4 Pro, and PICO 4 Enterprise.
|
||||
/// </summary>
|
||||
/// <param name="getInfo">Specifies the eye tracking data you want.</param>
|
||||
/// <param name="data">Returns the desired eye tracking data.</param>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
public static int GetEyeTrackingData(ref EyeTrackingDataGetInfo getInfo, ref EyeTrackingData data)
|
||||
{
|
||||
getInfo.SetVersion(PXR_EYE_TRACKING_API_VERSION);
|
||||
data.SetVersion(PXR_EYE_TRACKING_API_VERSION);
|
||||
return PXR_Plugin.MotionTracking.UPxr_GetEyeTrackingData1(ref getInfo, ref data);
|
||||
}
|
||||
|
||||
//PICO4E
|
||||
/// <summary>
|
||||
/// Gets the opennesses of the left and right eyes.
|
||||
/// @note
|
||||
/// - Only supported by PICO 4 Enterprise.
|
||||
/// - To use this API, you need to add `<meta-data android:name="pvr.app.et_tob_advance" android:value="true"/>` to the app's AndroidManifest.xml file.
|
||||
/// </summary>
|
||||
/// <param name="leftEyeOpenness">The openness of the left eye, which is a float value ranges from `0.0` to `1.0`. `0.0` indicates completely closed, `1.0` indicates completely open.</param>
|
||||
/// <param name="rightEyeOpenness">The openness of the right eye, which is a float value ranges from `0.0` to `1.0`. `0.0` indicates completely closed, `1.0` indicates completely open.</param>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
public static int GetEyeOpenness(ref float leftEyeOpenness, ref float rightEyeOpenness)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_GetEyeOpenness(ref leftEyeOpenness, ref rightEyeOpenness);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the information about the pupils of both eyes.
|
||||
/// @note
|
||||
/// - Only supported by PICO 4 Enterprise.
|
||||
/// - To use this API, you need to add `<meta-data android:name="pvr.app.et_tob_advance" android:value="true"/>` to the app's AndroidManifest.xml file.
|
||||
/// </summary>
|
||||
/// <param name="eyePupilPosition">Returns the diameters and positions of both pupils.</param>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
public static int GetEyePupilInfo(ref EyePupilInfo eyePupilPosition)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_GetEyePupilInfo(ref eyePupilPosition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pose of the left and right eyes.
|
||||
/// @note
|
||||
/// - Only supported by PICO 4 Enterprise.
|
||||
/// - To use this API, you need to add `<meta-data android:name="pvr.app.et_tob_advance" android:value="true"/>` to the app's AndroidManifest.xml file.
|
||||
/// </summary>
|
||||
/// <param name="timestamp">Returns the timestamp (unit: nanosecond) of the eye pose information.</param>
|
||||
/// <param name="leftEyePose">Returns the position and rotation of the left eye.</param>
|
||||
/// <param name="rightPose">Returns the position and rotation of the right eye.</param>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
public static int GetPerEyePose(ref long timestamp, ref Posef leftEyePose, ref Posef rightPose)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_GetPerEyePose(ref timestamp, ref leftEyePose, ref rightPose);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the left and right eyes blinked.
|
||||
/// @note
|
||||
/// - Only supported by PICO 4 Enterprise.
|
||||
/// - To use this API, you need to add `<meta-data android:name="pvr.app.et_tob_advance" android:value="true"/>` to the app's AndroidManifest.xml file.
|
||||
/// </summary>
|
||||
/// <param name="timestamp">Returns the timestamp (in nanoseconds) of the eye blink information.</param>
|
||||
/// <param name="isLeftBlink">Returns whether the left eye blinked:
|
||||
/// - `true`: blinked (the user's left eye is closed, which will usually open again immediately to generate a blink event)
|
||||
/// - `false`: didn't blink (the user's left eye is open)
|
||||
/// </param>
|
||||
/// <param name="isRightBlink">Returns whether the right eye blined:
|
||||
/// - `true`: blinked (the user's right eye is closed, which will usually open again immediately to generate a blink event)
|
||||
/// - `false`: didn't blink (the user's right eye is open)
|
||||
/// </param>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
public static int GetEyeBlink(ref long timestamp, ref bool isLeftBlink, ref bool isRightBlink)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_GetEyeBlink(ref timestamp, ref isLeftBlink, ref isRightBlink);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Face Tracking
|
||||
//Face Tracking
|
||||
public const int PXR_FACE_TRACKING_API_VERSION = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Wants face tracking service for the current app.
|
||||
/// </summary>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
[Obsolete("WantFaceTrackingService is not supported..", true)]
|
||||
public static int WantFaceTrackingService()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the current device supports face tracking.
|
||||
/// </summary>
|
||||
/// <param name="supported">Indicates whether the device supports face tracking:
|
||||
/// * `true`: support
|
||||
/// * `false`: not support
|
||||
/// </param>
|
||||
/// <param name="supportedModesCount">Returns the total number of face tracking modes supported by the device.</param>
|
||||
/// <param name="supportedModes">Returns the specific face tracking modes supported by the device.</param>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
[Obsolete("GetFaceTrackingSupported is not supported..", true)]
|
||||
public static unsafe int GetFaceTrackingSupported(ref bool supported, ref int supportedModesCount, ref FaceTrackingMode[] supportedModes)
|
||||
{
|
||||
// return PXR_Plugin.MotionTracking.UPxr_GetFaceTrackingSupported(ref supported, ref supportedModesCount, ref supportedModes);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts face tracking.
|
||||
/// @note Supported by PICO 4 Pro and PICO 4 Enterprise.
|
||||
/// </summary>
|
||||
/// <param name="startInfo">Passes the information for starting face tracking.</param>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
[Obsolete("StartFaceTracking is not supported..", true)]
|
||||
public static int StartFaceTracking(ref FaceTrackingStartInfo startInfo)
|
||||
{
|
||||
// startInfo.SetVersion(PXR_FACE_TRACKING_API_VERSION);
|
||||
// return PXR_Plugin.MotionTracking.UPxr_StartFaceTracking(ref startInfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops face tracking.
|
||||
/// @note Supported by PICO 4 Pro and PICO 4 Enterprise.
|
||||
/// </summary>
|
||||
/// <param name="stopInfo">Passes the information for stopping face tracking.</param>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
[Obsolete("StopFaceTracking is not supported..", true)]
|
||||
public static int StopFaceTracking(ref FaceTrackingStopInfo stopInfo)
|
||||
{
|
||||
// stopInfo.SetVersion(PXR_FACE_TRACKING_API_VERSION);
|
||||
// return PXR_Plugin.MotionTracking.UPxr_StopFaceTracking(ref stopInfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the state of face tracking.
|
||||
/// @note Supported by PICO 4 Pro and PICO 4 Enterprise.
|
||||
/// </summary>
|
||||
/// <param name="isTracking">Returns a bool indicating whether face tracking is working:
|
||||
/// * `true`: face tracking is working
|
||||
/// * `false`: face tracking has been stopped
|
||||
/// </param>
|
||||
/// <param name="state">Returns the state of face tracking, including the face tracking mode and face tracking state code.
|
||||
/// </param>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
[Obsolete("GetFaceTrackingState is not supported..", true)]
|
||||
public static int GetFaceTrackingState(ref bool isTracking, ref FaceTrackingState state)
|
||||
{
|
||||
// state.SetVersion(PXR_FACE_TRACKING_API_VERSION);
|
||||
// return PXR_Plugin.MotionTracking.UPxr_GetFaceTrackingState(ref isTracking, ref state);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets face tracking data.
|
||||
/// @note Supported by PICO 4 Pro and PICO 4 Enterprise.
|
||||
/// </summary>
|
||||
/// <param name="getInfo">Specifies the face tracking data you want.</param>
|
||||
/// <param name="data">Returns the desired face tracking data.</param>
|
||||
/// <returns>Returns `0` for success and other values for failure.</returns>
|
||||
[Obsolete("GetFaceTrackingData is not supported..", true)]
|
||||
public static int GetFaceTrackingData(ref FaceTrackingDataGetInfo getInfo, ref FaceTrackingData data)
|
||||
{
|
||||
// getInfo.SetVersion(PXR_FACE_TRACKING_API_VERSION);
|
||||
// data.SetVersion(PXR_FACE_TRACKING_API_VERSION);
|
||||
// return PXR_Plugin.MotionTracking.UPxr_GetFaceTrackingData1(ref getInfo, ref data);
|
||||
return -1;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Body Tracking
|
||||
/// <summary>
|
||||
/// A callback function that notifies calibration exceptions.
|
||||
/// The user then needs to recalibrate with PICO Motion Tracker.
|
||||
/// </summary>
|
||||
[Obsolete("BodyTrackingAbnormalCalibrationData is not supported..", true)]
|
||||
public static Action<int, int> BodyTrackingAbnormalCalibrationData;
|
||||
|
||||
/// <summary>You can use this callback function to receive the status code and error code for body tracking.</summary>
|
||||
/// <returns>
|
||||
/// - `BodyTrackingStatusCode`: The status code.
|
||||
/// - `BodyTrackingErrorCode`: The error code.
|
||||
/// </returns>
|
||||
[Obsolete("BodyTrackingStateError is not supported..", true)]
|
||||
public static Action<BodyTrackingStatusCode, BodyTrackingErrorCode> BodyTrackingStateError;
|
||||
|
||||
/// <summary>You can use this callback function to get notified when the action status of a tracked bone node changes.</summary>
|
||||
/// <returns>
|
||||
/// - `int`: Returns the bone No., and only `7` (`LEFT_ANKLE`) and `8` (`RIGHT_ANKLE`) are available currently. You can use the change of the status of the left and right ankles to get the foot-down action of the left and right feet.
|
||||
/// - `BodyActionList`: Receiving the `PxrFootDownAction` event indicates that the left and/or right foot has stepped on the floor.
|
||||
/// </returns>
|
||||
[Obsolete("BodyTrackingAction is not supported..", true)]
|
||||
public static Action<int, BodyActionList> BodyTrackingAction;
|
||||
|
||||
/// <summary>Launches the PICO Motion Tracker app to perform calibration.
|
||||
/// - For PICO Motion Tracker (Beta), the user needs to follow the instructions on the home of the PICO Motion Tracker app to complete calibration.
|
||||
/// - For PICO Motion Tracker (Official), "single-glance calibration" will be performed. When a user has a glance at the PICO Motion Tracker on their lower legs, calibration is completed.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
public static int StartMotionTrackerCalibApp()
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_StartMotionTrackerCalibApp();
|
||||
}
|
||||
|
||||
/// <summary>Gets whether the current device supports body tracking.</summary>
|
||||
/// <param name="supported">Returns whether the current device supports body tracking:
|
||||
/// - `true`: support
|
||||
/// - `false`: not support
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
public static int GetBodyTrackingSupported(ref bool supported)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_GetBodyTrackingSupported(ref supported);
|
||||
}
|
||||
|
||||
/// <summary>Starts body tracking.</summary>
|
||||
/// <param name="mode">Specifies the body tracking mode (default or high-accuracy).</param>
|
||||
/// <param name="boneLength">Specifies lengths (unit: cm) for the bones of the avatar, which is only available for the `BTM_FULL_BODY_HIGH` mode.
|
||||
/// Bones that are not set lengths for will use the default values.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Please use StartBodyTracking(BodyJointSet JointSet, BodyTrackingBoneLength boneLength)")]
|
||||
public static int StartBodyTracking(BodyTrackingMode mode, BodyTrackingBoneLength boneLength)
|
||||
{
|
||||
return StartBodyTracking(BodyJointSet.BODY_JOINT_SET_BODY_FULL_START,boneLength);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// >Starts body tracking.
|
||||
/// </summary>
|
||||
/// <param name="JointSet">Specifies the set of body joints to be tracked.</param>
|
||||
/// <param name="boneLength">Specifies lengths (unit: cm) for the bones of the avatar. Bones that are not set lengths for will use the default values.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
public static int StartBodyTracking(BodyJointSet JointSet, BodyTrackingBoneLength boneLength)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_StartBodyTracking(JointSet,boneLength);
|
||||
}
|
||||
|
||||
/// <summary>Stops body tracking.</summary>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
public static int StopBodyTracking()
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_StopBodyTracking();
|
||||
}
|
||||
|
||||
/// <summary>Gets the state of PICO Motion Tracker and, if any, the reason for an exception.</summary>
|
||||
/// <param name="isTracking">Indicates whether the PICO Motion Tracker is tracking normally:
|
||||
/// - `true`: is tracking
|
||||
/// - `false`: tracking lost
|
||||
/// </param>
|
||||
/// <param name="state">Returns the information about body tracking state.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Please use GetBodyTrackingState(ref bool isTracking, ref BodyTrackingStatus state)")]
|
||||
public static int GetBodyTrackingState(ref bool isTracking, ref BodyTrackingState state)
|
||||
{
|
||||
BodyTrackingStatus bs2 = new BodyTrackingStatus();
|
||||
int ret = GetBodyTrackingState(ref isTracking, ref bs2);
|
||||
state.stateCode=bs2.stateCode;
|
||||
state.errorCode=(BodyTrackingErrorCode)bs2.message;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// >Gets the state of body tracking.
|
||||
/// </summary>
|
||||
/// <param name="isTracking">Indicates whether the PICO Motion Tracker is tracking the body normally:
|
||||
/// - `true`: is tracking
|
||||
/// - `false`: tracking lost
|
||||
/// </param>
|
||||
/// <param name="state">Returns the current status of body tracking.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
public static int GetBodyTrackingState(ref bool isTracking, ref BodyTrackingStatus state)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_GetBodyTrackingState(ref isTracking, ref state);
|
||||
}
|
||||
|
||||
/// <summary>Gets body tracking data.</summary>
|
||||
/// <param name="getInfo"> Specifies the display time and the data filtering flags.
|
||||
/// For the display time, for example, when it is set to 0.1 second, it means predicting the pose of the tracked node 0.1 seconds ahead.
|
||||
/// </param>
|
||||
/// <param name="data">Returns the array of data for all tracked nodes.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
public static int GetBodyTrackingData(ref BodyTrackingGetDataInfo getInfo, ref BodyTrackingData data)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_GetBodyTrackingData(ref getInfo, ref data);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Motion Tracker
|
||||
//Motion Tracker
|
||||
|
||||
/// <summary>
|
||||
/// You can use this callback function to get notified when the connection state of PICO Motion Tracker changes.
|
||||
/// For connection status, `0` indicates "disconnected" and `1` indicates "connected".
|
||||
/// </summary>
|
||||
[Obsolete("Deprecated",true)]
|
||||
public static Action<int, int> MotionTrackerNumberOfConnections;
|
||||
|
||||
/// <summary>
|
||||
/// You can use this callback function to get notified when the battery level of PICO Motion Tracker changes.
|
||||
/// </summary>
|
||||
/// <Returns>
|
||||
/// The ID and battery level of the PICO Motion Tracker.
|
||||
/// - For PICO Motion Tracker (Beta), the value range of battery level is [0,5].
|
||||
/// `0` indicates a low battery, which can affect the tracking accuracy.
|
||||
/// </returns>
|
||||
[Obsolete("Deprecated",true)]
|
||||
public static Action<int, int> MotionTrackerBatteryLevel;
|
||||
|
||||
/// <summary>
|
||||
/// You can use this callback function to get the key actions of the motion tracker.
|
||||
/// </summary>
|
||||
[Obsolete("Deprecated",true)]
|
||||
public static Action<MotionTrackerEventData> MotionTrackerKeyAction;
|
||||
|
||||
/// <summary>
|
||||
/// You can use this callback function to get notified if the tracking mode changes.
|
||||
/// - `0`: body tracking
|
||||
/// - `1`: object tracking
|
||||
/// </summary>
|
||||
[Obsolete("Deprecated",true)]
|
||||
public static Action<MotionTrackerMode> MotionTrackingModeChangedAction;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// You can use the callback function to whether if PICO Motion Trackers are successfully connected to your PICO headset.
|
||||
/// </summary>
|
||||
public static Action<RequestMotionTrackerCompleteEventData> RequestMotionTrackerCompleteAction;
|
||||
/// <summary>
|
||||
/// You can use this callback function to be notified when the connection state of PICO Motion Tracker changes.
|
||||
/// </summary>
|
||||
public static Action<long, int> MotionTrackerConnectionAction;
|
||||
/// <summary>
|
||||
/// You can use this callback function to receive events for the Power key of PICO Motion Trackers.
|
||||
/// </summary>
|
||||
public static Action<long, bool> MotionTrackerPowerKeyAction;
|
||||
|
||||
|
||||
/// <summary>Gets the number of trackers currently connected and their serial numbers.</summary>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Deprecated.Please use MotionTrackerConnectionAction instead", true)]
|
||||
public static int GetMotionTrackerConnectStateWithSN(ref MotionTrackerConnectState connectState)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>Gets the type of the PICO Motion Tracker connected.</summary>
|
||||
/// <returns>The type of the motion tracker (beta or official).</summary>
|
||||
[Obsolete("Deprecated",true)]
|
||||
public static MotionTrackerType GetMotionTrackerDeviceType()
|
||||
{
|
||||
return MotionTrackerType.MT_2;
|
||||
}
|
||||
|
||||
/// <summary>Checks whether the current tracking mode and the number of motion trackers connected are as wanted.
|
||||
/// If not, a panel will appear to let the user switch the tracking mode and perform calibration accordingly.</summary>
|
||||
/// <param name="mode">Specifies the wanted tracking mode.</summary>
|
||||
/// <param name="number">Specifies the expected number of motion trackers. Value range: [0,3].
|
||||
/// - If you set `mode` to `BodyTracking`, you do not need to set this parameter as it will not work even if you set it.
|
||||
/// - If you set `mode` to `MotionTracking`, the default value of this parameter will be 0, and you can select a value from range [0,3].</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Deprecated.Please use CheckMotionTrackerNumber instead")]
|
||||
public static int CheckMotionTrackerModeAndNumber(MotionTrackerMode mode, MotionTrackerNum number = MotionTrackerNum.ONE)
|
||||
{
|
||||
return CheckMotionTrackerNumber(number);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the current tracking mode and the number of motion trackers connected are as expected.
|
||||
/// If not, a panel will appear to let the user switch the tracking mode and perform calibration accordingly.
|
||||
/// </summary>
|
||||
/// <param name="number">Specifies the expected number of motion trackers. Value range: [0,3]. You can get the result from callback `RequestMotionTrackerCompleteAction`.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
public static int CheckMotionTrackerNumber(MotionTrackerNum number)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_CheckMotionTrackerNumber((int)number);
|
||||
}
|
||||
|
||||
/// <summary>Gets the current tracking mode of the PICO Motion Tracker connected.</summary>
|
||||
/// <returns>The current tracking mode.</summary>
|
||||
[Obsolete("Deprecated")]
|
||||
public static MotionTrackerMode GetMotionTrackerMode()
|
||||
{
|
||||
return MotionTrackerMode.MotionTracking;
|
||||
}
|
||||
|
||||
/// <summary>Gets the location of a PICO Motion Tracker which is set to the "motion tracking" mode.</summary>
|
||||
/// <param name="trackerSN">Specifies the serial number of the motion tracker to get position for. You can pass only one serial number in one request.</param>
|
||||
/// <param name="locations">Returns the location of the specified motion tracker.</param>
|
||||
/// <param name="confidence">Returns the confidence of the returned data.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Deprecated.Please use GetMotionTrackerLocation instead",true)]
|
||||
public static int GetMotionTrackerLocations(TrackerSN trackerSN, ref MotionTrackerLocations locations, ref MotionTrackerConfidence confidence, double predictTime = 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the location of a PICO Motion Tracker which is set to the "motion tracking" mode.
|
||||
/// </summary>
|
||||
/// <param name="trackerid">Specifies the serial number of the motion tracker to get position for. You can pass only one serial number in one request.</param>
|
||||
/// <param name="location">Returns the location of the specified motion tracker.</param>
|
||||
/// <param name="isValidPose">Whether the returned pose data is valid:
|
||||
/// - `true`: valid
|
||||
/// - `false`: invalid
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
public static int GetMotionTrackerLocation(long trackerid,ref MotionTrackerLocation location,ref bool isValidPose)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_GetMotionTrackerLocation(trackerid, ref location, ref isValidPose);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the battery of a PICO Motion Tracker.
|
||||
/// </summary>
|
||||
/// <param name="trackerid">Specifies the serial number of the motion tracker to get battery for.</param>
|
||||
/// <param name="battery">Returns the battery of the motion tracker. Value range: [0,1]. The higher the value, the higher the current battery.</param>
|
||||
/// <param name="charger">Returns the charging status of the motion tracker.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
public static int GetMotionTrackerBattery(long trackerid,ref float battery, ref XrBatteryChargingState charger)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_GetMotionTrackerBatteryState(trackerid, ref battery, ref charger);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Motion Tracker For External Device
|
||||
/// <summary>You can use this callback function to get notified when the connection state of the external device changes.</summary>
|
||||
/// <returns>The connection state of the external device.</returns>
|
||||
[Obsolete("Deprecated.Please use ExpandDeviceConnectionAction instead",true)]
|
||||
public static Action<ExtDevConnectEventData> ExtDevConnectAction;
|
||||
|
||||
/// <summary>You can use this callback function to get notified when the battery level and charging status of the external device changes.</summary>
|
||||
/// <returns>The current better level and charging status of the external device.</returns>
|
||||
[Obsolete("Deprecated.Please use ExpandDeviceBatteryAction instead",true)]
|
||||
public static Action<ExtDevBatteryEventData> ExtDevBatteryAction;
|
||||
|
||||
/// <summary>
|
||||
/// You need to listen for this event to call the `GetExtDevTrackerByPassData` API:
|
||||
/// - When receiving `1`, it is necessary to call the `PXR_GetExtDevTrackerByPassData` API to obtain the data passed through.
|
||||
/// - When receiving `0`, stop obtaining the data passed through.
|
||||
/// </summary>
|
||||
public static Action<int> ExtDevPassDataAction;
|
||||
|
||||
/// <summary>You can use this callback function to get notified when the state of the connection between the PICO Motion Tracker and an external device changes.</summary>
|
||||
/// <returns>The series number of the motion tracker connected to the external device and the connection state (`0`: disconnected; `1`: connected).</returns>
|
||||
public static Action<long, int> ExpandDeviceConnectionAction;
|
||||
|
||||
/// <summary>You can use this callback function to get notified when the battery level and charging status of the external device changes.</summary>
|
||||
/// <returns>The current better level and charging status of the external device.</returns>
|
||||
public static Action<ExpandDeviceBatteryEventData> ExpandDeviceBatteryAction;
|
||||
|
||||
/// <summary>Gets the connection state of the external device.</summary>
|
||||
/// <param name="connectState">Returns the connection state of the external device.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Deprecated.Please use ExpandDeviceConnectionAction instead",true)]
|
||||
public static int GetExtDevTrackerConnectState(ref ExtDevTrackerConnectState connectState)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>Sets vibration for the external device.</summary>
|
||||
/// <param name="motorVibrate">Specifies vibration settings.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Deprecated.Please use SetExpandDeviceVibrate instead",true)]
|
||||
public static int SetExtDevTrackerMotorVibrate(ref ExtDevTrackerMotorVibrate motorVibrate)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>Sets the state for data passthrough-related APIs.</summary>
|
||||
/// <param name="state">Specifies the state of data passthrough-related APIs according to actual needs:
|
||||
/// Before calling `SetExpandDeviceCustomData` and `GetExpandDeviceCustomData`, set `state` to `true` to enable these APIs, or set `state` to `false` to disable these APIs.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
public static int SetExtDevTrackerPassDataState(bool state)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_SetExpandDeviceCustomDataCapability(state);
|
||||
}
|
||||
|
||||
/// <summary>Sets data passthrough for the external device. The protocol is defined by yourself according to your own hardware.
|
||||
/// There is no correspondence between the `set` and `get`-related methods themselves.</summary>
|
||||
/// <param name="passData">When PICO SDK's APIs are unable to meet your needs, you can define custom protocols and place them in the `passData` parameter.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Deprecated.Please use SetExpandDeviceCustomData instead",true)]
|
||||
public static int SetExtDevTrackerByPassData(ref ExtDevTrackerPassData passData)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>Gets the data passed through for an external device.</summary>
|
||||
/// <param name="passData">Returns the details of the data passed through.</param>
|
||||
/// <param name="realLength">Returns the number of `passData` arrays filled by the underlying layer.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Deprecated.Please use GetExpandDeviceCustomData instead",true)]
|
||||
public static int GetExtDevTrackerByPassData(ref ExtDevTrackerPassDataArray passData, ref int realLength)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>Gets the battery level of the external device.</summary>
|
||||
/// <param name="trackerSN">Specifies the serial number of the external device the get battery level for.</param>
|
||||
/// <param name="battery">Returns the current battery level of the external device. Value range: [0,10].</param>
|
||||
/// <param name="charger">Returns whether the external device is charging:
|
||||
/// - `0`: not charging
|
||||
/// - `1`: charging
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Deprecated.Please use GetExpandDeviceBattery instead",true)]
|
||||
public static int GetExtDevTrackerBattery(ref TrackerSN trackerSN, ref int battery, ref int charger)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>Gets the key values of the external device.</summary>
|
||||
/// <param name="trackerSN">Specifies the serial number of the external device to get key values for.</param>
|
||||
/// <param name="keyData">Returns the key values of the specified external device.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("Deprecated",true)]
|
||||
public static int GetExtDevTrackerKeyData(ref TrackerSN trackerSN, ref ExtDevTrackerKeyData keyData)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets vibration for the external device. The vibration command is passed to the external device via the PICO Motion Tracker connected to it.
|
||||
/// </summary>
|
||||
/// <param name="deviceid">Specifies the serial number of the external device.</param>
|
||||
/// <param name="motorVibrate">Specifies vibration settings.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
public static int SetExpandDeviceVibrate(long deviceid, ExpandDeviceVibrate motorVibrate)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_SetExpandDeviceVibrate(deviceid, motorVibrate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the array of serial numbers of the external devices connected to PICO Motion Trackers.
|
||||
/// </summary>
|
||||
/// <param name="deviceArray">Returns the array of serial numbers.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
public static int GetExpandDevice(out long[] deviceArray)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_GetExpandDevice(out deviceArray);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the battery level of the external device.
|
||||
/// </summary>
|
||||
/// <param name="deviceid">Specifies the serial number of the external device to get battery level for.</param>
|
||||
/// <param name="battery">Returns the current battery level of the external device. Value range: [0,1]. The higher the value, the higher the battery.</param>
|
||||
/// <param name="charger">Returns the charging status of the external device.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
public static int GetExpandDeviceBattery(long deviceid, ref float battery, ref XrBatteryChargingState charger)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_GetExpandDeviceBattery(deviceid, ref battery, ref charger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data passed from external devices.
|
||||
/// </summary>
|
||||
/// <param name="dataArray">Returns the array of data passed from external devices.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
public static int GetExpandDeviceCustomData(out List<ExpandDevicesCustomData> dataArray)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_GetExpandDeviceCustomData(out dataArray);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the data to be passed to external devices. The protocol is defined by yourself according to your own hardware.
|
||||
/// </summary>
|
||||
/// <param name="dataArray">Specifies the array of data to be passed to external devices.</param>
|
||||
/// <returns>
|
||||
/// - `0`: success
|
||||
/// - `1`: failure
|
||||
/// </returns>
|
||||
public static int SetExpandDeviceCustomData(ref ExpandDevicesCustomData[] dataArray)
|
||||
{
|
||||
return PXR_Plugin.MotionTracking.UPxr_SetExpandDeviceCustomData(ref dataArray);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 575693a8c0449a04f82b773bf343dcef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,861 @@
|
||||
/*******************************************************************************
|
||||
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;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.XR;
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
[Obsolete("PXR_OverLay is obsolete and will be removed in the next version. Please use PXR_CompositionLayer instead.", false)]
|
||||
public class PXR_OverLay : MonoBehaviour, IComparable<PXR_OverLay>
|
||||
{
|
||||
private const string TAG = "[PXR_CompositeLayers]";
|
||||
public static List<PXR_OverLay> Instances = new List<PXR_OverLay>();
|
||||
|
||||
[NonSerialized]
|
||||
public int overlayIndex;
|
||||
public int layerDepth;
|
||||
public int imageIndex = 0;
|
||||
public OverlayType overlayType = OverlayType.Overlay;
|
||||
public OverlayShape overlayShape = OverlayShape.Quad;
|
||||
public TextureType textureType = TextureType.ExternalSurface;
|
||||
public Transform overlayTransform;
|
||||
public Camera xrRig;
|
||||
|
||||
public Texture[] layerTextures = new Texture[2] { null, null };
|
||||
|
||||
public bool isPremultipliedAlpha = false;
|
||||
public bool isDynamic = false;
|
||||
public int[] overlayTextureIds = new int[2];
|
||||
public Matrix4x4[] mvMatrixs = new Matrix4x4[2];
|
||||
public Vector3[] modelScales = new Vector3[2];
|
||||
public Quaternion[] modelRotations = new Quaternion[2];
|
||||
public Vector3[] modelTranslations = new Vector3[2];
|
||||
public Quaternion[] cameraRotations = new Quaternion[2];
|
||||
public Vector3[] cameraTranslations = new Vector3[2];
|
||||
public Camera[] overlayEyeCamera = new Camera[2];
|
||||
|
||||
public bool overrideColorScaleAndOffset = false;
|
||||
public Vector4 colorScale = Vector4.one;
|
||||
public Vector4 colorOffset = Vector4.zero;
|
||||
|
||||
// Eac
|
||||
public Vector3 offsetPosLeft = Vector3.zero;
|
||||
public Vector3 offsetPosRight = Vector3.zero;
|
||||
public Vector4 offsetRotLeft = new Vector4(0, 0, 0, 1);
|
||||
public Vector4 offsetRotRight = new Vector4(0, 0, 0, 1);
|
||||
public EACModelType eacModelType = EACModelType.Eac360;
|
||||
public float overlapFactor = 1.0f;
|
||||
public ulong timestamp = 0;
|
||||
|
||||
private Vector4 overlayLayerColorScaleDefault = Vector4.one;
|
||||
private Vector4 overlayLayerColorOffsetDefault = Vector4.zero;
|
||||
|
||||
public bool isExternalAndroidSurface = false;
|
||||
public bool isExternalAndroidSurfaceDRM = false;
|
||||
public Surface3DType externalAndroidSurface3DType = Surface3DType.Single;
|
||||
|
||||
#region Blurred Quad
|
||||
public BlurredQuadMode blurredQuadMode = BlurredQuadMode.SmallWindow;
|
||||
|
||||
public float blurredQuadScale = 0.5f;
|
||||
public float blurredQuadShift = 0.01f;
|
||||
public float blurredQuadFOV = 61.05f;
|
||||
public float blurredQuadIPD = 0.064f;
|
||||
#endregion
|
||||
|
||||
public IntPtr externalAndroidSurfaceObject = IntPtr.Zero;
|
||||
public delegate void ExternalAndroidSurfaceObjectCreated();
|
||||
public ExternalAndroidSurfaceObjectCreated externalAndroidSurfaceObjectCreated = null;
|
||||
|
||||
// 360
|
||||
public float radius = 0; // >0
|
||||
|
||||
// ImageRect
|
||||
public bool useImageRect = false;
|
||||
public TextureRect textureRect = TextureRect.StereoScopic;
|
||||
public DestinationRect destinationRect = DestinationRect.Default;
|
||||
public Rect srcRectLeft = new Rect(0, 0, 1, 1);
|
||||
public Rect srcRectRight = new Rect(0, 0, 1, 1);
|
||||
public Rect dstRectLeft = new Rect(0, 0, 1, 1);
|
||||
public Rect dstRectRight = new Rect(0, 0, 1, 1);
|
||||
|
||||
public PxrRecti imageRectLeft;
|
||||
public PxrRecti imageRectRight;
|
||||
|
||||
|
||||
// LayerBlend
|
||||
public bool useLayerBlend = false;
|
||||
public PxrBlendFactor srcColor = PxrBlendFactor.PxrBlendFactorOne;
|
||||
public PxrBlendFactor dstColor = PxrBlendFactor.PxrBlendFactorOne;
|
||||
public PxrBlendFactor srcAlpha = PxrBlendFactor.PxrBlendFactorOne;
|
||||
public PxrBlendFactor dstAlpha = PxrBlendFactor.PxrBlendFactorOne;
|
||||
public float[] colorMatrix = new float[18] {
|
||||
1,0,0, // left
|
||||
0,1,0,
|
||||
0,0,1,
|
||||
1,0,0, // right
|
||||
0,1,0,
|
||||
0,0,1,
|
||||
};
|
||||
|
||||
public bool isClones = false;
|
||||
public bool isClonesToNew = false;
|
||||
|
||||
public bool enableSubmitLayer = true;
|
||||
public PXR_OverLay originalOverLay;
|
||||
public IntPtr layerSubmitPtr = IntPtr.Zero;
|
||||
|
||||
[HideInInspector]
|
||||
public SuperSamplingMode supersamplingMode = SuperSamplingMode.None;
|
||||
[HideInInspector]
|
||||
public SuperSamplingEnhance supersamplingEnhance = SuperSamplingEnhance.None;
|
||||
|
||||
[HideInInspector]
|
||||
public SharpeningMode sharpeningMode = SharpeningMode.None;
|
||||
[HideInInspector]
|
||||
public SharpeningEnhance sharpeningEnhance = SharpeningEnhance.None;
|
||||
//Super Resolution
|
||||
public bool superResolution;
|
||||
public bool normalSupersampling;
|
||||
public bool qualitySupersampling;
|
||||
public bool fixedFoveatedSupersampling;
|
||||
public bool normalSharpening;
|
||||
public bool qualitySharpening;
|
||||
public bool fixedFoveatedSharpening;
|
||||
public bool selfAdaptiveSharpening;
|
||||
|
||||
|
||||
private bool toCreateSwapChain = false;
|
||||
private bool toCopyRT = false;
|
||||
private bool copiedRT = false;
|
||||
private int eyeCount = 2;
|
||||
private UInt32 imageCounts = 0;
|
||||
private PxrLayerParam overlayParam = new PxrLayerParam();
|
||||
private struct NativeTexture
|
||||
{
|
||||
public Texture[] textures;
|
||||
};
|
||||
private NativeTexture[] nativeTextures;
|
||||
private static Material cubeM;
|
||||
private IntPtr leftPtr = IntPtr.Zero;
|
||||
private IntPtr rightPtr = IntPtr.Zero;
|
||||
private static Material textureM;
|
||||
|
||||
public HDRFlags hdr = HDRFlags.None;
|
||||
|
||||
public int CompareTo(PXR_OverLay other)
|
||||
{
|
||||
return layerDepth.CompareTo(other.layerDepth);
|
||||
}
|
||||
|
||||
protected void Awake()
|
||||
{
|
||||
xrRig = Camera.main;
|
||||
Instances.Add(this);
|
||||
if (null == xrRig.gameObject.GetComponent<PXR_OverlayManager>())
|
||||
{
|
||||
xrRig.gameObject.AddComponent<PXR_OverlayManager>();
|
||||
}
|
||||
|
||||
overlayEyeCamera[0] = xrRig;
|
||||
overlayEyeCamera[1] = xrRig;
|
||||
|
||||
overlayTransform = GetComponent<Transform>();
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
if (overlayTransform != null)
|
||||
{
|
||||
MeshRenderer render = overlayTransform.GetComponent<MeshRenderer>();
|
||||
if (render != null)
|
||||
{
|
||||
render.enabled = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!isClones)
|
||||
{
|
||||
InitializeBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (isClones)
|
||||
{
|
||||
InitializeBuffer();
|
||||
}
|
||||
|
||||
if (PXR_Manager.Instance == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Camera[] cam = PXR_Manager.Instance.GetEyeCamera();
|
||||
if (cam[0] != null && cam[0].enabled)
|
||||
{
|
||||
RefreshCamera(cam[0], cam[0]);
|
||||
}
|
||||
else if (cam[1] != null && cam[2] != null)
|
||||
{
|
||||
RefreshCamera(cam[1], cam[2]);
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshCamera(Camera leftCamera, Camera rightCamera)
|
||||
{
|
||||
overlayEyeCamera[0] = leftCamera;
|
||||
overlayEyeCamera[1] = rightCamera;
|
||||
}
|
||||
|
||||
private void InitializeBuffer()
|
||||
{
|
||||
if (!isExternalAndroidSurface && !isClones)
|
||||
{
|
||||
if (null == layerTextures[0] && null == layerTextures[1])
|
||||
{
|
||||
PLog.e(TAG, " The left and right images are all empty!");
|
||||
return;
|
||||
}
|
||||
else if (null == layerTextures[0] && null != layerTextures[1])
|
||||
{
|
||||
layerTextures[0] = layerTextures[1];
|
||||
}
|
||||
else if (null != layerTextures[0] && null == layerTextures[1])
|
||||
{
|
||||
layerTextures[1] = layerTextures[0];
|
||||
}
|
||||
overlayParam.width = (uint)layerTextures[1].width;
|
||||
overlayParam.height = (uint)layerTextures[1].height;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayParam.width = 1024;
|
||||
overlayParam.height = 1024;
|
||||
}
|
||||
|
||||
PXR_CompositionLayer.overlayID++;
|
||||
overlayIndex = PXR_CompositionLayer.overlayID;
|
||||
overlayParam.layerId = overlayIndex;
|
||||
overlayParam.layerShape = (PXR_CompositionLayer.OverlayShape)(overlayShape == 0 ? OverlayShape.Quad : overlayShape);
|
||||
overlayParam.layerType = (PXR_CompositionLayer.OverlayType)overlayType;
|
||||
overlayParam.arraySize = 1;
|
||||
overlayParam.mipmapCount = 1;
|
||||
overlayParam.sampleCount = 1;
|
||||
overlayParam.layerFlags = 0;
|
||||
|
||||
if (OverlayShape.Cubemap == overlayShape)
|
||||
{
|
||||
overlayParam.faceCount = 6;
|
||||
if (cubeM == null)
|
||||
cubeM = new Material(Shader.Find("PXR_SDK/PXR_CubemapBlit"));
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayParam.faceCount = 1;
|
||||
if (textureM == null)
|
||||
textureM = new Material(Shader.Find("PXR_SDK/PXR_Texture2DBlit"));
|
||||
}
|
||||
|
||||
if (GraphicsDeviceType.Vulkan == SystemInfo.graphicsDeviceType)
|
||||
{
|
||||
if (ColorSpace.Linear == QualitySettings.activeColorSpace)
|
||||
{
|
||||
overlayParam.format = (UInt64)ColorForamt.VK_FORMAT_R8G8B8A8_SRGB;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayParam.format = (UInt64)ColorForamt.VK_FORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
if (OverlayShape.Cubemap == overlayShape)
|
||||
{
|
||||
cubeM.SetFloat("_Gamma", 2.2f);
|
||||
}
|
||||
else
|
||||
{
|
||||
textureM.SetFloat("_Gamma", 2.2f);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayParam.format = (UInt64)ColorForamt.GL_SRGB8_ALPHA8;
|
||||
}
|
||||
|
||||
if (isClones)
|
||||
{
|
||||
if (null != originalOverLay)
|
||||
{
|
||||
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlagSharedImagesBetweenLayers;
|
||||
leftPtr = Marshal.AllocHGlobal(Marshal.SizeOf(originalOverLay.overlayIndex));
|
||||
rightPtr = Marshal.AllocHGlobal(Marshal.SizeOf(originalOverLay.overlayIndex));
|
||||
Marshal.WriteInt64(leftPtr, originalOverLay.overlayIndex);
|
||||
Marshal.WriteInt64(rightPtr, originalOverLay.overlayIndex);
|
||||
overlayParam.leftExternalImages = leftPtr;
|
||||
overlayParam.rightExternalImages = rightPtr;
|
||||
isExternalAndroidSurface = originalOverLay.isExternalAndroidSurface;
|
||||
isDynamic = originalOverLay.isDynamic;
|
||||
overlayParam.width = (UInt32)Mathf.Min(overlayParam.width, originalOverLay.overlayParam.width);
|
||||
overlayParam.height = (UInt32)Mathf.Min(overlayParam.height, originalOverLay.overlayParam.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
PLog.e(TAG, "In clone state, originalOverLay cannot be empty!");
|
||||
}
|
||||
}
|
||||
|
||||
if (isExternalAndroidSurface)
|
||||
{
|
||||
if (isExternalAndroidSurfaceDRM)
|
||||
{
|
||||
overlayParam.layerFlags |= (UInt32)(PxrLayerCreateFlags.PxrLayerFlagAndroidSurface | PxrLayerCreateFlags.PxrLayerFlagProtectedContent);
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlagAndroidSurface;
|
||||
}
|
||||
|
||||
if (Surface3DType.LeftRight == externalAndroidSurface3DType)
|
||||
{
|
||||
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlag3DLeftRightSurface;
|
||||
}
|
||||
else if (Surface3DType.TopBottom == externalAndroidSurface3DType)
|
||||
{
|
||||
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlag3DTopBottomSurface;
|
||||
}
|
||||
|
||||
overlayParam.layerLayout = (PXR_CompositionLayer.LayerLayout)LayerLayout.Mono;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isDynamic)
|
||||
{
|
||||
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlagStaticImage;
|
||||
}
|
||||
|
||||
if ((layerTextures[0] != null && layerTextures[1] != null && layerTextures[0] == layerTextures[1]) || null == layerTextures[1])
|
||||
{
|
||||
eyeCount = 1;
|
||||
overlayParam.layerLayout = (PXR_CompositionLayer.LayerLayout)LayerLayout.Mono;
|
||||
}
|
||||
else
|
||||
{
|
||||
eyeCount = 2;
|
||||
overlayParam.layerLayout = (PXR_CompositionLayer.LayerLayout)LayerLayout.Stereo;
|
||||
}
|
||||
|
||||
toCreateSwapChain = true;
|
||||
}
|
||||
|
||||
PLog.i(TAG, $"UPxr_CreateLayer() overlayParam.layerId={overlayParam.layerId}, layerShape={overlayParam.layerShape}, layerType={overlayParam.layerType}, width={overlayParam.width}, height={overlayParam.height}, layerFlags={overlayParam.layerFlags}, format={overlayParam.format}, layerLayout={overlayParam.layerLayout}.");
|
||||
PXR_Plugin.Render.UPxr_CreateLayerParam(overlayParam);
|
||||
}
|
||||
|
||||
public void CreateExternalSurface(PXR_OverLay overlayInstance)
|
||||
{
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
if (IntPtr.Zero != overlayInstance.externalAndroidSurfaceObject)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PXR_Plugin.Render.UPxr_GetLayerAndroidSurface(overlayInstance.overlayIndex, 0, ref overlayInstance.externalAndroidSurfaceObject);
|
||||
PLog.i(TAG, string.Format("CreateExternalSurface: Overlay Type:{0}, LayerDepth:{1}, SurfaceObject:{2}", overlayInstance.overlayType, overlayInstance.overlayIndex, overlayInstance.externalAndroidSurfaceObject));
|
||||
|
||||
if (IntPtr.Zero == overlayInstance.externalAndroidSurfaceObject || null == overlayInstance.externalAndroidSurfaceObjectCreated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
overlayInstance.externalAndroidSurfaceObjectCreated();
|
||||
#endif
|
||||
}
|
||||
|
||||
public void UpdateCoords()
|
||||
{
|
||||
if (null == overlayTransform || !overlayTransform.gameObject.activeSelf || null == overlayEyeCamera[0] || null == overlayEyeCamera[1])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < mvMatrixs.Length; i++)
|
||||
{
|
||||
mvMatrixs[i] = overlayEyeCamera[i].worldToCameraMatrix * overlayTransform.localToWorldMatrix;
|
||||
if (overlayTransform is RectTransform uiTransform)
|
||||
{
|
||||
var rect = uiTransform.rect;
|
||||
var lossyScale = overlayTransform.lossyScale;
|
||||
modelScales[i] = new Vector3(rect.width * lossyScale.x,
|
||||
rect.height * lossyScale.y, 1);
|
||||
modelTranslations[i] = uiTransform.TransformPoint(rect.center);
|
||||
}
|
||||
else
|
||||
{
|
||||
modelScales[i] = overlayTransform.lossyScale;
|
||||
modelTranslations[i] = overlayTransform.position;
|
||||
}
|
||||
modelRotations[i] = overlayTransform.rotation;
|
||||
cameraRotations[i] = overlayEyeCamera[i].transform.rotation;
|
||||
cameraTranslations[i] = overlayEyeCamera[i].transform.position;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CreateTexture()
|
||||
{
|
||||
if (!toCreateSwapChain)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null == nativeTextures)
|
||||
nativeTextures = new NativeTexture[eyeCount];
|
||||
|
||||
for (int i = 0; i < eyeCount; i++)
|
||||
{
|
||||
int ret = PXR_Plugin.Render.UPxr_GetLayerImageCount(overlayIndex, (EyeType)i, ref imageCounts);
|
||||
if (ret != 0 || imageCounts < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null == nativeTextures[i].textures)
|
||||
{
|
||||
nativeTextures[i].textures = new Texture[imageCounts];
|
||||
}
|
||||
|
||||
for (int j = 0; j < imageCounts; j++)
|
||||
{
|
||||
IntPtr ptr = IntPtr.Zero;
|
||||
PXR_Plugin.Render.UPxr_GetLayerImagePtr(overlayIndex, (EyeType)i, j, ref ptr);
|
||||
|
||||
if (IntPtr.Zero == ptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Texture texture;
|
||||
if (OverlayShape.Cubemap == overlayShape)
|
||||
{
|
||||
texture = Cubemap.CreateExternalTexture((int)overlayParam.width, TextureFormat.RGBA32, false, ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
texture = Texture2D.CreateExternalTexture((int)overlayParam.width, (int)overlayParam.height, TextureFormat.RGBA32, false, true, ptr);
|
||||
}
|
||||
|
||||
if (null == texture)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
nativeTextures[i].textures[j] = texture;
|
||||
}
|
||||
}
|
||||
|
||||
toCreateSwapChain = false;
|
||||
toCopyRT = true;
|
||||
copiedRT = false;
|
||||
|
||||
FreePtr();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CopyRT()
|
||||
{
|
||||
if (isClones)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!toCopyRT)
|
||||
{
|
||||
return copiedRT;
|
||||
}
|
||||
|
||||
if (!isDynamic && copiedRT)
|
||||
{
|
||||
return copiedRT;
|
||||
}
|
||||
|
||||
if (null == nativeTextures)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (enableSubmitLayer)
|
||||
{
|
||||
PXR_Plugin.Render.UPxr_GetLayerNextImageIndexByRender(overlayIndex, ref imageIndex);
|
||||
}
|
||||
for (int i = 0; i < eyeCount; i++)
|
||||
{
|
||||
Texture nativeTexture = nativeTextures[i].textures[imageIndex];
|
||||
|
||||
if (null == nativeTexture || null == layerTextures[i])
|
||||
continue;
|
||||
|
||||
RenderTexture texture = layerTextures[i] as RenderTexture;
|
||||
|
||||
if (OverlayShape.Cubemap == overlayShape && null == layerTextures[i] as Cubemap)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int f = 0; f < (int)overlayParam.faceCount; f++)
|
||||
{
|
||||
if (QualitySettings.activeColorSpace == ColorSpace.Gamma && texture != null && texture.format == RenderTextureFormat.ARGB32)
|
||||
{
|
||||
Graphics.CopyTexture(layerTextures[i], f, 0, nativeTexture, f, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderTextureDescriptor rtDes = new RenderTextureDescriptor((int)overlayParam.width, (int)overlayParam.height, RenderTextureFormat.ARGB32, 0);
|
||||
rtDes.msaaSamples = (int)overlayParam.sampleCount;
|
||||
rtDes.useMipMap = true;
|
||||
rtDes.autoGenerateMips = false;
|
||||
rtDes.sRGB = true;
|
||||
|
||||
RenderTexture renderTexture = RenderTexture.GetTemporary(rtDes);
|
||||
|
||||
if (!renderTexture.IsCreated())
|
||||
{
|
||||
renderTexture.Create();
|
||||
}
|
||||
renderTexture.DiscardContents();
|
||||
|
||||
if (OverlayShape.Cubemap == overlayShape)
|
||||
{
|
||||
cubeM.SetInt("_d", f);
|
||||
Graphics.Blit(layerTextures[i], renderTexture, cubeM);
|
||||
}
|
||||
else
|
||||
{
|
||||
textureM.mainTexture = texture;
|
||||
textureM.SetPass(0);
|
||||
textureM.SetInt("_premultiply", isPremultipliedAlpha ? 1 : 0);
|
||||
Graphics.Blit(layerTextures[i], renderTexture, textureM);
|
||||
}
|
||||
Graphics.CopyTexture(renderTexture, 0, 0, nativeTexture, f, 0);
|
||||
RenderTexture.ReleaseTemporary(renderTexture);
|
||||
}
|
||||
}
|
||||
copiedRT = true;
|
||||
}
|
||||
|
||||
return copiedRT;
|
||||
}
|
||||
|
||||
public void SetTexture(Texture texture, bool dynamic)
|
||||
{
|
||||
if (isExternalAndroidSurface)
|
||||
{
|
||||
PLog.w(TAG, "Not support setTexture !");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isClones)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (PXR_OverLay overlay in PXR_OverLay.Instances)
|
||||
{
|
||||
if (overlay.isClones && null != overlay.originalOverLay && overlay.originalOverLay.overlayIndex == overlayIndex)
|
||||
{
|
||||
overlay.DestroyLayer();
|
||||
overlay.isClonesToNew = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toCopyRT = false;
|
||||
PXR_Plugin.Render.UPxr_DestroyLayerByRender(overlayIndex);
|
||||
ClearTexture();
|
||||
for (int i = 0; i < layerTextures.Length; i++)
|
||||
{
|
||||
layerTextures[i] = texture;
|
||||
}
|
||||
|
||||
isDynamic = dynamic;
|
||||
InitializeBuffer();
|
||||
|
||||
if (!isClones)
|
||||
{
|
||||
foreach (PXR_OverLay overlay in PXR_OverLay.Instances)
|
||||
{
|
||||
if (overlay.isClones && overlay.isClonesToNew)
|
||||
{
|
||||
overlay.originalOverLay = this;
|
||||
overlay.InitializeBuffer();
|
||||
overlay.isClonesToNew = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FreePtr()
|
||||
{
|
||||
if (leftPtr != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(leftPtr);
|
||||
leftPtr = IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (rightPtr != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(rightPtr);
|
||||
rightPtr = IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (layerSubmitPtr != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(layerSubmitPtr);
|
||||
layerSubmitPtr = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDestroy()
|
||||
{
|
||||
DestroyLayer();
|
||||
Instances.Remove(this);
|
||||
}
|
||||
|
||||
public void DestroyLayer()
|
||||
{
|
||||
if (isExternalAndroidSurface)
|
||||
{
|
||||
PXR_Plugin.Render.UPxr_DestroyLayerByRender(overlayIndex);
|
||||
externalAndroidSurfaceObject = IntPtr.Zero;
|
||||
ClearTexture();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isClones)
|
||||
{
|
||||
List<PXR_OverLay> toDestroyClones = new List<PXR_OverLay>();
|
||||
foreach (PXR_OverLay overlay in Instances)
|
||||
{
|
||||
if (overlay.isClones && null != overlay.originalOverLay && overlay.originalOverLay.overlayIndex == overlayIndex)
|
||||
{
|
||||
toDestroyClones.Add(overlay);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (PXR_OverLay overLay in toDestroyClones)
|
||||
{
|
||||
PXR_Plugin.Render.UPxr_DestroyLayerByRender(overLay.overlayIndex);
|
||||
ClearTexture();
|
||||
}
|
||||
|
||||
PXR_Plugin.Render.UPxr_DestroyLayerByRender(overlayIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (null != originalOverLay && Instances.Contains(originalOverLay))
|
||||
{
|
||||
PXR_Plugin.Render.UPxr_DestroyLayerByRender(overlayIndex);
|
||||
}
|
||||
}
|
||||
ClearTexture();
|
||||
}
|
||||
|
||||
private void ClearTexture()
|
||||
{
|
||||
FreePtr();
|
||||
|
||||
if (isExternalAndroidSurface || null == nativeTextures || isClones)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < eyeCount; i++)
|
||||
{
|
||||
if (null == nativeTextures[i].textures)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 0; j < imageCounts; j++)
|
||||
DestroyImmediate(nativeTextures[i].textures[j]);
|
||||
}
|
||||
|
||||
nativeTextures = null;
|
||||
}
|
||||
|
||||
public void SetLayerColorScaleAndOffset(Vector4 scale, Vector4 offset)
|
||||
{
|
||||
colorScale = scale;
|
||||
colorOffset = offset;
|
||||
}
|
||||
|
||||
public void SetEACOffsetPosAndRot(Vector3 leftPos, Vector3 rightPos, Vector4 leftRot, Vector4 rightRot)
|
||||
{
|
||||
offsetPosLeft = leftPos;
|
||||
offsetPosRight = rightPos;
|
||||
offsetRotLeft = leftRot;
|
||||
offsetRotRight = rightRot;
|
||||
}
|
||||
|
||||
public void SetEACFactor(float factor)
|
||||
{
|
||||
overlapFactor = factor;
|
||||
}
|
||||
|
||||
public Vector4 GetLayerColorScale()
|
||||
{
|
||||
if (!overrideColorScaleAndOffset)
|
||||
{
|
||||
return overlayLayerColorScaleDefault;
|
||||
}
|
||||
return colorScale;
|
||||
}
|
||||
|
||||
public Vector4 GetLayerColorOffset()
|
||||
{
|
||||
if (!overrideColorScaleAndOffset)
|
||||
{
|
||||
return overlayLayerColorOffsetDefault;
|
||||
}
|
||||
return colorOffset;
|
||||
}
|
||||
|
||||
public PxrRecti getPxrRectiLeft(bool left)
|
||||
{
|
||||
if (left)
|
||||
{
|
||||
imageRectLeft.x = (int)(overlayParam.width * srcRectLeft.x);
|
||||
imageRectLeft.y = (int)(overlayParam.height * srcRectLeft.y);
|
||||
imageRectLeft.width = (int)(overlayParam.width * Mathf.Min(srcRectLeft.width, 1 - srcRectLeft.x));
|
||||
imageRectLeft.height = (int)(overlayParam.height * Mathf.Min(srcRectLeft.height, 1 - srcRectLeft.y));
|
||||
return imageRectLeft;
|
||||
}
|
||||
else
|
||||
{
|
||||
imageRectRight.x = (int)(overlayParam.width * srcRectRight.x);
|
||||
imageRectRight.y = (int)(overlayParam.height * srcRectRight.y);
|
||||
imageRectRight.width = (int)(overlayParam.width * Mathf.Min(srcRectRight.width, 1 - srcRectRight.x));
|
||||
imageRectRight.height = (int)(overlayParam.height * Mathf.Min(srcRectRight.height, 1 - srcRectRight.y));
|
||||
return imageRectRight;
|
||||
}
|
||||
}
|
||||
|
||||
public UInt32 getHDRFlags()
|
||||
{
|
||||
UInt32 hdrFlags = 0;
|
||||
if (!isExternalAndroidSurface)
|
||||
{
|
||||
return hdrFlags;
|
||||
}
|
||||
switch (hdr)
|
||||
{
|
||||
case HDRFlags.HdrPQ:
|
||||
hdrFlags |= (UInt32)PxrLayerSubmitFlags.PxrLayerFlagColorSpaceHdrPQ;
|
||||
break;
|
||||
case HDRFlags.HdrHLG:
|
||||
hdrFlags |= (UInt32)PxrLayerSubmitFlags.PxrLayerFlagColorSpaceHdrHLG;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return hdrFlags;
|
||||
}
|
||||
|
||||
public enum HDRFlags
|
||||
{
|
||||
None,
|
||||
HdrPQ,
|
||||
HdrHLG,
|
||||
}
|
||||
|
||||
public enum OverlayShape
|
||||
{
|
||||
Quad = 1,
|
||||
Cylinder = 2,
|
||||
Equirect = 4,
|
||||
Cubemap = 5,
|
||||
Eac = 6,
|
||||
Fisheye = 7,
|
||||
BlurredQuad = 9
|
||||
}
|
||||
|
||||
public enum OverlayType
|
||||
{
|
||||
Overlay = 0,
|
||||
Underlay = 1
|
||||
}
|
||||
|
||||
public enum TextureType
|
||||
{
|
||||
ExternalSurface,
|
||||
DynamicTexture,
|
||||
StaticTexture
|
||||
}
|
||||
|
||||
public enum LayerLayout
|
||||
{
|
||||
Stereo = 0,
|
||||
DoubleWide = 1,
|
||||
Array = 2,
|
||||
Mono = 3
|
||||
}
|
||||
|
||||
public enum Surface3DType
|
||||
{
|
||||
Single = 0,
|
||||
LeftRight,
|
||||
TopBottom
|
||||
}
|
||||
|
||||
public enum TextureRect
|
||||
{
|
||||
MonoScopic,
|
||||
StereoScopic,
|
||||
Custom
|
||||
}
|
||||
|
||||
public enum DestinationRect
|
||||
{
|
||||
Default,
|
||||
Custom
|
||||
}
|
||||
|
||||
public enum EACModelType
|
||||
{
|
||||
Eac360 = 0,
|
||||
Eac360ViewPort = 1,
|
||||
Eac180 = 4,
|
||||
Eac180ViewPort = 5,
|
||||
}
|
||||
|
||||
public enum ColorForamt
|
||||
{
|
||||
VK_FORMAT_R8G8B8A8_UNORM = 37,
|
||||
VK_FORMAT_R8G8B8A8_SRGB = 43,
|
||||
GL_SRGB8_ALPHA8 = 0x8c43,
|
||||
GL_RGBA8 = 0x8058
|
||||
}
|
||||
|
||||
public enum BlurredQuadMode
|
||||
{
|
||||
SmallWindow,
|
||||
Immersion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: daeec670ce18c8d488f9f5b2e51c817b
|
||||
timeCreated: 1590405833
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,214 @@
|
||||
/*******************************************************************************
|
||||
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;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
public class PXR_ScreenFade : MonoBehaviour
|
||||
{
|
||||
[Tooltip("The gradient of time.")]
|
||||
public float gradientTime = 5.0f;
|
||||
[Tooltip("Basic color.")]
|
||||
public Color fadeColor = new Color(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
[Tooltip("The default value is 4000.")]
|
||||
private int renderQueue = 4000;
|
||||
private MeshRenderer gradientMeshRenderer;
|
||||
private MeshFilter gradientMeshFilter;
|
||||
private Material gradientMaterial = null;
|
||||
private bool isGradient = false;
|
||||
private float currentAlpha;
|
||||
private float nowFadeAlpha;
|
||||
private List<Vector3> verts;
|
||||
private List<int> indices;
|
||||
private int N = 5;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
CreateFadeMesh();
|
||||
SetCurrentAlpha(0);
|
||||
}
|
||||
void OnEnable()
|
||||
{
|
||||
StartCoroutine(ScreenFade());
|
||||
}
|
||||
void OnDestroy()
|
||||
{
|
||||
DestoryGradientMesh();
|
||||
}
|
||||
|
||||
private void CreateFadeMesh()
|
||||
{
|
||||
verts = new List<Vector3>();
|
||||
indices = new List<int>();
|
||||
gradientMaterial = new Material(Shader.Find("PXR_SDK/PXR_Fade"));
|
||||
gradientMeshFilter = gameObject.AddComponent<MeshFilter>();
|
||||
gradientMeshRenderer = gameObject.AddComponent<MeshRenderer>();
|
||||
|
||||
CreateModel();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void SetCurrentAlpha(float alpha)
|
||||
{
|
||||
currentAlpha = alpha;
|
||||
SetAlpha();
|
||||
}
|
||||
|
||||
IEnumerator ScreenFade()
|
||||
{
|
||||
float nowTime = 0.0f;
|
||||
while (nowTime < gradientTime)
|
||||
{
|
||||
nowTime += Time.deltaTime;
|
||||
nowFadeAlpha = Mathf.Lerp(1.0f, 0, Mathf.Clamp01(nowTime / gradientTime));
|
||||
SetAlpha();
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetAlpha()
|
||||
{
|
||||
Color color = fadeColor;
|
||||
color.a = Mathf.Max(currentAlpha, nowFadeAlpha);
|
||||
isGradient = color.a > 0;
|
||||
if (gradientMaterial != null)
|
||||
{
|
||||
gradientMaterial.color = color;
|
||||
gradientMaterial.renderQueue = renderQueue;
|
||||
gradientMeshRenderer.material = gradientMaterial;
|
||||
gradientMeshRenderer.enabled = isGradient;
|
||||
}
|
||||
}
|
||||
|
||||
void CreateModel()
|
||||
{
|
||||
for (float i = -N / 2f; i <= N / 2f; i++)
|
||||
{
|
||||
for (float j = -N / 2f; j <= N / 2f; j++)
|
||||
{
|
||||
verts.Add(new Vector3(i, j, -N / 2f));
|
||||
}
|
||||
}
|
||||
for (float i = -N / 2f; i <= N / 2f; i++)
|
||||
{
|
||||
for (float j = -N / 2f; j <= N / 2f; j++)
|
||||
{
|
||||
verts.Add(new Vector3(N / 2f, j, i));
|
||||
}
|
||||
}
|
||||
for (float i = -N / 2f; i <= N / 2f; i++)
|
||||
{
|
||||
for (float j = -N / 2f; j <= N / 2f; j++)
|
||||
{
|
||||
verts.Add(new Vector3(i, N / 2f, j));
|
||||
}
|
||||
}
|
||||
for (float i = -N / 2f; i <= N / 2f; i++)
|
||||
{
|
||||
for (float j = -N / 2f; j <= N / 2f; j++)
|
||||
{
|
||||
verts.Add(new Vector3(-N / 2f, j, i));
|
||||
}
|
||||
}
|
||||
for (float i = -N / 2f; i <= N / 2f; i++)
|
||||
{
|
||||
for (float j = -N / 2f; j <= N / 2f; j++)
|
||||
{
|
||||
verts.Add(new Vector3(i, j, N / 2f));
|
||||
}
|
||||
}
|
||||
for (float i = -N / 2f; i <= N / 2f; i++)
|
||||
{
|
||||
for (float j = -N / 2f; j <= N / 2f; j++)
|
||||
{
|
||||
verts.Add(new Vector3(i, -N / 2f, j));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < verts.Count; i++)
|
||||
{
|
||||
verts[i] = verts[i].normalized * 0.7f;
|
||||
}
|
||||
|
||||
CreateMakePos(0);
|
||||
CreateMakePos(1);
|
||||
CreateMakePos(2);
|
||||
OtherMakePos(3);
|
||||
OtherMakePos(4);
|
||||
OtherMakePos(5);
|
||||
Mesh mesh = new Mesh();
|
||||
mesh.vertices = verts.ToArray();
|
||||
mesh.triangles = indices.ToArray();
|
||||
mesh.RecalculateNormals();
|
||||
mesh.RecalculateBounds();
|
||||
Vector3[] normals = mesh.normals;
|
||||
for (int i = 0; i < normals.Length; i++)
|
||||
{
|
||||
normals[i] = -normals[i];
|
||||
}
|
||||
mesh.normals = normals;
|
||||
int[] triangles = mesh.triangles;
|
||||
for (int i = 0; i < triangles.Length; i += 3)
|
||||
{
|
||||
int t = triangles[i];
|
||||
triangles[i] = triangles[i + 2];
|
||||
triangles[i + 2] = t;
|
||||
}
|
||||
mesh.triangles = triangles;
|
||||
gradientMeshFilter.mesh = mesh;
|
||||
}
|
||||
public void CreateMakePos(int num)
|
||||
{
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
for (int j = 0; j < N; j++)
|
||||
{
|
||||
int index = j * (N + 1) + (N + 1) * (N + 1) * num + i;
|
||||
int up = (j + 1) * (N + 1) + (N + 1) * (N + 1) * num + i;
|
||||
indices.AddRange(new int[] { index, index + 1, up + 1 });
|
||||
indices.AddRange(new int[] { index, up + 1, up });
|
||||
}
|
||||
}
|
||||
}
|
||||
public void OtherMakePos(int num)
|
||||
{
|
||||
for (int i = 0; i < N + 1; i++)
|
||||
{
|
||||
for (int j = 0; j < N + 1; j++)
|
||||
{
|
||||
if (i != N && j != N)
|
||||
{
|
||||
int index = j * (N + 1) + (N + 1) * (N + 1) * num + i;
|
||||
int up = (j + 1) * (N + 1) + (N + 1) * (N + 1) * num + i;
|
||||
indices.AddRange(new int[] { index, up + 1, index + 1 });
|
||||
indices.AddRange(new int[] { index, up, up + 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void DestoryGradientMesh()
|
||||
{
|
||||
if (gradientMeshRenderer != null)
|
||||
Destroy(gradientMeshRenderer);
|
||||
|
||||
if (gradientMaterial != null)
|
||||
Destroy(gradientMaterial);
|
||||
|
||||
if (gradientMeshFilter != null)
|
||||
Destroy(gradientMeshFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ee8dd1042c84fa4fa2411e8c4ebcc01
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,440 @@
|
||||
#if !PICO_OPENXR_SDK
|
||||
/*******************************************************************************
|
||||
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;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
public class PXR_System
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the SDK version.
|
||||
/// </summary>
|
||||
/// <returns>The SDK version.</returns>
|
||||
public static string GetSDKVersion()
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_GetSDKVersion();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the predicted time a frame will be displayed after being rendered.
|
||||
/// </summary>
|
||||
/// <returns>The predicted time (in miliseconds).</returns>
|
||||
public static double GetPredictedDisplayTime()
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_GetPredictedDisplayTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the extra latency mode. Note: Call this function once only.
|
||||
/// </summary>
|
||||
/// <param name="mode">The latency mode:
|
||||
/// * `0`: ExtraLatencyModeOff (Disable ExtraLatencyMode mode. This option will display the latest rendered frame for display)
|
||||
/// * `1`: ExtraLatencyModeOn (Enable ExtraLatencyMode mode. This option will display one frame prior to the latest rendered frame)
|
||||
/// * `2`: ExtraLatencyModeDynamic (Use system default setup)
|
||||
/// </param>
|
||||
/// <returns>Whether the extra latency mode has been set:
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
[Obsolete("SetExtraLatencyMode has been deprecated", true)]
|
||||
public static bool SetExtraLatencyMode(int mode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sensor's status.
|
||||
/// </summary>
|
||||
/// <returns>The sensor's status:
|
||||
/// * `0`: null
|
||||
/// * `1`: 3DoF
|
||||
/// * `3`: 6DoF
|
||||
/// </returns>
|
||||
public static int GetSensorStatus()
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_GetSensorStatus();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the system display frequency rate.
|
||||
/// </summary>
|
||||
/// <param name="rate">The frequency rate: `72`; `90`; `120`. Other values are invalid.</param>
|
||||
public static void SetSystemDisplayFrequency(float rate)
|
||||
{
|
||||
PXR_Plugin.System.UPxr_SetSystemDisplayFrequency(rate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the system display frequency rate.
|
||||
/// </summary>
|
||||
/// <returns>The system display frequency rate.</returns>
|
||||
public static float GetSystemDisplayFrequency()
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_GetSystemDisplayFrequency();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the available display refresh rates.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The available refresh rates (in Hz).
|
||||
/// </returns>
|
||||
public static float[] GetDisplayFrequenciesAvailable()
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_GetDisplayFrequenciesAvailable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the predicted status of the sensor.
|
||||
/// </summary>
|
||||
/// <param name="sensorState">Sensor's coordinate:
|
||||
/// * `pose`: in-app coordinate
|
||||
/// * `globalPose`: global coordinate
|
||||
/// </param>
|
||||
/// <param name="sensorFrameIndex">Sensor frame index.</param>
|
||||
/// <returns>The predicted status of the sensor.</returns>
|
||||
public static int GetPredictedMainSensorStateNew(ref PxrSensorState2 sensorState, ref int sensorFrameIndex) {
|
||||
return PXR_Plugin.System.UPxr_GetPredictedMainSensorStateNew(ref sensorState, ref sensorFrameIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables/disables content protection.
|
||||
/// </summary>
|
||||
/// <param name="data">Specifies whether to enable/disable content protection:
|
||||
/// * `0`: disable
|
||||
/// * `1`: enable
|
||||
/// </param>
|
||||
/// <returns>Whether content protection is successfully enabled/disabled:
|
||||
/// * `0`: success
|
||||
/// * `1`: failure
|
||||
/// </returns>
|
||||
public static int ContentProtect(int data) {
|
||||
return PXR_Plugin.System.UPxr_ContentProtect(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables/disables face tracking.
|
||||
/// @note Only supported by PICO 4 Pro and PICO 4 Enterprise.
|
||||
/// </summary>
|
||||
/// <param name="enable">Whether to enable/disable face tracking:
|
||||
/// * `true`: enable
|
||||
/// * `false`: disable
|
||||
/// </param>
|
||||
[Obsolete("EnableFaceTracking has been deprecated", true)]
|
||||
public static void EnableFaceTracking(bool enable)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables/disables lipsync.
|
||||
/// @note Only supported by PICO 4 Pro and PICO 4 Enterprise.
|
||||
/// </summary>
|
||||
/// <param name="enable">Whether to enable/disable lipsync:
|
||||
/// * `true`: enable
|
||||
/// * `false`: disable
|
||||
/// </param>
|
||||
[Obsolete("EnableLipSync has been deprecated", true)]
|
||||
public static void EnableLipSync(bool enable)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets face tracking data.
|
||||
/// @note Only supported by PICO 4 Pro and PICO 4 Enterprise.
|
||||
/// </summary>
|
||||
/// <param name="ts">(Optional) A reserved parameter, pass `0`.</param>
|
||||
/// <param name="flags">The face tracking mode to retrieve data for. Enumertions:
|
||||
/// * `PXR_GET_FACE_DATA_DEFAULT` (invalid, only for making it compatible with older SDK version)
|
||||
/// * `PXR_GET_FACE_DATA`: face only
|
||||
/// * `PXR_GET_LIP_DATA`: lipsync only
|
||||
/// * `PXR_GET_FACELIP_DATA`: hybrid (both face and lipsync)
|
||||
/// </param>
|
||||
/// <param name="faceTrackingInfo">Returns the `PxrFaceTrackingInfo` struct that contains the following face tracking data:
|
||||
/// * `timestamp`: Int64, reserved field
|
||||
/// * `blendShapeWeight`: float[], pass `0`.
|
||||
/// * `videoInputValid`: float[], the input validity of the upper and lower parts of the face.
|
||||
/// * `laughingProb`: float[], the coefficient of laughter.
|
||||
/// * `emotionProb`: float[], the emotion factor.
|
||||
/// * `reserved`: float[], reserved field.
|
||||
/// </param>
|
||||
[Obsolete("GetFaceTrackingData has been deprecated", true)]
|
||||
public static void GetFaceTrackingData(Int64 ts, GetDataType flags, ref PxrFaceTrackingInfo faceTrackingInfo)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Sets a GPU or CPU level for the device.</summary>
|
||||
/// <param name="which">Choose to set a GPU or CPU level:
|
||||
/// * `CPU`
|
||||
/// * `GPU`
|
||||
/// </param>
|
||||
/// <param name="level">Select a level from the following:
|
||||
/// * `POWER_SAVINGS`: power-saving level
|
||||
/// * `SUSTAINED_LOW`: low level
|
||||
/// * `SUSTAINED_HIGH`: high level
|
||||
/// * `BOOST`: top-high level, be careful to use this level
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `1`: failure
|
||||
/// </returns>
|
||||
public static int SetPerformanceLevels(PxrPerfSettings which, PxrSettingsLevel level)
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_SetPerformanceLevels(which, level);
|
||||
}
|
||||
|
||||
/// <summary>Gets the device's GPU or CPU level.</summary>
|
||||
/// <param name="which">Choose to get GPU or CPU level:
|
||||
/// * `CPU`
|
||||
/// * `GPU`
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Returns one of the following levels:
|
||||
/// * `POWER_SAVINGS`: power-saving level
|
||||
/// * `SUSTAINED_LOW`: low level
|
||||
/// * `SUSTAINED_HIGH`: high level
|
||||
/// * `BOOST`: top-high level, be careful to use this level
|
||||
/// </returns>
|
||||
public static PxrSettingsLevel GetPerformanceLevels(PxrPerfSettings which)
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_GetPerformanceLevels(which);
|
||||
}
|
||||
|
||||
/// <summary>Sets FOV in four directions (left, right, up, and down) for specified eye(s).</summary>
|
||||
/// <param name="eye">The eye to set FOV for:
|
||||
/// * `LeftEye`
|
||||
/// * `RightEye`
|
||||
/// * `BothEye`
|
||||
/// </param>
|
||||
/// <param name="fovLeft">The horizontal FOV (in degrees) for the left part of the eye, for example, `47.5`.</param>
|
||||
/// <param name="fovRight">The horizontal FOV (in degrees) for the right part of the eye..</param>
|
||||
/// <param name="fovUp">The vertical FOV (in degrees) for the upper part of the eye.</param>
|
||||
/// <param name="fovDown">The vertical FOV (in degrees) for the lower part of the eye.</param>
|
||||
/// <returns>
|
||||
/// * `0`: success
|
||||
/// * `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("SetEyeFOV has been deprecated", true)]
|
||||
public static int SetEyeFOV(EyeType eye, float fovLeft, float fovRight, float fovUp, float fovDown)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Switches the face tracking mode.
|
||||
/// @note Only supported by PICO 4 Pro and PICO 4 Enterprise.
|
||||
/// </summary>
|
||||
/// <param name="value">
|
||||
/// `STOP_FT`: to stop the "Face Only" mode.
|
||||
/// `STOP_LIPSYNC`: to stop the "Lipsync Only" mode.
|
||||
/// `START_FT`: to start the "Face Only" mode.
|
||||
/// `START_LIPSYNC`: to start the "Lipsync Only" mode.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// `0`: success
|
||||
/// `1`: failure
|
||||
/// </returns>
|
||||
[Obsolete("SetFaceTrackingStatus has been deprecated", true)]
|
||||
public static int SetFaceTrackingStatus(PxrFtLipsyncValue value) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a tracking origin mode for the app.
|
||||
/// When the user moves in the virtual scene, the system tracks and calculates the user's positional changes based on the origin.
|
||||
/// </summary>
|
||||
/// <param name="originMode">Selects a tracking origin mode from the following:
|
||||
/// * `TrackingOriginModeFlags.Device`: Device mode. The system sets the device's initial position as the origin. The device's height from the floor is not calculated.
|
||||
/// * `TrackingOriginModeFlags.Floor`: Floor mode. The system sets an origin based on the device's original position and the device's height from the floor.
|
||||
/// </param>
|
||||
public static void SetTrackingOrigin(PxrTrackingOrigin originMode)
|
||||
{
|
||||
PXR_Plugin.System.UPxr_SetTrackingOrigin(originMode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tracking origin mode of the app.
|
||||
/// </summary>
|
||||
/// <param name="originMode">Returns the app's tracking origin mode:
|
||||
/// * `TrackingOriginModeFlags.Device`: Device mode
|
||||
/// * `TrackingOriginModeFlags.Floor`: Floor mode
|
||||
/// For the description of each mode, refer to `SetTrackingOrigin`.
|
||||
/// </param>
|
||||
public static void GetTrackingOrigin(out PxrTrackingOrigin originMode)
|
||||
{
|
||||
originMode = PxrTrackingOrigin.Eye;
|
||||
PXR_Plugin.System.UPxr_GetTrackingOrigin(ref originMode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Turns on the power service for a specified object.
|
||||
/// </summary>
|
||||
/// <param name="objName">The name of the object to turn on the power service for.</param>
|
||||
/// <returns>Whether the power service has been turned on:
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool StartBatteryReceiver(string objName)
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_StartBatteryReceiver(objName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Turns off the power service.
|
||||
/// </summary>
|
||||
/// <returns>Whether the power service has been turned off:
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool StopBatteryReceiver()
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_StopBatteryReceiver();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the brightness for the current HMD.
|
||||
/// </summary>
|
||||
/// <param name="brightness">Target brightness. Value range: [0,255].</param>
|
||||
/// <returns>Whether the brightness has been set successfully:
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
[Obsolete("SetCommonBrightness has been deprecated", true)]
|
||||
public static bool SetCommonBrightness(int brightness)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the brightness of the current HMD.
|
||||
/// </summary>
|
||||
/// <returns>An int value that indicates the brightness. Value range: [0,255].</returns>
|
||||
[Obsolete("GetCommonBrightness has been deprecated", true)]
|
||||
public static int GetCommonBrightness()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the brightness level of the current screen.
|
||||
/// </summary>
|
||||
/// <returns>An int array. The first bit is the total brightness level supported, the second bit is the current brightness level, and it is the interval value of the brightness level from the third bit to the end bit.</returns>
|
||||
[Obsolete("GetScreenBrightnessLevel has been deprecated", true)]
|
||||
public static int[] GetScreenBrightnessLevel()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a brightness level for the current screen.
|
||||
/// </summary>
|
||||
/// <param name="brightness">Brightness mode:
|
||||
/// * `0`: system default brightness setting.
|
||||
/// * `1`: custom brightness setting, you can then set param `level`.
|
||||
/// </param>
|
||||
/// <param name="level">Brightness level. Value range: [1,255].</param>
|
||||
[Obsolete("GetScreenBrightnessLevel has been deprecated", true)]
|
||||
public static void SetScreenBrightnessLevel(int brightness, int level)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Turns on the volume service for a specified object.
|
||||
/// </summary>
|
||||
/// <param name="objName">The name of the object to turn on the volume service for.</param>
|
||||
/// <returns>Whether the volume service has been turned on:
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool StartAudioReceiver(string objName)
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_StartAudioReceiver(objName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Turns off the volume service.
|
||||
/// </summary>
|
||||
/// <returns>Whether the volume service has been turned off:
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool StopAudioReceiver()
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_StopAudioReceiver();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum volume.
|
||||
/// </summary>
|
||||
/// <returns>An int value that indicates the maximum volume.</returns>
|
||||
public static int GetMaxVolumeNumber()
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_GetMaxVolumeNumber();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current volume.
|
||||
/// </summary>
|
||||
/// <returns>An int value that indicates the current volume. Value range: [0,15].</returns>
|
||||
public static int GetCurrentVolumeNumber()
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_GetCurrentVolumeNumber();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases the volume.
|
||||
/// </summary>
|
||||
/// <returns>Whether the volume has been increased:
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool VolumeUp()
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_VolumeUp();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decreases the volume.
|
||||
/// </summary>
|
||||
/// <returns>Whether the volume has been decreased:
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool VolumeDown()
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_VolumeDown();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a volume.
|
||||
/// </summary>
|
||||
/// <param name="volume">The target volume. Value range: [0,15].</param>
|
||||
/// <returns>Whether the target volume has been set:
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool SetVolumeNum(int volume)
|
||||
{
|
||||
return PXR_Plugin.System.UPxr_SetVolumeNum(volume);
|
||||
}
|
||||
|
||||
public static string GetProductName()
|
||||
{
|
||||
return PXR_Plugin.System.ProductName;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 00e4f0103b06c774b9ba07b7c06221b6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user