Загрузка PICO Unity OpenXR Integration SDK
This commit is contained in:
@ -0,0 +1,681 @@
|
||||
/*******************************************************************************
|
||||
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;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
public class CompositeLayerFeature : MonoBehaviour, IComparable<CompositeLayerFeature>
|
||||
{
|
||||
private const string TAG = "[POXR_CompositeLayers]";
|
||||
public static List<CompositeLayerFeature> Instances = new List<CompositeLayerFeature>();
|
||||
|
||||
private 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.StaticTexture;
|
||||
public Transform overlayTransform;
|
||||
public Camera xrRig;
|
||||
|
||||
public Texture[] layerTextures = new Texture[2] { null, null };
|
||||
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.one;
|
||||
public Vector3 offsetPosRight = Vector3.one;
|
||||
public Vector4 offsetRotLeft = Vector4.one;
|
||||
public Vector4 offsetRotRight = Vector4.one;
|
||||
public DegreeType degreeType = DegreeType.Eac360;
|
||||
public float overlapFactor = 0;
|
||||
|
||||
private Vector4 overlayLayerColorScaleDefault = Vector4.one;
|
||||
private Vector4 overlayLayerColorOffsetDefault = Vector4.zero;
|
||||
|
||||
// 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.One;
|
||||
public PxrBlendFactor dstColor = PxrBlendFactor.One;
|
||||
public PxrBlendFactor srcAlpha = PxrBlendFactor.One;
|
||||
public PxrBlendFactor dstAlpha = PxrBlendFactor.One;
|
||||
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 CompositeLayerFeature originalOverLay;
|
||||
|
||||
|
||||
public IntPtr layerSubmitPtr = IntPtr.Zero;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
public int CompareTo(CompositeLayerFeature other)
|
||||
{
|
||||
return layerDepth.CompareTo(other.layerDepth);
|
||||
}
|
||||
|
||||
protected void Awake()
|
||||
{
|
||||
xrRig = Camera.main;
|
||||
Instances.Add(this);
|
||||
if (null == xrRig.gameObject.GetComponent<CompositeLayerManager>())
|
||||
{
|
||||
xrRig.gameObject.AddComponent<CompositeLayerManager>();
|
||||
}
|
||||
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 (PICOManager.Instance == null)
|
||||
{
|
||||
PLog.e(TAG + " PICOManager.Instance is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
Camera[] cam = PICOManager.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 (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];
|
||||
}
|
||||
|
||||
overlayID++;
|
||||
overlayIndex = overlayID;
|
||||
overlayParam.layerId = overlayIndex;
|
||||
overlayParam.layerShape = overlayShape == 0 ? OverlayShape.Quad : overlayShape;
|
||||
overlayParam.layerType = overlayType;
|
||||
overlayParam.width = (uint)layerTextures[1].width;
|
||||
overlayParam.height = (uint)layerTextures[1].height;
|
||||
overlayParam.arraySize = 1;
|
||||
overlayParam.mipmapCount = 1;
|
||||
overlayParam.sampleCount = 1;
|
||||
overlayParam.layerFlags = 0;
|
||||
overlayParam.faceCount = 1;
|
||||
if (OverlayShape.Cubemap == overlayShape)
|
||||
{
|
||||
overlayParam.faceCount = 6;
|
||||
if (cubeM == null)
|
||||
cubeM = new Material(Shader.Find("PXR_SDK/PXR_CubemapBlit"));
|
||||
}
|
||||
|
||||
if (GraphicsDeviceType.Vulkan == SystemInfo.graphicsDeviceType)
|
||||
{
|
||||
overlayParam.format = QualitySettings.activeColorSpace == ColorSpace.Linear ? (UInt64)ColorForamt.VK_FORMAT_R8G8B8A8_SRGB : (UInt64)RenderTextureFormat.Default;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayParam.format = QualitySettings.activeColorSpace == ColorSpace.Linear ? (UInt64)ColorForamt.GL_SRGB8_ALPHA8 : (UInt64)RenderTextureFormat.Default;
|
||||
}
|
||||
|
||||
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;
|
||||
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 (!isDynamic)
|
||||
{
|
||||
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlagStaticImage;
|
||||
}
|
||||
|
||||
if (layerTextures[0] == layerTextures[1])
|
||||
{
|
||||
eyeCount = 1;
|
||||
overlayParam.layerLayout = LayerLayout.Mono;
|
||||
}
|
||||
else
|
||||
{
|
||||
eyeCount = 2;
|
||||
overlayParam.layerLayout = LayerLayout.Stereo;
|
||||
}
|
||||
|
||||
OpenXRExtensions.CreateLayerParam(overlayParam);
|
||||
toCreateSwapChain = true;
|
||||
CreateTexture();
|
||||
}
|
||||
|
||||
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 = OpenXRExtensions.GetLayerImageCount(overlayIndex, (EyeType)i, ref imageCounts);
|
||||
if (ret != 0 || imageCounts < 1)
|
||||
{
|
||||
PLog.e(TAG + $" ret={ret}, imageCounts={imageCounts}");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null == nativeTextures[i].textures)
|
||||
{
|
||||
nativeTextures[i].textures = new Texture[imageCounts];
|
||||
}
|
||||
|
||||
for (int j = 0; j < imageCounts; j++)
|
||||
{
|
||||
IntPtr ptr = IntPtr.Zero;
|
||||
OpenXRExtensions.GetLayerImagePtr(overlayIndex, (EyeType)i, j, ref ptr);
|
||||
|
||||
if (IntPtr.Zero == ptr)
|
||||
{
|
||||
PLog.e(TAG + $" ptr is zero!");
|
||||
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)
|
||||
{
|
||||
PLog.e(TAG + $" texture is null!");
|
||||
return false;
|
||||
}
|
||||
nativeTextures[i].textures[j] = texture;
|
||||
PLog.i($"composition_layer 2. i={i}, j={j},imageCounts={imageCounts}, ptr={ptr}");
|
||||
}
|
||||
PLog.i("composition_layer 3");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
PLog.e(TAG + $" nativeTextures is null!");
|
||||
return false;
|
||||
}
|
||||
|
||||
OpenXRExtensions.GetLayerNextImageIndex(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)
|
||||
{
|
||||
PLog.e(TAG + $" Cubemap. The type of layerTextures is not a Cubemap!");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool enable = QualitySettings.activeColorSpace == ColorSpace.Gamma && texture != null && texture.format == RenderTextureFormat.ARGB32;
|
||||
|
||||
for (int f = 0; f < (int)overlayParam.faceCount; f++)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
PLog.d(TAG + $" gamma CopyTexture. f={f}");
|
||||
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
|
||||
{
|
||||
Graphics.Blit(layerTextures[i], renderTexture);
|
||||
}
|
||||
PLog.d(TAG + $" linear CopyTexture. f={f}");
|
||||
Graphics.CopyTexture(renderTexture, 0, 0, nativeTexture, f, 0);
|
||||
RenderTexture.ReleaseTemporary(renderTexture);
|
||||
}
|
||||
}
|
||||
copiedRT = true;
|
||||
}
|
||||
|
||||
return copiedRT;
|
||||
}
|
||||
|
||||
public void SetTexture(Texture texture, bool dynamic)
|
||||
{
|
||||
if (isClones)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (CompositeLayerFeature overlay in CompositeLayerFeature.Instances)
|
||||
{
|
||||
if (overlay.isClones && null != overlay.originalOverLay && overlay.originalOverLay.overlayIndex == overlayIndex)
|
||||
{
|
||||
overlay.DestroyLayer();
|
||||
overlay.isClonesToNew = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toCopyRT = false;
|
||||
OpenXRExtensions.DestroyLayerByRender(overlayIndex);
|
||||
ClearTexture();
|
||||
for (int i = 0; i < layerTextures.Length; i++)
|
||||
{
|
||||
layerTextures[i] = texture;
|
||||
}
|
||||
|
||||
isDynamic = dynamic;
|
||||
InitializeBuffer();
|
||||
|
||||
if (!isClones)
|
||||
{
|
||||
foreach (CompositeLayerFeature overlay in CompositeLayerFeature.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 (!isClones)
|
||||
{
|
||||
List<CompositeLayerFeature> toDestroyClones = new List<CompositeLayerFeature>();
|
||||
foreach (CompositeLayerFeature overlay in Instances)
|
||||
{
|
||||
if (overlay.isClones && null != overlay.originalOverLay && overlay.originalOverLay.overlayIndex == overlayIndex)
|
||||
{
|
||||
toDestroyClones.Add(overlay);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (CompositeLayerFeature overLay in toDestroyClones)
|
||||
{
|
||||
OpenXRExtensions.DestroyLayerByRender(overLay.overlayIndex);
|
||||
ClearTexture();
|
||||
}
|
||||
}
|
||||
|
||||
OpenXRExtensions.DestroyLayerByRender(overlayIndex);
|
||||
ClearTexture();
|
||||
}
|
||||
|
||||
private void ClearTexture()
|
||||
{
|
||||
FreePtr();
|
||||
|
||||
if (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, float factor)
|
||||
{
|
||||
offsetPosLeft = leftPos;
|
||||
offsetPosRight = rightPos;
|
||||
offsetRotLeft = leftRot;
|
||||
offsetRotRight = rightRot;
|
||||
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));
|
||||
// Debug.LogFormat("imageRectLeft width={0}, height={1}, x={2}, y={3}",imageRectLeft.width,imageRectLeft.height,imageRectLeft.x,imageRectLeft.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));
|
||||
// Debug.LogFormat("imageRectRight width={0}, height={1}, x={2}, y={3}",imageRectRight.width,imageRectRight.height,imageRectRight.x,imageRectRight.y);
|
||||
return imageRectRight;
|
||||
}
|
||||
}
|
||||
|
||||
public enum OverlayShape
|
||||
{
|
||||
Quad = 1,
|
||||
Cylinder = 2,
|
||||
Equirect = 4,
|
||||
Cubemap = 5,
|
||||
}
|
||||
|
||||
public enum OverlayType
|
||||
{
|
||||
Overlay = 0,
|
||||
Underlay = 1
|
||||
}
|
||||
|
||||
public enum TextureType
|
||||
{
|
||||
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 DegreeType
|
||||
{
|
||||
Eac360 = 0,
|
||||
Eac180 = 4,
|
||||
}
|
||||
|
||||
public enum ColorForamt
|
||||
{
|
||||
VK_FORMAT_R8G8B8A8_UNORM = 37,
|
||||
VK_FORMAT_R8G8B8A8_SRGB = 43,
|
||||
GL_SRGB8_ALPHA8 = 0x8c43,
|
||||
GL_RGBA8 = 0x8058
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 03ca3817c49e82b499325fde5c9e66ff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,338 @@
|
||||
/*******************************************************************************
|
||||
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;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
public class CompositeLayerManager : MonoBehaviour
|
||||
{
|
||||
private void OnEnable()
|
||||
{
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
if (GraphicsSettings.renderPipelineAsset != null)
|
||||
{
|
||||
RenderPipelineManager.beginFrameRendering += BeginRendering;
|
||||
RenderPipelineManager.endFrameRendering += EndRendering;
|
||||
}
|
||||
else
|
||||
{
|
||||
Camera.onPreRender += OnPreRenderCallBack;
|
||||
Camera.onPostRender += OnPostRenderCallBack;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
if (GraphicsSettings.renderPipelineAsset != null)
|
||||
{
|
||||
RenderPipelineManager.beginFrameRendering -= BeginRendering;
|
||||
RenderPipelineManager.endFrameRendering -= EndRendering;
|
||||
}
|
||||
else
|
||||
{
|
||||
Camera.onPreRender -= OnPreRenderCallBack;
|
||||
Camera.onPostRender -= OnPostRenderCallBack;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void BeginRendering(ScriptableRenderContext arg1, Camera[] arg2)
|
||||
{
|
||||
foreach (Camera cam in arg2)
|
||||
{
|
||||
OnPreRenderCallBack(cam);
|
||||
}
|
||||
}
|
||||
|
||||
private void EndRendering(ScriptableRenderContext arg1, Camera[] arg2)
|
||||
{
|
||||
foreach (Camera cam in arg2)
|
||||
{
|
||||
OnPostRenderCallBack(cam);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPreRenderCallBack(Camera cam)
|
||||
{
|
||||
// There is only one XR main camera in the scene.
|
||||
if (null == Camera.main) return;
|
||||
if (cam == null || cam != Camera.main || cam.stereoActiveEye == Camera.MonoOrStereoscopicEye.Right) return;
|
||||
|
||||
//CompositeLayers
|
||||
if (null == CompositeLayerFeature.Instances) return;
|
||||
if (CompositeLayerFeature.Instances.Count > 0)
|
||||
{
|
||||
foreach (var overlay in CompositeLayerFeature.Instances)
|
||||
{
|
||||
if (!overlay.isActiveAndEnabled) continue;
|
||||
if (null == overlay.layerTextures) continue;
|
||||
if (!overlay.isClones && overlay.layerTextures[0] == null && overlay.layerTextures[1] == null) continue;
|
||||
if (overlay.overlayTransform != null && !overlay.overlayTransform.gameObject.activeSelf) continue;
|
||||
overlay.CreateTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPostRenderCallBack(Camera cam)
|
||||
{
|
||||
// There is only one XR main camera in the scene.
|
||||
if (null == Camera.main) return;
|
||||
if (cam == null || cam != Camera.main || cam.stereoActiveEye == Camera.MonoOrStereoscopicEye.Right) return;
|
||||
|
||||
if (null == CompositeLayerFeature.Instances) return;
|
||||
if (CompositeLayerFeature.Instances.Count > 0)
|
||||
{
|
||||
CompositeLayerFeature.Instances.Sort();
|
||||
foreach (var compositeLayer in CompositeLayerFeature.Instances)
|
||||
{
|
||||
if (null == compositeLayer) continue;
|
||||
compositeLayer.UpdateCoords();
|
||||
if (!compositeLayer.isActiveAndEnabled) continue;
|
||||
if (null == compositeLayer.layerTextures) continue;
|
||||
if (!compositeLayer.isClones && compositeLayer.layerTextures[0] == null && compositeLayer.layerTextures[1] == null) continue;
|
||||
if (compositeLayer.overlayTransform != null && null == compositeLayer.overlayTransform.gameObject) continue;
|
||||
if (compositeLayer.overlayTransform != null && !compositeLayer.overlayTransform.gameObject.activeSelf) continue;
|
||||
|
||||
Vector4 colorScale = compositeLayer.GetLayerColorScale();
|
||||
Vector4 colorBias = compositeLayer.GetLayerColorOffset();
|
||||
bool isHeadLocked = compositeLayer.overlayTransform != null && compositeLayer.overlayTransform.parent == transform;
|
||||
|
||||
if (!compositeLayer.CopyRT()) continue;
|
||||
if (null == compositeLayer.cameraRotations || null == compositeLayer.modelScales || null == compositeLayer.modelTranslations) continue;
|
||||
|
||||
PxrLayerHeader2 header = new PxrLayerHeader2();
|
||||
PxrPosef poseLeft = new PxrPosef();
|
||||
PxrPosef poseRight = new PxrPosef();
|
||||
|
||||
header.layerId = compositeLayer.overlayIndex;
|
||||
header.colorScaleX = colorScale.x;
|
||||
header.colorScaleY = colorScale.y;
|
||||
header.colorScaleZ = colorScale.z;
|
||||
header.colorScaleW = colorScale.w;
|
||||
header.colorBiasX = colorBias.x;
|
||||
header.colorBiasY = colorBias.y;
|
||||
header.colorBiasZ = colorBias.z;
|
||||
header.colorBiasW = colorBias.w;
|
||||
header.compositionDepth = compositeLayer.layerDepth;
|
||||
header.headPose.orientation.x = compositeLayer.cameraRotations[0].x;
|
||||
header.headPose.orientation.y = compositeLayer.cameraRotations[0].y;
|
||||
header.headPose.orientation.z = -compositeLayer.cameraRotations[0].z;
|
||||
header.headPose.orientation.w = -compositeLayer.cameraRotations[0].w;
|
||||
header.headPose.position.x = (compositeLayer.cameraTranslations[0].x + compositeLayer.cameraTranslations[1].x) / 2;
|
||||
header.headPose.position.y = (compositeLayer.cameraTranslations[0].y + compositeLayer.cameraTranslations[1].y) / 2;
|
||||
header.headPose.position.z = -(compositeLayer.cameraTranslations[0].z + compositeLayer.cameraTranslations[1].z) / 2;
|
||||
header.layerShape = compositeLayer.overlayShape;
|
||||
header.useLayerBlend = (UInt32)(compositeLayer.useLayerBlend ? 1 : 0);
|
||||
header.layerBlend.srcColor = compositeLayer.srcColor;
|
||||
header.layerBlend.dstColor = compositeLayer.dstColor;
|
||||
header.layerBlend.srcAlpha = compositeLayer.srcAlpha;
|
||||
header.layerBlend.dstAlpha = compositeLayer.dstAlpha;
|
||||
header.useImageRect = (UInt32)(compositeLayer.useImageRect ? 1 : 0);
|
||||
header.imageRectLeft = compositeLayer.getPxrRectiLeft(true);
|
||||
header.imageRectRight = compositeLayer.getPxrRectiLeft(false);
|
||||
|
||||
if (isHeadLocked)
|
||||
{
|
||||
poseLeft.orientation.x = compositeLayer.overlayTransform.localRotation.x;
|
||||
poseLeft.orientation.y = compositeLayer.overlayTransform.localRotation.y;
|
||||
poseLeft.orientation.z = -compositeLayer.overlayTransform.localRotation.z;
|
||||
poseLeft.orientation.w = -compositeLayer.overlayTransform.localRotation.w;
|
||||
poseLeft.position.x = compositeLayer.overlayTransform.localPosition.x;
|
||||
poseLeft.position.y = compositeLayer.overlayTransform.localPosition.y;
|
||||
poseLeft.position.z = -compositeLayer.overlayTransform.localPosition.z;
|
||||
|
||||
poseRight.orientation.x = compositeLayer.overlayTransform.localRotation.x;
|
||||
poseRight.orientation.y = compositeLayer.overlayTransform.localRotation.y;
|
||||
poseRight.orientation.z = -compositeLayer.overlayTransform.localRotation.z;
|
||||
poseRight.orientation.w = -compositeLayer.overlayTransform.localRotation.w;
|
||||
poseRight.position.x = compositeLayer.overlayTransform.localPosition.x;
|
||||
poseRight.position.y = compositeLayer.overlayTransform.localPosition.y;
|
||||
poseRight.position.z = -compositeLayer.overlayTransform.localPosition.z;
|
||||
|
||||
header.layerFlags = (UInt32)(
|
||||
PxrLayerSubmitFlags.PxrLayerFlagLayerPoseNotInTrackingSpace |
|
||||
PxrLayerSubmitFlags.PxrLayerFlagHeadLocked);
|
||||
}
|
||||
else
|
||||
{
|
||||
Quaternion quaternion = new Quaternion(compositeLayer.modelRotations[0].x,
|
||||
compositeLayer.modelRotations[0].y, compositeLayer.modelRotations[0].z,
|
||||
compositeLayer.modelRotations[0].w);
|
||||
|
||||
Vector3 cameraPos = Vector3.zero;
|
||||
Quaternion cameraRot = Quaternion.identity;
|
||||
Transform origin = null;
|
||||
bool ret = PICOManager.Instance.GetOrigin(ref cameraPos, ref cameraRot, ref origin);
|
||||
if (!ret)
|
||||
{
|
||||
PLog.e(" GetOrigin ret false!");
|
||||
return;
|
||||
}
|
||||
|
||||
Quaternion lQuaternion = new Quaternion(-cameraRot.x, -cameraRot.y, -cameraRot.z, cameraRot.w);
|
||||
Vector3 pos = new Vector3(compositeLayer.modelTranslations[0].x - cameraPos.x,
|
||||
compositeLayer.modelTranslations[0].y - PICOManager.Instance.getCameraYOffset() +
|
||||
PICOManager.Instance.GetOriginY() - cameraPos.y, compositeLayer.modelTranslations[0].z - cameraPos.z);
|
||||
|
||||
quaternion *= lQuaternion;
|
||||
origin.rotation *= lQuaternion;
|
||||
pos = origin.TransformPoint(pos);
|
||||
|
||||
// Quaternion.l
|
||||
poseLeft.position.x = pos.x;
|
||||
poseLeft.position.y = pos.y;
|
||||
poseLeft.position.z = -pos.z;
|
||||
poseLeft.orientation.x = -quaternion.x;
|
||||
poseLeft.orientation.y = -quaternion.y;
|
||||
poseLeft.orientation.z = quaternion.z;
|
||||
poseLeft.orientation.w = quaternion.w;
|
||||
|
||||
poseRight.position.x = pos.x;
|
||||
poseRight.position.y = pos.y;
|
||||
poseRight.position.z = -pos.z;
|
||||
poseRight.orientation.x = -quaternion.x;
|
||||
poseRight.orientation.y = -quaternion.y;
|
||||
poseRight.orientation.z = quaternion.z;
|
||||
poseRight.orientation.w = quaternion.w;
|
||||
|
||||
header.layerFlags = (UInt32)(
|
||||
PxrLayerSubmitFlags.PxrLayerFlagUseExternalHeadPose |
|
||||
PxrLayerSubmitFlags.PxrLayerFlagLayerPoseNotInTrackingSpace);
|
||||
}
|
||||
|
||||
if (compositeLayer.overlayShape == CompositeLayerFeature.OverlayShape.Quad)
|
||||
{
|
||||
PxrLayerQuad layerSubmit2 = new PxrLayerQuad();
|
||||
layerSubmit2.header = header;
|
||||
layerSubmit2.poseLeft = poseLeft;
|
||||
layerSubmit2.poseRight = poseRight;
|
||||
layerSubmit2.sizeLeft.x = compositeLayer.modelScales[0].x;
|
||||
layerSubmit2.sizeLeft.y = compositeLayer.modelScales[0].y;
|
||||
layerSubmit2.sizeRight.x = compositeLayer.modelScales[0].x;
|
||||
layerSubmit2.sizeRight.y = compositeLayer.modelScales[0].y;
|
||||
|
||||
if (compositeLayer.useImageRect)
|
||||
{
|
||||
layerSubmit2.poseLeft.position.x += compositeLayer.modelScales[0].x * (-0.5f + compositeLayer.dstRectLeft.x + 0.5f * Mathf.Min(compositeLayer.dstRectLeft.width, 1 - compositeLayer.dstRectLeft.x));
|
||||
layerSubmit2.poseLeft.position.y += compositeLayer.modelScales[0].y * (-0.5f + compositeLayer.dstRectLeft.y + 0.5f * Mathf.Min(compositeLayer.dstRectLeft.height, 1 - compositeLayer.dstRectLeft.y));
|
||||
layerSubmit2.poseRight.position.x += compositeLayer.modelScales[0].x * (-0.5f + compositeLayer.dstRectRight.x + 0.5f * Mathf.Min(compositeLayer.dstRectRight.width, 1 - compositeLayer.dstRectRight.x));
|
||||
layerSubmit2.poseRight.position.y += compositeLayer.modelScales[0].y * (-0.5f + compositeLayer.dstRectRight.y + 0.5f * Mathf.Min(compositeLayer.dstRectRight.height, 1 - compositeLayer.dstRectRight.y));
|
||||
|
||||
layerSubmit2.sizeLeft.x = compositeLayer.modelScales[0].x * Mathf.Min(compositeLayer.dstRectLeft.width, 1 - compositeLayer.dstRectLeft.x);
|
||||
layerSubmit2.sizeLeft.y = compositeLayer.modelScales[0].y * Mathf.Min(compositeLayer.dstRectLeft.height, 1 - compositeLayer.dstRectLeft.y);
|
||||
layerSubmit2.sizeRight.x = compositeLayer.modelScales[0].x * Mathf.Min(compositeLayer.dstRectRight.width, 1 - compositeLayer.dstRectRight.x);
|
||||
layerSubmit2.sizeRight.y = compositeLayer.modelScales[0].y * Mathf.Min(compositeLayer.dstRectRight.height, 1 - compositeLayer.dstRectRight.y);
|
||||
}
|
||||
if (compositeLayer.layerSubmitPtr != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(compositeLayer.layerSubmitPtr);
|
||||
compositeLayer.layerSubmitPtr = IntPtr.Zero;
|
||||
}
|
||||
|
||||
compositeLayer.layerSubmitPtr = Marshal.AllocHGlobal(Marshal.SizeOf(layerSubmit2));
|
||||
Marshal.StructureToPtr(layerSubmit2, compositeLayer.layerSubmitPtr, false);
|
||||
|
||||
OpenXRExtensions.SubmitLayerQuad(compositeLayer.layerSubmitPtr);
|
||||
}
|
||||
else if (compositeLayer.overlayShape == CompositeLayerFeature.OverlayShape.Cylinder)
|
||||
{
|
||||
PxrLayerCylinder layerSubmit2 = new PxrLayerCylinder();
|
||||
layerSubmit2.header = header;
|
||||
layerSubmit2.poseLeft = poseLeft;
|
||||
layerSubmit2.poseRight = poseRight;
|
||||
|
||||
if (compositeLayer.modelScales[0].z != 0)
|
||||
{
|
||||
layerSubmit2.centralAngleLeft = compositeLayer.modelScales[0].x / compositeLayer.modelScales[0].z;
|
||||
layerSubmit2.centralAngleRight = compositeLayer.modelScales[0].x / compositeLayer.modelScales[0].z;
|
||||
}
|
||||
else
|
||||
{
|
||||
PLog.e("Cylinder modelScales scale.z is 0!");
|
||||
}
|
||||
layerSubmit2.heightLeft = compositeLayer.modelScales[0].y;
|
||||
layerSubmit2.heightRight = compositeLayer.modelScales[0].y;
|
||||
layerSubmit2.radiusLeft = compositeLayer.modelScales[0].z;
|
||||
layerSubmit2.radiusRight = compositeLayer.modelScales[0].z;
|
||||
|
||||
if (compositeLayer.layerSubmitPtr != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(compositeLayer.layerSubmitPtr);
|
||||
compositeLayer.layerSubmitPtr = IntPtr.Zero;
|
||||
}
|
||||
|
||||
compositeLayer.layerSubmitPtr = Marshal.AllocHGlobal(Marshal.SizeOf(layerSubmit2));
|
||||
Marshal.StructureToPtr(layerSubmit2, compositeLayer.layerSubmitPtr, false);
|
||||
|
||||
OpenXRExtensions.SubmitLayerCylinder(compositeLayer.layerSubmitPtr);
|
||||
}
|
||||
else if (compositeLayer.overlayShape == CompositeLayerFeature.OverlayShape.Equirect)
|
||||
{
|
||||
PxrLayerEquirect layerSubmit2 = new PxrLayerEquirect();
|
||||
layerSubmit2.header = header;
|
||||
layerSubmit2.poseLeft = poseLeft;
|
||||
layerSubmit2.poseRight = poseRight;
|
||||
|
||||
layerSubmit2.radiusLeft = compositeLayer.radius;
|
||||
layerSubmit2.radiusRight = compositeLayer.radius;
|
||||
layerSubmit2.centralHorizontalAngleLeft = compositeLayer.dstRectLeft.width * 2 * Mathf.PI;
|
||||
layerSubmit2.centralHorizontalAngleRight = compositeLayer.dstRectRight.width * 2 * Mathf.PI;
|
||||
layerSubmit2.upperVerticalAngleLeft = (compositeLayer.dstRectLeft.height + compositeLayer.dstRectLeft.y - 0.5f) * Mathf.PI;
|
||||
layerSubmit2.upperVerticalAngleRight = (compositeLayer.dstRectRight.height + compositeLayer.dstRectRight.y - 0.5f) * Mathf.PI;
|
||||
layerSubmit2.lowerVerticalAngleLeft = (compositeLayer.dstRectLeft.y - 0.5f) * Mathf.PI;
|
||||
layerSubmit2.lowerVerticalAngleRight = (compositeLayer.dstRectRight.y - 0.5f) * Mathf.PI;
|
||||
|
||||
if (compositeLayer.layerSubmitPtr != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(compositeLayer.layerSubmitPtr);
|
||||
compositeLayer.layerSubmitPtr = IntPtr.Zero;
|
||||
}
|
||||
|
||||
compositeLayer.layerSubmitPtr = Marshal.AllocHGlobal(Marshal.SizeOf(layerSubmit2));
|
||||
Marshal.StructureToPtr(layerSubmit2, compositeLayer.layerSubmitPtr, false);
|
||||
|
||||
OpenXRExtensions.SubmitLayerEquirect(compositeLayer.layerSubmitPtr);
|
||||
}
|
||||
else if (compositeLayer.overlayShape == CompositeLayerFeature.OverlayShape.Cubemap)
|
||||
{
|
||||
PxrLayerCube layerSubmit2 = new PxrLayerCube();
|
||||
layerSubmit2.header = header;
|
||||
layerSubmit2.poseLeft = poseLeft;
|
||||
layerSubmit2.poseRight = poseRight;
|
||||
|
||||
if (compositeLayer.layerSubmitPtr != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(compositeLayer.layerSubmitPtr);
|
||||
compositeLayer.layerSubmitPtr = IntPtr.Zero;
|
||||
}
|
||||
|
||||
compositeLayer.layerSubmitPtr = Marshal.AllocHGlobal(Marshal.SizeOf(layerSubmit2));
|
||||
Marshal.StructureToPtr(layerSubmit2, compositeLayer.layerSubmitPtr, false);
|
||||
|
||||
OpenXRExtensions.SubmitLayerCube(compositeLayer.layerSubmitPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9164f0a21d04d4544bc6682b3b94ddea
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Unity.Collections;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.OpenXR;
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor.XR.OpenXR.Features;
|
||||
#endif
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
public enum SystemDisplayFrequency
|
||||
{
|
||||
Default,
|
||||
RefreshRate72=72,
|
||||
RefreshRate90=90,
|
||||
RefreshRate120=120,
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
[OpenXRFeature(UiName = "OpenXR Display Refresh Rate",
|
||||
Hidden = false,
|
||||
BuildTargetGroups = new[] { UnityEditor.BuildTargetGroup.Android },
|
||||
Company = "PICO",
|
||||
OpenxrExtensionStrings = extensionString,
|
||||
Version = "1.0.0",
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class DisplayRefreshRateFeature : OpenXRFeatureBase
|
||||
{
|
||||
public const string featureId = "com.pico.openxr.feature.refreshrate";
|
||||
public const string extensionString = "XR_FB_display_refresh_rate";
|
||||
public static bool isExtensionEnable =false;
|
||||
public override void Initialize(IntPtr intPtr)
|
||||
{
|
||||
isExtensionEnable=_isExtensionEnable;
|
||||
initialize(intPtr, xrInstance);
|
||||
}
|
||||
public override string GetExtensionString()
|
||||
{
|
||||
return extensionString;
|
||||
}
|
||||
|
||||
public override void SessionCreate()
|
||||
{
|
||||
PICOProjectSetting projectConfig = PICOProjectSetting.GetProjectConfig();
|
||||
if (projectConfig.displayFrequency != SystemDisplayFrequency.Default)
|
||||
{
|
||||
float displayRefreshRate = 0;
|
||||
GetDisplayRefreshRate(ref displayRefreshRate);
|
||||
PLog.i($"GetDisplayRefreshRate:{displayRefreshRate}");
|
||||
SetDisplayRefreshRate(projectConfig.displayFrequency);
|
||||
}
|
||||
}
|
||||
public static bool SetDisplayRefreshRate(SystemDisplayFrequency DisplayFrequency)
|
||||
{
|
||||
if (!isExtensionEnable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
PLog.i($"SetDisplayRefreshRate:{DisplayFrequency}");
|
||||
float rate = 0;
|
||||
switch (DisplayFrequency)
|
||||
{
|
||||
case SystemDisplayFrequency.Default:
|
||||
return true;
|
||||
case SystemDisplayFrequency.RefreshRate72:
|
||||
rate = 72;
|
||||
break;
|
||||
case SystemDisplayFrequency.RefreshRate90:
|
||||
rate = 90;
|
||||
break;
|
||||
case SystemDisplayFrequency.RefreshRate120:
|
||||
rate = 120;
|
||||
break;
|
||||
}
|
||||
|
||||
return SetDisplayRefreshRate(rate);
|
||||
}
|
||||
|
||||
public static bool GetDisplayRefreshRate(ref float displayRefreshRate)
|
||||
{
|
||||
if (!isExtensionEnable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return xrGetDisplayRefreshRateFB(
|
||||
xrSession, ref displayRefreshRate);
|
||||
}
|
||||
|
||||
private static bool SetDisplayRefreshRate(float displayRefreshRate)
|
||||
{
|
||||
if (!isExtensionEnable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return xrRequestDisplayRefreshRateFB(
|
||||
xrSession, displayRefreshRate);
|
||||
}
|
||||
|
||||
private static bool EnumerateDisplayRefreshRates(uint displayRefreshRateCapacityInput,
|
||||
ref uint displayRefreshRateCountOutput, ref float displayRefreshRates)
|
||||
{
|
||||
if (!isExtensionEnable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return xrEnumerateDisplayRefreshRatesFB(
|
||||
xrSession, displayRefreshRateCapacityInput, ref displayRefreshRateCountOutput, ref displayRefreshRates);
|
||||
}
|
||||
|
||||
public static int GetDisplayRefreshRateCount()
|
||||
{
|
||||
if (!isExtensionEnable)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return xrGetDisplayRefreshRateCount(xrSession);
|
||||
}
|
||||
|
||||
public static bool TryGetSupportedDisplayRefreshRates(
|
||||
Allocator allocator, out NativeArray<float> refreshRates)
|
||||
{
|
||||
refreshRates = default;
|
||||
|
||||
if (!isExtensionEnable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var numDisplayRefreshRates = xrGetDisplayRefreshRateCount(xrSession);
|
||||
if (numDisplayRefreshRates == 0)
|
||||
{
|
||||
Debug.LogError($"{nameof(TryGetSupportedDisplayRefreshRates)} failed due to an unknown error.");
|
||||
return false;
|
||||
}
|
||||
|
||||
unsafe
|
||||
{
|
||||
refreshRates = new NativeArray<float>(numDisplayRefreshRates, allocator);
|
||||
if (!refreshRates.IsCreated)
|
||||
return false;
|
||||
|
||||
return TryGetDisplayRefreshRates(xrSession,
|
||||
NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(refreshRates),
|
||||
(uint)numDisplayRefreshRates);
|
||||
}
|
||||
}
|
||||
|
||||
private const string ExtLib = "openxr_pico";
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_initialize_DisplayRefreshRates", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void initialize(IntPtr xrGetInstanceProcAddr, ulong xrInstance);
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_xrEnumerateDisplayRefreshRatesFB", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool xrEnumerateDisplayRefreshRatesFB(ulong xrSession,
|
||||
uint displayRefreshRateCapacityInput, ref uint displayRefreshRateCountOutput,
|
||||
ref float displayRefreshRates);
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_xrGetDisplayRefreshRateFB", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool xrGetDisplayRefreshRateFB(ulong xrSession, ref float displayRefreshRate);
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_xrRequestDisplayRefreshRateFB", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool xrRequestDisplayRefreshRateFB(ulong xrSession, float displayRefreshRate);
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_xrGetDisplayRefreshRateCount", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int xrGetDisplayRefreshRateCount(ulong xrSession);
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_xrTryGetDisplayRefreshRates", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern unsafe bool TryGetDisplayRefreshRates(ulong xrSession,void* refreshRates, uint capacity);
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 233eef4f97ef4b0b8b65c5030c0b05f7
|
||||
timeCreated: 1685686551
|
@ -0,0 +1,159 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
using System.Runtime.InteropServices;
|
||||
using System;
|
||||
using Unity.XR.OpenXR.Features.PICOSupport;
|
||||
using UnityEngine;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor.XR.OpenXR.Features;
|
||||
|
||||
[OpenXRFeature(UiName = "OpenXR Foveation",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Android },
|
||||
OpenxrExtensionStrings = extensionList,
|
||||
Company = "PICO",
|
||||
Version = "1.0.0",
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
|
||||
|
||||
public class FoveationFeature : OpenXRFeatureBase
|
||||
{
|
||||
public const string extensionList = "XR_FB_foveation " +
|
||||
"XR_FB_foveation_configuration " +
|
||||
"XR_FB_foveation_vulkan " +
|
||||
"XR_META_foveation_eye_tracked " +
|
||||
"XR_META_vulkan_swapchain_create_info " +
|
||||
"XR_FB_swapchain_update_state ";
|
||||
|
||||
public const string featureId = "com.pico.openxr.feature.foveation";
|
||||
|
||||
public enum FoveatedRenderingLevel
|
||||
{
|
||||
Off = 0,
|
||||
Low = 1,
|
||||
Medium = 2,
|
||||
High = 3
|
||||
}
|
||||
public enum FoveatedRenderingMode
|
||||
{
|
||||
FixedFoveatedRendering = 0,
|
||||
EyeTrackedFoveatedRendering = 1
|
||||
}
|
||||
private static string TAG = "FoveationFeature";
|
||||
|
||||
private static UInt32 _foveatedRenderingLevel = 0;
|
||||
private static UInt32 _useDynamicFoveation = 0;
|
||||
public static bool isExtensionEnable =false;
|
||||
|
||||
public override string GetExtensionString()
|
||||
{
|
||||
return extensionList;
|
||||
}
|
||||
public override void Initialize(IntPtr intPtr)
|
||||
{
|
||||
isExtensionEnable=_isExtensionEnable;
|
||||
}
|
||||
public override void SessionCreate()
|
||||
{
|
||||
if (!isExtensionEnable)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
PICOProjectSetting projectConfig = PICOProjectSetting.GetProjectConfig();
|
||||
if (projectConfig.foveationEnable)
|
||||
{
|
||||
setFoveationEyeTracked(projectConfig.foveatedRenderingMode ==
|
||||
FoveatedRenderingMode.EyeTrackedFoveatedRendering);
|
||||
foveatedRenderingLevel = projectConfig.foveatedRenderingLevel;
|
||||
setSubsampledEnabled(projectConfig.isSubsampledEnabled);
|
||||
}
|
||||
}
|
||||
public static FoveatedRenderingLevel foveatedRenderingLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!isExtensionEnable)
|
||||
{
|
||||
return FoveatedRenderingLevel.Off;
|
||||
}
|
||||
UInt32 level;
|
||||
FBGetFoveationLevel(out level);
|
||||
PLog.i($" foveatedRenderingLevel get if level= {level}");
|
||||
return (FoveatedRenderingLevel)level;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (!isExtensionEnable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
PLog.i($" foveatedRenderingLevel set if value= {value}");
|
||||
_foveatedRenderingLevel = (UInt32)value;
|
||||
FBSetFoveationLevel(xrSession, _foveatedRenderingLevel, 0.0f, _useDynamicFoveation);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool useDynamicFoveatedRendering
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!isExtensionEnable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
UInt32 dynamic;
|
||||
FBGetFoveationLevel(out dynamic);
|
||||
return dynamic != 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (!isExtensionEnable)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
if (value)
|
||||
_useDynamicFoveation = 1;
|
||||
else
|
||||
_useDynamicFoveation = 0;
|
||||
FBSetFoveationLevel(xrSession, _foveatedRenderingLevel, 0.0f, _useDynamicFoveation);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool supportsFoveationEyeTracked
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!isExtensionEnable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return isSupportsFoveationEyeTracked(xrInstance);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region OpenXR Plugin DLL Imports
|
||||
|
||||
[DllImport("UnityOpenXR", EntryPoint = "FBSetFoveationLevel")]
|
||||
private static extern void FBSetFoveationLevel(UInt64 session, UInt32 level, float verticalOffset, UInt32 dynamic);
|
||||
|
||||
[DllImport("UnityOpenXR", EntryPoint = "FBGetFoveationLevel")]
|
||||
private static extern void FBGetFoveationLevel(out UInt32 level);
|
||||
|
||||
[DllImport("UnityOpenXR", EntryPoint = "FBGetFoveationDynamic")]
|
||||
private static extern void FBGetFoveationDynamic(out UInt32 dynamic);
|
||||
|
||||
#endregion
|
||||
|
||||
const string extLib = "openxr_pico";
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_isSupportsFoveationEyeTracked", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool isSupportsFoveationEyeTracked(ulong xrInstance);
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_setFoveationEyeTracked", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void setFoveationEyeTracked(bool value);
|
||||
[DllImport(extLib, EntryPoint = "PICO_setSubsampledEnabled", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void setSubsampledEnabled(bool value);
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f636716e11d15b4bbafb76eb9d63555
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.OpenXR;
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor.XR.OpenXR.Features;
|
||||
#endif
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
[OpenXRFeature(UiName = "OpenXR Composition Layer Secure Content",
|
||||
Hidden = false,
|
||||
BuildTargetGroups = new[] { UnityEditor.BuildTargetGroup.Android },
|
||||
Company = "PICO",
|
||||
OpenxrExtensionStrings = extensionString,
|
||||
Version = "1.0.0",
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class LayerSecureContentFeature : OpenXRFeatureBase
|
||||
{
|
||||
public const string featureId = "com.pico.openxr.feature.LayerSecureContent";
|
||||
public const string extensionString = "XR_FB_composition_layer_secure_content";
|
||||
|
||||
public static bool isExtensionEnable =false;
|
||||
public override string GetExtensionString()
|
||||
{
|
||||
return extensionString;
|
||||
}
|
||||
|
||||
public override void Initialize(IntPtr intPtr)
|
||||
{
|
||||
isExtensionEnable=_isExtensionEnable;
|
||||
}
|
||||
public override void SessionCreate()
|
||||
{
|
||||
PICOProjectSetting projectConfig = PICOProjectSetting.GetProjectConfig();
|
||||
if (projectConfig.useContentProtect)
|
||||
{
|
||||
SetSecureContentFlag(projectConfig.contentProtectFlags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void SetSecureContentFlag(SecureContentFlag flag)
|
||||
{
|
||||
if (!isExtensionEnable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setSecureContentFlag((int)flag);
|
||||
}
|
||||
|
||||
const string extLib = "openxr_pico";
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_setSecureContentFlag", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void setSecureContentFlag(Int32 flag);
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 105a2b5276c1435d8411162e42e5064e
|
||||
timeCreated: 1687177588
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 11da15b829408094e9a647e4b3d566c7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,927 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Unity.Collections;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
using Unity.XR.OpenXR.Features.PICOSupport;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
public partial class PXR_Plugin
|
||||
{
|
||||
public static class MixedReality
|
||||
{
|
||||
private const string TAG = "[MR_Plugin/MixedReality]";
|
||||
const string PXR_PLATFORM_DLL = "openxr_pico";
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int Pxr_SetMeshLOD(ushort spatialMeshLod);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_StartSenseDataProviderAsync(ulong providerHandle, out ulong future);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_PollFutureEXT(ref XrFuturePollInfoEXT pollInfo, ref XrFuturePollResultEXT pollResult);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_CreateSenseDataProvider(ref XrSenseDataProviderCreateInfoBaseHeader createInfo, out ulong providerHandle);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_StartSenseDataProviderComplete(ulong future, ref XrSenseDataProviderStartCompletion completion);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_GetSenseDataProviderState(ulong providerHandle, ref PxrSenseDataProviderState state);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_StopSenseDataProvider(ulong providerHandle);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_DestroySenseDataProvider(ulong providerHandle);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_CreateSpatialAnchorAsync(ulong providerHandle, ref PxrPosef info, out ulong future);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_CreateSpatialAnchorComplete(ulong providerHandle, ulong future, ref XrSpatialAnchorCompletion completion);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_PersistSpatialAnchorAsync(ulong providerHandle, ref XrSpatialAnchorPersistInfo info, out ulong future);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_PersistSpatialAnchorComplete(ulong providerHandle, ulong future, ref XrSpatialAnchorCompletion completion);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_DestroyAnchor(ulong anchorHandle);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_QuerySenseDataAsync(ulong providerHandle, ref XrSenseDataQueryInfo info, out ulong future);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_QuerySenseDataComplete(ulong providerHandle, ulong future, ref XrSenseDataQueryCompletion completion);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_GetQueriedSenseData(ulong providerHandle, ref XrQueriedSenseDataGetInfo info, ref XrQueriedSenseData senseData);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_RetrieveSpatialEntityAnchor(ulong snapshotHandle, ref XrSpatialEntityAnchorRetrieveInfo info, out ulong anchorHandle);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_DestroySenseDataQueryResult(ulong snapshotHandle);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_LocateAnchor(ulong anchorHandle, ref XrSpaceLocation location);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_GetAnchorUuid(ulong anchorHandle, out PxrUuid uuid);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_UnpersistSpatialAnchorAsync(ulong providerHandle, ref XrSpatialAnchorUnpersistInfo info, out ulong future);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_UnpersistSpatialAnchorComplete(ulong providerHandle, ulong future, ref XrSpatialAnchorCompletion completion);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_StartSceneCaptureAsync(ulong providerHandle, out ulong future);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_StartSceneCaptureComplete(ulong providerHandle, ulong future, ref XrSceneCaptureStartCompletion completion);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_EnumerateSpatialEntityComponentTypes(ulong snapshotHandle, ulong spatialEntity, uint inputCount, out uint outputCount,
|
||||
IntPtr types);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern ulong Pxr_GetSpatialMeshProviderHandle();
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_GetSpatialEntityComponentInfo(ulong snapshotHandle, ref XrSpatialEntityComponentGetInfoBaseHeader componentGetInfo,
|
||||
ref XrSpatialEntityComponentDataBaseHeader componentInfo);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_GetSpatialEntitySemanticInfo(ulong snapshotHandle, ref XrSpatialEntityGetInfo componentGetInfo,
|
||||
ref XrSpatialEntitySemanticData componentInfo);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_GetSpatialEntityLocationInfo(ulong snapshotHandle, ref XrSpatialEntityLocationGetInfo componentGetInfo,
|
||||
ref XrSpatialEntityLocationData componentInfo);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_GetSpatialEntityBox3DInfo(ulong snapshotHandle, ref XrSpatialEntityGetInfo componentGetInfo,
|
||||
ref XrSpatialEntityBoundingBox3DData componentInfo);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_GetSpatialEntityBox2DInfo(ulong snapshotHandle, ref XrSpatialEntityGetInfo componentGetInfo,
|
||||
ref XrSpatialEntityBoundingBox2DData componentInfo);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_GetSpatialEntityPolygonInfo(ulong snapshotHandle, ref XrSpatialEntityGetInfo componentGetInfo,
|
||||
ref XrSpatialEntityPolygonData componentInfo);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int Pxr_GetSpatialMeshVerticesAndIndices(ulong snapshotHandle, ref XrSpatialEntityGetInfo componentGetInfo,
|
||||
ref PxrTriangleMeshInfo componentInfo);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern unsafe void Pxr_AddOrUpdateMesh(ulong id1, ulong id2, int numVertices, void* vertices, int numTriangles, void* indices,
|
||||
Vector3 position, Quaternion rotation);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void Pxr_RemoveMesh(ulong id1, ulong id2);
|
||||
|
||||
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void Pxr_ClearMeshes();
|
||||
public static ulong SpatialAnchorProviderHandle { get; set; }
|
||||
public static ulong SceneCaptureProviderHandle { get; set; }
|
||||
|
||||
|
||||
public static Dictionary<Guid, ulong> meshAnchorLastData = new Dictionary<Guid, ulong>();
|
||||
public static Dictionary<ulong, PxrSceneComponentData> SceneAnchorData = new Dictionary<ulong, PxrSceneComponentData>();
|
||||
public static Dictionary<Guid, PxrSpatialMeshInfo> SpatialMeshData = new Dictionary<Guid, PxrSpatialMeshInfo>();
|
||||
private static readonly Dictionary<Guid, List<IDisposable>> nativeMeshArrays = new Dictionary<Guid, List<IDisposable>>();
|
||||
|
||||
public static ulong UPxr_GetSenseDataProviderHandle(PxrSenseDataProviderType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PxrSenseDataProviderType.SpatialAnchor:
|
||||
return SpatialAnchorProviderHandle;
|
||||
case PxrSenseDataProviderType.SceneCapture:
|
||||
return SceneCaptureProviderHandle;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(type), type, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_StartSenseDataProviderAsync(ulong providerHandle, out ulong future)
|
||||
{
|
||||
future = UInt64.MinValue;
|
||||
var pxrResult = (PxrResult)Pxr_StartSenseDataProviderAsync(providerHandle, out future);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_PollFuture(ulong future, out PxrFutureState futureState)
|
||||
{
|
||||
XrFuturePollInfoEXT pollInfo = new XrFuturePollInfoEXT()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_FUTURE_POLL_INFO_EXT,
|
||||
future = future,
|
||||
};
|
||||
XrFuturePollResultEXT pollResult = new XrFuturePollResultEXT()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_FUTURE_POLL_RESULT_EXT,
|
||||
};
|
||||
var pxrResult = (PxrResult)Pxr_PollFutureEXT(ref pollInfo, ref pollResult);
|
||||
futureState = pollResult.state;
|
||||
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_CreateSenseDataProvider(ref XrSenseDataProviderCreateInfoBaseHeader info, out ulong providerHandle)
|
||||
{
|
||||
var pxrResult = (PxrResult)Pxr_CreateSenseDataProvider(ref info, out providerHandle);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_CreateSpatialAnchorSenseDataProvider()
|
||||
{
|
||||
XrSenseDataProviderCreateInfoBaseHeader header = new XrSenseDataProviderCreateInfoBaseHeader()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SENSE_DATA_PROVIDER_CREATE_INFO_SPATIAL_ANCHOR
|
||||
};
|
||||
|
||||
var pxrResult = UPxr_CreateSenseDataProvider(ref header, out var providerHandle);
|
||||
SpatialAnchorProviderHandle = providerHandle;
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_CreateSceneCaptureSenseDataProvider()
|
||||
{
|
||||
XrSenseDataProviderCreateInfoBaseHeader header = new XrSenseDataProviderCreateInfoBaseHeader()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SENSE_DATA_PROVIDER_CREATE_INFO_SCENE_CAPTURE,
|
||||
};
|
||||
|
||||
var pxrResult = UPxr_CreateSenseDataProvider(ref header, out var providerHandle);
|
||||
SceneCaptureProviderHandle = providerHandle;
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_StartSenseDataProviderComplete(ulong future, out XrSenseDataProviderStartCompletion completion)
|
||||
{
|
||||
completion = new XrSenseDataProviderStartCompletion()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SENSE_DATA_PROVIDER_START_COMPLETION,
|
||||
};
|
||||
var pxrResult = (PxrResult)Pxr_StartSenseDataProviderComplete(future, ref completion);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_GetSenseDataProviderState(ulong providerHandle, out PxrSenseDataProviderState state)
|
||||
{
|
||||
state = PxrSenseDataProviderState.Stopped;
|
||||
var pxrResult = (PxrResult)Pxr_GetSenseDataProviderState(providerHandle, ref state);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_StopSenseDataProvide(ulong providerHandle)
|
||||
{
|
||||
var pxrResult = (PxrResult)Pxr_StopSenseDataProvider(providerHandle);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_DestroySenseDataProvider(ulong providerHandle)
|
||||
{
|
||||
var pxrResult = (PxrResult)Pxr_DestroySenseDataProvider(providerHandle);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_CreateSpatialAnchorAsync(ulong providerHandle, Vector3 position, Quaternion rotation, out ulong future)
|
||||
{
|
||||
PxrPosef pose = new PxrPosef()
|
||||
{
|
||||
orientation = new PxrVector4f()
|
||||
{
|
||||
x = rotation.x,
|
||||
y = rotation.y,
|
||||
z = -rotation.z,
|
||||
w = -rotation.w
|
||||
},
|
||||
position = new PxrVector3f()
|
||||
{
|
||||
x = position.x,
|
||||
y = position.y,
|
||||
z = -position.z
|
||||
}
|
||||
};
|
||||
var pxrResult = (PxrResult)Pxr_CreateSpatialAnchorAsync(providerHandle, ref pose, out future);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_CreateSpatialAnchorComplete(ulong providerHandle, ulong future, out XrSpatialAnchorCompletion completion)
|
||||
{
|
||||
completion = new XrSpatialAnchorCompletion()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ANCHOR_CREATE_COMPLETION
|
||||
};
|
||||
var pxrResult = (PxrResult)Pxr_CreateSpatialAnchorComplete(providerHandle, future, ref completion);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_PersistSpatialAnchorAsync(ulong providerHandle, ulong anchorHandle, out ulong future)
|
||||
{
|
||||
XrSpatialAnchorPersistInfo persistInfo = new XrSpatialAnchorPersistInfo()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ANCHOR_PERSIST_INFO,
|
||||
location = PxrPersistenceLocation.Local,
|
||||
anchorHandle = anchorHandle
|
||||
};
|
||||
var pxrResult = (PxrResult)Pxr_PersistSpatialAnchorAsync(providerHandle, ref persistInfo, out future);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_PersistSpatialAnchorComplete(ulong providerHandle,ulong future,out XrSpatialAnchorCompletion completion)
|
||||
{
|
||||
completion = new XrSpatialAnchorCompletion()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ANCHOR_PERSIST_COMPLETION,
|
||||
};
|
||||
var pxrResult = (PxrResult)Pxr_PersistSpatialAnchorComplete(providerHandle, future, ref completion);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_DestroyAnchor(ulong anchorHandle)
|
||||
{
|
||||
var pxrResult = (PxrResult)Pxr_DestroyAnchor(anchorHandle);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_QuerySenseDataAsync(ulong providerHandle,ref XrSenseDataQueryInfo info, out ulong future)
|
||||
{
|
||||
var pxrResult = (PxrResult)Pxr_QuerySenseDataAsync(providerHandle, ref info, out future);
|
||||
return pxrResult;
|
||||
}
|
||||
public static PxrResult UPxr_QuerySenseDataByUuidAsync(Guid[] uuids, out ulong future)
|
||||
{
|
||||
XrSenseDataQueryInfo info = new XrSenseDataQueryInfo()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SENSE_DATA_QUERY_INFO,
|
||||
};
|
||||
XrSenseDataFilterUuid uuidFilter = new XrSenseDataFilterUuid()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SENSE_DATA_FILTER_UUID
|
||||
};
|
||||
|
||||
if (uuids.Length > 0)
|
||||
{
|
||||
uuidFilter.uuidCount = (uint)uuids.Length;
|
||||
uuidFilter.uuidList = Marshal.AllocHGlobal(uuids.Length * Marshal.SizeOf(typeof(Guid)));
|
||||
byte[] bytes = uuids.SelectMany(g => g.ToByteArray()).ToArray();
|
||||
Marshal.Copy(bytes, 0, uuidFilter.uuidList, uuids.Length * Marshal.SizeOf(typeof(Guid)));
|
||||
int size = Marshal.SizeOf<XrSenseDataFilterUuid>();
|
||||
info.filter = Marshal.AllocHGlobal(size);
|
||||
Marshal.StructureToPtr(uuidFilter, info.filter, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
info.filter = IntPtr.Zero;
|
||||
}
|
||||
|
||||
var pxrResult = UPxr_QuerySenseDataAsync(UPxr_GetSenseDataProviderHandle(PxrSenseDataProviderType.SpatialAnchor), ref info, out future);
|
||||
Marshal.FreeHGlobal(uuidFilter.uuidList);
|
||||
Marshal.FreeHGlobal(info.filter);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_QuerySenseDataComplete(ulong providerHandle,ulong future,out XrSenseDataQueryCompletion completion)
|
||||
{
|
||||
completion = new XrSenseDataQueryCompletion()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SENSE_DATA_QUERY_COMPLETION,
|
||||
};
|
||||
var pxrResult = (PxrResult)Pxr_QuerySenseDataComplete(providerHandle, future,ref completion);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static PxrResult UPxr_GetQueriedSenseData(ulong providerHandle, ulong snapshotHandle, out List<PxrQueriedSpatialEntityInfo> entityinfos)
|
||||
{
|
||||
XrQueriedSenseDataGetInfo info = new XrQueriedSenseDataGetInfo()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_QUERIED_SENSE_DATA_GET_INFO,
|
||||
snapshotHandle = snapshotHandle
|
||||
};
|
||||
|
||||
XrQueriedSenseData senseDataFirst = new XrQueriedSenseData()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_QUERIED_SENSE_DATA_GET_INFO,
|
||||
queriedSpatialEntityCapacityInput = 0,
|
||||
queriedSpatialEntityCountOutput = 0,
|
||||
};
|
||||
|
||||
var getResultFirst = (PxrResult)Pxr_GetQueriedSenseData(providerHandle, ref info, ref senseDataFirst);
|
||||
if (getResultFirst == PxrResult.SUCCESS)
|
||||
{
|
||||
XrQueriedSenseData senseDataSecond = new XrQueriedSenseData()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_QUERIED_SENSE_DATA_GET_INFO,
|
||||
queriedSpatialEntityCapacityInput = senseDataFirst.queriedSpatialEntityCountOutput,
|
||||
queriedSpatialEntityCountOutput = senseDataFirst.queriedSpatialEntityCountOutput,
|
||||
};
|
||||
int resultSize = Marshal.SizeOf<PxrQueriedSpatialEntityInfo>();
|
||||
// Debug.Log("[PoxrUnity] PxrQueriedSpatialEntityInfo size:"+resultSize);
|
||||
int bytesSize = (int)senseDataFirst.queriedSpatialEntityCountOutput * resultSize;
|
||||
senseDataSecond.queriedSpatialEntities = Marshal.AllocHGlobal(bytesSize);
|
||||
var getResultSecond = (PxrResult)Pxr_GetQueriedSenseData(providerHandle, ref info, ref senseDataSecond);
|
||||
entityinfos = new List<PxrQueriedSpatialEntityInfo>();
|
||||
if (getResultSecond==PxrResult.SUCCESS)
|
||||
{
|
||||
for (int i = 0; i < senseDataFirst.queriedSpatialEntityCountOutput; i++)
|
||||
{
|
||||
PxrQueriedSpatialEntityInfo t =
|
||||
(PxrQueriedSpatialEntityInfo)Marshal.PtrToStructure(senseDataSecond.queriedSpatialEntities + i * resultSize,
|
||||
typeof(PxrQueriedSpatialEntityInfo));
|
||||
// Debug.Log($"[PoxrUnity] {i} spatialEntity="+t.spatialEntity);
|
||||
entityinfos.Add(t);
|
||||
}
|
||||
}
|
||||
Marshal.FreeHGlobal(senseDataSecond.queriedSpatialEntities);
|
||||
return getResultSecond;
|
||||
}
|
||||
else
|
||||
{
|
||||
entityinfos = new List<PxrQueriedSpatialEntityInfo>();
|
||||
return getResultFirst;
|
||||
}
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_RetrieveSpatialEntityAnchor(ulong snapshotHandle, ulong spatialEntityHandle,out ulong anchorHandle)
|
||||
{
|
||||
XrSpatialEntityAnchorRetrieveInfo info = new XrSpatialEntityAnchorRetrieveInfo()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ENTITY_ANCHOR_RETRIEVE_INFO,
|
||||
spatialEntity = spatialEntityHandle,
|
||||
};
|
||||
var pxrResult = (PxrResult)Pxr_RetrieveSpatialEntityAnchor(snapshotHandle, ref info,out anchorHandle);
|
||||
return pxrResult;
|
||||
}
|
||||
public static PxrResult UPxr_DestroySenseDataQueryResult(ulong queryResultHandle)
|
||||
{
|
||||
var pxrResult = (PxrResult)Pxr_DestroySenseDataQueryResult(queryResultHandle);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_LocateAnchor(ulong anchorHandle, out Vector3 position, out Quaternion rotation)
|
||||
{
|
||||
|
||||
|
||||
XrSpaceLocation location = new XrSpaceLocation()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPACE_LOCATION,
|
||||
};
|
||||
var pxrResult = (PxrResult)Pxr_LocateAnchor(anchorHandle, ref location);
|
||||
foreach (PxrSpaceLocationFlags value in Enum.GetValues(typeof(PxrSpaceLocationFlags)))
|
||||
{
|
||||
if ((location.locationFlags & (ulong)value) != (ulong)value)
|
||||
{
|
||||
position = Vector3.zero;
|
||||
rotation = Quaternion.identity;
|
||||
return PxrResult.ERROR_POSE_INVALID;
|
||||
}
|
||||
}
|
||||
rotation = new Quaternion(location.pose.orientation.x, location.pose.orientation.y, -location.pose.orientation.z, -location.pose.orientation.w);
|
||||
position = new Vector3(location.pose.position.x, location.pose.position.y, -location.pose.position.z);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_GetAnchorUuid(ulong anchorHandle, out Guid uuid)
|
||||
{
|
||||
var pxrResult = (PxrResult)Pxr_GetAnchorUuid(anchorHandle,out var pUuid);
|
||||
byte[] byteArray = new byte[16];
|
||||
BitConverter.GetBytes(pUuid.value0).CopyTo(byteArray, 0);
|
||||
BitConverter.GetBytes(pUuid.value1).CopyTo(byteArray, 8);
|
||||
// Debug.Log($"GetAnchorUuid, uuid byteArray result is {string.Join(", ", byteArray)}");
|
||||
uuid = new Guid(byteArray);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
|
||||
public static PxrResult UPxr_UnPersistSpatialAnchorAsync(ulong providerHandle, ulong anchorHandle, out ulong future)
|
||||
{
|
||||
XrSpatialAnchorUnpersistInfo unPersistInfo = new XrSpatialAnchorUnpersistInfo()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ANCHOR_UNPERSIST_INFO,
|
||||
location = PxrPersistenceLocation.Local,
|
||||
anchorHandle = anchorHandle
|
||||
};
|
||||
var pxrResult = (PxrResult)Pxr_UnpersistSpatialAnchorAsync(providerHandle, ref unPersistInfo, out future);
|
||||
return pxrResult;
|
||||
}
|
||||
public static PxrResult UPxr_UnPersistSpatialAnchorComplete(ulong providerHandle,ulong future, out XrSpatialAnchorCompletion completion)
|
||||
{
|
||||
completion = new XrSpatialAnchorCompletion()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ANCHOR_UNPERSIST_COMPLETION,
|
||||
};
|
||||
var pxrResult = (PxrResult)Pxr_UnpersistSpatialAnchorComplete(providerHandle, future, ref completion);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_StartSceneCaptureAsync(out ulong future)
|
||||
{
|
||||
var pxrResult = (PxrResult)Pxr_StartSceneCaptureAsync(UPxr_GetSenseDataProviderHandle(PxrSenseDataProviderType.SceneCapture), out future);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_StartSceneCaptureComplete(ulong future,out XrSceneCaptureStartCompletion completion)
|
||||
{
|
||||
completion = new XrSceneCaptureStartCompletion()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SCENE_CAPTURE_START_COMPLETION
|
||||
};
|
||||
var pxrResult = (PxrResult)Pxr_StartSceneCaptureComplete(UPxr_GetSenseDataProviderHandle(PxrSenseDataProviderType.SceneCapture), future,ref completion);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_QuerySenseDataBySemanticAsync(PxrSemanticLabel[] labels, out ulong future)
|
||||
{
|
||||
XrSenseDataQueryInfo info = new XrSenseDataQueryInfo()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SENSE_DATA_QUERY_INFO,
|
||||
};
|
||||
|
||||
XrSenseDataFilterSemantic semanticFilter = new XrSenseDataFilterSemantic()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SENSE_DATA_FILTER_SEMANTIC
|
||||
};
|
||||
|
||||
if (labels.Length > 0)
|
||||
{
|
||||
semanticFilter.semanticCount = (uint)labels.Length;
|
||||
int[] labelsAsInts = labels.Select(x => (int)x).ToArray();
|
||||
semanticFilter.semantics = Marshal.AllocHGlobal(labels.Length * Marshal.SizeOf(typeof(int)));
|
||||
Marshal.Copy(labelsAsInts, 0, semanticFilter.semantics, labelsAsInts.Length);
|
||||
int size = Marshal.SizeOf<XrSenseDataFilterSemantic>();
|
||||
info.filter = Marshal.AllocHGlobal(size);
|
||||
Marshal.StructureToPtr(semanticFilter, info.filter, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
info.filter = IntPtr.Zero;
|
||||
}
|
||||
|
||||
var pxrResult = UPxr_QuerySenseDataAsync(UPxr_GetSenseDataProviderHandle(PxrSenseDataProviderType.SceneCapture), ref info, out future);
|
||||
Marshal.FreeHGlobal(semanticFilter.semantics);
|
||||
Marshal.FreeHGlobal(info.filter);
|
||||
return pxrResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static PxrResult UPxr_GetSpatialEntitySemanticInfo(ulong snapshotHandle, ulong spatialEntityHandle, out PxrSemanticLabel label)
|
||||
{
|
||||
label = PxrSemanticLabel.Unknown;
|
||||
PxrResult result = UPxr_GetSpatialSemantics(snapshotHandle, spatialEntityHandle, out var labels);
|
||||
if (result==PxrResult.SUCCESS&&labels.Length>0)
|
||||
{
|
||||
label = labels[0];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static PxrResult UPxr_GetSpatialEntityLocationInfo(ulong snapshotHandle, ulong spatialEntityHandle, out Vector3 position,
|
||||
out Quaternion rotation)
|
||||
{
|
||||
position = Vector3.zero;
|
||||
rotation = Quaternion.identity;
|
||||
var getInfo = new XrSpatialEntityLocationGetInfo
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ENTITY_LOCATION_GET_INFO,
|
||||
entity = spatialEntityHandle,
|
||||
componentType = PxrSceneComponentType.Location,
|
||||
baseSpace = 0,
|
||||
time = 0,
|
||||
};
|
||||
XrSpatialEntityLocationData locationInfo = new XrSpatialEntityLocationData()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ENTITY_LOCATION_DATA
|
||||
};
|
||||
var result = (PxrResult)Pxr_GetSpatialEntityLocationInfo(snapshotHandle, ref getInfo, ref locationInfo);
|
||||
if (result == PxrResult.SUCCESS)
|
||||
{
|
||||
foreach (PxrSpaceLocationFlags value in Enum.GetValues(typeof(PxrSpaceLocationFlags)))
|
||||
{
|
||||
if ((locationInfo.location.locationFlags & (ulong)value) != (ulong)value)
|
||||
{
|
||||
position = Vector3.zero;
|
||||
rotation = Quaternion.identity;
|
||||
return PxrResult.ERROR_POSE_INVALID;
|
||||
}
|
||||
}
|
||||
rotation = new Quaternion(locationInfo.location.pose.orientation.x, locationInfo.location.pose.orientation.y, -locationInfo.location.pose.orientation.z,
|
||||
-locationInfo.location.pose.orientation.w);
|
||||
position = new Vector3(locationInfo.location.pose.position.x, locationInfo.location.pose.position.y, -locationInfo.location.pose.position.z);
|
||||
// Debug.Log("[PoxrUnity] UPxr_GetSpatialEntityLocationInfo rotation:"+rotation+" position:"+position);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_EnumerateSpatialEntityComponentTypes(ulong snapshotHandle, ulong spatialEntityHandle,
|
||||
out PxrSceneComponentType[] types)
|
||||
{
|
||||
var componentTypes = IntPtr.Zero;
|
||||
types = Array.Empty<PxrSceneComponentType>();
|
||||
var firstResult =
|
||||
(PxrResult)Pxr_EnumerateSpatialEntityComponentTypes(snapshotHandle, spatialEntityHandle, 0, out var firstOutputCount, componentTypes);
|
||||
if (firstResult == PxrResult.SUCCESS)
|
||||
{
|
||||
int size = (int)firstOutputCount * Marshal.SizeOf(typeof(int));
|
||||
componentTypes = Marshal.AllocHGlobal(size);
|
||||
var secondResult = (PxrResult)Pxr_EnumerateSpatialEntityComponentTypes(snapshotHandle, spatialEntityHandle, firstOutputCount,
|
||||
out var outputCount, componentTypes);
|
||||
if (secondResult == PxrResult.SUCCESS)
|
||||
{
|
||||
types = new PxrSceneComponentType[outputCount];
|
||||
int[] typesInts = new int[outputCount];
|
||||
Marshal.Copy(componentTypes, typesInts, 0, (int)firstOutputCount);
|
||||
for (int i = 0; i < outputCount; i++)
|
||||
{
|
||||
types[i] = (PxrSceneComponentType)typesInts[i];
|
||||
// Debug.Log("[PoxrUnity] UPxr_EnumerateSpatialEntityComponentTypes componentTypes="+ typesInts[i]);
|
||||
}
|
||||
|
||||
Marshal.FreeHGlobal(componentTypes);
|
||||
return PxrResult.SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
types = Array.Empty<PxrSceneComponentType>();
|
||||
Marshal.FreeHGlobal(componentTypes);
|
||||
return secondResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
types = Array.Empty<PxrSceneComponentType>();
|
||||
return firstResult;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static PxrResult UPxr_GetSpatialEntityBox3DInfo(ulong snapshotHandle, ulong spatialEntityHandle, out Vector3 position,
|
||||
out Quaternion rotation, out Vector3 extent)
|
||||
{
|
||||
position = Vector3.zero;
|
||||
rotation = Quaternion.identity;
|
||||
extent = Vector3.zero;
|
||||
var getInfo = new XrSpatialEntityGetInfo
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ENTITY_BOUNDING_BOX_3D_GET_INFO,
|
||||
next = IntPtr.Zero,
|
||||
entity = spatialEntityHandle,
|
||||
componentType = PxrSceneComponentType.Box3D
|
||||
};
|
||||
|
||||
|
||||
XrSpatialEntityBoundingBox3DData box3DInfo = new XrSpatialEntityBoundingBox3DData()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ENTITY_BOUNDING_BOX_3D_DATA,
|
||||
next = IntPtr.Zero
|
||||
};
|
||||
|
||||
var result = (PxrResult)Pxr_GetSpatialEntityBox3DInfo(snapshotHandle, ref getInfo, ref box3DInfo);
|
||||
if (result == PxrResult.SUCCESS)
|
||||
{
|
||||
position = new Vector3(box3DInfo.box3D.center.position.x, box3DInfo.box3D.center.position.y, box3DInfo.box3D.center.position.z);
|
||||
rotation = new Quaternion(box3DInfo.box3D.center.orientation.x, box3DInfo.box3D.center.orientation.y, box3DInfo.box3D.center.orientation.z,
|
||||
box3DInfo.box3D.center.orientation.w);
|
||||
extent = new Vector3(box3DInfo.box3D.extents.width, box3DInfo.box3D.extents.height, box3DInfo.box3D.extents.depth);
|
||||
// Debug.Log($"[PoxrUnity] UPxr_GetSpatialEntityBox3DInfo snapshotHandle={snapshotHandle} position={position} rotation={rotation} extent={ extent}");
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_GetSpatialEntityBox2DInfo(ulong snapshotHandle, ulong spatialEntityHandle, out Vector2 offset, out Vector2 extent)
|
||||
{
|
||||
offset = Vector2.zero;
|
||||
extent = Vector2.zero;
|
||||
var getInfo = new XrSpatialEntityGetInfo
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ENTITY_BOUNDING_BOX_2D_GET_INFO,
|
||||
entity = spatialEntityHandle,
|
||||
componentType = PxrSceneComponentType.Box2D
|
||||
};
|
||||
|
||||
XrSpatialEntityBoundingBox2DData box2DInfo = new XrSpatialEntityBoundingBox2DData()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ENTITY_BOUNDING_BOX_2D_DATA,
|
||||
};
|
||||
|
||||
var result = (PxrResult)Pxr_GetSpatialEntityBox2DInfo(snapshotHandle, ref getInfo, ref box2DInfo);
|
||||
if (result == PxrResult.SUCCESS)
|
||||
{
|
||||
offset = box2DInfo.box2D.offset;
|
||||
extent =box2DInfo.box2D.extent.ToVector2();
|
||||
Debug.Log($"[PoxrUnity] UPxr_GetSpatialEntityBox2DInfo snapshotHandle={snapshotHandle} offset={offset} extent={extent} ");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static PxrResult UPxr_GetSpatialEntityPolygonInfo(ulong snapshotHandle, ulong spatialEntityHandle, out Vector2[] vertices)
|
||||
{
|
||||
vertices = Array.Empty<Vector2>();
|
||||
var getInfo = new XrSpatialEntityGetInfo
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ENTITY_POLYGON_GET_INFO,
|
||||
entity = spatialEntityHandle,
|
||||
componentType = PxrSceneComponentType.Polygon
|
||||
};
|
||||
|
||||
XrSpatialEntityPolygonData polygonInfo = new XrSpatialEntityPolygonData()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ENTITY_POLYGON_DATA,
|
||||
polygonCapacityInput = 0,
|
||||
polygonCountOutput = 0,
|
||||
vertices = IntPtr.Zero
|
||||
};
|
||||
|
||||
var result = (PxrResult)Pxr_GetSpatialEntityPolygonInfo(snapshotHandle, ref getInfo, ref polygonInfo);
|
||||
|
||||
if (result == PxrResult.SUCCESS)
|
||||
{
|
||||
if (polygonInfo.polygonCountOutput > 0)
|
||||
{
|
||||
polygonInfo.polygonCapacityInput = polygonInfo.polygonCountOutput;
|
||||
polygonInfo.vertices = Marshal.AllocHGlobal((int)polygonInfo.polygonCountOutput * Marshal.SizeOf(typeof(PxrVector2f)));
|
||||
|
||||
result = (PxrResult)Pxr_GetSpatialEntityPolygonInfo(snapshotHandle, ref getInfo, ref polygonInfo);
|
||||
if (result == PxrResult.SUCCESS)
|
||||
{
|
||||
vertices = new Vector2[polygonInfo.polygonCountOutput];
|
||||
var vector2fs = new PxrVector2f[polygonInfo.polygonCountOutput];
|
||||
for (int i = 0; i < polygonInfo.polygonCountOutput; i++)
|
||||
{
|
||||
vector2fs[i] = Marshal.PtrToStructure<PxrVector2f>(polygonInfo.vertices + i * Marshal.SizeOf(typeof(PxrVector2f)));
|
||||
vertices[i].x = vector2fs[i].x;
|
||||
vertices[i].y = vector2fs[i].y;
|
||||
// Debug.Log($"[PoxrUnity] UPxr_GetSpatialEntityPolygonInfo snapshotHandle={snapshotHandle} vertices[{i}]={vertices[i]}");
|
||||
}
|
||||
}
|
||||
|
||||
Marshal.FreeHGlobal(polygonInfo.vertices);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
public static ulong UPxr_GetSpatialMeshProviderHandle()
|
||||
{
|
||||
return Pxr_GetSpatialMeshProviderHandle();
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_GetSpatialMesh(ulong snapshotHandle, ulong entityHandle, ref PxrSpatialMeshInfo meshInfo)
|
||||
{
|
||||
var result = UPxr_GetSpatialMeshVerticesAndIndices(snapshotHandle, entityHandle, out var indices, out var vertices);
|
||||
if (result == PxrResult.SUCCESS)
|
||||
{
|
||||
meshInfo.indices = indices;
|
||||
meshInfo.vertices = vertices;
|
||||
result = UPxr_GetSpatialSemantics(snapshotHandle, entityHandle, out var labels);
|
||||
if (result == PxrResult.SUCCESS)
|
||||
{
|
||||
meshInfo.labels = labels;
|
||||
result = UPxr_GetSpatialEntityLocationInfo(snapshotHandle, entityHandle, out var position, out var rotation);
|
||||
if (result == PxrResult.SUCCESS)
|
||||
{
|
||||
meshInfo.position = position;
|
||||
meshInfo.rotation = rotation;
|
||||
|
||||
return PxrResult.SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static PxrResult UPxr_GetSpatialMeshVerticesAndIndices(ulong snapshotHandle, ulong entityHandle, out ushort[] indices, out Vector3[] vertices)
|
||||
{
|
||||
indices = Array.Empty<ushort>();
|
||||
vertices = Array.Empty<Vector3>();
|
||||
var getInfo = new XrSpatialEntityGetInfo
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ENTITY_TRIANGLE_MESH_GET_INFO,
|
||||
entity = entityHandle,
|
||||
componentType = PxrSceneComponentType.TriangleMesh
|
||||
};
|
||||
|
||||
PxrTriangleMeshInfo meshInfo = new PxrTriangleMeshInfo()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ENTITY_TRIANGLE_MESH_DATA,
|
||||
vertexCapacityInput = 0,
|
||||
vertexCountOutput = 0,
|
||||
vertices = IntPtr.Zero,
|
||||
indexCapacityInput = 0,
|
||||
indexCountOutput = 0,
|
||||
indices = IntPtr.Zero
|
||||
};
|
||||
|
||||
var result = (PxrResult)Pxr_GetSpatialMeshVerticesAndIndices(snapshotHandle, ref getInfo, ref meshInfo);
|
||||
if (result == PxrResult.SUCCESS)
|
||||
{
|
||||
|
||||
meshInfo.indexCapacityInput = meshInfo.indexCountOutput;
|
||||
meshInfo.indices = Marshal.AllocHGlobal((int)meshInfo.indexCountOutput * Marshal.SizeOf(typeof(ushort)));
|
||||
meshInfo.vertexCapacityInput = meshInfo.vertexCountOutput;
|
||||
meshInfo.vertices = Marshal.AllocHGlobal((int)meshInfo.vertexCountOutput * Marshal.SizeOf(typeof(PxrVector3f)));
|
||||
|
||||
result = (PxrResult)Pxr_GetSpatialMeshVerticesAndIndices(snapshotHandle, ref getInfo, ref meshInfo);
|
||||
if (result == PxrResult.SUCCESS)
|
||||
{
|
||||
|
||||
indices = new ushort[meshInfo.indexCountOutput];
|
||||
if (meshInfo.indexCountOutput > 0)
|
||||
{
|
||||
var indicesTmp = new short[meshInfo.indexCountOutput];
|
||||
Marshal.Copy(meshInfo.indices, indicesTmp, 0, (int)meshInfo.indexCountOutput);
|
||||
indices = indicesTmp.Select(l => (ushort)l).ToArray();
|
||||
|
||||
for (int i = 0; i < indices.Length; i += 3)
|
||||
{
|
||||
(indices[i + 1], indices[i + 2]) = (indices[i + 2], indices[i + 1]);
|
||||
}
|
||||
}
|
||||
vertices = new Vector3[meshInfo.vertexCountOutput];
|
||||
if (meshInfo.vertexCountOutput > 0)
|
||||
{
|
||||
IntPtr tempPtr = meshInfo.vertices;
|
||||
for (int i = 0; i < meshInfo.vertexCountOutput; i++)
|
||||
{
|
||||
vertices[i] = Marshal.PtrToStructure<Vector3>(tempPtr);
|
||||
tempPtr += Marshal.SizeOf(typeof(Vector3));
|
||||
}
|
||||
|
||||
vertices = vertices.Select(v => new Vector3(v.x, v.y, -v.z)).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
Marshal.FreeHGlobal(meshInfo.indices);
|
||||
Marshal.FreeHGlobal(meshInfo.vertices);
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public static PxrResult UPxr_GetSpatialSemantics(ulong snapshotHandle, ulong spatialEntityHandle, out PxrSemanticLabel[] labels)
|
||||
{
|
||||
labels = Array.Empty<PxrSemanticLabel>();
|
||||
XrSpatialEntityGetInfo getInfo = new XrSpatialEntityGetInfo
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ENTITY_SEMANTIC_GET_INFO,
|
||||
entity = spatialEntityHandle,
|
||||
componentType = PxrSceneComponentType.Semantic
|
||||
};
|
||||
XrSpatialEntitySemanticData semanticInfo = new XrSpatialEntitySemanticData()
|
||||
{
|
||||
type = XrStructureType.XR_TYPE_SPATIAL_ENTITY_SEMANTIC_DATA,
|
||||
semanticCapacityInput = 0,
|
||||
semanticCountOutput = 0,
|
||||
semanticLabels = IntPtr.Zero
|
||||
};
|
||||
|
||||
var result = (PxrResult)Pxr_GetSpatialEntitySemanticInfo(snapshotHandle, ref getInfo, ref semanticInfo);
|
||||
if (result == PxrResult.SUCCESS)
|
||||
{
|
||||
if (semanticInfo.semanticCountOutput > 0)
|
||||
{
|
||||
semanticInfo.semanticCapacityInput = semanticInfo.semanticCountOutput;
|
||||
|
||||
semanticInfo.semanticLabels = Marshal.AllocHGlobal((int)semanticInfo.semanticCapacityInput*Marshal.SizeOf(typeof(int)));
|
||||
|
||||
result = (PxrResult)Pxr_GetSpatialEntitySemanticInfo(snapshotHandle, ref getInfo, ref semanticInfo);
|
||||
if (result == PxrResult.SUCCESS)
|
||||
{
|
||||
labels = new PxrSemanticLabel[semanticInfo.semanticCountOutput];
|
||||
var sTmp = new int[semanticInfo.semanticCountOutput];
|
||||
Marshal.Copy(semanticInfo.semanticLabels, sTmp, 0, (int)semanticInfo.semanticCountOutput);
|
||||
labels = sTmp.Select(l => (PxrSemanticLabel)l).ToArray();
|
||||
// label = (PxrSemanticLabel)Marshal.ReadInt32(semanticInfo.semanticLabels);
|
||||
// Debug.Log("[PoxrUnity] UPxr_GetSpatialEntitySemanticInfo semanticLabels:"+label);
|
||||
}
|
||||
|
||||
Marshal.FreeHGlobal(semanticInfo.semanticLabels);
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void UPxr_AddOrUpdateMesh(PxrSpatialMeshInfo meshInfo)
|
||||
{
|
||||
byte[] temp = meshInfo.uuid.ToByteArray();
|
||||
var id1 = BitConverter.ToUInt64(temp, 0);
|
||||
var id2 = BitConverter.ToUInt64(temp, 8);
|
||||
var vertices = new NativeArray<Vector3>(meshInfo.vertices, Allocator.Persistent);
|
||||
var indices = new NativeArray<ushort>(meshInfo.indices, Allocator.Persistent);
|
||||
|
||||
unsafe
|
||||
{
|
||||
Pxr_AddOrUpdateMesh(id1, id2, meshInfo.vertices.Length, NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr(vertices), meshInfo.indices.Length, NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr(indices), meshInfo.position, meshInfo.rotation);
|
||||
}
|
||||
|
||||
if (nativeMeshArrays.TryGetValue(meshInfo.uuid, out var nativeArrays))
|
||||
nativeArrays.ForEach(x => x.Dispose());
|
||||
nativeMeshArrays[meshInfo.uuid] = new List<IDisposable> { vertices, indices};
|
||||
}
|
||||
public static void UPxr_RemoveMesh(Guid uuid)
|
||||
{
|
||||
byte[] temp = uuid.ToByteArray();
|
||||
var id1 = BitConverter.ToUInt64(temp, 0);
|
||||
var id2 = BitConverter.ToUInt64(temp, 8);
|
||||
Pxr_RemoveMesh(id1, id2);
|
||||
if (nativeMeshArrays.TryGetValue(uuid, out var nativeArrays))
|
||||
{
|
||||
nativeArrays.ForEach(x => x.Dispose());
|
||||
nativeMeshArrays.Remove(uuid);
|
||||
}
|
||||
}
|
||||
public static void UPxr_DisposeMesh()
|
||||
{
|
||||
foreach (var nativeArrays in nativeMeshArrays.Values)
|
||||
{
|
||||
nativeArrays.ForEach(x => x.Dispose());
|
||||
}
|
||||
|
||||
nativeMeshArrays.Clear();
|
||||
UPxr_ClearMeshes();
|
||||
}
|
||||
public static void UPxr_ClearMeshes()
|
||||
{
|
||||
Pxr_ClearMeshes();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22c136dcdaaa485aaa5680cf25bf28d5
|
||||
timeCreated: 1721811189
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b4c8a0079dc90a48b34d0456b0e8d26
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,296 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Unity.XR.OpenXR.Features.PICOSupport;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.XR;
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public class PXR_SpatialMeshManager : MonoBehaviour
|
||||
{
|
||||
public GameObject meshPrefab;
|
||||
private Dictionary<Guid, GameObject> meshIDToGameobject;
|
||||
private Dictionary<Guid, PxrSpatialMeshInfo> spatialMeshNeedingDraw;
|
||||
private Mesh mesh;
|
||||
private XRMeshSubsystem subsystem;
|
||||
static List<XRMeshSubsystem> s_SubsystemsReuse = new List<XRMeshSubsystem>();
|
||||
private int objectPoolMaxSize = 200;
|
||||
private Queue<GameObject> meshObjectsPool;
|
||||
private const float frameCount = 15.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The drawing of the new spatial mesh is complete.
|
||||
/// </summary>
|
||||
public static Action<Guid, GameObject> MeshAdded;
|
||||
|
||||
/// <summary>
|
||||
/// The drawing the updated spatial mesh is complete.
|
||||
/// </summary>
|
||||
public static Action<Guid, GameObject> MeshUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// The deletion of the disappeared spatial mesh is complete.
|
||||
/// </summary>
|
||||
public static Action<Guid> MeshRemoved;
|
||||
|
||||
void Start()
|
||||
{
|
||||
spatialMeshNeedingDraw = new Dictionary<Guid, PxrSpatialMeshInfo>();
|
||||
meshIDToGameobject = new Dictionary<Guid, GameObject>();
|
||||
meshObjectsPool = new Queue<GameObject>();
|
||||
|
||||
InitializePool();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
GetXRMeshSubsystem();
|
||||
if (subsystem != null && subsystem.running)
|
||||
{
|
||||
DrawMesh();
|
||||
}
|
||||
}
|
||||
|
||||
void GetXRMeshSubsystem()
|
||||
{
|
||||
if (subsystem != null)
|
||||
return;
|
||||
SubsystemManager.GetSubsystems(s_SubsystemsReuse);
|
||||
|
||||
if (s_SubsystemsReuse.Count == 0)
|
||||
return;
|
||||
|
||||
subsystem = s_SubsystemsReuse[0];
|
||||
|
||||
|
||||
PXR_PermissionRequest.RequestUserPermissionMR(Granted =>
|
||||
{
|
||||
subsystem.Start();
|
||||
if (subsystem.running)
|
||||
{
|
||||
OpenXRExtensions.SpatialMeshDataUpdated += SpatialMeshDataUpdated;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
GetXRMeshSubsystem();
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
if (subsystem != null && subsystem.running)
|
||||
subsystem.Stop();
|
||||
}
|
||||
|
||||
private void InitializePool()
|
||||
{
|
||||
if (meshPrefab != null)
|
||||
{
|
||||
while (meshObjectsPool.Count < objectPoolMaxSize)
|
||||
{
|
||||
GameObject obj = Instantiate(meshPrefab);
|
||||
obj.transform.SetParent(this.transform);
|
||||
obj.SetActive(false);
|
||||
meshObjectsPool.Enqueue(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawMesh()
|
||||
{
|
||||
if (meshPrefab != null)
|
||||
{
|
||||
StartCoroutine(ForeachLoopCoroutine());
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator ForeachLoopCoroutine()
|
||||
{
|
||||
int totalWork = spatialMeshNeedingDraw.Count;
|
||||
if (totalWork > 0 )
|
||||
{
|
||||
var meshList = spatialMeshNeedingDraw.Values.ToList();
|
||||
int workPerFrame = Mathf.CeilToInt(totalWork / frameCount);
|
||||
int currentIndex = 0;
|
||||
|
||||
while (currentIndex < totalWork)
|
||||
{
|
||||
int workThisFrame = 0;
|
||||
while (workThisFrame < workPerFrame && currentIndex < totalWork)
|
||||
{
|
||||
CreateMeshRoutine(meshList[currentIndex]);
|
||||
currentIndex++;
|
||||
workThisFrame++;
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpatialMeshDataUpdated(List<PxrSpatialMeshInfo> meshInfos)
|
||||
{
|
||||
for (int i = 0; i < meshInfos.Count; i++)
|
||||
{
|
||||
switch (meshInfos[i].state)
|
||||
{
|
||||
case MeshChangeState.Added:
|
||||
{
|
||||
spatialMeshNeedingDraw.Add(meshInfos[i].uuid, meshInfos[i]);
|
||||
}
|
||||
break;
|
||||
case MeshChangeState.Updated:
|
||||
{
|
||||
if (!spatialMeshNeedingDraw.ContainsKey(meshInfos[i].uuid))
|
||||
{
|
||||
spatialMeshNeedingDraw.Add(meshInfos[i].uuid, meshInfos[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
spatialMeshNeedingDraw[meshInfos[i].uuid] = meshInfos[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MeshChangeState.Removed:
|
||||
{
|
||||
MeshRemoved?.Invoke(meshInfos[i].uuid);
|
||||
|
||||
spatialMeshNeedingDraw.Remove(meshInfos[i].uuid);
|
||||
GameObject removedGo;
|
||||
if (meshIDToGameobject.TryGetValue(meshInfos[i].uuid, out removedGo))
|
||||
{
|
||||
if (meshObjectsPool.Count < objectPoolMaxSize)
|
||||
{
|
||||
removedGo.SetActive(false);
|
||||
meshObjectsPool.Enqueue(removedGo);
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy(removedGo);
|
||||
}
|
||||
meshIDToGameobject.Remove(meshInfos[i].uuid);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MeshChangeState.Unchanged:
|
||||
{
|
||||
spatialMeshNeedingDraw.Remove(meshInfos[i].uuid);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateMeshRoutine(PxrSpatialMeshInfo block)
|
||||
{
|
||||
GameObject meshGameObject = GetOrCreateGameObject(block.uuid);
|
||||
var meshFilter = meshGameObject.GetComponentInChildren<MeshFilter>();
|
||||
var meshCollider = meshGameObject.GetComponentInChildren<MeshCollider>();
|
||||
|
||||
if (meshFilter.mesh == null)
|
||||
{
|
||||
mesh = new Mesh();
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh = meshFilter.mesh;
|
||||
mesh.Clear();
|
||||
}
|
||||
Color[] normalizedColors = new Color[block.vertices.Length];
|
||||
for (int i = 0; i < block.vertices.Length; i++)
|
||||
{
|
||||
normalizedColors[i] = GetMeshColorBySemanticLabel(block.labels[i]);
|
||||
}
|
||||
mesh.SetVertices(block.vertices);
|
||||
mesh.SetColors(normalizedColors);
|
||||
mesh.SetTriangles(block.indices, 0);
|
||||
meshFilter.mesh = mesh;
|
||||
if (meshCollider != null)
|
||||
{
|
||||
meshCollider.sharedMesh = mesh;
|
||||
}
|
||||
meshGameObject.transform.position = block.position;
|
||||
meshGameObject.transform.rotation = block.rotation;
|
||||
|
||||
switch (block.state)
|
||||
{
|
||||
case MeshChangeState.Added:
|
||||
{
|
||||
MeshAdded?.Invoke(block.uuid, meshGameObject);
|
||||
}
|
||||
break;
|
||||
case MeshChangeState.Updated:
|
||||
{
|
||||
MeshUpdated?.Invoke(block.uuid, meshGameObject);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
GameObject CreateGameObject(Guid meshId)
|
||||
{
|
||||
GameObject meshObject = meshObjectsPool.Dequeue();
|
||||
meshObject.name = $"Mesh {meshId}";
|
||||
meshObject.SetActive(true);
|
||||
return meshObject;
|
||||
}
|
||||
|
||||
GameObject GetOrCreateGameObject(Guid meshId)
|
||||
{
|
||||
GameObject go = null;
|
||||
if (!meshIDToGameobject.TryGetValue(meshId, out go))
|
||||
{
|
||||
go = CreateGameObject(meshId);
|
||||
meshIDToGameobject[meshId] = go;
|
||||
}
|
||||
|
||||
return go;
|
||||
}
|
||||
|
||||
private Color GetMeshColorBySemanticLabel(PxrSemanticLabel label)
|
||||
{
|
||||
switch (label)
|
||||
{
|
||||
case PxrSemanticLabel.Unknown:
|
||||
return Color.white;
|
||||
case PxrSemanticLabel.Floor:
|
||||
return Color.red;
|
||||
case PxrSemanticLabel.Ceiling:
|
||||
return Color.green;
|
||||
case PxrSemanticLabel.Wall:
|
||||
return Color.blue;
|
||||
case PxrSemanticLabel.Door:
|
||||
return Color.grey;
|
||||
case PxrSemanticLabel.Window:
|
||||
return Color.yellow;
|
||||
case PxrSemanticLabel.Opening:
|
||||
return Color.cyan;
|
||||
case PxrSemanticLabel.Table:
|
||||
return Color.magenta;
|
||||
case PxrSemanticLabel.Sofa:
|
||||
return Color.gray;
|
||||
case PxrSemanticLabel.Chair:
|
||||
return new Color(0.8f, 0.2f, 0.5f);
|
||||
case PxrSemanticLabel.Human:
|
||||
return new Color(0.8f, 0.2f, 0.6f);
|
||||
default:
|
||||
return Color.white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9a7bfb0312c046479b565c21f977fec
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,411 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using AOT;
|
||||
using Unity.XR.PXR;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR;
|
||||
#if AR_FOUNDATION
|
||||
using UnityEngine.XR.ARSubsystems;
|
||||
#endif
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor.XR.OpenXR.Features;
|
||||
#endif
|
||||
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
public class FeatureConfig
|
||||
{
|
||||
public const string OpenXrExtensionList = "XR_EXT_local_floor " +
|
||||
"XR_FB_triangle_mesh " +
|
||||
"XR_FB_composition_layer_alpha_blend " +
|
||||
"XR_KHR_composition_layer_color_scale_bias " +
|
||||
"XR_KHR_composition_layer_cylinder " +
|
||||
"XR_KHR_composition_layer_equirect " +
|
||||
"XR_KHR_composition_layer_cube";
|
||||
}
|
||||
|
||||
[OpenXRFeature(UiName = "PICO OpenXR Features",
|
||||
Desc = "PICO XR Features for OpenXR.",
|
||||
Company = "PICO",
|
||||
Version = "1.0.0",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Android },
|
||||
OpenxrExtensionStrings = FeatureConfig.OpenXrExtensionList,
|
||||
FeatureId = featureId
|
||||
)]
|
||||
#endif
|
||||
public class OpenXRExtensions : OpenXRFeature
|
||||
{
|
||||
public const string featureId = "com.unity.openxr.pico.features";
|
||||
private static ulong xrInstance = 0ul;
|
||||
private static ulong xrSession = 0ul;
|
||||
public static event Action<ulong> SenseDataUpdated;
|
||||
public static event Action SpatialAnchorDataUpdated;
|
||||
public static event Action SceneAnchorDataUpdated;
|
||||
|
||||
public static event Action<PxrEventSenseDataProviderStateChanged> SenseDataProviderStateChanged;
|
||||
public static event Action<List<PxrSpatialMeshInfo>> SpatialMeshDataUpdated;
|
||||
|
||||
static bool isCoroutineRunning = false;
|
||||
protected override bool OnInstanceCreate(ulong instance)
|
||||
{
|
||||
xrInstance = instance;
|
||||
xrSession = 0ul;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnSessionCreate(ulong xrSessionId)
|
||||
{
|
||||
xrSession = xrSessionId;
|
||||
Initialize(xrGetInstanceProcAddr, xrInstance, xrSession);
|
||||
Pxr_SetEventDataBufferCallBack(XrEventDataBufferFunction);
|
||||
setColorSpace((int)QualitySettings.activeColorSpace);
|
||||
base.OnSessionCreate(xrSessionId);
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnInstanceDestroy(ulong xrInstance)
|
||||
{
|
||||
base.OnInstanceDestroy(xrInstance);
|
||||
xrInstance = 0ul;
|
||||
}
|
||||
|
||||
// HookGetInstanceProcAddr
|
||||
protected override IntPtr HookGetInstanceProcAddr(IntPtr func)
|
||||
{
|
||||
// return base.HookGetInstanceProcAddr(func);
|
||||
return HookCreateInstance(func);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnSessionDestroy(ulong xrSessionId)
|
||||
{
|
||||
base.OnSessionDestroy(xrSessionId);
|
||||
xrSession = 0ul;
|
||||
}
|
||||
|
||||
protected override void OnAppSpaceChange(ulong xrSpace)
|
||||
{
|
||||
SpaceChange(xrSpace);
|
||||
base.OnAppSpaceChange(xrSpace);
|
||||
}
|
||||
|
||||
public static int GetReferenceSpaceBoundsRect(XrReferenceSpaceType referenceSpace, ref XrExtent2Df extent2D)
|
||||
{
|
||||
return xrGetReferenceSpaceBoundsRect(
|
||||
xrSession, referenceSpace, ref extent2D);
|
||||
}
|
||||
|
||||
public static XrReferenceSpaceType[] EnumerateReferenceSpaces()
|
||||
{
|
||||
UInt32 Output = 0;
|
||||
XrReferenceSpaceType[] outSpaces = null;
|
||||
xrEnumerateReferenceSpaces(xrSession, 0, ref Output, outSpaces);
|
||||
if (Output <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
outSpaces = new XrReferenceSpaceType[Output];
|
||||
xrEnumerateReferenceSpaces(xrSession, Output, ref Output, outSpaces);
|
||||
return outSpaces;
|
||||
}
|
||||
|
||||
public static void CreateLayerParam(PxrLayerParam layerParam)
|
||||
{
|
||||
PLog.i("POXR_CreateLayerParam() ");
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
xrCreateLayerParam(layerParam);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static int GetLayerImageCount(int layerId, EyeType eye, ref UInt32 imageCount)
|
||||
{
|
||||
int result = 0;
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
result = xrGetLayerImageCount(layerId, eye, ref imageCount);
|
||||
#endif
|
||||
PLog.i("GetLayerImageCount() layerId:" + layerId + " eye:" + eye + " imageCount:" + imageCount +
|
||||
" result:" + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void GetLayerImagePtr(int layerId, EyeType eye, int imageIndex, ref IntPtr image)
|
||||
{
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
xrGetLayerImagePtr(layerId, eye, imageIndex, ref image);
|
||||
#endif
|
||||
PLog.i("GetLayerImagePtr() layerId:" + layerId + " eye:" + eye + " imageIndex:" + imageIndex + " image:" +
|
||||
image);
|
||||
}
|
||||
|
||||
public static void DestroyLayerByRender(int layerId)
|
||||
{
|
||||
PLog.i("DestroyLayerByRender() layerId:" + layerId);
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
xrDestroyLayerByRender(layerId);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool SubmitLayerQuad(IntPtr ptr)
|
||||
{
|
||||
int result = 0;
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
result = xrSubmitLayerQuad(ptr);
|
||||
#endif
|
||||
PLog.d("SubmitLayerQuad() ptr:" + ptr + " result:" + result);
|
||||
return result == -8;
|
||||
}
|
||||
|
||||
public static bool SubmitLayerCylinder(IntPtr ptr)
|
||||
{
|
||||
int result = 0;
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
result = xrSubmitLayerCylinder(ptr);
|
||||
#endif
|
||||
PLog.d("SubmitLayerCylinder() ptr:" + ptr + " result:" + result);
|
||||
return result == -8;
|
||||
}
|
||||
|
||||
public static bool SubmitLayerEquirect(IntPtr ptr)
|
||||
{
|
||||
int result = 0;
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
result = xrSubmitLayerEquirect(ptr);
|
||||
#endif
|
||||
PLog.d("SubmitLayerEquirect() ptr:" + ptr + " result:" + result);
|
||||
return result == -8;
|
||||
}
|
||||
|
||||
public static bool SubmitLayerCube(IntPtr ptr)
|
||||
{
|
||||
int result = 0;
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
result = xrSubmitLayerCube(ptr);
|
||||
#endif
|
||||
PLog.d("xrSubmitLayerCube() ptr:" + ptr + " result:" + result);
|
||||
return result == -8;
|
||||
}
|
||||
|
||||
public static int GetLayerNextImageIndex(int layerId, ref int imageIndex)
|
||||
{
|
||||
int result = 0;
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
result = xrGetLayerNextImageIndex(layerId, ref imageIndex);
|
||||
#endif
|
||||
PLog.d("GetLayerNextImageIndex() layerId:" + layerId + " imageIndex:" + imageIndex + " result:" + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected override void OnSystemChange(ulong xrSystem)
|
||||
{
|
||||
base.OnSystemChange(xrSystem);
|
||||
SystemChange(xrSystem);
|
||||
}
|
||||
|
||||
public static float GetLocationHeight()
|
||||
{
|
||||
float height = 0;
|
||||
getLocationHeight( ref height);
|
||||
return height;
|
||||
}
|
||||
|
||||
public static int GetControllerType()
|
||||
{
|
||||
int type = 0;
|
||||
Pxr_GetControllerType(ref type);
|
||||
return type;
|
||||
}
|
||||
|
||||
[MonoPInvokeCallback(typeof(XrEventDataBufferCallBack))]
|
||||
static void XrEventDataBufferFunction(ref XrEventDataBuffer eventDB)
|
||||
{
|
||||
int status, action;
|
||||
PLog.i($"XrEventDataBufferFunction eventType={eventDB.type}");
|
||||
switch (eventDB.type)
|
||||
{
|
||||
case XrStructureType.XR_TYPE_EVENT_DATA_SENSE_DATA_PROVIDER_STATE_CHANGED:
|
||||
{
|
||||
if (SenseDataProviderStateChanged != null)
|
||||
{
|
||||
PxrEventSenseDataProviderStateChanged data = new PxrEventSenseDataProviderStateChanged()
|
||||
{
|
||||
providerHandle = BitConverter.ToUInt64(eventDB.data, 0),
|
||||
newState = (PxrSenseDataProviderState)BitConverter.ToInt32(eventDB.data, 8),
|
||||
};
|
||||
SenseDataProviderStateChanged(data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XrStructureType.XR_TYPE_EVENT_DATA_SENSE_DATA_UPDATED:
|
||||
{
|
||||
ulong providerHandle = BitConverter.ToUInt64(eventDB.data, 0);
|
||||
PLog.i($"providerHandle ={providerHandle}");
|
||||
if (SenseDataUpdated != null)
|
||||
{
|
||||
SenseDataUpdated(providerHandle);
|
||||
}
|
||||
|
||||
if (providerHandle == PXR_Plugin.MixedReality.UPxr_GetSenseDataProviderHandle(PxrSenseDataProviderType.SpatialAnchor))
|
||||
{
|
||||
if (SpatialAnchorDataUpdated != null)
|
||||
{
|
||||
SpatialAnchorDataUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
if (providerHandle == PXR_Plugin.MixedReality.UPxr_GetSenseDataProviderHandle(PxrSenseDataProviderType.SceneCapture))
|
||||
{
|
||||
if (SceneAnchorDataUpdated != null)
|
||||
{
|
||||
SceneAnchorDataUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
if (providerHandle == PXR_Plugin.MixedReality.UPxr_GetSpatialMeshProviderHandle())
|
||||
{
|
||||
if (!isCoroutineRunning)
|
||||
{
|
||||
QuerySpatialMeshAnchor();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static async void QuerySpatialMeshAnchor()
|
||||
{
|
||||
isCoroutineRunning = true;
|
||||
var task = await PXR_MixedReality.QueryMeshAnchorAsync();
|
||||
isCoroutineRunning = false;
|
||||
var (result, meshInfos) = task;
|
||||
for (int i = 0; i < meshInfos.Count; i++)
|
||||
{
|
||||
switch (meshInfos[i].state)
|
||||
{
|
||||
case MeshChangeState.Added:
|
||||
case MeshChangeState.Updated:
|
||||
{
|
||||
PXR_Plugin.MixedReality.UPxr_AddOrUpdateMesh(meshInfos[i]);
|
||||
}
|
||||
break;
|
||||
case MeshChangeState.Removed:
|
||||
{
|
||||
PXR_Plugin.MixedReality.UPxr_RemoveMesh(meshInfos[i].uuid);
|
||||
}
|
||||
break;
|
||||
case MeshChangeState.Unchanged:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result == PxrResult.SUCCESS)
|
||||
{
|
||||
SpatialMeshDataUpdated?.Invoke(meshInfos);
|
||||
}
|
||||
}
|
||||
#if AR_FOUNDATION
|
||||
public bool isSessionSubsystem=true;
|
||||
private static List<XRSessionSubsystemDescriptor> sessionSubsystemDescriptors = new List<XRSessionSubsystemDescriptor>();
|
||||
protected override void OnSubsystemCreate()
|
||||
{
|
||||
base.OnSubsystemCreate();
|
||||
if (isSessionSubsystem)
|
||||
{
|
||||
CreateSubsystem<XRSessionSubsystemDescriptor, XRSessionSubsystem>(sessionSubsystemDescriptors, PICOSessionSubsystem.k_SubsystemId);
|
||||
}
|
||||
}
|
||||
protected override void OnSubsystemStart()
|
||||
{
|
||||
if (isSessionSubsystem)
|
||||
{
|
||||
StartSubsystem<XRHumanBodySubsystem>();
|
||||
}
|
||||
}
|
||||
protected override void OnSubsystemStop()
|
||||
{
|
||||
if (isSessionSubsystem)
|
||||
{
|
||||
StopSubsystem<XRHumanBodySubsystem>();
|
||||
}
|
||||
}
|
||||
protected override void OnSubsystemDestroy()
|
||||
{
|
||||
if (isSessionSubsystem)
|
||||
{
|
||||
DestroySubsystem<XRHumanBodySubsystem>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const string extLib = "openxr_pico";
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_Initialize", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void Initialize(IntPtr xrGetInstanceProcAddr, ulong xrInstance, ulong xrSession);
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_HookCreateInstance", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr HookCreateInstance(IntPtr func);
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_OnAppSpaceChange", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void SpaceChange(ulong xrSession);
|
||||
[DllImport(extLib, EntryPoint = "PICO_OnSystemChange", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void SystemChange(ulong xrSystem);
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_xrEnumerateReferenceSpaces", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int xrEnumerateReferenceSpaces(ulong xrSession, UInt32 CountInput, ref UInt32 CountOutput,
|
||||
XrReferenceSpaceType[] Spaces);
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_xrGetReferenceSpaceBoundsRect", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int xrGetReferenceSpaceBoundsRect(ulong xrSession, XrReferenceSpaceType referenceSpace,
|
||||
ref XrExtent2Df extent2D);
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_CreateLayerParam", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void xrCreateLayerParam(PxrLayerParam layerParam);
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_GetLayerImageCount", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int xrGetLayerImageCount(int layerId, EyeType eye, ref UInt32 imageCount);
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_GetLayerImagePtr", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void xrGetLayerImagePtr(int layerId, EyeType eye, int imageIndex, ref IntPtr image);
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_DestroyLayerByRender", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void xrDestroyLayerByRender(int layerId);
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_SubmitLayerQuad", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int xrSubmitLayerQuad(IntPtr ptr);
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_SubmitLayerCylinder", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int xrSubmitLayerCylinder(IntPtr ptr);
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_SubmitLayerEquirect", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int xrSubmitLayerEquirect(IntPtr ptr);
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_SubmitLayerCube", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int xrSubmitLayerCube(IntPtr ptr);
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_GetLayerNextImageIndex", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int xrGetLayerNextImageIndex(int layerId, ref int imageIndex);
|
||||
|
||||
[DllImport(extLib, EntryPoint = "PICO_SetColorSpace", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int setColorSpace(int colorSpace);
|
||||
[DllImport(extLib, EntryPoint = "PICO_GetLocationHeight", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern XrResult getLocationHeight(ref float delaY);
|
||||
[DllImport(extLib, EntryPoint = "PICO_SetMarkMode", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void SetMarkMode();
|
||||
[DllImport(extLib, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void Pxr_GetControllerType(ref int type);
|
||||
[DllImport(extLib, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void Pxr_SetEventDataBufferCallBack(XrEventDataBufferCallBack callback);
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 077bca9897b444788c83491c066a79b1
|
||||
timeCreated: 1689921014
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97367776cd8a48ddb9070381398beda6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Unity.XR.CoreUtils;
|
||||
using Unity.XR.PXR;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.OpenXR;
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor.XR.OpenXR.Features;
|
||||
#endif
|
||||
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
[OpenXRFeature(UiName = "PICO Scene Capture",
|
||||
Hidden = false,
|
||||
BuildTargetGroups = new[] { UnityEditor.BuildTargetGroup.Android },
|
||||
Company = "PICO",
|
||||
OpenxrExtensionStrings = extensionString,
|
||||
Version = "1.0.0",
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class PICOSceneCapture: OpenXRFeature
|
||||
{
|
||||
public const string featureId = "com.pico.openxr.feature.scenecapture";
|
||||
public const string extensionString = "XR_PICO_scene_capture XR_PICO_spatial_sensing XR_EXT_future";
|
||||
public static bool isEnable => OpenXRRuntime.IsExtensionEnabled("XR_PICO_scene_capture");
|
||||
protected override void OnSessionCreate(ulong xrSession)
|
||||
{
|
||||
base.OnSessionCreate(xrSession);
|
||||
PXR_Plugin.MixedReality.UPxr_CreateSceneCaptureSenseDataProvider();
|
||||
}
|
||||
|
||||
protected override void OnSessionExiting(ulong xrSession)
|
||||
{
|
||||
PXR_MixedReality.GetSenseDataProviderState(PxrSenseDataProviderType.SceneCapture, out var providerState);
|
||||
if (providerState == PxrSenseDataProviderState.Running)
|
||||
{
|
||||
PXR_MixedReality.StopSenseDataProvider(PxrSenseDataProviderType.SceneCapture);
|
||||
}
|
||||
|
||||
PXR_Plugin.MixedReality.UPxr_DestroySenseDataProvider(
|
||||
PXR_Plugin.MixedReality.UPxr_GetSenseDataProviderHandle(PxrSenseDataProviderType.SceneCapture));
|
||||
|
||||
base.OnSessionExiting(xrSession);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0b5403262c64d5888bf5672e1e1f3bb
|
||||
timeCreated: 1721806849
|
@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Unity.XR.CoreUtils;
|
||||
using Unity.XR.PXR;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
#if AR_FOUNDATION
|
||||
using UnityEngine.XR.ARSubsystems;
|
||||
#endif
|
||||
using UnityEngine.XR.OpenXR;
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor.XR.OpenXR.Features;
|
||||
#endif
|
||||
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
[OpenXRFeature(UiName = "PICO Spatial Anchor",
|
||||
Hidden = false,
|
||||
BuildTargetGroups = new[] { UnityEditor.BuildTargetGroup.Android },
|
||||
Company = "PICO",
|
||||
OpenxrExtensionStrings = extensionString,
|
||||
Version = "1.0.0",
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class PICOSpatialAnchor: OpenXRFeature
|
||||
{
|
||||
public const string featureId = "com.pico.openxr.feature.spatialanchor";
|
||||
public const string extensionString = "XR_PICO_spatial_anchor XR_PICO_spatial_sensing XR_EXT_future";
|
||||
|
||||
public static bool isEnable => OpenXRRuntime.IsExtensionEnabled("XR_PICO_spatial_anchor");
|
||||
|
||||
protected override void OnSessionCreate(ulong xrSession)
|
||||
{
|
||||
base.OnSessionCreate(xrSession);
|
||||
PXR_Plugin.MixedReality.UPxr_CreateSpatialAnchorSenseDataProvider();
|
||||
}
|
||||
protected override void OnSessionExiting(ulong xrSession)
|
||||
{
|
||||
PXR_MixedReality.GetSenseDataProviderState(PxrSenseDataProviderType.SpatialAnchor, out var providerState);
|
||||
if (providerState == PxrSenseDataProviderState.Running)
|
||||
{
|
||||
PXR_MixedReality.StopSenseDataProvider(PxrSenseDataProviderType.SpatialAnchor);
|
||||
}
|
||||
|
||||
PXR_Plugin.MixedReality.UPxr_DestroySenseDataProvider(
|
||||
PXR_Plugin.MixedReality.UPxr_GetSenseDataProviderHandle(PxrSenseDataProviderType.SpatialAnchor));
|
||||
|
||||
base.OnSessionExiting(xrSession);
|
||||
}
|
||||
|
||||
#if AR_FOUNDATION
|
||||
public bool isAnchorSubsystem=true;
|
||||
static List<XRAnchorSubsystemDescriptor> anchorSubsystemDescriptors = new List<XRAnchorSubsystemDescriptor>();
|
||||
protected override void OnSubsystemCreate()
|
||||
{
|
||||
base.OnSubsystemCreate();
|
||||
if (isAnchorSubsystem)
|
||||
{
|
||||
CreateSubsystem<XRAnchorSubsystemDescriptor, XRAnchorSubsystem>(
|
||||
anchorSubsystemDescriptors,
|
||||
PICOAnchorSubsystem.k_SubsystemId);
|
||||
}
|
||||
|
||||
}
|
||||
protected override void OnSubsystemStart()
|
||||
{
|
||||
if (isAnchorSubsystem)
|
||||
{
|
||||
StartSubsystem<XRAnchorSubsystem>();
|
||||
}
|
||||
}
|
||||
protected override void OnSubsystemStop()
|
||||
{
|
||||
if (isAnchorSubsystem)
|
||||
{
|
||||
StopSubsystem<XRAnchorSubsystem>();
|
||||
}
|
||||
}
|
||||
protected override void OnSubsystemDestroy()
|
||||
{
|
||||
if (isAnchorSubsystem)
|
||||
{
|
||||
DestroySubsystem<XRAnchorSubsystem>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a8b7731b990240c0b289e41fb880787b
|
||||
timeCreated: 1721806849
|
@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Unity.XR.CoreUtils;
|
||||
using Unity.XR.PXR;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR;
|
||||
using UnityEngine.XR.OpenXR;
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor.XR.OpenXR.Features;
|
||||
#endif
|
||||
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
[OpenXRFeature(UiName = "PICO Spatial Mesh",
|
||||
Hidden = false,
|
||||
BuildTargetGroups = new[] { UnityEditor.BuildTargetGroup.Android },
|
||||
Company = "PICO",
|
||||
OpenxrExtensionStrings = extensionString,
|
||||
Version = "1.0.0",
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class PICOSpatialMesh: OpenXRFeature
|
||||
{
|
||||
public const string featureId = "com.pico.openxr.feature.spatialmesh";
|
||||
public const string extensionString = "XR_PICO_spatial_mesh XR_PICO_spatial_sensing XR_EXT_future";
|
||||
private static List<XRMeshSubsystemDescriptor> meshSubsystemDescriptors = new List<XRMeshSubsystemDescriptor>();
|
||||
|
||||
public PxrMeshLod LOD;
|
||||
|
||||
private XRMeshSubsystem subsystem;
|
||||
public static bool isEnable => OpenXRRuntime.IsExtensionEnabled("XR_PICO_spatial_mesh");
|
||||
protected override void OnSubsystemCreate()
|
||||
{
|
||||
base.OnSubsystemCreate();
|
||||
PXR_Plugin.MixedReality.Pxr_SetMeshLOD(Convert.ToUInt16(LOD));
|
||||
|
||||
}
|
||||
|
||||
protected override void OnSessionCreate(ulong xrSession)
|
||||
{
|
||||
base.OnSessionCreate(xrSession);
|
||||
CreateSubsystem<XRMeshSubsystemDescriptor, XRMeshSubsystem>(meshSubsystemDescriptors, "PICO Mesh");
|
||||
}
|
||||
|
||||
protected override void OnSubsystemStop()
|
||||
{
|
||||
base.OnSubsystemStop();
|
||||
StopSubsystem<XRMeshSubsystem>();
|
||||
|
||||
}
|
||||
|
||||
protected override void OnSubsystemDestroy()
|
||||
{
|
||||
base.OnSubsystemDestroy();
|
||||
PXR_Plugin.MixedReality.UPxr_DisposeMesh();
|
||||
DestroySubsystem<XRMeshSubsystem>();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1248416ce414cd0a788c5240bec5766
|
||||
timeCreated: 1721806849
|
@ -0,0 +1,532 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Unity.XR.CoreUtils;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
#if AR_FOUNDATION
|
||||
using UnityEngine.XR.ARSubsystems;
|
||||
#endif
|
||||
using UnityEngine.XR.OpenXR;
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor.XR.OpenXR.Features;
|
||||
#endif
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
[OpenXRFeature(UiName = "OpenXR Passthrough",
|
||||
Hidden = false,
|
||||
BuildTargetGroups = new[] { UnityEditor.BuildTargetGroup.Android },
|
||||
Company = "PICO",
|
||||
OpenxrExtensionStrings = extensionString,
|
||||
Version = "1.0.0",
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class PassthroughFeature : OpenXRFeatureBase
|
||||
{
|
||||
public const string featureId = "com.pico.openxr.feature.passthrough";
|
||||
public const string extensionString = "XR_FB_passthrough";
|
||||
public static bool isExtensionEnable = false;
|
||||
public const int XR_PASSTHROUGH_COLOR_MAP_MONO_SIZE_FB = 256;
|
||||
private static byte[] colorData;
|
||||
private static uint Size = 0;
|
||||
private static bool isInit = false;
|
||||
private static bool isPause = false;
|
||||
private static int _enableVideoSeeThrough=-1;
|
||||
public static event Action<bool> EnableVideoSeeThroughAction;
|
||||
[HideInInspector]
|
||||
public static bool EnableVideoSeeThrough
|
||||
{
|
||||
get => _enableVideoSeeThrough==1;
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
if (_enableVideoSeeThrough != 1)
|
||||
{
|
||||
_enableVideoSeeThrough = 1;
|
||||
EnableSeeThroughManual(value);
|
||||
|
||||
if (EnableVideoSeeThroughAction != null)
|
||||
{
|
||||
EnableVideoSeeThroughAction(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_enableVideoSeeThrough == 1)
|
||||
{
|
||||
_enableVideoSeeThrough = 0;
|
||||
EnableSeeThroughManual(value);
|
||||
|
||||
if (EnableVideoSeeThroughAction != null)
|
||||
{
|
||||
EnableVideoSeeThroughAction(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void Initialize(IntPtr intPtr)
|
||||
{
|
||||
isExtensionEnable = _isExtensionEnable;
|
||||
initialize(intPtr, xrInstance);
|
||||
}
|
||||
|
||||
public override string GetExtensionString()
|
||||
{
|
||||
return extensionString;
|
||||
}
|
||||
|
||||
public static void PassthroughStart()
|
||||
{
|
||||
passthroughStart();
|
||||
isPause = false;
|
||||
}
|
||||
|
||||
public static void PassthroughPause()
|
||||
{
|
||||
passthroughPause();
|
||||
isPause = true;
|
||||
}
|
||||
|
||||
public static bool EnableSeeThroughManual(bool value)
|
||||
{
|
||||
if (!isExtensionEnable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isInit)
|
||||
{
|
||||
isInit = initializePassthrough();
|
||||
}
|
||||
|
||||
if (value)
|
||||
{
|
||||
createFullScreenLayer();
|
||||
if (!isPause)
|
||||
{
|
||||
passthroughStart();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
passthroughPause();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void Destroy()
|
||||
{
|
||||
if (!isExtensionEnable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Passthrough_Destroy();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
private static void AllocateColorMapData(uint size)
|
||||
{
|
||||
if (colorData != null && size != colorData.Length)
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
if (colorData == null)
|
||||
{
|
||||
colorData = new byte[size];
|
||||
}
|
||||
}
|
||||
|
||||
private static void Clear()
|
||||
{
|
||||
if (colorData != null)
|
||||
{
|
||||
colorData = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteVector3ToColorMap(int colorIndex, ref Vector3 color)
|
||||
{
|
||||
for (int c = 0; c < 3; c++)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(color[c]);
|
||||
Buffer.BlockCopy(bytes, 0, colorData, colorIndex * 12 + c * 4, 4);
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteFloatToColorMap(int index, float value)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
Buffer.BlockCopy(bytes, 0, colorData, index * sizeof(float), sizeof(float));
|
||||
}
|
||||
|
||||
private static void WriteColorToColorMap(int colorIndex, ref Color color)
|
||||
{
|
||||
for (int c = 0; c < 4; c++)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(color[c]);
|
||||
Buffer.BlockCopy(bytes, 0, colorData, colorIndex * 16 + c * 4, 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static unsafe void SetBrightnessContrastSaturation(ref PassthroughStyle style, float brightness = 0.0f,
|
||||
float contrast = 0.0f, float saturation = 0.0f)
|
||||
{
|
||||
style.enableColorMap = true;
|
||||
style.TextureColorMapType = PassthroughColorMapType.BrightnessContrastSaturation;
|
||||
Size = 3 * sizeof(float);
|
||||
AllocateColorMapData(Size);
|
||||
WriteFloatToColorMap(0, brightness);
|
||||
|
||||
WriteFloatToColorMap(1, contrast);
|
||||
|
||||
WriteFloatToColorMap(2, saturation);
|
||||
fixed (byte* p = colorData)
|
||||
{
|
||||
style.TextureColorMapData = (IntPtr)p;
|
||||
}
|
||||
|
||||
style.TextureColorMapDataSize = Size;
|
||||
StringBuilder str = new StringBuilder();
|
||||
for (int i = 0; i < Size; i++)
|
||||
{
|
||||
str.Append(colorData[i]);
|
||||
}
|
||||
|
||||
Debug.Log("SetPassthroughStyle SetBrightnessContrastSaturation colorData:" + str);
|
||||
}
|
||||
|
||||
public static unsafe void SetColorMapbyMonoToMono(ref PassthroughStyle style, int[] values)
|
||||
{
|
||||
if (values.Length != XR_PASSTHROUGH_COLOR_MAP_MONO_SIZE_FB)
|
||||
throw new ArgumentException("Must provide exactly 256 values");
|
||||
style.enableColorMap = true;
|
||||
style.TextureColorMapType = PassthroughColorMapType.MonoToMono;
|
||||
Size = XR_PASSTHROUGH_COLOR_MAP_MONO_SIZE_FB * 4;
|
||||
AllocateColorMapData(Size);
|
||||
Buffer.BlockCopy(values, 0, colorData, 0, (int)Size);
|
||||
|
||||
fixed (byte* p = colorData)
|
||||
{
|
||||
style.TextureColorMapData = (IntPtr)p;
|
||||
}
|
||||
|
||||
style.TextureColorMapDataSize = Size;
|
||||
}
|
||||
|
||||
public static unsafe void SetColorMapbyMonoToRgba(ref PassthroughStyle style, Color[] values)
|
||||
{
|
||||
if (values.Length != XR_PASSTHROUGH_COLOR_MAP_MONO_SIZE_FB)
|
||||
throw new ArgumentException("Must provide exactly 256 colors");
|
||||
|
||||
style.TextureColorMapType = PassthroughColorMapType.MonoToRgba;
|
||||
style.enableColorMap = true;
|
||||
Size = XR_PASSTHROUGH_COLOR_MAP_MONO_SIZE_FB * 4 * 4;
|
||||
|
||||
AllocateColorMapData(Size);
|
||||
|
||||
for (int i = 0; i < XR_PASSTHROUGH_COLOR_MAP_MONO_SIZE_FB; i++)
|
||||
{
|
||||
WriteColorToColorMap(i, ref values[i]);
|
||||
}
|
||||
|
||||
fixed (byte* p = colorData)
|
||||
{
|
||||
style.TextureColorMapData = (IntPtr)p;
|
||||
}
|
||||
|
||||
style.TextureColorMapDataSize = Size;
|
||||
}
|
||||
|
||||
public static _PassthroughStyle ToPassthroughStyle(PassthroughStyle c)
|
||||
{
|
||||
_PassthroughStyle mPassthroughStyle = new _PassthroughStyle();
|
||||
mPassthroughStyle.enableEdgeColor = (uint)(c.enableEdgeColor ? 1 : 0);
|
||||
mPassthroughStyle.enableColorMap = (uint)(c.enableColorMap ? 1 : 0);
|
||||
mPassthroughStyle.TextureOpacityFactor = c.TextureOpacityFactor;
|
||||
mPassthroughStyle.TextureColorMapType = c.TextureColorMapType;
|
||||
mPassthroughStyle.TextureColorMapDataSize = c.TextureColorMapDataSize;
|
||||
mPassthroughStyle.TextureColorMapData = c.TextureColorMapData;
|
||||
mPassthroughStyle.EdgeColor = new Colorf()
|
||||
{ r = c.EdgeColor.r, g = c.EdgeColor.g, b = c.EdgeColor.b, a = c.EdgeColor.a };
|
||||
return mPassthroughStyle;
|
||||
}
|
||||
|
||||
public static void SetPassthroughStyle(PassthroughStyle style)
|
||||
{
|
||||
setPassthroughStyle(ToPassthroughStyle(style));
|
||||
}
|
||||
|
||||
public static bool IsPassthroughSupported()
|
||||
{
|
||||
return isPassthroughSupported();
|
||||
}
|
||||
|
||||
|
||||
public static unsafe bool CreateTriangleMesh(int id, Vector3[] vertices, int[] triangles,
|
||||
GeometryInstanceTransform transform)
|
||||
{
|
||||
if (vertices == null || triangles == null || vertices.Length == 0 || triangles.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isInit)
|
||||
{
|
||||
isInit = initializePassthrough();
|
||||
}
|
||||
|
||||
int vertexCount = vertices.Length;
|
||||
int triangleCount = triangles.Length;
|
||||
|
||||
Size = (uint)vertexCount * 3 * 4;
|
||||
|
||||
AllocateColorMapData(Size);
|
||||
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
{
|
||||
WriteVector3ToColorMap(i, ref vertices[i]);
|
||||
}
|
||||
|
||||
IntPtr vertexDataPtr = IntPtr.Zero;
|
||||
|
||||
fixed (byte* p = colorData)
|
||||
{
|
||||
vertexDataPtr = (IntPtr)p;
|
||||
}
|
||||
|
||||
StringBuilder str = new StringBuilder();
|
||||
for (int i = 0; i < 3 * 4; i++)
|
||||
{
|
||||
str.Append(colorData[i]);
|
||||
}
|
||||
|
||||
Debug.Log("CreateTriangleMesh vertexDataPtr colorData:" + str);
|
||||
str.Clear();
|
||||
|
||||
Size = (uint)triangleCount * 4;
|
||||
AllocateColorMapData(Size);
|
||||
Buffer.BlockCopy(triangles, 0, colorData, 0, (int)Size);
|
||||
IntPtr triangleDataPtr = IntPtr.Zero;
|
||||
fixed (byte* p = colorData)
|
||||
{
|
||||
triangleDataPtr = (IntPtr)p;
|
||||
}
|
||||
|
||||
for (int i = 0; i < colorData.Length; i++)
|
||||
{
|
||||
str.Append(colorData[i]);
|
||||
}
|
||||
|
||||
// Debug.Log("CreateTriangleMesh triangleDataPtr colorData:" + str);
|
||||
//
|
||||
// Debug.Log("CreateTriangleMesh vertexDataPtr=" + vertexDataPtr + " vertexCount=" + vertexCount);
|
||||
// Debug.Log("CreateTriangleMesh triangleDataPtr=" + triangleDataPtr + " triangleCount=" + triangleCount);
|
||||
|
||||
XrResult result =
|
||||
createTriangleMesh(id, vertexDataPtr, vertexCount, triangleDataPtr, triangleCount, transform);
|
||||
Clear();
|
||||
if (result == XrResult.Success)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void UpdateMeshTransform(int id, GeometryInstanceTransform transform)
|
||||
{
|
||||
updatePassthroughMeshTransform(id, transform);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Validation Rules for ARCameraFeature.
|
||||
/// </summary>
|
||||
protected override void GetValidationChecks(List<ValidationRule> rules, BuildTargetGroup targetGroup)
|
||||
{
|
||||
var AdditionalRules = new ValidationRule[]
|
||||
{
|
||||
new ValidationRule(this)
|
||||
{
|
||||
message = "Passthrough requires Camera clear flags set to solid color with alpha value zero.",
|
||||
checkPredicate = () =>
|
||||
{
|
||||
|
||||
var xrOrigin = FindObjectsOfType<XROrigin>();
|
||||
|
||||
if (xrOrigin != null && xrOrigin.Length > 0)
|
||||
{
|
||||
if (!xrOrigin[0].enabled) return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var camera = xrOrigin[0].Camera;
|
||||
if (camera == null) return true;
|
||||
|
||||
return camera.clearFlags == CameraClearFlags.SolidColor && Mathf.Approximately(camera.backgroundColor.a, 0);
|
||||
},
|
||||
fixItAutomatic = true,
|
||||
fixItMessage = "Set your XR Origin camera's Clear Flags to solid color with alpha value zero.",
|
||||
fixIt = () =>
|
||||
{
|
||||
var xrOrigin = FindObjectsOfType<XROrigin>();
|
||||
if (xrOrigin!=null&&xrOrigin.Length>0)
|
||||
{
|
||||
if (xrOrigin[0].enabled)
|
||||
{
|
||||
var camera = xrOrigin[0].Camera;
|
||||
if (camera != null )
|
||||
{
|
||||
camera.clearFlags = CameraClearFlags.SolidColor;
|
||||
Color clearColor = camera.backgroundColor;
|
||||
clearColor.a = 0;
|
||||
camera.backgroundColor = clearColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
error = false
|
||||
}
|
||||
};
|
||||
|
||||
rules.AddRange(AdditionalRules);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if AR_FOUNDATION
|
||||
public bool isCameraSubsystem=true;
|
||||
static List<XRCameraSubsystemDescriptor> s_CameraDescriptors = new List<XRCameraSubsystemDescriptor>();
|
||||
protected override void OnSubsystemCreate()
|
||||
{
|
||||
base.OnSubsystemCreate();
|
||||
if (isCameraSubsystem)
|
||||
{
|
||||
CreateSubsystem<XRCameraSubsystemDescriptor, XRCameraSubsystem>(
|
||||
s_CameraDescriptors,
|
||||
PICOCameraSubsystem.k_SubsystemId);
|
||||
}
|
||||
|
||||
}
|
||||
protected override void OnSubsystemStart()
|
||||
{
|
||||
if (isCameraSubsystem)
|
||||
{
|
||||
StartSubsystem<XRCameraSubsystem>();
|
||||
}
|
||||
}
|
||||
protected override void OnSubsystemStop()
|
||||
{
|
||||
if (isCameraSubsystem)
|
||||
{
|
||||
StopSubsystem<XRCameraSubsystem>();
|
||||
}
|
||||
}
|
||||
protected override void OnSubsystemDestroy()
|
||||
{
|
||||
if (isCameraSubsystem)
|
||||
{
|
||||
DestroySubsystem<XRCameraSubsystem>();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
protected override void OnSessionStateChange(int oldState, int newState)
|
||||
{
|
||||
base.OnSessionStateChange(oldState, newState);
|
||||
if (newState == 1)
|
||||
{
|
||||
#if AR_FOUNDATION
|
||||
if (isCameraSubsystem)
|
||||
{
|
||||
StopSubsystem<XRCameraSubsystem>();
|
||||
}else{
|
||||
if (_enableVideoSeeThrough!=-1)
|
||||
{
|
||||
EnableSeeThroughManual(false);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (_enableVideoSeeThrough!=-1)
|
||||
{
|
||||
EnableSeeThroughManual(false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (newState == 5)
|
||||
{
|
||||
#if AR_FOUNDATION
|
||||
if (isCameraSubsystem)
|
||||
{
|
||||
StartSubsystem<XRCameraSubsystem>();
|
||||
}else{
|
||||
if (_enableVideoSeeThrough!=-1)
|
||||
{
|
||||
EnableSeeThroughManual(EnableVideoSeeThrough);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (_enableVideoSeeThrough!=-1)
|
||||
{
|
||||
EnableSeeThroughManual(EnableVideoSeeThrough);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
private const string ExtLib = "openxr_pico";
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_initialize_Passthrough", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void initialize(IntPtr xrGetInstanceProcAddr, ulong xrInstance);
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_InitializePassthrough", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool initializePassthrough();
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_CreateFullScreenLayer", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool createFullScreenLayer();
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_PassthroughStart", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void passthroughStart();
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_PassthroughPause", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void passthroughPause();
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_SetPassthroughStyle", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void setPassthroughStyle(_PassthroughStyle style);
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_IsPassthroughSupported", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool isPassthroughSupported();
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_Passthrough_Destroy", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void Passthrough_Destroy();
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_CreateTriangleMesh", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern XrResult createTriangleMesh(int id, IntPtr vertices, int vertexCount, IntPtr triangles,
|
||||
int triangleCount, GeometryInstanceTransform transform);
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_UpdatePassthroughMeshTransform",
|
||||
CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void updatePassthroughMeshTransform(int id, GeometryInstanceTransform transform);
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d49168b6dfb469dadf8cd56e4ab8884
|
||||
timeCreated: 1689933482
|
@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
public class PassthroughLayerFeature : LayerBase
|
||||
{
|
||||
private int id = 0;
|
||||
private Vector3[] vertices;
|
||||
private int[] triangles;
|
||||
private Mesh mesh;
|
||||
private bool isPassthroughSupported = false;
|
||||
private bool isCreateTriangleMesh = false;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
id = ID;
|
||||
Debug.Log("AAA:"+this.gameObject.name+" ID="+id);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
MeshFilter meshFilter = this.gameObject.GetComponent<MeshFilter>();
|
||||
if (meshFilter == null)
|
||||
{
|
||||
Debug.LogError("Passthrough GameObject does not have a mesh component.");
|
||||
return;
|
||||
}
|
||||
|
||||
mesh = meshFilter.sharedMesh;
|
||||
vertices = mesh.vertices;
|
||||
triangles = mesh.triangles;
|
||||
isPassthroughSupported = PassthroughFeature.IsPassthroughSupported();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (isPassthroughSupported && !isCreateTriangleMesh)
|
||||
{
|
||||
GeometryInstanceTransform Transform = new GeometryInstanceTransform();
|
||||
UpdateCoords();
|
||||
GetCurrentTransform(ref Transform);
|
||||
isCreateTriangleMesh = PassthroughFeature.CreateTriangleMesh(id, vertices, triangles, Transform);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
Camera.onPostRender += OnPostRenderCallBack;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
Camera.onPostRender -= OnPostRenderCallBack;
|
||||
}
|
||||
|
||||
|
||||
private void OnPostRenderCallBack(Camera cam)
|
||||
{
|
||||
GeometryInstanceTransform Transform = new GeometryInstanceTransform();
|
||||
UpdateCoords();
|
||||
GetCurrentTransform(ref Transform);
|
||||
PassthroughFeature.UpdateMeshTransform(id, Transform);
|
||||
}
|
||||
|
||||
void OnApplicationPause(bool pause)
|
||||
{
|
||||
if (pause)
|
||||
{
|
||||
PassthroughFeature.PassthroughPause();
|
||||
}
|
||||
else
|
||||
{
|
||||
PassthroughFeature.PassthroughStart();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8853b182e1e842fbb91b68c168d5b587
|
||||
timeCreated: 1694522562
|
@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using AOT;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.OpenXR;
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor.XR.OpenXR.Features;
|
||||
#endif
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
public enum XrPerfSettingsDomainEXT
|
||||
{
|
||||
XR_PERF_SETTINGS_DOMAIN_CPU_EXT = 1,
|
||||
XR_PERF_SETTINGS_DOMAIN_GPU_EXT = 2,
|
||||
}
|
||||
|
||||
public enum XrPerfSettingsLevelEXT
|
||||
{
|
||||
XR_PERF_SETTINGS_LEVEL_POWER_SAVINGS_EXT = 0,
|
||||
XR_PERF_SETTINGS_LEVEL_SUSTAINED_LOW_EXT = 25,
|
||||
XR_PERF_SETTINGS_LEVEL_SUSTAINED_HIGH_EXT = 50,
|
||||
XR_PERF_SETTINGS_LEVEL_BOOST_EXT = 75,
|
||||
}
|
||||
|
||||
public enum XrPerfSettingsSubDomainEXT
|
||||
{
|
||||
XR_PERF_SETTINGS_SUB_DOMAIN_COMPOSITING_EXT = 1,
|
||||
XR_PERF_SETTINGS_SUB_DOMAIN_RENDERING_EXT = 2,
|
||||
XR_PERF_SETTINGS_SUB_DOMAIN_THERMAL_EXT = 3,
|
||||
}
|
||||
|
||||
public enum XrPerfSettingsNotificationLevelEXT
|
||||
{
|
||||
XR_PERF_SETTINGS_NOTIF_LEVEL_NORMAL_EXT = 0,
|
||||
XR_PERF_SETTINGS_NOTIF_LEVEL_WARNING_EXT = 25,
|
||||
XR_PERF_SETTINGS_NOTIF_LEVEL_IMPAIRED_EXT = 75,
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
[OpenXRFeature(UiName = "OpenXR Performance Settings",
|
||||
Hidden = false,
|
||||
BuildTargetGroups = new[] { UnityEditor.BuildTargetGroup.Android },
|
||||
Company = "PICO",
|
||||
OpenxrExtensionStrings = extensionString,
|
||||
Version = "1.0.0",
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
|
||||
public class PerformanceSettingsFeature : OpenXRFeatureBase
|
||||
{
|
||||
public const string featureId = "com.pico.openxr.feature.performancesettings";
|
||||
public const string extensionString = "XR_EXT_performance_settings";
|
||||
public static bool isExtensionEnable = false;
|
||||
|
||||
private static Action<XrPerfSettingsDomainEXT, XrPerfSettingsSubDomainEXT, XrPerfSettingsNotificationLevelEXT,
|
||||
XrPerfSettingsNotificationLevelEXT> mCallback;
|
||||
|
||||
public delegate void EventDelegate(XrPerfSettingsDomainEXT domain, XrPerfSettingsSubDomainEXT subDomain,
|
||||
XrPerfSettingsNotificationLevelEXT fromLevel,
|
||||
XrPerfSettingsNotificationLevelEXT toLevel);
|
||||
|
||||
public override void Initialize(IntPtr intPtr)
|
||||
{
|
||||
isExtensionEnable = _isExtensionEnable;
|
||||
initialize(intPtr, xrInstance, EventFromCpp);
|
||||
}
|
||||
|
||||
|
||||
[MonoPInvokeCallback(typeof(EventDelegate))]
|
||||
public static void EventFromCpp(XrPerfSettingsDomainEXT domain, XrPerfSettingsSubDomainEXT subDomain,
|
||||
XrPerfSettingsNotificationLevelEXT fromLevel,
|
||||
XrPerfSettingsNotificationLevelEXT toLevel)
|
||||
{
|
||||
if (mCallback != null)
|
||||
{
|
||||
mCallback(domain, subDomain, fromLevel, toLevel);
|
||||
}
|
||||
}
|
||||
|
||||
public override string GetExtensionString()
|
||||
{
|
||||
return extensionString;
|
||||
}
|
||||
|
||||
public static XrResult XrPerfSettingsSetPerformanceLevelEXT(XrPerfSettingsDomainEXT domain,
|
||||
XrPerfSettingsLevelEXT level)
|
||||
{
|
||||
return xrPerfSettingsSetPerformanceLevelEXT(xrSession, domain, level);
|
||||
}
|
||||
|
||||
|
||||
public static void AddPerfSettingsSetPerformanceEvent(
|
||||
Action<XrPerfSettingsDomainEXT, XrPerfSettingsSubDomainEXT, XrPerfSettingsNotificationLevelEXT,
|
||||
XrPerfSettingsNotificationLevelEXT> callback)
|
||||
{
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
private const string ExtLib = "openxr_pico";
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_initialize_PerformanceSettings",
|
||||
CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void initialize(IntPtr xrGetInstanceProcAddr, ulong xrInstance,
|
||||
EventDelegate eventDelegate);
|
||||
|
||||
[DllImport(ExtLib, EntryPoint = "PICO_xrPerfSettingsSetPerformanceLevelEXT",
|
||||
CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern XrResult xrPerfSettingsSetPerformanceLevelEXT(ulong xrSession,
|
||||
XrPerfSettingsDomainEXT domain, XrPerfSettingsLevelEXT level);
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48a4218836ed47e2b2fe51c7c56925c7
|
||||
timeCreated: 1695634496
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eef38826347e4f57aadf5fa0a9a299cd
|
||||
timeCreated: 1687328262
|
@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
public class LayerBase : MonoBehaviour
|
||||
{
|
||||
public static int ID = 0;
|
||||
private Transform overlayTransform;
|
||||
private Camera[] overlayEyeCamera = new Camera[2];
|
||||
private Camera xrRig;
|
||||
private Matrix4x4[] mvMatrixs = new Matrix4x4[2];
|
||||
private Vector3[] modelScales = new Vector3[2];
|
||||
private Vector3[] modelTranslations = new Vector3[2];
|
||||
private Quaternion[] modelRotations = new Quaternion[2];
|
||||
private Quaternion[] cameraRotations = new Quaternion[2];
|
||||
private Vector3[] cameraTranslations = new Vector3[2];
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
ID++;
|
||||
xrRig = Camera.main;
|
||||
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
|
||||
}
|
||||
private void OnDestroy()
|
||||
{
|
||||
ID--;
|
||||
}
|
||||
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 void GetCurrentTransform(ref GeometryInstanceTransform geometryInstanceTransform)
|
||||
{
|
||||
Quaternion quaternion = new Quaternion(modelRotations[0].x,
|
||||
modelRotations[0].y, modelRotations[0].z,
|
||||
modelRotations[0].w);
|
||||
Vector3 cameraPos = Vector3.zero;
|
||||
Quaternion cameraRot = Quaternion.identity;
|
||||
Transform origin = null;
|
||||
bool ret = PICOManager.Instance.GetOrigin(ref cameraPos, ref cameraRot, ref origin);
|
||||
if (!ret)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Quaternion lQuaternion = new Quaternion(-cameraRot.x, -cameraRot.y, -cameraRot.z, cameraRot.w);
|
||||
Vector3 pos = new Vector3(modelTranslations[0].x - cameraPos.x,
|
||||
modelTranslations[0].y - PICOManager.Instance.getCameraYOffset() +
|
||||
PICOManager.Instance.GetOriginY() - cameraPos.y, modelTranslations[0].z - cameraPos.z);
|
||||
|
||||
quaternion *= lQuaternion;
|
||||
origin.rotation *= lQuaternion;
|
||||
pos = origin.TransformPoint(pos);
|
||||
|
||||
geometryInstanceTransform.pose.position.x = pos.x;
|
||||
geometryInstanceTransform.pose.position.y = pos.y;
|
||||
geometryInstanceTransform.pose.position.z = -pos.z;
|
||||
geometryInstanceTransform.pose.orientation.x = -quaternion.x;
|
||||
geometryInstanceTransform.pose.orientation.y = -quaternion.y;
|
||||
geometryInstanceTransform.pose.orientation.z = quaternion.z;
|
||||
geometryInstanceTransform.pose.orientation.w = quaternion.w;
|
||||
|
||||
geometryInstanceTransform.scale.x = modelScales[0].x;
|
||||
geometryInstanceTransform.scale.y = modelScales[0].y;
|
||||
geometryInstanceTransform.scale.z = 1;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 619cbe0f286043ec9552bc759e03b9d7
|
||||
timeCreated: 1695197751
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e80d58020bdd4b42b9c135992067180
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,60 @@
|
||||
#region Header
|
||||
/**
|
||||
* IJsonWrapper.cs
|
||||
* Interface that represents a type capable of handling all kinds of JSON
|
||||
* data. This is mainly used when mapping objects through JsonMapper, and
|
||||
* it's implemented by JsonData.
|
||||
*
|
||||
* The authors disclaim copyright to this source code. For more details, see
|
||||
* the COPYING file included with this distribution.
|
||||
**/
|
||||
#endregion
|
||||
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
|
||||
namespace LitJson
|
||||
{
|
||||
public enum JsonType
|
||||
{
|
||||
None,
|
||||
|
||||
Object,
|
||||
Array,
|
||||
String,
|
||||
Int,
|
||||
Long,
|
||||
Double,
|
||||
Boolean
|
||||
}
|
||||
|
||||
public interface IJsonWrapper : IList, IOrderedDictionary
|
||||
{
|
||||
bool IsArray { get; }
|
||||
bool IsBoolean { get; }
|
||||
bool IsDouble { get; }
|
||||
bool IsInt { get; }
|
||||
bool IsLong { get; }
|
||||
bool IsObject { get; }
|
||||
bool IsString { get; }
|
||||
|
||||
bool GetBoolean ();
|
||||
double GetDouble ();
|
||||
int GetInt ();
|
||||
JsonType GetJsonType ();
|
||||
long GetLong ();
|
||||
string GetString ();
|
||||
|
||||
void SetBoolean (bool val);
|
||||
void SetDouble (double val);
|
||||
void SetInt (int val);
|
||||
void SetJsonType (JsonType type);
|
||||
void SetLong (long val);
|
||||
void SetString (string val);
|
||||
|
||||
string ToJson ();
|
||||
void ToJson (JsonWriter writer);
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e1ef0f496c0fb5146b7aa4877024fa79
|
||||
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: d3ae25b6b7cd44b40a54c07476a52456
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,65 @@
|
||||
#region Header
|
||||
/**
|
||||
* JsonException.cs
|
||||
* Base class throwed by LitJSON when a parsing error occurs.
|
||||
*
|
||||
* The authors disclaim copyright to this source code. For more details, see
|
||||
* the COPYING file included with this distribution.
|
||||
**/
|
||||
#endregion
|
||||
|
||||
|
||||
using System;
|
||||
|
||||
|
||||
namespace LitJson
|
||||
{
|
||||
public class JsonException :
|
||||
#if NETSTANDARD1_5
|
||||
Exception
|
||||
#else
|
||||
ApplicationException
|
||||
#endif
|
||||
{
|
||||
public JsonException () : base ()
|
||||
{
|
||||
}
|
||||
|
||||
internal JsonException (ParserToken token) :
|
||||
base (String.Format (
|
||||
"Invalid token '{0}' in input string", token))
|
||||
{
|
||||
}
|
||||
|
||||
internal JsonException (ParserToken token,
|
||||
Exception inner_exception) :
|
||||
base (String.Format (
|
||||
"Invalid token '{0}' in input string", token),
|
||||
inner_exception)
|
||||
{
|
||||
}
|
||||
|
||||
internal JsonException (int c) :
|
||||
base (String.Format (
|
||||
"Invalid character '{0}' in input string", (char) c))
|
||||
{
|
||||
}
|
||||
|
||||
internal JsonException (int c, Exception inner_exception) :
|
||||
base (String.Format (
|
||||
"Invalid character '{0}' in input string", (char) c),
|
||||
inner_exception)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public JsonException (string message) : base (message)
|
||||
{
|
||||
}
|
||||
|
||||
public JsonException (string message, Exception inner_exception) :
|
||||
base (message, inner_exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81e400e6b0dcff7418936a822864e3a6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,987 @@
|
||||
#region Header
|
||||
/**
|
||||
* JsonMapper.cs
|
||||
* JSON to .Net object and object to JSON conversions.
|
||||
*
|
||||
* The authors disclaim copyright to this source code. For more details, see
|
||||
* the COPYING file included with this distribution.
|
||||
**/
|
||||
#endregion
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
|
||||
namespace LitJson
|
||||
{
|
||||
internal struct PropertyMetadata
|
||||
{
|
||||
public MemberInfo Info;
|
||||
public bool IsField;
|
||||
public Type Type;
|
||||
}
|
||||
|
||||
|
||||
internal struct ArrayMetadata
|
||||
{
|
||||
private Type element_type;
|
||||
private bool is_array;
|
||||
private bool is_list;
|
||||
|
||||
|
||||
public Type ElementType {
|
||||
get {
|
||||
if (element_type == null)
|
||||
return typeof (JsonData);
|
||||
|
||||
return element_type;
|
||||
}
|
||||
|
||||
set { element_type = value; }
|
||||
}
|
||||
|
||||
public bool IsArray {
|
||||
get { return is_array; }
|
||||
set { is_array = value; }
|
||||
}
|
||||
|
||||
public bool IsList {
|
||||
get { return is_list; }
|
||||
set { is_list = value; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal struct ObjectMetadata
|
||||
{
|
||||
private Type element_type;
|
||||
private bool is_dictionary;
|
||||
|
||||
private IDictionary<string, PropertyMetadata> properties;
|
||||
|
||||
|
||||
public Type ElementType {
|
||||
get {
|
||||
if (element_type == null)
|
||||
return typeof (JsonData);
|
||||
|
||||
return element_type;
|
||||
}
|
||||
|
||||
set { element_type = value; }
|
||||
}
|
||||
|
||||
public bool IsDictionary {
|
||||
get { return is_dictionary; }
|
||||
set { is_dictionary = value; }
|
||||
}
|
||||
|
||||
public IDictionary<string, PropertyMetadata> Properties {
|
||||
get { return properties; }
|
||||
set { properties = value; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal delegate void ExporterFunc (object obj, JsonWriter writer);
|
||||
public delegate void ExporterFunc<T> (T obj, JsonWriter writer);
|
||||
|
||||
internal delegate object ImporterFunc (object input);
|
||||
public delegate TValue ImporterFunc<TJson, TValue> (TJson input);
|
||||
|
||||
public delegate IJsonWrapper WrapperFactory ();
|
||||
|
||||
|
||||
public class JsonMapper
|
||||
{
|
||||
#region Fields
|
||||
private static readonly int max_nesting_depth;
|
||||
|
||||
private static readonly IFormatProvider datetime_format;
|
||||
|
||||
private static readonly IDictionary<Type, ExporterFunc> base_exporters_table;
|
||||
private static readonly IDictionary<Type, ExporterFunc> custom_exporters_table;
|
||||
|
||||
private static readonly IDictionary<Type,
|
||||
IDictionary<Type, ImporterFunc>> base_importers_table;
|
||||
private static readonly IDictionary<Type,
|
||||
IDictionary<Type, ImporterFunc>> custom_importers_table;
|
||||
|
||||
private static readonly IDictionary<Type, ArrayMetadata> array_metadata;
|
||||
private static readonly object array_metadata_lock = new Object ();
|
||||
|
||||
private static readonly IDictionary<Type,
|
||||
IDictionary<Type, MethodInfo>> conv_ops;
|
||||
private static readonly object conv_ops_lock = new Object ();
|
||||
|
||||
private static readonly IDictionary<Type, ObjectMetadata> object_metadata;
|
||||
private static readonly object object_metadata_lock = new Object ();
|
||||
|
||||
private static readonly IDictionary<Type,
|
||||
IList<PropertyMetadata>> type_properties;
|
||||
private static readonly object type_properties_lock = new Object ();
|
||||
|
||||
private static readonly JsonWriter static_writer;
|
||||
private static readonly object static_writer_lock = new Object ();
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
static JsonMapper ()
|
||||
{
|
||||
max_nesting_depth = 100;
|
||||
|
||||
array_metadata = new Dictionary<Type, ArrayMetadata> ();
|
||||
conv_ops = new Dictionary<Type, IDictionary<Type, MethodInfo>> ();
|
||||
object_metadata = new Dictionary<Type, ObjectMetadata> ();
|
||||
type_properties = new Dictionary<Type,
|
||||
IList<PropertyMetadata>> ();
|
||||
|
||||
static_writer = new JsonWriter ();
|
||||
|
||||
datetime_format = DateTimeFormatInfo.InvariantInfo;
|
||||
|
||||
base_exporters_table = new Dictionary<Type, ExporterFunc> ();
|
||||
custom_exporters_table = new Dictionary<Type, ExporterFunc> ();
|
||||
|
||||
base_importers_table = new Dictionary<Type,
|
||||
IDictionary<Type, ImporterFunc>> ();
|
||||
custom_importers_table = new Dictionary<Type,
|
||||
IDictionary<Type, ImporterFunc>> ();
|
||||
|
||||
RegisterBaseExporters ();
|
||||
RegisterBaseImporters ();
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Private Methods
|
||||
private static void AddArrayMetadata (Type type)
|
||||
{
|
||||
if (array_metadata.ContainsKey (type))
|
||||
return;
|
||||
|
||||
ArrayMetadata data = new ArrayMetadata ();
|
||||
|
||||
data.IsArray = type.IsArray;
|
||||
|
||||
if (type.GetInterface ("System.Collections.IList") != null)
|
||||
data.IsList = true;
|
||||
|
||||
foreach (PropertyInfo p_info in type.GetProperties ()) {
|
||||
if (p_info.Name != "Item")
|
||||
continue;
|
||||
|
||||
ParameterInfo[] parameters = p_info.GetIndexParameters ();
|
||||
|
||||
if (parameters.Length != 1)
|
||||
continue;
|
||||
|
||||
if (parameters[0].ParameterType == typeof (int))
|
||||
data.ElementType = p_info.PropertyType;
|
||||
}
|
||||
|
||||
lock (array_metadata_lock) {
|
||||
try {
|
||||
array_metadata.Add (type, data);
|
||||
} catch (ArgumentException) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddObjectMetadata (Type type)
|
||||
{
|
||||
if (object_metadata.ContainsKey (type))
|
||||
return;
|
||||
|
||||
ObjectMetadata data = new ObjectMetadata ();
|
||||
|
||||
if (type.GetInterface ("System.Collections.IDictionary") != null)
|
||||
data.IsDictionary = true;
|
||||
|
||||
data.Properties = new Dictionary<string, PropertyMetadata> ();
|
||||
|
||||
foreach (PropertyInfo p_info in type.GetProperties ()) {
|
||||
if (p_info.Name == "Item") {
|
||||
ParameterInfo[] parameters = p_info.GetIndexParameters ();
|
||||
|
||||
if (parameters.Length != 1)
|
||||
continue;
|
||||
|
||||
if (parameters[0].ParameterType == typeof (string))
|
||||
data.ElementType = p_info.PropertyType;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
PropertyMetadata p_data = new PropertyMetadata ();
|
||||
p_data.Info = p_info;
|
||||
p_data.Type = p_info.PropertyType;
|
||||
|
||||
data.Properties.Add (p_info.Name, p_data);
|
||||
}
|
||||
|
||||
foreach (FieldInfo f_info in type.GetFields ()) {
|
||||
PropertyMetadata p_data = new PropertyMetadata ();
|
||||
p_data.Info = f_info;
|
||||
p_data.IsField = true;
|
||||
p_data.Type = f_info.FieldType;
|
||||
|
||||
data.Properties.Add (f_info.Name, p_data);
|
||||
}
|
||||
|
||||
lock (object_metadata_lock) {
|
||||
try {
|
||||
object_metadata.Add (type, data);
|
||||
} catch (ArgumentException) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddTypeProperties (Type type)
|
||||
{
|
||||
if (type_properties.ContainsKey (type))
|
||||
return;
|
||||
|
||||
IList<PropertyMetadata> props = new List<PropertyMetadata> ();
|
||||
|
||||
foreach (PropertyInfo p_info in type.GetProperties ()) {
|
||||
if (p_info.Name == "Item")
|
||||
continue;
|
||||
|
||||
PropertyMetadata p_data = new PropertyMetadata ();
|
||||
p_data.Info = p_info;
|
||||
p_data.IsField = false;
|
||||
props.Add (p_data);
|
||||
}
|
||||
|
||||
foreach (FieldInfo f_info in type.GetFields ()) {
|
||||
PropertyMetadata p_data = new PropertyMetadata ();
|
||||
p_data.Info = f_info;
|
||||
p_data.IsField = true;
|
||||
|
||||
props.Add (p_data);
|
||||
}
|
||||
|
||||
lock (type_properties_lock) {
|
||||
try {
|
||||
type_properties.Add (type, props);
|
||||
} catch (ArgumentException) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static MethodInfo GetConvOp (Type t1, Type t2)
|
||||
{
|
||||
lock (conv_ops_lock) {
|
||||
if (! conv_ops.ContainsKey (t1))
|
||||
conv_ops.Add (t1, new Dictionary<Type, MethodInfo> ());
|
||||
}
|
||||
|
||||
if (conv_ops[t1].ContainsKey (t2))
|
||||
return conv_ops[t1][t2];
|
||||
|
||||
MethodInfo op = t1.GetMethod (
|
||||
"op_Implicit", new Type[] { t2 });
|
||||
|
||||
lock (conv_ops_lock) {
|
||||
try {
|
||||
conv_ops[t1].Add (t2, op);
|
||||
} catch (ArgumentException) {
|
||||
return conv_ops[t1][t2];
|
||||
}
|
||||
}
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
private static object ReadValue (Type inst_type, JsonReader reader)
|
||||
{
|
||||
reader.Read ();
|
||||
|
||||
if (reader.Token == JsonToken.ArrayEnd)
|
||||
return null;
|
||||
|
||||
Type underlying_type = Nullable.GetUnderlyingType(inst_type);
|
||||
Type value_type = underlying_type ?? inst_type;
|
||||
|
||||
if (reader.Token == JsonToken.Null) {
|
||||
#if NETSTANDARD1_5
|
||||
if (inst_type.IsClass() || underlying_type != null) {
|
||||
return null;
|
||||
}
|
||||
#else
|
||||
if (inst_type.IsClass || underlying_type != null) {
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
|
||||
throw new JsonException (String.Format (
|
||||
"Can't assign null to an instance of type {0}",
|
||||
inst_type));
|
||||
}
|
||||
|
||||
if (reader.Token == JsonToken.Double ||
|
||||
reader.Token == JsonToken.Int ||
|
||||
reader.Token == JsonToken.Long ||
|
||||
reader.Token == JsonToken.String ||
|
||||
reader.Token == JsonToken.Boolean) {
|
||||
|
||||
Type json_type = reader.Value.GetType ();
|
||||
|
||||
if (value_type.IsAssignableFrom (json_type))
|
||||
return reader.Value;
|
||||
|
||||
// If there's a custom importer that fits, use it
|
||||
if (custom_importers_table.ContainsKey (json_type) &&
|
||||
custom_importers_table[json_type].ContainsKey (
|
||||
value_type)) {
|
||||
|
||||
ImporterFunc importer =
|
||||
custom_importers_table[json_type][value_type];
|
||||
|
||||
return importer (reader.Value);
|
||||
}
|
||||
|
||||
// Maybe there's a base importer that works
|
||||
if (base_importers_table.ContainsKey (json_type) &&
|
||||
base_importers_table[json_type].ContainsKey (
|
||||
value_type)) {
|
||||
|
||||
ImporterFunc importer =
|
||||
base_importers_table[json_type][value_type];
|
||||
|
||||
return importer (reader.Value);
|
||||
}
|
||||
|
||||
// Maybe it's an enum
|
||||
#if NETSTANDARD1_5
|
||||
if (value_type.IsEnum())
|
||||
return Enum.ToObject (value_type, reader.Value);
|
||||
#else
|
||||
if (value_type.IsEnum)
|
||||
return Enum.ToObject (value_type, reader.Value);
|
||||
#endif
|
||||
// Try using an implicit conversion operator
|
||||
MethodInfo conv_op = GetConvOp (value_type, json_type);
|
||||
|
||||
if (conv_op != null)
|
||||
return conv_op.Invoke (null,
|
||||
new object[] { reader.Value });
|
||||
|
||||
// No luck
|
||||
throw new JsonException (String.Format (
|
||||
"Can't assign value '{0}' (type {1}) to type {2}",
|
||||
reader.Value, json_type, inst_type));
|
||||
}
|
||||
|
||||
object instance = null;
|
||||
|
||||
if (reader.Token == JsonToken.ArrayStart) {
|
||||
|
||||
AddArrayMetadata (inst_type);
|
||||
ArrayMetadata t_data = array_metadata[inst_type];
|
||||
|
||||
if (! t_data.IsArray && ! t_data.IsList)
|
||||
throw new JsonException (String.Format (
|
||||
"Type {0} can't act as an array",
|
||||
inst_type));
|
||||
|
||||
IList list;
|
||||
Type elem_type;
|
||||
|
||||
if (! t_data.IsArray) {
|
||||
list = (IList) Activator.CreateInstance (inst_type);
|
||||
elem_type = t_data.ElementType;
|
||||
} else {
|
||||
list = new ArrayList ();
|
||||
elem_type = inst_type.GetElementType ();
|
||||
}
|
||||
|
||||
list.Clear();
|
||||
|
||||
while (true) {
|
||||
object item = ReadValue (elem_type, reader);
|
||||
if (item == null && reader.Token == JsonToken.ArrayEnd)
|
||||
break;
|
||||
|
||||
list.Add (item);
|
||||
}
|
||||
|
||||
if (t_data.IsArray) {
|
||||
int n = list.Count;
|
||||
instance = Array.CreateInstance (elem_type, n);
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
((Array) instance).SetValue (list[i], i);
|
||||
} else
|
||||
instance = list;
|
||||
|
||||
} else if (reader.Token == JsonToken.ObjectStart) {
|
||||
AddObjectMetadata (value_type);
|
||||
ObjectMetadata t_data = object_metadata[value_type];
|
||||
|
||||
instance = Activator.CreateInstance (value_type);
|
||||
|
||||
while (true) {
|
||||
reader.Read ();
|
||||
|
||||
if (reader.Token == JsonToken.ObjectEnd)
|
||||
break;
|
||||
|
||||
string property = (string) reader.Value;
|
||||
|
||||
if (t_data.Properties.ContainsKey (property)) {
|
||||
PropertyMetadata prop_data =
|
||||
t_data.Properties[property];
|
||||
|
||||
if (prop_data.IsField) {
|
||||
((FieldInfo) prop_data.Info).SetValue (
|
||||
instance, ReadValue (prop_data.Type, reader));
|
||||
} else {
|
||||
PropertyInfo p_info =
|
||||
(PropertyInfo) prop_data.Info;
|
||||
|
||||
if (p_info.CanWrite)
|
||||
p_info.SetValue (
|
||||
instance,
|
||||
ReadValue (prop_data.Type, reader),
|
||||
null);
|
||||
else
|
||||
ReadValue (prop_data.Type, reader);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (! t_data.IsDictionary) {
|
||||
|
||||
if (! reader.SkipNonMembers) {
|
||||
throw new JsonException (String.Format (
|
||||
"The type {0} doesn't have the " +
|
||||
"property '{1}'",
|
||||
inst_type, property));
|
||||
} else {
|
||||
ReadSkip (reader);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
((IDictionary) instance).Add (
|
||||
property, ReadValue (
|
||||
t_data.ElementType, reader));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static IJsonWrapper ReadValue (WrapperFactory factory,
|
||||
JsonReader reader)
|
||||
{
|
||||
reader.Read ();
|
||||
|
||||
if (reader.Token == JsonToken.ArrayEnd ||
|
||||
reader.Token == JsonToken.Null)
|
||||
return null;
|
||||
|
||||
IJsonWrapper instance = factory ();
|
||||
|
||||
if (reader.Token == JsonToken.String) {
|
||||
instance.SetString ((string) reader.Value);
|
||||
return instance;
|
||||
}
|
||||
|
||||
if (reader.Token == JsonToken.Double) {
|
||||
instance.SetDouble ((double) reader.Value);
|
||||
return instance;
|
||||
}
|
||||
|
||||
if (reader.Token == JsonToken.Int) {
|
||||
instance.SetInt ((int) reader.Value);
|
||||
return instance;
|
||||
}
|
||||
|
||||
if (reader.Token == JsonToken.Long) {
|
||||
instance.SetLong ((long) reader.Value);
|
||||
return instance;
|
||||
}
|
||||
|
||||
if (reader.Token == JsonToken.Boolean) {
|
||||
instance.SetBoolean ((bool) reader.Value);
|
||||
return instance;
|
||||
}
|
||||
|
||||
if (reader.Token == JsonToken.ArrayStart) {
|
||||
instance.SetJsonType (JsonType.Array);
|
||||
|
||||
while (true) {
|
||||
IJsonWrapper item = ReadValue (factory, reader);
|
||||
if (item == null && reader.Token == JsonToken.ArrayEnd)
|
||||
break;
|
||||
|
||||
((IList) instance).Add (item);
|
||||
}
|
||||
}
|
||||
else if (reader.Token == JsonToken.ObjectStart) {
|
||||
instance.SetJsonType (JsonType.Object);
|
||||
|
||||
while (true) {
|
||||
reader.Read ();
|
||||
|
||||
if (reader.Token == JsonToken.ObjectEnd)
|
||||
break;
|
||||
|
||||
string property = (string) reader.Value;
|
||||
|
||||
((IDictionary) instance)[property] = ReadValue (
|
||||
factory, reader);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static void ReadSkip (JsonReader reader)
|
||||
{
|
||||
ToWrapper (
|
||||
delegate { return new JsonMockWrapper (); }, reader);
|
||||
}
|
||||
|
||||
private static void RegisterBaseExporters ()
|
||||
{
|
||||
base_exporters_table[typeof (byte)] =
|
||||
delegate (object obj, JsonWriter writer) {
|
||||
writer.Write (Convert.ToInt32 ((byte) obj));
|
||||
};
|
||||
|
||||
base_exporters_table[typeof (char)] =
|
||||
delegate (object obj, JsonWriter writer) {
|
||||
writer.Write (Convert.ToString ((char) obj));
|
||||
};
|
||||
|
||||
base_exporters_table[typeof (DateTime)] =
|
||||
delegate (object obj, JsonWriter writer) {
|
||||
writer.Write (Convert.ToString ((DateTime) obj,
|
||||
datetime_format));
|
||||
};
|
||||
|
||||
base_exporters_table[typeof (decimal)] =
|
||||
delegate (object obj, JsonWriter writer) {
|
||||
writer.Write ((decimal) obj);
|
||||
};
|
||||
|
||||
base_exporters_table[typeof (sbyte)] =
|
||||
delegate (object obj, JsonWriter writer) {
|
||||
writer.Write (Convert.ToInt32 ((sbyte) obj));
|
||||
};
|
||||
|
||||
base_exporters_table[typeof (short)] =
|
||||
delegate (object obj, JsonWriter writer) {
|
||||
writer.Write (Convert.ToInt32 ((short) obj));
|
||||
};
|
||||
|
||||
base_exporters_table[typeof (ushort)] =
|
||||
delegate (object obj, JsonWriter writer) {
|
||||
writer.Write (Convert.ToInt32 ((ushort) obj));
|
||||
};
|
||||
|
||||
base_exporters_table[typeof (uint)] =
|
||||
delegate (object obj, JsonWriter writer) {
|
||||
writer.Write (Convert.ToUInt64 ((uint) obj));
|
||||
};
|
||||
|
||||
base_exporters_table[typeof (ulong)] =
|
||||
delegate (object obj, JsonWriter writer) {
|
||||
writer.Write ((ulong) obj);
|
||||
};
|
||||
|
||||
base_exporters_table[typeof(DateTimeOffset)] =
|
||||
delegate (object obj, JsonWriter writer) {
|
||||
writer.Write(((DateTimeOffset)obj).ToString("yyyy-MM-ddTHH:mm:ss.fffffffzzz", datetime_format));
|
||||
};
|
||||
}
|
||||
|
||||
private static void RegisterBaseImporters ()
|
||||
{
|
||||
ImporterFunc importer;
|
||||
|
||||
importer = delegate (object input) {
|
||||
return Convert.ToByte ((int) input);
|
||||
};
|
||||
RegisterImporter (base_importers_table, typeof (int),
|
||||
typeof (byte), importer);
|
||||
|
||||
importer = delegate (object input) {
|
||||
return Convert.ToUInt64 ((int) input);
|
||||
};
|
||||
RegisterImporter (base_importers_table, typeof (int),
|
||||
typeof (ulong), importer);
|
||||
|
||||
importer = delegate (object input) {
|
||||
return Convert.ToInt64((int)input);
|
||||
};
|
||||
RegisterImporter(base_importers_table, typeof(int),
|
||||
typeof(long), importer);
|
||||
|
||||
importer = delegate (object input) {
|
||||
return Convert.ToSByte ((int) input);
|
||||
};
|
||||
RegisterImporter (base_importers_table, typeof (int),
|
||||
typeof (sbyte), importer);
|
||||
|
||||
importer = delegate (object input) {
|
||||
return Convert.ToInt16 ((int) input);
|
||||
};
|
||||
RegisterImporter (base_importers_table, typeof (int),
|
||||
typeof (short), importer);
|
||||
|
||||
importer = delegate (object input) {
|
||||
return Convert.ToUInt16 ((int) input);
|
||||
};
|
||||
RegisterImporter (base_importers_table, typeof (int),
|
||||
typeof (ushort), importer);
|
||||
|
||||
importer = delegate (object input) {
|
||||
return Convert.ToUInt32 ((int) input);
|
||||
};
|
||||
RegisterImporter (base_importers_table, typeof (int),
|
||||
typeof (uint), importer);
|
||||
|
||||
importer = delegate (object input) {
|
||||
return Convert.ToSingle ((int) input);
|
||||
};
|
||||
RegisterImporter (base_importers_table, typeof (int),
|
||||
typeof (float), importer);
|
||||
|
||||
importer = delegate (object input) {
|
||||
return Convert.ToDouble ((int) input);
|
||||
};
|
||||
RegisterImporter (base_importers_table, typeof (int),
|
||||
typeof (double), importer);
|
||||
|
||||
importer = delegate (object input) {
|
||||
return Convert.ToDecimal ((double) input);
|
||||
};
|
||||
RegisterImporter (base_importers_table, typeof (double),
|
||||
typeof (decimal), importer);
|
||||
|
||||
importer = delegate (object input) {
|
||||
return Convert.ToSingle((double)input);
|
||||
};
|
||||
RegisterImporter(base_importers_table, typeof(double),
|
||||
typeof(float), importer);
|
||||
|
||||
importer = delegate (object input) {
|
||||
return Convert.ToUInt32 ((long) input);
|
||||
};
|
||||
RegisterImporter (base_importers_table, typeof (long),
|
||||
typeof (uint), importer);
|
||||
|
||||
importer = delegate (object input) {
|
||||
return Convert.ToChar ((string) input);
|
||||
};
|
||||
RegisterImporter (base_importers_table, typeof (string),
|
||||
typeof (char), importer);
|
||||
|
||||
importer = delegate (object input) {
|
||||
return Convert.ToDateTime ((string) input, datetime_format);
|
||||
};
|
||||
RegisterImporter (base_importers_table, typeof (string),
|
||||
typeof (DateTime), importer);
|
||||
|
||||
importer = delegate (object input) {
|
||||
return DateTimeOffset.Parse((string)input, datetime_format);
|
||||
};
|
||||
RegisterImporter(base_importers_table, typeof(string),
|
||||
typeof(DateTimeOffset), importer);
|
||||
}
|
||||
|
||||
private static void RegisterImporter (
|
||||
IDictionary<Type, IDictionary<Type, ImporterFunc>> table,
|
||||
Type json_type, Type value_type, ImporterFunc importer)
|
||||
{
|
||||
if (! table.ContainsKey (json_type))
|
||||
table.Add (json_type, new Dictionary<Type, ImporterFunc> ());
|
||||
|
||||
table[json_type][value_type] = importer;
|
||||
}
|
||||
|
||||
private static void WriteValue (object obj, JsonWriter writer,
|
||||
bool writer_is_private,
|
||||
int depth)
|
||||
{
|
||||
if (depth > max_nesting_depth)
|
||||
throw new JsonException (
|
||||
String.Format ("Max allowed object depth reached while " +
|
||||
"trying to export from type {0}",
|
||||
obj.GetType ()));
|
||||
|
||||
if (obj == null) {
|
||||
writer.Write (null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj is IJsonWrapper) {
|
||||
if (writer_is_private)
|
||||
writer.TextWriter.Write (((IJsonWrapper) obj).ToJson ());
|
||||
else
|
||||
((IJsonWrapper) obj).ToJson (writer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj is String) {
|
||||
writer.Write ((string) obj);
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj is Double) {
|
||||
writer.Write ((double) obj);
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj is Single)
|
||||
{
|
||||
writer.Write((float)obj);
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj is Int32) {
|
||||
writer.Write ((int) obj);
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj is Boolean) {
|
||||
writer.Write ((bool) obj);
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj is Int64) {
|
||||
writer.Write ((long) obj);
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj is Array) {
|
||||
writer.WriteArrayStart ();
|
||||
|
||||
foreach (object elem in (Array) obj)
|
||||
WriteValue (elem, writer, writer_is_private, depth + 1);
|
||||
|
||||
writer.WriteArrayEnd ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj is IList) {
|
||||
writer.WriteArrayStart ();
|
||||
foreach (object elem in (IList) obj)
|
||||
WriteValue (elem, writer, writer_is_private, depth + 1);
|
||||
writer.WriteArrayEnd ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj is IDictionary dictionary) {
|
||||
writer.WriteObjectStart ();
|
||||
foreach (DictionaryEntry entry in dictionary) {
|
||||
var propertyName = entry.Key is string key ?
|
||||
key
|
||||
: Convert.ToString(entry.Key, CultureInfo.InvariantCulture);
|
||||
writer.WritePropertyName (propertyName);
|
||||
WriteValue (entry.Value, writer, writer_is_private,
|
||||
depth + 1);
|
||||
}
|
||||
writer.WriteObjectEnd ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Type obj_type = obj.GetType ();
|
||||
|
||||
// See if there's a custom exporter for the object
|
||||
if (custom_exporters_table.ContainsKey (obj_type)) {
|
||||
ExporterFunc exporter = custom_exporters_table[obj_type];
|
||||
exporter (obj, writer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If not, maybe there's a base exporter
|
||||
if (base_exporters_table.ContainsKey (obj_type)) {
|
||||
ExporterFunc exporter = base_exporters_table[obj_type];
|
||||
exporter (obj, writer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Last option, let's see if it's an enum
|
||||
if (obj is Enum) {
|
||||
Type e_type = Enum.GetUnderlyingType (obj_type);
|
||||
|
||||
if (e_type == typeof (long))
|
||||
writer.Write ((long) obj);
|
||||
else if (e_type == typeof (uint))
|
||||
writer.Write ((uint) obj);
|
||||
else if (e_type == typeof (ulong))
|
||||
writer.Write ((ulong) obj);
|
||||
else if (e_type == typeof(ushort))
|
||||
writer.Write ((ushort)obj);
|
||||
else if (e_type == typeof(short))
|
||||
writer.Write ((short)obj);
|
||||
else if (e_type == typeof(byte))
|
||||
writer.Write ((byte)obj);
|
||||
else if (e_type == typeof(sbyte))
|
||||
writer.Write ((sbyte)obj);
|
||||
else
|
||||
writer.Write ((int) obj);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Okay, so it looks like the input should be exported as an
|
||||
// object
|
||||
AddTypeProperties (obj_type);
|
||||
IList<PropertyMetadata> props = type_properties[obj_type];
|
||||
|
||||
writer.WriteObjectStart ();
|
||||
foreach (PropertyMetadata p_data in props) {
|
||||
if (p_data.IsField) {
|
||||
writer.WritePropertyName (p_data.Info.Name);
|
||||
WriteValue (((FieldInfo) p_data.Info).GetValue (obj),
|
||||
writer, writer_is_private, depth + 1);
|
||||
}
|
||||
else {
|
||||
PropertyInfo p_info = (PropertyInfo) p_data.Info;
|
||||
|
||||
if (p_info.CanRead) {
|
||||
writer.WritePropertyName (p_data.Info.Name);
|
||||
WriteValue (p_info.GetValue (obj, null),
|
||||
writer, writer_is_private, depth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
writer.WriteObjectEnd ();
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
public static string ToJson (object obj)
|
||||
{
|
||||
lock (static_writer_lock) {
|
||||
static_writer.Reset ();
|
||||
|
||||
WriteValue (obj, static_writer, true, 0);
|
||||
|
||||
return static_writer.ToString ();
|
||||
}
|
||||
}
|
||||
|
||||
public static void ToJson (object obj, JsonWriter writer)
|
||||
{
|
||||
WriteValue (obj, writer, false, 0);
|
||||
}
|
||||
|
||||
public static JsonData ToObject (JsonReader reader)
|
||||
{
|
||||
return (JsonData) ToWrapper (
|
||||
delegate { return new JsonData (); }, reader);
|
||||
}
|
||||
|
||||
public static JsonData ToObject (TextReader reader)
|
||||
{
|
||||
JsonReader json_reader = new JsonReader (reader);
|
||||
|
||||
return (JsonData) ToWrapper (
|
||||
delegate { return new JsonData (); }, json_reader);
|
||||
}
|
||||
|
||||
public static JsonData ToObject (string json)
|
||||
{
|
||||
return (JsonData) ToWrapper (
|
||||
delegate { return new JsonData (); }, json);
|
||||
}
|
||||
|
||||
public static T ToObject<T> (JsonReader reader)
|
||||
{
|
||||
return (T) ReadValue (typeof (T), reader);
|
||||
}
|
||||
|
||||
public static T ToObject<T> (TextReader reader)
|
||||
{
|
||||
JsonReader json_reader = new JsonReader (reader);
|
||||
|
||||
return (T) ReadValue (typeof (T), json_reader);
|
||||
}
|
||||
|
||||
public static T ToObject<T> (string json)
|
||||
{
|
||||
JsonReader reader = new JsonReader (json);
|
||||
|
||||
return (T) ReadValue (typeof (T), reader);
|
||||
}
|
||||
|
||||
public static object ToObject(string json, Type ConvertType )
|
||||
{
|
||||
JsonReader reader = new JsonReader(json);
|
||||
|
||||
return ReadValue(ConvertType, reader);
|
||||
}
|
||||
|
||||
public static IJsonWrapper ToWrapper (WrapperFactory factory,
|
||||
JsonReader reader)
|
||||
{
|
||||
return ReadValue (factory, reader);
|
||||
}
|
||||
|
||||
public static IJsonWrapper ToWrapper (WrapperFactory factory,
|
||||
string json)
|
||||
{
|
||||
JsonReader reader = new JsonReader (json);
|
||||
|
||||
return ReadValue (factory, reader);
|
||||
}
|
||||
|
||||
public static void RegisterExporter<T> (ExporterFunc<T> exporter)
|
||||
{
|
||||
ExporterFunc exporter_wrapper =
|
||||
delegate (object obj, JsonWriter writer) {
|
||||
exporter ((T) obj, writer);
|
||||
};
|
||||
|
||||
custom_exporters_table[typeof (T)] = exporter_wrapper;
|
||||
}
|
||||
|
||||
public static void RegisterImporter<TJson, TValue> (
|
||||
ImporterFunc<TJson, TValue> importer)
|
||||
{
|
||||
ImporterFunc importer_wrapper =
|
||||
delegate (object input) {
|
||||
return importer ((TJson) input);
|
||||
};
|
||||
|
||||
RegisterImporter (custom_importers_table, typeof (TJson),
|
||||
typeof (TValue), importer_wrapper);
|
||||
}
|
||||
|
||||
public static void UnregisterExporters ()
|
||||
{
|
||||
custom_exporters_table.Clear ();
|
||||
}
|
||||
|
||||
public static void UnregisterImporters ()
|
||||
{
|
||||
custom_importers_table.Clear ();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e63e0f11bef8d6429a261ce53a94f70
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,105 @@
|
||||
#region Header
|
||||
/**
|
||||
* JsonMockWrapper.cs
|
||||
* Mock object implementing IJsonWrapper, to facilitate actions like
|
||||
* skipping data more efficiently.
|
||||
*
|
||||
* The authors disclaim copyright to this source code. For more details, see
|
||||
* the COPYING file included with this distribution.
|
||||
**/
|
||||
#endregion
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
|
||||
namespace LitJson
|
||||
{
|
||||
public class JsonMockWrapper : IJsonWrapper
|
||||
{
|
||||
public bool IsArray { get { return false; } }
|
||||
public bool IsBoolean { get { return false; } }
|
||||
public bool IsDouble { get { return false; } }
|
||||
public bool IsInt { get { return false; } }
|
||||
public bool IsLong { get { return false; } }
|
||||
public bool IsObject { get { return false; } }
|
||||
public bool IsString { get { return false; } }
|
||||
|
||||
public bool GetBoolean () { return false; }
|
||||
public double GetDouble () { return 0.0; }
|
||||
public int GetInt () { return 0; }
|
||||
public JsonType GetJsonType () { return JsonType.None; }
|
||||
public long GetLong () { return 0L; }
|
||||
public string GetString () { return ""; }
|
||||
|
||||
public void SetBoolean (bool val) {}
|
||||
public void SetDouble (double val) {}
|
||||
public void SetInt (int val) {}
|
||||
public void SetJsonType (JsonType type) {}
|
||||
public void SetLong (long val) {}
|
||||
public void SetString (string val) {}
|
||||
|
||||
public string ToJson () { return ""; }
|
||||
public void ToJson (JsonWriter writer) {}
|
||||
|
||||
|
||||
bool IList.IsFixedSize { get { return true; } }
|
||||
bool IList.IsReadOnly { get { return true; } }
|
||||
|
||||
object IList.this[int index] {
|
||||
get { return null; }
|
||||
set {}
|
||||
}
|
||||
|
||||
int IList.Add (object value) { return 0; }
|
||||
void IList.Clear () {}
|
||||
bool IList.Contains (object value) { return false; }
|
||||
int IList.IndexOf (object value) { return -1; }
|
||||
void IList.Insert (int i, object v) {}
|
||||
void IList.Remove (object value) {}
|
||||
void IList.RemoveAt (int index) {}
|
||||
|
||||
|
||||
int ICollection.Count { get { return 0; } }
|
||||
bool ICollection.IsSynchronized { get { return false; } }
|
||||
object ICollection.SyncRoot { get { return null; } }
|
||||
|
||||
void ICollection.CopyTo (Array array, int index) {}
|
||||
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator () { return null; }
|
||||
|
||||
|
||||
bool IDictionary.IsFixedSize { get { return true; } }
|
||||
bool IDictionary.IsReadOnly { get { return true; } }
|
||||
|
||||
ICollection IDictionary.Keys { get { return null; } }
|
||||
ICollection IDictionary.Values { get { return null; } }
|
||||
|
||||
object IDictionary.this[object key] {
|
||||
get { return null; }
|
||||
set {}
|
||||
}
|
||||
|
||||
void IDictionary.Add (object k, object v) {}
|
||||
void IDictionary.Clear () {}
|
||||
bool IDictionary.Contains (object key) { return false; }
|
||||
void IDictionary.Remove (object key) {}
|
||||
|
||||
IDictionaryEnumerator IDictionary.GetEnumerator () { return null; }
|
||||
|
||||
|
||||
object IOrderedDictionary.this[int idx] {
|
||||
get { return null; }
|
||||
set {}
|
||||
}
|
||||
|
||||
IDictionaryEnumerator IOrderedDictionary.GetEnumerator () {
|
||||
return null;
|
||||
}
|
||||
void IOrderedDictionary.Insert (int i, object k, object v) {}
|
||||
void IOrderedDictionary.RemoveAt (int i) {}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eccf65801d671bc41b6df3f29c184857
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,478 @@
|
||||
#region Header
|
||||
/**
|
||||
* JsonReader.cs
|
||||
* Stream-like access to JSON text.
|
||||
*
|
||||
* The authors disclaim copyright to this source code. For more details, see
|
||||
* the COPYING file included with this distribution.
|
||||
**/
|
||||
#endregion
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
|
||||
namespace LitJson
|
||||
{
|
||||
public enum JsonToken
|
||||
{
|
||||
None,
|
||||
|
||||
ObjectStart,
|
||||
PropertyName,
|
||||
ObjectEnd,
|
||||
|
||||
ArrayStart,
|
||||
ArrayEnd,
|
||||
|
||||
Int,
|
||||
Long,
|
||||
Double,
|
||||
|
||||
String,
|
||||
|
||||
Boolean,
|
||||
Null
|
||||
}
|
||||
|
||||
|
||||
public class JsonReader
|
||||
{
|
||||
#region Fields
|
||||
private static readonly IDictionary<int, IDictionary<int, int[]>> parse_table;
|
||||
|
||||
private Stack<int> automaton_stack;
|
||||
private int current_input;
|
||||
private int current_symbol;
|
||||
private bool end_of_json;
|
||||
private bool end_of_input;
|
||||
private Lexer lexer;
|
||||
private bool parser_in_string;
|
||||
private bool parser_return;
|
||||
private bool read_started;
|
||||
private TextReader reader;
|
||||
private bool reader_is_owned;
|
||||
private bool skip_non_members;
|
||||
private object token_value;
|
||||
private JsonToken token;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Public Properties
|
||||
public bool AllowComments {
|
||||
get { return lexer.AllowComments; }
|
||||
set { lexer.AllowComments = value; }
|
||||
}
|
||||
|
||||
public bool AllowSingleQuotedStrings {
|
||||
get { return lexer.AllowSingleQuotedStrings; }
|
||||
set { lexer.AllowSingleQuotedStrings = value; }
|
||||
}
|
||||
|
||||
public bool SkipNonMembers {
|
||||
get { return skip_non_members; }
|
||||
set { skip_non_members = value; }
|
||||
}
|
||||
|
||||
public bool EndOfInput {
|
||||
get { return end_of_input; }
|
||||
}
|
||||
|
||||
public bool EndOfJson {
|
||||
get { return end_of_json; }
|
||||
}
|
||||
|
||||
public JsonToken Token {
|
||||
get { return token; }
|
||||
}
|
||||
|
||||
public object Value {
|
||||
get { return token_value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
static JsonReader ()
|
||||
{
|
||||
parse_table = PopulateParseTable ();
|
||||
}
|
||||
|
||||
public JsonReader (string json_text) :
|
||||
this (new StringReader (json_text), true)
|
||||
{
|
||||
}
|
||||
|
||||
public JsonReader (TextReader reader) :
|
||||
this (reader, false)
|
||||
{
|
||||
}
|
||||
|
||||
private JsonReader (TextReader reader, bool owned)
|
||||
{
|
||||
if (reader == null)
|
||||
throw new ArgumentNullException ("reader");
|
||||
|
||||
parser_in_string = false;
|
||||
parser_return = false;
|
||||
|
||||
read_started = false;
|
||||
automaton_stack = new Stack<int> ();
|
||||
automaton_stack.Push ((int) ParserToken.End);
|
||||
automaton_stack.Push ((int) ParserToken.Text);
|
||||
|
||||
lexer = new Lexer (reader);
|
||||
|
||||
end_of_input = false;
|
||||
end_of_json = false;
|
||||
|
||||
skip_non_members = true;
|
||||
|
||||
this.reader = reader;
|
||||
reader_is_owned = owned;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Static Methods
|
||||
private static IDictionary<int, IDictionary<int, int[]>> PopulateParseTable ()
|
||||
{
|
||||
// See section A.2. of the manual for details
|
||||
IDictionary<int, IDictionary<int, int[]>> parse_table = new Dictionary<int, IDictionary<int, int[]>> ();
|
||||
|
||||
TableAddRow (parse_table, ParserToken.Array);
|
||||
TableAddCol (parse_table, ParserToken.Array, '[',
|
||||
'[',
|
||||
(int) ParserToken.ArrayPrime);
|
||||
|
||||
TableAddRow (parse_table, ParserToken.ArrayPrime);
|
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, '"',
|
||||
(int) ParserToken.Value,
|
||||
|
||||
(int) ParserToken.ValueRest,
|
||||
']');
|
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, '[',
|
||||
(int) ParserToken.Value,
|
||||
(int) ParserToken.ValueRest,
|
||||
']');
|
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, ']',
|
||||
']');
|
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, '{',
|
||||
(int) ParserToken.Value,
|
||||
(int) ParserToken.ValueRest,
|
||||
']');
|
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.Number,
|
||||
(int) ParserToken.Value,
|
||||
(int) ParserToken.ValueRest,
|
||||
']');
|
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.True,
|
||||
(int) ParserToken.Value,
|
||||
(int) ParserToken.ValueRest,
|
||||
']');
|
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.False,
|
||||
(int) ParserToken.Value,
|
||||
(int) ParserToken.ValueRest,
|
||||
']');
|
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.Null,
|
||||
(int) ParserToken.Value,
|
||||
(int) ParserToken.ValueRest,
|
||||
']');
|
||||
|
||||
TableAddRow (parse_table, ParserToken.Object);
|
||||
TableAddCol (parse_table, ParserToken.Object, '{',
|
||||
'{',
|
||||
(int) ParserToken.ObjectPrime);
|
||||
|
||||
TableAddRow (parse_table, ParserToken.ObjectPrime);
|
||||
TableAddCol (parse_table, ParserToken.ObjectPrime, '"',
|
||||
(int) ParserToken.Pair,
|
||||
(int) ParserToken.PairRest,
|
||||
'}');
|
||||
TableAddCol (parse_table, ParserToken.ObjectPrime, '}',
|
||||
'}');
|
||||
|
||||
TableAddRow (parse_table, ParserToken.Pair);
|
||||
TableAddCol (parse_table, ParserToken.Pair, '"',
|
||||
(int) ParserToken.String,
|
||||
':',
|
||||
(int) ParserToken.Value);
|
||||
|
||||
TableAddRow (parse_table, ParserToken.PairRest);
|
||||
TableAddCol (parse_table, ParserToken.PairRest, ',',
|
||||
',',
|
||||
(int) ParserToken.Pair,
|
||||
(int) ParserToken.PairRest);
|
||||
TableAddCol (parse_table, ParserToken.PairRest, '}',
|
||||
(int) ParserToken.Epsilon);
|
||||
|
||||
TableAddRow (parse_table, ParserToken.String);
|
||||
TableAddCol (parse_table, ParserToken.String, '"',
|
||||
'"',
|
||||
(int) ParserToken.CharSeq,
|
||||
'"');
|
||||
|
||||
TableAddRow (parse_table, ParserToken.Text);
|
||||
TableAddCol (parse_table, ParserToken.Text, '[',
|
||||
(int) ParserToken.Array);
|
||||
TableAddCol (parse_table, ParserToken.Text, '{',
|
||||
(int) ParserToken.Object);
|
||||
|
||||
TableAddRow (parse_table, ParserToken.Value);
|
||||
TableAddCol (parse_table, ParserToken.Value, '"',
|
||||
(int) ParserToken.String);
|
||||
TableAddCol (parse_table, ParserToken.Value, '[',
|
||||
(int) ParserToken.Array);
|
||||
TableAddCol (parse_table, ParserToken.Value, '{',
|
||||
(int) ParserToken.Object);
|
||||
TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.Number,
|
||||
(int) ParserToken.Number);
|
||||
TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.True,
|
||||
(int) ParserToken.True);
|
||||
TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.False,
|
||||
(int) ParserToken.False);
|
||||
TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.Null,
|
||||
(int) ParserToken.Null);
|
||||
|
||||
TableAddRow (parse_table, ParserToken.ValueRest);
|
||||
TableAddCol (parse_table, ParserToken.ValueRest, ',',
|
||||
',',
|
||||
(int) ParserToken.Value,
|
||||
(int) ParserToken.ValueRest);
|
||||
TableAddCol (parse_table, ParserToken.ValueRest, ']',
|
||||
(int) ParserToken.Epsilon);
|
||||
|
||||
return parse_table;
|
||||
}
|
||||
|
||||
private static void TableAddCol (IDictionary<int, IDictionary<int, int[]>> parse_table, ParserToken row, int col,
|
||||
params int[] symbols)
|
||||
{
|
||||
parse_table[(int) row].Add (col, symbols);
|
||||
}
|
||||
|
||||
private static void TableAddRow (IDictionary<int, IDictionary<int, int[]>> parse_table, ParserToken rule)
|
||||
{
|
||||
parse_table.Add ((int) rule, new Dictionary<int, int[]> ());
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Private Methods
|
||||
private void ProcessNumber (string number)
|
||||
{
|
||||
if (number.IndexOf ('.') != -1 ||
|
||||
number.IndexOf ('e') != -1 ||
|
||||
number.IndexOf ('E') != -1) {
|
||||
|
||||
double n_double;
|
||||
if (double.TryParse (number, NumberStyles.Any, CultureInfo.InvariantCulture, out n_double)) {
|
||||
token = JsonToken.Double;
|
||||
token_value = n_double;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int n_int32;
|
||||
if (int.TryParse (number, NumberStyles.Integer, CultureInfo.InvariantCulture, out n_int32)) {
|
||||
token = JsonToken.Int;
|
||||
token_value = n_int32;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
long n_int64;
|
||||
if (long.TryParse (number, NumberStyles.Integer, CultureInfo.InvariantCulture, out n_int64)) {
|
||||
token = JsonToken.Long;
|
||||
token_value = n_int64;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ulong n_uint64;
|
||||
if (ulong.TryParse(number, NumberStyles.Integer, CultureInfo.InvariantCulture, out n_uint64))
|
||||
{
|
||||
token = JsonToken.Long;
|
||||
token_value = n_uint64;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Shouldn't happen, but just in case, return something
|
||||
token = JsonToken.Int;
|
||||
token_value = 0;
|
||||
}
|
||||
|
||||
private void ProcessSymbol ()
|
||||
{
|
||||
if (current_symbol == '[') {
|
||||
token = JsonToken.ArrayStart;
|
||||
parser_return = true;
|
||||
|
||||
} else if (current_symbol == ']') {
|
||||
token = JsonToken.ArrayEnd;
|
||||
parser_return = true;
|
||||
|
||||
} else if (current_symbol == '{') {
|
||||
token = JsonToken.ObjectStart;
|
||||
parser_return = true;
|
||||
|
||||
} else if (current_symbol == '}') {
|
||||
token = JsonToken.ObjectEnd;
|
||||
parser_return = true;
|
||||
|
||||
} else if (current_symbol == '"') {
|
||||
if (parser_in_string) {
|
||||
parser_in_string = false;
|
||||
|
||||
parser_return = true;
|
||||
|
||||
} else {
|
||||
if (token == JsonToken.None)
|
||||
token = JsonToken.String;
|
||||
|
||||
parser_in_string = true;
|
||||
}
|
||||
|
||||
} else if (current_symbol == (int) ParserToken.CharSeq) {
|
||||
token_value = lexer.StringValue;
|
||||
|
||||
} else if (current_symbol == (int) ParserToken.False) {
|
||||
token = JsonToken.Boolean;
|
||||
token_value = false;
|
||||
parser_return = true;
|
||||
|
||||
} else if (current_symbol == (int) ParserToken.Null) {
|
||||
token = JsonToken.Null;
|
||||
parser_return = true;
|
||||
|
||||
} else if (current_symbol == (int) ParserToken.Number) {
|
||||
ProcessNumber (lexer.StringValue);
|
||||
|
||||
parser_return = true;
|
||||
|
||||
} else if (current_symbol == (int) ParserToken.Pair) {
|
||||
token = JsonToken.PropertyName;
|
||||
|
||||
} else if (current_symbol == (int) ParserToken.True) {
|
||||
token = JsonToken.Boolean;
|
||||
token_value = true;
|
||||
parser_return = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private bool ReadToken ()
|
||||
{
|
||||
if (end_of_input)
|
||||
return false;
|
||||
|
||||
lexer.NextToken ();
|
||||
|
||||
if (lexer.EndOfInput) {
|
||||
Close ();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
current_input = lexer.Token;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
public void Close ()
|
||||
{
|
||||
if (end_of_input)
|
||||
return;
|
||||
|
||||
end_of_input = true;
|
||||
end_of_json = true;
|
||||
|
||||
if (reader_is_owned)
|
||||
{
|
||||
using(reader){}
|
||||
}
|
||||
|
||||
reader = null;
|
||||
}
|
||||
|
||||
public bool Read ()
|
||||
{
|
||||
if (end_of_input)
|
||||
return false;
|
||||
|
||||
if (end_of_json) {
|
||||
end_of_json = false;
|
||||
automaton_stack.Clear ();
|
||||
automaton_stack.Push ((int) ParserToken.End);
|
||||
automaton_stack.Push ((int) ParserToken.Text);
|
||||
}
|
||||
|
||||
parser_in_string = false;
|
||||
parser_return = false;
|
||||
|
||||
token = JsonToken.None;
|
||||
token_value = null;
|
||||
|
||||
if (! read_started) {
|
||||
read_started = true;
|
||||
|
||||
if (! ReadToken ())
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int[] entry_symbols;
|
||||
|
||||
while (true) {
|
||||
if (parser_return) {
|
||||
if (automaton_stack.Peek () == (int) ParserToken.End)
|
||||
end_of_json = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
current_symbol = automaton_stack.Pop ();
|
||||
|
||||
ProcessSymbol ();
|
||||
|
||||
if (current_symbol == current_input) {
|
||||
if (! ReadToken ()) {
|
||||
if (automaton_stack.Peek () != (int) ParserToken.End)
|
||||
throw new JsonException (
|
||||
"Input doesn't evaluate to proper JSON text");
|
||||
|
||||
if (parser_return)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
entry_symbols =
|
||||
parse_table[current_symbol][current_input];
|
||||
|
||||
} catch (KeyNotFoundException e) {
|
||||
throw new JsonException ((ParserToken) current_input, e);
|
||||
}
|
||||
|
||||
if (entry_symbols[0] == (int) ParserToken.Epsilon)
|
||||
continue;
|
||||
|
||||
for (int i = entry_symbols.Length - 1; i >= 0; i--)
|
||||
automaton_stack.Push (entry_symbols[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9e68f25477380e49b9cc15cf5aeabe4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,484 @@
|
||||
#region Header
|
||||
/**
|
||||
* JsonWriter.cs
|
||||
* Stream-like facility to output JSON text.
|
||||
*
|
||||
* The authors disclaim copyright to this source code. For more details, see
|
||||
* the COPYING file included with this distribution.
|
||||
**/
|
||||
#endregion
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
|
||||
namespace LitJson
|
||||
{
|
||||
internal enum Condition
|
||||
{
|
||||
InArray,
|
||||
InObject,
|
||||
NotAProperty,
|
||||
Property,
|
||||
Value
|
||||
}
|
||||
|
||||
internal class WriterContext
|
||||
{
|
||||
public int Count;
|
||||
public bool InArray;
|
||||
public bool InObject;
|
||||
public bool ExpectingValue;
|
||||
public int Padding;
|
||||
}
|
||||
|
||||
public class JsonWriter
|
||||
{
|
||||
#region Fields
|
||||
private static readonly NumberFormatInfo number_format;
|
||||
|
||||
private WriterContext context;
|
||||
private Stack<WriterContext> ctx_stack;
|
||||
private bool has_reached_end;
|
||||
private char[] hex_seq;
|
||||
private int indentation;
|
||||
private int indent_value;
|
||||
private StringBuilder inst_string_builder;
|
||||
private bool pretty_print;
|
||||
private bool validate;
|
||||
private bool lower_case_properties;
|
||||
private TextWriter writer;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
public int IndentValue {
|
||||
get { return indent_value; }
|
||||
set {
|
||||
indentation = (indentation / indent_value) * value;
|
||||
indent_value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool PrettyPrint {
|
||||
get { return pretty_print; }
|
||||
set { pretty_print = value; }
|
||||
}
|
||||
|
||||
public TextWriter TextWriter {
|
||||
get { return writer; }
|
||||
}
|
||||
|
||||
public bool Validate {
|
||||
get { return validate; }
|
||||
set { validate = value; }
|
||||
}
|
||||
|
||||
public bool LowerCaseProperties {
|
||||
get { return lower_case_properties; }
|
||||
set { lower_case_properties = value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
static JsonWriter ()
|
||||
{
|
||||
number_format = NumberFormatInfo.InvariantInfo;
|
||||
}
|
||||
|
||||
public JsonWriter ()
|
||||
{
|
||||
inst_string_builder = new StringBuilder ();
|
||||
writer = new StringWriter (inst_string_builder);
|
||||
|
||||
Init ();
|
||||
}
|
||||
|
||||
public JsonWriter (StringBuilder sb) :
|
||||
this (new StringWriter (sb))
|
||||
{
|
||||
}
|
||||
|
||||
public JsonWriter (TextWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
throw new ArgumentNullException ("writer");
|
||||
|
||||
this.writer = writer;
|
||||
|
||||
Init ();
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Private Methods
|
||||
private void DoValidation (Condition cond)
|
||||
{
|
||||
if (! context.ExpectingValue)
|
||||
context.Count++;
|
||||
|
||||
if (! validate)
|
||||
return;
|
||||
|
||||
if (has_reached_end)
|
||||
throw new JsonException (
|
||||
"A complete JSON symbol has already been written");
|
||||
|
||||
switch (cond) {
|
||||
case Condition.InArray:
|
||||
if (! context.InArray)
|
||||
throw new JsonException (
|
||||
"Can't close an array here");
|
||||
break;
|
||||
|
||||
case Condition.InObject:
|
||||
if (! context.InObject || context.ExpectingValue)
|
||||
throw new JsonException (
|
||||
"Can't close an object here");
|
||||
break;
|
||||
|
||||
case Condition.NotAProperty:
|
||||
if (context.InObject && ! context.ExpectingValue)
|
||||
throw new JsonException (
|
||||
"Expected a property");
|
||||
break;
|
||||
|
||||
case Condition.Property:
|
||||
if (! context.InObject || context.ExpectingValue)
|
||||
throw new JsonException (
|
||||
"Can't add a property here");
|
||||
break;
|
||||
|
||||
case Condition.Value:
|
||||
if (! context.InArray &&
|
||||
(! context.InObject || ! context.ExpectingValue))
|
||||
throw new JsonException (
|
||||
"Can't add a value here");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void Init ()
|
||||
{
|
||||
has_reached_end = false;
|
||||
hex_seq = new char[4];
|
||||
indentation = 0;
|
||||
indent_value = 4;
|
||||
pretty_print = false;
|
||||
validate = true;
|
||||
lower_case_properties = false;
|
||||
|
||||
ctx_stack = new Stack<WriterContext> ();
|
||||
context = new WriterContext ();
|
||||
ctx_stack.Push (context);
|
||||
}
|
||||
|
||||
private static void IntToHex (int n, char[] hex)
|
||||
{
|
||||
int num;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
num = n % 16;
|
||||
|
||||
if (num < 10)
|
||||
hex[3 - i] = (char) ('0' + num);
|
||||
else
|
||||
hex[3 - i] = (char) ('A' + (num - 10));
|
||||
|
||||
n >>= 4;
|
||||
}
|
||||
}
|
||||
|
||||
private void Indent ()
|
||||
{
|
||||
if (pretty_print)
|
||||
indentation += indent_value;
|
||||
}
|
||||
|
||||
|
||||
private void Put (string str)
|
||||
{
|
||||
if (pretty_print && ! context.ExpectingValue)
|
||||
for (int i = 0; i < indentation; i++)
|
||||
writer.Write (' ');
|
||||
|
||||
writer.Write (str);
|
||||
}
|
||||
|
||||
private void PutNewline ()
|
||||
{
|
||||
PutNewline (true);
|
||||
}
|
||||
|
||||
private void PutNewline (bool add_comma)
|
||||
{
|
||||
if (add_comma && ! context.ExpectingValue &&
|
||||
context.Count > 1)
|
||||
writer.Write (',');
|
||||
|
||||
if (pretty_print && ! context.ExpectingValue)
|
||||
writer.Write (Environment.NewLine);
|
||||
}
|
||||
|
||||
private void PutString (string str)
|
||||
{
|
||||
Put (String.Empty);
|
||||
|
||||
writer.Write ('"');
|
||||
|
||||
int n = str.Length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
switch (str[i]) {
|
||||
case '\n':
|
||||
writer.Write ("\\n");
|
||||
continue;
|
||||
|
||||
case '\r':
|
||||
writer.Write ("\\r");
|
||||
continue;
|
||||
|
||||
case '\t':
|
||||
writer.Write ("\\t");
|
||||
continue;
|
||||
|
||||
case '"':
|
||||
case '\\':
|
||||
writer.Write ('\\');
|
||||
writer.Write (str[i]);
|
||||
continue;
|
||||
|
||||
case '\f':
|
||||
writer.Write ("\\f");
|
||||
continue;
|
||||
|
||||
case '\b':
|
||||
writer.Write ("\\b");
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((int) str[i] >= 32 && (int) str[i] <= 126) {
|
||||
writer.Write (str[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Default, turn into a \uXXXX sequence
|
||||
IntToHex ((int) str[i], hex_seq);
|
||||
writer.Write ("\\u");
|
||||
writer.Write (hex_seq);
|
||||
}
|
||||
|
||||
writer.Write ('"');
|
||||
}
|
||||
|
||||
private void Unindent ()
|
||||
{
|
||||
if (pretty_print)
|
||||
indentation -= indent_value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
public override string ToString ()
|
||||
{
|
||||
if (inst_string_builder == null)
|
||||
return String.Empty;
|
||||
|
||||
return inst_string_builder.ToString ();
|
||||
}
|
||||
|
||||
public void Reset ()
|
||||
{
|
||||
has_reached_end = false;
|
||||
|
||||
ctx_stack.Clear ();
|
||||
context = new WriterContext ();
|
||||
ctx_stack.Push (context);
|
||||
|
||||
if (inst_string_builder != null)
|
||||
inst_string_builder.Remove (0, inst_string_builder.Length);
|
||||
}
|
||||
|
||||
public void Write (bool boolean)
|
||||
{
|
||||
DoValidation (Condition.Value);
|
||||
PutNewline ();
|
||||
|
||||
Put (boolean ? "true" : "false");
|
||||
|
||||
context.ExpectingValue = false;
|
||||
}
|
||||
|
||||
public void Write (decimal number)
|
||||
{
|
||||
DoValidation (Condition.Value);
|
||||
PutNewline ();
|
||||
|
||||
Put (Convert.ToString (number, number_format));
|
||||
|
||||
context.ExpectingValue = false;
|
||||
}
|
||||
|
||||
public void Write (double number)
|
||||
{
|
||||
DoValidation (Condition.Value);
|
||||
PutNewline ();
|
||||
|
||||
string str = Convert.ToString (number, number_format);
|
||||
Put (str);
|
||||
|
||||
if (str.IndexOf ('.') == -1 &&
|
||||
str.IndexOf ('E') == -1)
|
||||
writer.Write (".0");
|
||||
|
||||
context.ExpectingValue = false;
|
||||
}
|
||||
|
||||
public void Write(float number)
|
||||
{
|
||||
DoValidation(Condition.Value);
|
||||
PutNewline();
|
||||
|
||||
string str = Convert.ToString(number, number_format);
|
||||
Put(str);
|
||||
|
||||
context.ExpectingValue = false;
|
||||
}
|
||||
|
||||
public void Write (int number)
|
||||
{
|
||||
DoValidation (Condition.Value);
|
||||
PutNewline ();
|
||||
|
||||
Put (Convert.ToString (number, number_format));
|
||||
|
||||
context.ExpectingValue = false;
|
||||
}
|
||||
|
||||
public void Write (long number)
|
||||
{
|
||||
DoValidation (Condition.Value);
|
||||
PutNewline ();
|
||||
|
||||
Put (Convert.ToString (number, number_format));
|
||||
|
||||
context.ExpectingValue = false;
|
||||
}
|
||||
|
||||
public void Write (string str)
|
||||
{
|
||||
DoValidation (Condition.Value);
|
||||
PutNewline ();
|
||||
|
||||
if (str == null)
|
||||
Put ("null");
|
||||
else
|
||||
PutString (str);
|
||||
|
||||
context.ExpectingValue = false;
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
public void Write (ulong number)
|
||||
{
|
||||
DoValidation (Condition.Value);
|
||||
PutNewline ();
|
||||
|
||||
Put (Convert.ToString (number, number_format));
|
||||
|
||||
context.ExpectingValue = false;
|
||||
}
|
||||
|
||||
public void WriteArrayEnd ()
|
||||
{
|
||||
DoValidation (Condition.InArray);
|
||||
PutNewline (false);
|
||||
|
||||
ctx_stack.Pop ();
|
||||
if (ctx_stack.Count == 1)
|
||||
has_reached_end = true;
|
||||
else {
|
||||
context = ctx_stack.Peek ();
|
||||
context.ExpectingValue = false;
|
||||
}
|
||||
|
||||
Unindent ();
|
||||
Put ("]");
|
||||
}
|
||||
|
||||
public void WriteArrayStart ()
|
||||
{
|
||||
DoValidation (Condition.NotAProperty);
|
||||
PutNewline ();
|
||||
|
||||
Put ("[");
|
||||
|
||||
context = new WriterContext ();
|
||||
context.InArray = true;
|
||||
ctx_stack.Push (context);
|
||||
|
||||
Indent ();
|
||||
}
|
||||
|
||||
public void WriteObjectEnd ()
|
||||
{
|
||||
DoValidation (Condition.InObject);
|
||||
PutNewline (false);
|
||||
|
||||
ctx_stack.Pop ();
|
||||
if (ctx_stack.Count == 1)
|
||||
has_reached_end = true;
|
||||
else {
|
||||
context = ctx_stack.Peek ();
|
||||
context.ExpectingValue = false;
|
||||
}
|
||||
|
||||
Unindent ();
|
||||
Put ("}");
|
||||
}
|
||||
|
||||
public void WriteObjectStart ()
|
||||
{
|
||||
DoValidation (Condition.NotAProperty);
|
||||
PutNewline ();
|
||||
|
||||
Put ("{");
|
||||
|
||||
context = new WriterContext ();
|
||||
context.InObject = true;
|
||||
ctx_stack.Push (context);
|
||||
|
||||
Indent ();
|
||||
}
|
||||
|
||||
public void WritePropertyName (string property_name)
|
||||
{
|
||||
DoValidation (Condition.Property);
|
||||
PutNewline ();
|
||||
string propertyName = (property_name == null || !lower_case_properties)
|
||||
? property_name
|
||||
: property_name.ToLowerInvariant();
|
||||
|
||||
PutString (propertyName);
|
||||
|
||||
if (pretty_print) {
|
||||
if (propertyName.Length > context.Padding)
|
||||
context.Padding = propertyName.Length;
|
||||
|
||||
for (int i = context.Padding - propertyName.Length;
|
||||
i >= 0; i--)
|
||||
writer.Write (' ');
|
||||
|
||||
writer.Write (": ");
|
||||
} else
|
||||
writer.Write (':');
|
||||
|
||||
context.ExpectingValue = true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4dd365314ca7114282641abfb814cdb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,912 @@
|
||||
#region Header
|
||||
/**
|
||||
* Lexer.cs
|
||||
* JSON lexer implementation based on a finite state machine.
|
||||
*
|
||||
* The authors disclaim copyright to this source code. For more details, see
|
||||
* the COPYING file included with this distribution.
|
||||
**/
|
||||
#endregion
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
|
||||
namespace LitJson
|
||||
{
|
||||
internal class FsmContext
|
||||
{
|
||||
public bool Return;
|
||||
public int NextState;
|
||||
public Lexer L;
|
||||
public int StateStack;
|
||||
}
|
||||
|
||||
|
||||
internal class Lexer
|
||||
{
|
||||
#region Fields
|
||||
private delegate bool StateHandler (FsmContext ctx);
|
||||
|
||||
private static readonly int[] fsm_return_table;
|
||||
private static readonly StateHandler[] fsm_handler_table;
|
||||
|
||||
private bool allow_comments;
|
||||
private bool allow_single_quoted_strings;
|
||||
private bool end_of_input;
|
||||
private FsmContext fsm_context;
|
||||
private int input_buffer;
|
||||
private int input_char;
|
||||
private TextReader reader;
|
||||
private int state;
|
||||
private StringBuilder string_buffer;
|
||||
private string string_value;
|
||||
private int token;
|
||||
private int unichar;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
public bool AllowComments {
|
||||
get { return allow_comments; }
|
||||
set { allow_comments = value; }
|
||||
}
|
||||
|
||||
public bool AllowSingleQuotedStrings {
|
||||
get { return allow_single_quoted_strings; }
|
||||
set { allow_single_quoted_strings = value; }
|
||||
}
|
||||
|
||||
public bool EndOfInput {
|
||||
get { return end_of_input; }
|
||||
}
|
||||
|
||||
public int Token {
|
||||
get { return token; }
|
||||
}
|
||||
|
||||
public string StringValue {
|
||||
get { return string_value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
static Lexer ()
|
||||
{
|
||||
PopulateFsmTables (out fsm_handler_table, out fsm_return_table);
|
||||
}
|
||||
|
||||
public Lexer (TextReader reader)
|
||||
{
|
||||
allow_comments = true;
|
||||
allow_single_quoted_strings = true;
|
||||
|
||||
input_buffer = 0;
|
||||
string_buffer = new StringBuilder (128);
|
||||
state = 1;
|
||||
end_of_input = false;
|
||||
this.reader = reader;
|
||||
|
||||
fsm_context = new FsmContext ();
|
||||
fsm_context.L = this;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Static Methods
|
||||
private static int HexValue (int digit)
|
||||
{
|
||||
switch (digit) {
|
||||
case 'a':
|
||||
case 'A':
|
||||
return 10;
|
||||
|
||||
case 'b':
|
||||
case 'B':
|
||||
return 11;
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
return 12;
|
||||
|
||||
case 'd':
|
||||
case 'D':
|
||||
return 13;
|
||||
|
||||
case 'e':
|
||||
case 'E':
|
||||
return 14;
|
||||
|
||||
case 'f':
|
||||
case 'F':
|
||||
return 15;
|
||||
|
||||
default:
|
||||
return digit - '0';
|
||||
}
|
||||
}
|
||||
|
||||
private static void PopulateFsmTables (out StateHandler[] fsm_handler_table, out int[] fsm_return_table)
|
||||
{
|
||||
// See section A.1. of the manual for details of the finite
|
||||
// state machine.
|
||||
fsm_handler_table = new StateHandler[28] {
|
||||
State1,
|
||||
State2,
|
||||
State3,
|
||||
State4,
|
||||
State5,
|
||||
State6,
|
||||
State7,
|
||||
State8,
|
||||
State9,
|
||||
State10,
|
||||
State11,
|
||||
State12,
|
||||
State13,
|
||||
State14,
|
||||
State15,
|
||||
State16,
|
||||
State17,
|
||||
State18,
|
||||
State19,
|
||||
State20,
|
||||
State21,
|
||||
State22,
|
||||
State23,
|
||||
State24,
|
||||
State25,
|
||||
State26,
|
||||
State27,
|
||||
State28
|
||||
};
|
||||
|
||||
fsm_return_table = new int[28] {
|
||||
(int) ParserToken.Char,
|
||||
0,
|
||||
(int) ParserToken.Number,
|
||||
(int) ParserToken.Number,
|
||||
0,
|
||||
(int) ParserToken.Number,
|
||||
0,
|
||||
(int) ParserToken.Number,
|
||||
0,
|
||||
0,
|
||||
(int) ParserToken.True,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
(int) ParserToken.False,
|
||||
0,
|
||||
0,
|
||||
(int) ParserToken.Null,
|
||||
(int) ParserToken.CharSeq,
|
||||
(int) ParserToken.Char,
|
||||
0,
|
||||
0,
|
||||
(int) ParserToken.CharSeq,
|
||||
(int) ParserToken.Char,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
}
|
||||
|
||||
private static char ProcessEscChar (int esc_char)
|
||||
{
|
||||
switch (esc_char) {
|
||||
case '"':
|
||||
case '\'':
|
||||
case '\\':
|
||||
case '/':
|
||||
return Convert.ToChar (esc_char);
|
||||
|
||||
case 'n':
|
||||
return '\n';
|
||||
|
||||
case 't':
|
||||
return '\t';
|
||||
|
||||
case 'r':
|
||||
return '\r';
|
||||
|
||||
case 'b':
|
||||
return '\b';
|
||||
|
||||
case 'f':
|
||||
return '\f';
|
||||
|
||||
default:
|
||||
// Unreachable
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State1 (FsmContext ctx)
|
||||
{
|
||||
while (ctx.L.GetChar ()) {
|
||||
if (ctx.L.input_char == ' ' ||
|
||||
ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r')
|
||||
continue;
|
||||
|
||||
if (ctx.L.input_char >= '1' && ctx.L.input_char <= '9') {
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
ctx.NextState = 3;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case '"':
|
||||
ctx.NextState = 19;
|
||||
ctx.Return = true;
|
||||
return true;
|
||||
|
||||
case ',':
|
||||
case ':':
|
||||
case '[':
|
||||
case ']':
|
||||
case '{':
|
||||
case '}':
|
||||
ctx.NextState = 1;
|
||||
ctx.Return = true;
|
||||
return true;
|
||||
|
||||
case '-':
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
ctx.NextState = 2;
|
||||
return true;
|
||||
|
||||
case '0':
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
ctx.NextState = 4;
|
||||
return true;
|
||||
|
||||
case 'f':
|
||||
ctx.NextState = 12;
|
||||
return true;
|
||||
|
||||
case 'n':
|
||||
ctx.NextState = 16;
|
||||
return true;
|
||||
|
||||
case 't':
|
||||
ctx.NextState = 9;
|
||||
return true;
|
||||
|
||||
case '\'':
|
||||
if (! ctx.L.allow_single_quoted_strings)
|
||||
return false;
|
||||
|
||||
ctx.L.input_char = '"';
|
||||
ctx.NextState = 23;
|
||||
ctx.Return = true;
|
||||
return true;
|
||||
|
||||
case '/':
|
||||
if (! ctx.L.allow_comments)
|
||||
return false;
|
||||
|
||||
ctx.NextState = 25;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool State2 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
if (ctx.L.input_char >= '1' && ctx.L.input_char<= '9') {
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
ctx.NextState = 3;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case '0':
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
ctx.NextState = 4;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State3 (FsmContext ctx)
|
||||
{
|
||||
while (ctx.L.GetChar ()) {
|
||||
if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') {
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ctx.L.input_char == ' ' ||
|
||||
ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') {
|
||||
ctx.Return = true;
|
||||
ctx.NextState = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case ',':
|
||||
case ']':
|
||||
case '}':
|
||||
ctx.L.UngetChar ();
|
||||
ctx.Return = true;
|
||||
ctx.NextState = 1;
|
||||
return true;
|
||||
|
||||
case '.':
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
ctx.NextState = 5;
|
||||
return true;
|
||||
|
||||
case 'e':
|
||||
case 'E':
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
ctx.NextState = 7;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool State4 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
if (ctx.L.input_char == ' ' ||
|
||||
ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') {
|
||||
ctx.Return = true;
|
||||
ctx.NextState = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case ',':
|
||||
case ']':
|
||||
case '}':
|
||||
ctx.L.UngetChar ();
|
||||
ctx.Return = true;
|
||||
ctx.NextState = 1;
|
||||
return true;
|
||||
|
||||
case '.':
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
ctx.NextState = 5;
|
||||
return true;
|
||||
|
||||
case 'e':
|
||||
case 'E':
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
ctx.NextState = 7;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State5 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') {
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
ctx.NextState = 6;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool State6 (FsmContext ctx)
|
||||
{
|
||||
while (ctx.L.GetChar ()) {
|
||||
if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') {
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ctx.L.input_char == ' ' ||
|
||||
ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') {
|
||||
ctx.Return = true;
|
||||
ctx.NextState = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case ',':
|
||||
case ']':
|
||||
case '}':
|
||||
ctx.L.UngetChar ();
|
||||
ctx.Return = true;
|
||||
ctx.NextState = 1;
|
||||
return true;
|
||||
|
||||
case 'e':
|
||||
case 'E':
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
ctx.NextState = 7;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool State7 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
if (ctx.L.input_char >= '0' && ctx.L.input_char<= '9') {
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
ctx.NextState = 8;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case '+':
|
||||
case '-':
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
ctx.NextState = 8;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State8 (FsmContext ctx)
|
||||
{
|
||||
while (ctx.L.GetChar ()) {
|
||||
if (ctx.L.input_char >= '0' && ctx.L.input_char<= '9') {
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ctx.L.input_char == ' ' ||
|
||||
ctx.L.input_char >= '\t' && ctx.L.input_char<= '\r') {
|
||||
ctx.Return = true;
|
||||
ctx.NextState = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case ',':
|
||||
case ']':
|
||||
case '}':
|
||||
ctx.L.UngetChar ();
|
||||
ctx.Return = true;
|
||||
ctx.NextState = 1;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool State9 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case 'r':
|
||||
ctx.NextState = 10;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State10 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case 'u':
|
||||
ctx.NextState = 11;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State11 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case 'e':
|
||||
ctx.Return = true;
|
||||
ctx.NextState = 1;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State12 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case 'a':
|
||||
ctx.NextState = 13;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State13 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case 'l':
|
||||
ctx.NextState = 14;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State14 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case 's':
|
||||
ctx.NextState = 15;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State15 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case 'e':
|
||||
ctx.Return = true;
|
||||
ctx.NextState = 1;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State16 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case 'u':
|
||||
ctx.NextState = 17;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State17 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case 'l':
|
||||
ctx.NextState = 18;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State18 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case 'l':
|
||||
ctx.Return = true;
|
||||
ctx.NextState = 1;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State19 (FsmContext ctx)
|
||||
{
|
||||
while (ctx.L.GetChar ()) {
|
||||
switch (ctx.L.input_char) {
|
||||
case '"':
|
||||
ctx.L.UngetChar ();
|
||||
ctx.Return = true;
|
||||
ctx.NextState = 20;
|
||||
return true;
|
||||
|
||||
case '\\':
|
||||
ctx.StateStack = 19;
|
||||
ctx.NextState = 21;
|
||||
return true;
|
||||
|
||||
default:
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool State20 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case '"':
|
||||
ctx.Return = true;
|
||||
ctx.NextState = 1;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State21 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case 'u':
|
||||
ctx.NextState = 22;
|
||||
return true;
|
||||
|
||||
case '"':
|
||||
case '\'':
|
||||
case '/':
|
||||
case '\\':
|
||||
case 'b':
|
||||
case 'f':
|
||||
case 'n':
|
||||
case 'r':
|
||||
case 't':
|
||||
ctx.L.string_buffer.Append (
|
||||
ProcessEscChar (ctx.L.input_char));
|
||||
ctx.NextState = ctx.StateStack;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State22 (FsmContext ctx)
|
||||
{
|
||||
int counter = 0;
|
||||
int mult = 4096;
|
||||
|
||||
ctx.L.unichar = 0;
|
||||
|
||||
while (ctx.L.GetChar ()) {
|
||||
|
||||
if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9' ||
|
||||
ctx.L.input_char >= 'A' && ctx.L.input_char <= 'F' ||
|
||||
ctx.L.input_char >= 'a' && ctx.L.input_char <= 'f') {
|
||||
|
||||
ctx.L.unichar += HexValue (ctx.L.input_char) * mult;
|
||||
|
||||
counter++;
|
||||
mult /= 16;
|
||||
|
||||
if (counter == 4) {
|
||||
ctx.L.string_buffer.Append (
|
||||
Convert.ToChar (ctx.L.unichar));
|
||||
ctx.NextState = ctx.StateStack;
|
||||
return true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool State23 (FsmContext ctx)
|
||||
{
|
||||
while (ctx.L.GetChar ()) {
|
||||
switch (ctx.L.input_char) {
|
||||
case '\'':
|
||||
ctx.L.UngetChar ();
|
||||
ctx.Return = true;
|
||||
ctx.NextState = 24;
|
||||
return true;
|
||||
|
||||
case '\\':
|
||||
ctx.StateStack = 23;
|
||||
ctx.NextState = 21;
|
||||
return true;
|
||||
|
||||
default:
|
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool State24 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case '\'':
|
||||
ctx.L.input_char = '"';
|
||||
ctx.Return = true;
|
||||
ctx.NextState = 1;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State25 (FsmContext ctx)
|
||||
{
|
||||
ctx.L.GetChar ();
|
||||
|
||||
switch (ctx.L.input_char) {
|
||||
case '*':
|
||||
ctx.NextState = 27;
|
||||
return true;
|
||||
|
||||
case '/':
|
||||
ctx.NextState = 26;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool State26 (FsmContext ctx)
|
||||
{
|
||||
while (ctx.L.GetChar ()) {
|
||||
if (ctx.L.input_char == '\n') {
|
||||
ctx.NextState = 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool State27 (FsmContext ctx)
|
||||
{
|
||||
while (ctx.L.GetChar ()) {
|
||||
if (ctx.L.input_char == '*') {
|
||||
ctx.NextState = 28;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool State28 (FsmContext ctx)
|
||||
{
|
||||
while (ctx.L.GetChar ()) {
|
||||
if (ctx.L.input_char == '*')
|
||||
continue;
|
||||
|
||||
if (ctx.L.input_char == '/') {
|
||||
ctx.NextState = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
ctx.NextState = 27;
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
private bool GetChar ()
|
||||
{
|
||||
if ((input_char = NextChar ()) != -1)
|
||||
return true;
|
||||
|
||||
end_of_input = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private int NextChar ()
|
||||
{
|
||||
if (input_buffer != 0) {
|
||||
int tmp = input_buffer;
|
||||
input_buffer = 0;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
return reader.Read ();
|
||||
}
|
||||
|
||||
public bool NextToken ()
|
||||
{
|
||||
StateHandler handler;
|
||||
fsm_context.Return = false;
|
||||
|
||||
while (true) {
|
||||
handler = fsm_handler_table[state - 1];
|
||||
|
||||
if (! handler (fsm_context))
|
||||
throw new JsonException (input_char);
|
||||
|
||||
if (end_of_input)
|
||||
return false;
|
||||
|
||||
if (fsm_context.Return) {
|
||||
string_value = string_buffer.ToString ();
|
||||
string_buffer.Remove (0, string_buffer.Length);
|
||||
token = fsm_return_table[state - 1];
|
||||
|
||||
if (token == (int) ParserToken.Char)
|
||||
token = input_char;
|
||||
|
||||
state = fsm_context.NextState;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
state = fsm_context.NextState;
|
||||
}
|
||||
}
|
||||
|
||||
private void UngetChar ()
|
||||
{
|
||||
input_buffer = input_char;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aadd9cba7eae43a42b4cc217ba457e54
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,24 @@
|
||||
#if NETSTANDARD1_5
|
||||
using System;
|
||||
using System.Reflection;
|
||||
namespace LitJson
|
||||
{
|
||||
internal static class Netstandard15Polyfill
|
||||
{
|
||||
internal static Type GetInterface(this Type type, string name)
|
||||
{
|
||||
return type.GetTypeInfo().GetInterface(name);
|
||||
}
|
||||
|
||||
internal static bool IsClass(this Type type)
|
||||
{
|
||||
return type.GetTypeInfo().IsClass;
|
||||
}
|
||||
|
||||
internal static bool IsEnum(this Type type)
|
||||
{
|
||||
return type.GetTypeInfo().IsEnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd46d201658351647a556d32b2cd1edb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,44 @@
|
||||
#region Header
|
||||
/**
|
||||
* ParserToken.cs
|
||||
* Internal representation of the tokens used by the lexer and the parser.
|
||||
*
|
||||
* The authors disclaim copyright to this source code. For more details, see
|
||||
* the COPYING file included with this distribution.
|
||||
**/
|
||||
#endregion
|
||||
|
||||
|
||||
namespace LitJson
|
||||
{
|
||||
internal enum ParserToken
|
||||
{
|
||||
// Lexer tokens (see section A.1.1. of the manual)
|
||||
None = System.Char.MaxValue + 1,
|
||||
Number,
|
||||
True,
|
||||
False,
|
||||
Null,
|
||||
CharSeq,
|
||||
// Single char
|
||||
Char,
|
||||
|
||||
// Parser Rules (see section A.2.1 of the manual)
|
||||
Text,
|
||||
Object,
|
||||
ObjectPrime,
|
||||
Pair,
|
||||
PairRest,
|
||||
Array,
|
||||
ArrayPrime,
|
||||
Value,
|
||||
ValueRest,
|
||||
String,
|
||||
|
||||
// End of input
|
||||
End,
|
||||
|
||||
// The empty rule
|
||||
Epsilon
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e84bd194d881f84e81d978238a310ea
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.OpenXR;
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
public abstract class OpenXRFeatureBase : OpenXRFeature
|
||||
{
|
||||
protected static ulong xrInstance = 0ul;
|
||||
protected static ulong xrSession = 0ul;
|
||||
protected string extensionUrl = "";
|
||||
protected bool _isExtensionEnable = false;
|
||||
|
||||
protected override bool OnInstanceCreate(ulong instance)
|
||||
{
|
||||
extensionUrl = GetExtensionString();
|
||||
_isExtensionEnable = isExtensionEnabled();
|
||||
if (!_isExtensionEnable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
xrInstance = instance;
|
||||
xrSession = 0ul;
|
||||
|
||||
Initialize(xrGetInstanceProcAddr);
|
||||
return true;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void GetValidationChecks(List<ValidationRule> rules, BuildTargetGroup targetGroup)
|
||||
{
|
||||
var settings = OpenXRSettings.GetSettingsForBuildTargetGroup(targetGroup);
|
||||
rules.Add(new ValidationRule(this)
|
||||
{
|
||||
message = "No PICO OpenXR Features selected.",
|
||||
checkPredicate = () =>
|
||||
{
|
||||
if (null == settings)
|
||||
return false;
|
||||
|
||||
foreach (var feature in settings.GetFeatures<OpenXRFeature>())
|
||||
{
|
||||
if (feature is OpenXRExtensions)
|
||||
{
|
||||
return feature.enabled;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
fixIt = () =>
|
||||
{
|
||||
if (null == settings)
|
||||
return ;
|
||||
var openXRExtensions = settings.GetFeature<OpenXRExtensions>();
|
||||
if (openXRExtensions != null)
|
||||
{
|
||||
openXRExtensions.enabled = true;
|
||||
}
|
||||
},
|
||||
error = true
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
public bool isExtensionEnabled()
|
||||
{
|
||||
string[] exts = extensionUrl.Split(' ');
|
||||
if (exts.Length>0)
|
||||
{
|
||||
foreach (var _ext in exts)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_ext) && !OpenXRRuntime.IsExtensionEnabled(_ext))
|
||||
{
|
||||
PLog.e(_ext + " is not enabled");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrEmpty(extensionUrl) && !OpenXRRuntime.IsExtensionEnabled(extensionUrl))
|
||||
{
|
||||
PLog.e(extensionUrl + " is not enabled");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnSessionCreate(ulong xrSessionId)
|
||||
{
|
||||
xrSession = xrSessionId;
|
||||
base.OnSessionCreate(xrSession);
|
||||
SessionCreate();
|
||||
}
|
||||
|
||||
protected override void OnInstanceDestroy(ulong xrInstance)
|
||||
{
|
||||
base.OnInstanceDestroy(xrInstance);
|
||||
xrInstance = 0ul;
|
||||
}
|
||||
|
||||
protected override void OnSessionDestroy(ulong xrSessionId)
|
||||
{
|
||||
base.OnSessionDestroy(xrSessionId);
|
||||
xrSession = 0ul;
|
||||
}
|
||||
|
||||
public virtual void Initialize(IntPtr intPtr)
|
||||
{
|
||||
}
|
||||
|
||||
public abstract string GetExtensionString();
|
||||
|
||||
public virtual void SessionCreate()
|
||||
{
|
||||
}
|
||||
public static bool IsSuccess(XrResult result) => result == 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 350057506ea44d55a5e042ce07f9f3b7
|
||||
timeCreated: 1687328246
|
@ -0,0 +1,755 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
public enum XrResult
|
||||
{
|
||||
Success = 0,
|
||||
TimeoutExpored = 1,
|
||||
LossPending = 3,
|
||||
EventUnavailable = 4,
|
||||
SpaceBoundsUnavailable = 7,
|
||||
SessionNotFocused = 8,
|
||||
FrameDiscarded = 9,
|
||||
ValidationFailure = -1,
|
||||
RuntimeFailure = -2,
|
||||
OutOfMemory = -3,
|
||||
ApiVersionUnsupported = -4,
|
||||
InitializationFailed = -6,
|
||||
FunctionUnsupported = -7,
|
||||
FeatureUnsupported = -8,
|
||||
ExtensionNotPresent = -9,
|
||||
LimitReached = -10,
|
||||
SizeInsufficient = -11,
|
||||
HandleInvalid = -12,
|
||||
InstanceLOst = -13,
|
||||
SessionRunning = -14,
|
||||
SessionNotRunning = -16,
|
||||
SessionLost = -17,
|
||||
SystemInvalid = -18,
|
||||
PathInvalid = -19,
|
||||
PathCountExceeded = -20,
|
||||
PathFormatInvalid = -21,
|
||||
PathUnsupported = -22,
|
||||
LayerInvalid = -23,
|
||||
LayerLimitExceeded = -24,
|
||||
SpwachainRectInvalid = -25,
|
||||
SwapchainFormatUnsupported = -26,
|
||||
ActionTypeMismatch = -27,
|
||||
SessionNotReady = -28,
|
||||
SessionNotStopping = -29,
|
||||
TimeInvalid = -30,
|
||||
ReferenceSpaceUnsupported = -31,
|
||||
FileAccessError = -32,
|
||||
FileContentsInvalid = -33,
|
||||
FormFactorUnsupported = -34,
|
||||
FormFactorUnavailable = -35,
|
||||
ApiLayerNotPresent = -36,
|
||||
CallOrderInvalid = -37,
|
||||
GraphicsDeviceInvalid = -38,
|
||||
PoseInvalid = -39,
|
||||
IndexOutOfRange = -40,
|
||||
ViewConfigurationTypeUnsupported = -41,
|
||||
EnvironmentBlendModeUnsupported = -42,
|
||||
NameDuplicated = -44,
|
||||
NameInvalid = -45,
|
||||
ActionsetNotAttached = -46,
|
||||
ActionsetsAlreadyAttached = -47,
|
||||
LocalizedNameDuplicated = -48,
|
||||
LocalizedNameInvalid = -49,
|
||||
AndroidThreadSettingsIdInvalidKHR = -1000003000,
|
||||
AndroidThreadSettingsdFailureKHR = -1000003001,
|
||||
CreateSpatialAnchorFailedMSFT = -1000039001,
|
||||
SecondaryViewConfigurationTypeNotEnabledMSFT = -1000053000,
|
||||
MaxResult = 0x7FFFFFFF
|
||||
}
|
||||
|
||||
public struct XrExtent2Df
|
||||
{
|
||||
public float width;
|
||||
public float height;
|
||||
|
||||
public XrExtent2Df(float x, float y)
|
||||
{
|
||||
this.width = x;
|
||||
this.height = y;
|
||||
}
|
||||
|
||||
public XrExtent2Df(Vector2 value)
|
||||
{
|
||||
width = value.x;
|
||||
height = value.y;
|
||||
}
|
||||
|
||||
public Vector2 ToVector2()
|
||||
{
|
||||
return new Vector2() { x = width, y = height };
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{nameof(width)}: {width}, {nameof(height)}: {height}";
|
||||
}
|
||||
};
|
||||
|
||||
// [Flags]
|
||||
public enum XrReferenceSpaceType
|
||||
{
|
||||
View = 1,
|
||||
Local = 2,
|
||||
Stage = 3,
|
||||
UnboundedMsft = 1000038000,
|
||||
CombinedEyeVarjo = 1000121000,
|
||||
LocalizationMap = 1000139000,
|
||||
LocalFloor = 1000426000,
|
||||
MAX_ENUM = 0x7FFFFFFF
|
||||
|
||||
}
|
||||
|
||||
public enum XrBodyJointSetBD
|
||||
{
|
||||
XR_BODY_JOINT_SET_DEFAULT_BD = 0, //default joint set XR_BODY_JOINT_SET_BODY_STAR_WITHOUT_ARM_BD
|
||||
XR_BODY_JOINT_SET_BODY_STAR_WITHOUT_ARM_BD = 1,
|
||||
XR_BODY_JOINT_SET_BODY_FULL_STAR_BD = 2
|
||||
}
|
||||
|
||||
public struct xrPose
|
||||
{
|
||||
public double PosX; // position of x
|
||||
public double PosY; // position of y
|
||||
public double PosZ; // position of z
|
||||
public double RotQx; // x components of Quaternion
|
||||
public double RotQy; // y components of Quaternion
|
||||
public double RotQz; // z components of Quaternion
|
||||
public double RotQw; // w components of Quaternion
|
||||
}
|
||||
|
||||
public struct BodyTrackerResult
|
||||
{
|
||||
public bool IsActive;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
|
||||
public FPICOBodyState[] trackingdata;
|
||||
}
|
||||
|
||||
public struct FPICOBodyState
|
||||
{
|
||||
public bool bIsValid;
|
||||
public xrPose pose;
|
||||
}
|
||||
|
||||
public enum SecureContentFlag
|
||||
{
|
||||
SECURE_CONTENT_OFF = 0,
|
||||
SECURE_CONTENT_EXCLUDE_LAYER = 1,
|
||||
SECURE_CONTENT_REPLACE_LAYER = 2
|
||||
}
|
||||
|
||||
public enum XrFaceTrackingModeBD
|
||||
{
|
||||
DEFAULT_BD = 0, // face
|
||||
COMBINED_AUDIO_BD = 1, // combined bs
|
||||
COMBINED_AUDIO_WITH_LIP_BD = 2, // combined vis
|
||||
ONLY_AUDIO_WITH_LIP_BD = 3, // lip sync
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enum values that identify the face action units affecting the expression on the face.
|
||||
/// </summary>
|
||||
/// <remarks>Each action unit corresponds to a facial feature that can move. A coefficient of zero for the
|
||||
/// feature represents the neutral position, while a coefficient of one represents the fully articulated
|
||||
/// position.
|
||||
/// </remarks>
|
||||
public enum BlendShapeLocation
|
||||
{
|
||||
/// <summary>
|
||||
/// The coefficient describing closure of the eyelids over the left eye.
|
||||
/// </summary>
|
||||
EyeBlinkLeft = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing movement of the left eyelids consistent with a downward gaze.
|
||||
/// </summary>
|
||||
EyeLookDownLeft = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing movement of the left eyelids consistent with a rightward gaze.
|
||||
/// </summary>
|
||||
EyeLookInLeft = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing movement of the left eyelids consistent with a leftward gaze.
|
||||
/// </summary>
|
||||
EyeLookOutLeft = 3,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing movement of the left eyelids consistent with an upward gaze.
|
||||
/// </summary>
|
||||
EyeLookUpLeft = 4,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing contraction of the face around the left eye.
|
||||
/// </summary>
|
||||
EyeSquintLeft = 5,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing a widening of the eyelids around the left eye.
|
||||
/// </summary>
|
||||
EyeWideLeft = 6,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing closure of the eyelids over the right eye.
|
||||
/// </summary>
|
||||
EyeBlinkRight = 7,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing movement of the right eyelids consistent with a downward gaze.
|
||||
/// </summary>
|
||||
EyeLookDownRight = 8,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing movement of the right eyelids consistent with a leftward gaze.
|
||||
/// </summary>
|
||||
EyeLookInRight = 9,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing movement of the right eyelids consistent with a rightward gaze.
|
||||
/// </summary>
|
||||
EyeLookOutRight = 10,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing movement of the right eyelids consistent with an upward gaze.
|
||||
/// </summary>
|
||||
EyeLookUpRight = 11,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing contraction of the face around the right eye.
|
||||
/// </summary>
|
||||
EyeSquintRight = 12,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing a widening of the eyelids around the right eye.
|
||||
/// </summary>
|
||||
EyeWideRight = 13,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing forward movement of the lower jaw.
|
||||
/// </summary>
|
||||
JawForward = 14,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing leftward movement of the lower jaw.
|
||||
/// </summary>
|
||||
JawLeft = 15,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing rightward movement of the lower jaw.
|
||||
/// </summary>
|
||||
JawRight = 16,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing an opening of the lower jaw.
|
||||
/// </summary>
|
||||
JawOpen = 17,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing closure of the lips independent of jaw position.
|
||||
/// </summary>
|
||||
MouthClose = 18,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing contraction of both lips into an open shape.
|
||||
/// </summary>
|
||||
MouthFunnel = 19,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing contraction and compression of both closed lips.
|
||||
/// </summary>
|
||||
MouthPucker = 20,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing leftward movement of both lips together.
|
||||
/// </summary>
|
||||
MouthLeft = 21,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing rightward movement of both lips together.
|
||||
/// </summary>
|
||||
MouthRight = 22,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing upward movement of the left corner of the mouth.
|
||||
/// </summary>
|
||||
MouthSmileLeft = 23,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing upward movement of the right corner of the mouth.
|
||||
/// </summary>
|
||||
MouthSmileRight = 24,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing downward movement of the left corner of the mouth.
|
||||
/// </summary>
|
||||
MouthFrownLeft = 25,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing downward movement of the right corner of the mouth.
|
||||
/// </summary>
|
||||
MouthFrownRight = 26,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing backward movement of the left corner of the mouth.
|
||||
/// </summary>
|
||||
MouthDimpleLeft = 27,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing backward movement of the right corner of the mouth.
|
||||
/// </summary>
|
||||
MouthDimpleRight = 28,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing leftward movement of the left corner of the mouth.
|
||||
/// </summary>
|
||||
MouthStretchLeft = 29,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing rightward movement of the left corner of the mouth.
|
||||
/// </summary>
|
||||
MouthStretchRight = 30,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing movement of the lower lip toward the inside of the mouth.
|
||||
/// </summary>
|
||||
MouthRollLower = 31,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing movement of the upper lip toward the inside of the mouth.
|
||||
/// </summary>
|
||||
MouthRollUpper = 32,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing outward movement of the lower lip.
|
||||
/// </summary>
|
||||
MouthShrugLower = 33,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing outward movement of the upper lip.
|
||||
/// </summary>
|
||||
MouthShrugUpper = 34,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing upward compression of the lower lip on the left side.
|
||||
/// </summary>
|
||||
MouthPressLeft = 35,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing upward compression of the lower lip on the right side.
|
||||
/// </summary>
|
||||
MouthPressRight = 36,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing downward movement of the lower lip on the left side.
|
||||
/// </summary>
|
||||
MouthLowerDownLeft = 37,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing downward movement of the lower lip on the right side.
|
||||
/// </summary>
|
||||
MouthLowerDownRight = 38,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing upward movement of the upper lip on the left side.
|
||||
/// </summary>
|
||||
MouthUpperUpLeft = 39,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing upward movement of the upper lip on the right side.
|
||||
/// </summary>
|
||||
MouthUpperUpRight = 40,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing downward movement of the outer portion of the left eyebrow.
|
||||
/// </summary>
|
||||
BrowDownLeft = 41,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing downward movement of the outer portion of the right eyebrow.
|
||||
/// </summary>
|
||||
BrowDownRight = 42,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing upward movement of the inner portion of both eyebrows.
|
||||
/// </summary>
|
||||
BrowInnerUp = 43,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing upward movement of the outer portion of the left eyebrow.
|
||||
/// </summary>
|
||||
BrowOuterUpLeft = 44,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing upward movement of the outer portion of the right eyebrow.
|
||||
/// </summary>
|
||||
BrowOuterUpRight = 45,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing outward movement of both cheeks.
|
||||
/// </summary>
|
||||
CheekPuff = 46,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing upward movement of the cheek around and below the left eye.
|
||||
/// </summary>
|
||||
CheekSquintLeft = 47,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing upward movement of the cheek around and below the right eye.
|
||||
/// </summary>
|
||||
CheekSquintRight = 48,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing a raising of the left side of the nose around the nostril.
|
||||
/// </summary>
|
||||
NoseSneerLeft = 49,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing a raising of the right side of the nose around the nostril.
|
||||
/// </summary>
|
||||
NoseSneerRight = 50,
|
||||
|
||||
/// <summary>
|
||||
/// The coefficient describing extension of the tongue.
|
||||
/// </summary>
|
||||
TongueOut = 51
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct PxrFaceTrackingInfo
|
||||
{
|
||||
public Int64 timestamp; //
|
||||
public fixed float faceExpressionWeights[52]; //
|
||||
public fixed float lipsyncExpressionWeights[20]; //
|
||||
public bool isUpperFaceDataValid; //
|
||||
public bool isLowerFaceDataValid; //
|
||||
};
|
||||
|
||||
public enum ConfigsEXT
|
||||
{
|
||||
RENDER_TEXTURE_WIDTH = 0,
|
||||
RENDER_TEXTURE_HEIGHT,
|
||||
SHOW_FPS,
|
||||
RUNTIME_LOG_LEVEL,
|
||||
PXRPLUGIN_LOG_LEVEL,
|
||||
UNITY_LOG_LEVEL,
|
||||
UNREAL_LOG_LEVEL,
|
||||
NATIVE_LOG_LEVEL,
|
||||
TARGET_FRAME_RATE,
|
||||
NECK_MODEL_X,
|
||||
NECK_MODEL_Y,
|
||||
NECK_MODEL_Z,
|
||||
DISPLAY_REFRESH_RATE,
|
||||
ENABLE_6DOF,
|
||||
CONTROLLER_TYPE,
|
||||
PHYSICAL_IPD,
|
||||
TO_DELTA_SENSOR_Y,
|
||||
GET_DISPLAY_RATE,
|
||||
FOVEATION_SUBSAMPLED_ENABLED = 18,
|
||||
TRACKING_ORIGIN_HEIGHT = 19,
|
||||
RENDER_FPS = 20,
|
||||
MRC_POSITION_Y_OFFSET,
|
||||
GET_SINGLEPASS = 22,
|
||||
GET_FOVLEVEL,
|
||||
SDK_TRACE_ENABLE,
|
||||
SDK_SEETHROUGH_DELAY_LOG_ENABLE = 25,
|
||||
GET_SEETHROUGH_STATE = 26,
|
||||
EYEORIENTATAION_LEFT_X = 27,
|
||||
EYEORIENTATAION_LEFT_Y = 28,
|
||||
EYEORIENTATAION_LEFT_Z = 29,
|
||||
EYEORIENTATAION_LEFT_W = 30,
|
||||
EYEORIENTATAION_RIGHT_X = 31,
|
||||
EYEORIENTATAION_RIGHT_Y = 32,
|
||||
EYEORIENTATAION_RIGHT_Z = 33,
|
||||
EYEORIENTATAION_RIGHT_W = 34,
|
||||
SDK_SEETHROUGH_DELAY_DATA_REPORT = 35,
|
||||
};
|
||||
|
||||
public struct PxrRecti
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
public int width;
|
||||
public int height;
|
||||
};
|
||||
|
||||
public enum PxrBlendFactor
|
||||
{
|
||||
Zero = 0,
|
||||
One = 1,
|
||||
SrcAlpha = 2,
|
||||
OneMinusSrcAlpha = 3,
|
||||
DstAlpha = 4,
|
||||
OneMinusDstAlpha = 5
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrLayerParam
|
||||
{
|
||||
public int layerId;
|
||||
public CompositeLayerFeature.OverlayShape layerShape;
|
||||
public CompositeLayerFeature.OverlayType layerType;
|
||||
public CompositeLayerFeature.LayerLayout layerLayout;
|
||||
public UInt64 format;
|
||||
public UInt32 width;
|
||||
public UInt32 height;
|
||||
public UInt32 sampleCount;
|
||||
public UInt32 faceCount;
|
||||
public UInt32 arraySize;
|
||||
public UInt32 mipmapCount;
|
||||
public UInt32 layerFlags;
|
||||
public UInt32 externalImageCount;
|
||||
public IntPtr leftExternalImages;
|
||||
public IntPtr rightExternalImages;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrVector4f
|
||||
{
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
public float w;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrVector3f
|
||||
{
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
};
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrExtent3Df
|
||||
{
|
||||
public float width;
|
||||
public float height;
|
||||
public float depth;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrPosef
|
||||
{
|
||||
public PxrVector4f orientation;
|
||||
public PxrVector3f position;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrLayerBlend
|
||||
{
|
||||
public PxrBlendFactor srcColor;
|
||||
public PxrBlendFactor dstColor;
|
||||
public PxrBlendFactor srcAlpha;
|
||||
public PxrBlendFactor dstAlpha;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrLayerHeader2
|
||||
{
|
||||
public int layerId;
|
||||
public UInt32 layerFlags;
|
||||
public float colorScaleX;
|
||||
public float colorScaleY;
|
||||
public float colorScaleZ;
|
||||
public float colorScaleW;
|
||||
public float colorBiasX;
|
||||
public float colorBiasY;
|
||||
public float colorBiasZ;
|
||||
public float colorBiasW;
|
||||
public int compositionDepth;
|
||||
public int sensorFrameIndex;
|
||||
public int imageIndex;
|
||||
public PxrPosef headPose;
|
||||
public CompositeLayerFeature.OverlayShape layerShape;
|
||||
public UInt32 useLayerBlend;
|
||||
public PxrLayerBlend layerBlend;
|
||||
public UInt32 useImageRect;
|
||||
public PxrRecti imageRectLeft;
|
||||
public PxrRecti imageRectRight;
|
||||
public UInt64 reserved0;
|
||||
public UInt64 reserved1;
|
||||
public UInt64 reserved2;
|
||||
public UInt64 reserved3;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrVector2f
|
||||
{
|
||||
public float x;
|
||||
public float y;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrLayerQuad
|
||||
{
|
||||
public PxrLayerHeader2 header;
|
||||
public PxrPosef poseLeft;
|
||||
public PxrPosef poseRight;
|
||||
public PxrVector2f sizeLeft;
|
||||
public PxrVector2f sizeRight;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct PxrLayerCylinder
|
||||
{
|
||||
public PxrLayerHeader2 header;
|
||||
public PxrPosef poseLeft;
|
||||
public PxrPosef poseRight;
|
||||
public float radiusLeft;
|
||||
public float radiusRight;
|
||||
public float centralAngleLeft;
|
||||
public float centralAngleRight;
|
||||
public float heightLeft;
|
||||
public float heightRight;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrLayerEquirect
|
||||
{
|
||||
public PxrLayerHeader2 header;
|
||||
public PxrPosef poseLeft;
|
||||
public PxrPosef poseRight;
|
||||
public float radiusLeft;
|
||||
public float radiusRight;
|
||||
public float centralHorizontalAngleLeft;
|
||||
public float centralHorizontalAngleRight;
|
||||
public float upperVerticalAngleLeft;
|
||||
public float upperVerticalAngleRight;
|
||||
public float lowerVerticalAngleLeft;
|
||||
public float lowerVerticalAngleRight;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrLayerCube
|
||||
{
|
||||
public PxrLayerHeader2 header;
|
||||
public PxrPosef poseLeft;
|
||||
public PxrPosef poseRight;
|
||||
};
|
||||
|
||||
public enum PxrLayerSubmitFlags
|
||||
{
|
||||
PxrLayerFlagNoCompositionDepthTesting = 1 << 3,
|
||||
PxrLayerFlagUseExternalHeadPose = 1 << 5,
|
||||
PxrLayerFlagLayerPoseNotInTrackingSpace = 1 << 6,
|
||||
PxrLayerFlagHeadLocked = 1 << 7,
|
||||
PxrLayerFlagUseExternalImageIndex = 1 << 8,
|
||||
}
|
||||
|
||||
public enum PxrLayerCreateFlags
|
||||
{
|
||||
PxrLayerFlagAndroidSurface = 1 << 0,
|
||||
PxrLayerFlagProtectedContent = 1 << 1,
|
||||
PxrLayerFlagStaticImage = 1 << 2,
|
||||
PxrLayerFlagUseExternalImages = 1 << 4,
|
||||
PxrLayerFlag3DLeftRightSurface = 1 << 5,
|
||||
PxrLayerFlag3DTopBottomSurface = 1 << 6,
|
||||
PxrLayerFlagEnableFrameExtrapolation = 1 << 7,
|
||||
PxrLayerFlagEnableSubsampled = 1 << 8,
|
||||
PxrLayerFlagEnableFrameExtrapolationPTW = 1 << 9,
|
||||
PxrLayerFlagSharedImagesBetweenLayers = 1 << 10,
|
||||
}
|
||||
|
||||
public enum EyeType
|
||||
{
|
||||
EyeLeft,
|
||||
EyeRight,
|
||||
EyeBoth
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Information about PICO Motion Tracker's connection state.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct PxrFitnessBandConnectState
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Byte num;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public fixed Byte trackerID[12];
|
||||
}
|
||||
|
||||
public enum PassthroughColorMapType
|
||||
{
|
||||
None = 0,
|
||||
MonoToRgba = 1,
|
||||
MonoToMono = 2,
|
||||
BrightnessContrastSaturation = 3
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Colorf
|
||||
{
|
||||
public float r;
|
||||
public float g;
|
||||
public float b;
|
||||
public float a;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture,
|
||||
"R:{0:F3} G:{1:F3} B:{2:F3} A:{3:F3}", r, g, b, a);
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct _PassthroughStyle
|
||||
{
|
||||
public uint enableEdgeColor;
|
||||
public uint enableColorMap;
|
||||
public float TextureOpacityFactor;
|
||||
public Colorf EdgeColor;
|
||||
public PassthroughColorMapType TextureColorMapType;
|
||||
public uint TextureColorMapDataSize;
|
||||
public IntPtr TextureColorMapData;
|
||||
}
|
||||
public struct PassthroughStyle
|
||||
{
|
||||
public bool enableEdgeColor;
|
||||
public bool enableColorMap;
|
||||
public float TextureOpacityFactor;
|
||||
public Color EdgeColor;
|
||||
public PassthroughColorMapType TextureColorMapType;
|
||||
public uint TextureColorMapDataSize;
|
||||
public IntPtr TextureColorMapData;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct GeometryInstanceTransform
|
||||
{
|
||||
public PxrPosef pose;
|
||||
public PxrVector3f scale;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture,
|
||||
"Rotation:({0:F3},{1:F3},{2:F3},{3:F3}) Position:({4:F3},{5:F3},{6:F3}) scale:({7},{8},{9})", pose.orientation.x,
|
||||
pose.orientation.y, pose.orientation.z, pose.orientation.w, pose.position.x, pose.position.y,
|
||||
pose.position.z,scale.x,scale.y,scale.z);
|
||||
}
|
||||
};
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrSensorState2
|
||||
{
|
||||
public int status;
|
||||
public PxrPosef pose;
|
||||
public PxrPosef globalPose;
|
||||
public PxrVector3f angularVelocity;
|
||||
public PxrVector3f linearVelocity;
|
||||
public PxrVector3f angularAcceleration;
|
||||
public PxrVector3f linearAcceleration;
|
||||
public UInt64 poseTimeStampNs;
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 70222e482e03417ab1388191c49f1c23
|
||||
timeCreated: 1686552171
|
@ -0,0 +1,104 @@
|
||||
/*******************************************************************************
|
||||
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 hererin 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.
|
||||
*******************************************************************************/
|
||||
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
public class PLog
|
||||
{
|
||||
public static string TAG = "[PoxrUnity] ";
|
||||
// 7--all print, 4--info to fatal, 3--warning to fatal,
|
||||
// 2--error to fatal, 1--only fatal print
|
||||
public static LogLevel logLevel = LogLevel.LogInfo;
|
||||
|
||||
public enum LogLevel
|
||||
{
|
||||
LogFatal = 1,
|
||||
LogError = 2,
|
||||
LogWarn = 3,
|
||||
LogInfo = 4,
|
||||
LogDebug = 5,
|
||||
LogVerbose,
|
||||
}
|
||||
|
||||
public static void v(string message)
|
||||
{
|
||||
v(TAG,message);
|
||||
}
|
||||
|
||||
public static void d(string message)
|
||||
{
|
||||
d(TAG,message);
|
||||
}
|
||||
|
||||
public static void i(string message)
|
||||
{
|
||||
i(TAG,message);
|
||||
}
|
||||
|
||||
public static void w(string message)
|
||||
{
|
||||
w(TAG,message);
|
||||
}
|
||||
|
||||
public static void e(string message)
|
||||
{
|
||||
e(TAG,message);
|
||||
}
|
||||
|
||||
public static void f(string message)
|
||||
{
|
||||
f(TAG,message);
|
||||
}
|
||||
|
||||
|
||||
public static void v(string tag,string message)
|
||||
{
|
||||
if (LogLevel.LogVerbose <= logLevel)
|
||||
Debug.Log(string.Format("{0} FrameID={1}>>>>>>{2}", TAG, Time.frameCount, message));
|
||||
}
|
||||
|
||||
public static void d(string tag,string message)
|
||||
{
|
||||
if (LogLevel.LogDebug <= logLevel)
|
||||
Debug.Log(string.Format("{0} FrameID={1}>>>>>>{2}", TAG, Time.frameCount, message));
|
||||
}
|
||||
|
||||
public static void i(string tag,string message)
|
||||
{
|
||||
if (LogLevel.LogInfo <= logLevel)
|
||||
Debug.Log(string.Format("{0} FrameID={1}>>>>>>{2}", TAG, Time.frameCount, message));
|
||||
}
|
||||
|
||||
public static void w(string tag,string message)
|
||||
{
|
||||
if (LogLevel.LogWarn <= logLevel)
|
||||
Debug.LogWarning(string.Format("{0} FrameID={1}>>>>>>{2}", TAG, Time.frameCount, message));
|
||||
}
|
||||
|
||||
public static void e(string tag,string message)
|
||||
{
|
||||
if (LogLevel.LogError <= logLevel)
|
||||
Debug.LogError(string.Format("{0} FrameID={1}>>>>>>{2}", TAG, Time.frameCount, message));
|
||||
}
|
||||
|
||||
public static void f(string tag,string message)
|
||||
{
|
||||
if (LogLevel.LogFatal <= logLevel)
|
||||
Debug.LogError(string.Format("{0} FrameID={1}>>>>>>{2}", TAG, Time.frameCount, message));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df58f5069538b8c4ba1ccb810f392606
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Android;
|
||||
|
||||
public class PXR_PermissionRequest : MonoBehaviour
|
||||
{
|
||||
public bool requestMR=false;
|
||||
|
||||
|
||||
private List<string> _permissions = new List<string>();
|
||||
private const string _permissionMr = "com.picovr.permission.SPATIAL_DATA";
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (requestMR)
|
||||
{
|
||||
_permissions.Add(_permissionMr);
|
||||
}
|
||||
RequestUserPermissionAll();
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void RequestUserPermissionAll()
|
||||
{
|
||||
var callbacks = new PermissionCallbacks();
|
||||
callbacks.PermissionDenied += PermissionCallbacks_PermissionDenied;
|
||||
callbacks.PermissionGranted += PermissionCallbacks_PermissionGranted;
|
||||
callbacks.PermissionDeniedAndDontAskAgain += PermissionCallbacks_PermissionDeniedAndDontAskAgain;
|
||||
Debug.Log("HHHH Permission.Camera Request");
|
||||
Permission.RequestUserPermissions(_permissions.ToArray(), callbacks);
|
||||
}
|
||||
|
||||
internal void PermissionCallbacks_PermissionDeniedAndDontAskAgain(string permissionName)
|
||||
{
|
||||
Debug.Log($"HHHH {permissionName} PermissionDeniedAndDontAskAgain");
|
||||
}
|
||||
|
||||
internal void PermissionCallbacks_PermissionGranted(string permissionName)
|
||||
{
|
||||
Debug.Log($"HHHH {permissionName} PermissionCallbacks_PermissionGranted");
|
||||
}
|
||||
|
||||
internal void PermissionCallbacks_PermissionDenied(string permissionName)
|
||||
{
|
||||
Debug.Log($"HHHH {permissionName} PermissionCallbacks_PermissionDenied");
|
||||
}
|
||||
|
||||
|
||||
public static void RequestUserPermissionMR(Action<string> _PermissionDenied=null,Action<string> _PermissionGranted=null,Action<string> _PermissionDeniedAndDontAskAgain=null)
|
||||
{
|
||||
if (Permission.HasUserAuthorizedPermission(_permissionMr))
|
||||
{
|
||||
if (_PermissionGranted != null)
|
||||
{
|
||||
_PermissionGranted(_permissionMr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var callbacks = new PermissionCallbacks();
|
||||
callbacks.PermissionDenied += _PermissionDenied;
|
||||
callbacks.PermissionGranted += _PermissionGranted;
|
||||
callbacks.PermissionDeniedAndDontAskAgain += _PermissionDeniedAndDontAskAgain;
|
||||
Permission.RequestUserPermission(_permissionMr,callbacks);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RequestUserPermissionMR(Action<string> _PermissionGranted)
|
||||
{
|
||||
if (Permission.HasUserAuthorizedPermission(_permissionMr))
|
||||
{
|
||||
if (_PermissionGranted != null)
|
||||
{
|
||||
_PermissionGranted(_permissionMr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var callbacks = new PermissionCallbacks();
|
||||
callbacks.PermissionGranted += _PermissionGranted;
|
||||
Permission.RequestUserPermission(_permissionMr,callbacks);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: abf8973c00047e14e86e0c66151edeaf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,251 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using Unity.XR.OpenXR.Features.PICOSupport;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR;
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
public delegate void XrEventDataBufferCallBack(ref XrEventDataBuffer dataBuffer);
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrEventDataBuffer
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4000)]
|
||||
public byte[] data;
|
||||
};
|
||||
public enum PxrSenseDataProviderState
|
||||
{
|
||||
Initialized,
|
||||
Running,
|
||||
Stopped
|
||||
}
|
||||
public enum PxrFutureState
|
||||
{
|
||||
Pending = 1,
|
||||
Ready = 2
|
||||
}
|
||||
public enum PxrSemanticLabel
|
||||
{
|
||||
Unknown = 0,
|
||||
Floor,
|
||||
Ceiling,
|
||||
Wall,
|
||||
Door,
|
||||
Window,
|
||||
Opening,
|
||||
Table,
|
||||
Sofa,
|
||||
Chair,
|
||||
Human = 10,
|
||||
VirtualWall = 18,
|
||||
}
|
||||
public enum PxrSceneComponentType
|
||||
{
|
||||
Location = 0,
|
||||
Semantic,
|
||||
Box2D,
|
||||
Polygon,
|
||||
Box3D,
|
||||
TriangleMesh = 5,
|
||||
}
|
||||
|
||||
public enum PxrSenseDataProviderType
|
||||
{
|
||||
SpatialAnchor,
|
||||
SceneCapture,
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrSceneBox2D
|
||||
{
|
||||
public Vector2 offset;
|
||||
public XrExtent2Df extent;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrScenePolygon
|
||||
{
|
||||
public Vector2[] vertices;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrSceneBox3D
|
||||
{
|
||||
public Vector3 position;
|
||||
public Quaternion rotation;
|
||||
public Vector3 extent;
|
||||
}
|
||||
public struct PxrSceneComponentData
|
||||
{
|
||||
public Guid uuid;
|
||||
public Vector3 position;
|
||||
public Quaternion rotation;
|
||||
public PxrSemanticLabel label;
|
||||
public PxrSceneComponentType[] types;
|
||||
public PxrSceneBox3D box3D;
|
||||
public PxrSceneBox2D box2D;
|
||||
public PxrScenePolygon polygon;
|
||||
}
|
||||
public enum PxrMeshLod
|
||||
{
|
||||
Low,
|
||||
Medium,
|
||||
High
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrSpatialMeshInfo
|
||||
{
|
||||
public Guid uuid;
|
||||
public MeshChangeState state;
|
||||
public Vector3 position;
|
||||
public Quaternion rotation;
|
||||
public ushort[] indices;
|
||||
public Vector3[] vertices;
|
||||
public PxrSemanticLabel[] labels;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrEventSenseDataProviderStateChanged
|
||||
{
|
||||
public ulong providerHandle;
|
||||
public PxrSenseDataProviderState newState;
|
||||
}
|
||||
public enum PxrResult
|
||||
{
|
||||
SUCCESS = 0,
|
||||
TIMEOUT_EXPIRED = 1,
|
||||
SESSION_LOSS_PENDING = 3,
|
||||
EVENT_UNAVAILABLE = 4,
|
||||
SPACE_BOUNDS_UNAVAILABLE = 7,
|
||||
SESSION_NOT_FOCUSED = 8,
|
||||
FRAME_DISCARDED = 9,
|
||||
ERROR_VALIDATION_FAILURE = -1,
|
||||
ERROR_RUNTIME_FAILURE = -2,
|
||||
ERROR_OUT_OF_MEMORY = -3,
|
||||
ERROR_API_VERSION_UNSUPPORTED = -4,
|
||||
ERROR_INITIALIZATION_FAILED = -6,
|
||||
ERROR_FUNCTION_UNSUPPORTED = -7,
|
||||
ERROR_FEATURE_UNSUPPORTED = -8,
|
||||
ERROR_EXTENSION_NOT_PRESENT = -9,
|
||||
ERROR_LIMIT_REACHED = -10,
|
||||
ERROR_SIZE_INSUFFICIENT = -11,
|
||||
ERROR_HANDLE_INVALID = -12,
|
||||
ERROR_INSTANCE_LOST = -13,
|
||||
ERROR_SESSION_RUNNING = -14,
|
||||
ERROR_SESSION_NOT_RUNNING = -16,
|
||||
ERROR_SESSION_LOST = -17,
|
||||
ERROR_SYSTEM_INVALID = -18,
|
||||
ERROR_PATH_INVALID = -19,
|
||||
ERROR_PATH_COUNT_EXCEEDED = -20,
|
||||
ERROR_PATH_FORMAT_INVALID = -21,
|
||||
ERROR_PATH_UNSUPPORTED = -22,
|
||||
ERROR_LAYER_INVALID = -23,
|
||||
ERROR_LAYER_LIMIT_EXCEEDED = -24,
|
||||
ERROR_SWAPCHAIN_RECT_INVALID = -25,
|
||||
ERROR_SWAPCHAIN_FORMAT_UNSUPPORTED = -26,
|
||||
ERROR_ACTION_TYPE_MISMATCH = -27,
|
||||
ERROR_SESSION_NOT_READY = -28,
|
||||
ERROR_SESSION_NOT_STOPPING = -29,
|
||||
ERROR_TIME_INVALID = -30,
|
||||
ERROR_REFERENCE_SPACE_UNSUPPORTED = -31,
|
||||
ERROR_FILE_ACCESS_ERROR = -32,
|
||||
ERROR_FILE_CONTENTS_INVALID = -33,
|
||||
ERROR_FORM_FACTOR_UNSUPPORTED = -34,
|
||||
ERROR_FORM_FACTOR_UNAVAILABLE = -35,
|
||||
ERROR_API_LAYER_NOT_PRESENT = -36,
|
||||
ERROR_CALL_ORDER_INVALID = -37,
|
||||
ERROR_GRAPHICS_DEVICE_INVALID = -38,
|
||||
ERROR_POSE_INVALID = -39,
|
||||
ERROR_INDEX_OUT_OF_RANGE = -40,
|
||||
ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED = -41,
|
||||
ERROR_ENVIRONMENT_BLEND_MODE_UNSUPPORTED = -42,
|
||||
ERROR_NAME_DUPLICATED = -44,
|
||||
ERROR_NAME_INVALID = -45,
|
||||
ERROR_ACTIONSET_NOT_ATTACHED = -46,
|
||||
ERROR_ACTIONSETS_ALREADY_ATTACHED = -47,
|
||||
ERROR_LOCALIZED_NAME_DUPLICATED = -48,
|
||||
ERROR_LOCALIZED_NAME_INVALID = -49,
|
||||
ERROR_GRAPHICS_REQUIREMENTS_CALL_MISSING = -50,
|
||||
ERROR_RUNTIME_UNAVAILABLE = -51,
|
||||
ERROR_EXTENSION_NOT_ENABLED = -800,
|
||||
|
||||
ERROR_SPATIAL_LOCALIZATION_RUNNING = -1000,
|
||||
ERROR_SPATIAL_LOCALIZATION_NOT_RUNNING = -1001,
|
||||
ERROR_SPATIAL_MAP_CREATED = -1002,
|
||||
ERROR_SPATIAL_MAP_NOT_CREATED = -1003,
|
||||
ERROR_COMPONENT_NOT_SUPPORTED = -501,
|
||||
ERROR_COMPONENT_CONFLICT = -502,
|
||||
ERROR_COMPONENT_NOT_ADDED = -503,
|
||||
ERROR_COMPONENT_ADDED = -504,
|
||||
ERROR_ANCHOR_ENTITY_NOT_FOUND = -505,
|
||||
ERROR_TRACKING_STATE_INVALID = -506,
|
||||
|
||||
ERROR_ANCHOR_SHARING_NETWORK_TIMEOUT = -601,
|
||||
ERROR_ANCHOR_SHARING_AUTHENTICATION_FAILURE = -602,
|
||||
ERROR_ANCHOR_SHARING_NETWORK_FAILURE = -603,
|
||||
ERROR_ANCHOR_SHARING_LOCALIZATION_FAIL = -604,
|
||||
ERROR_ANCHOR_SHARING_MAP_INSUFFICIENT = -605,
|
||||
|
||||
|
||||
ERROR_EXTENSION_DEPENDENCY_NOT_ENABLED = -1000710001,
|
||||
ERROR_PERMISSION_INSUFFICIENT = -1000710000,
|
||||
ERROR_ANDROID_THREAD_SETTINGS_ID_INVALID_KHR = -1000003000,
|
||||
ERROR_ANDROID_THREAD_SETTINGS_FAILURE_KHR = -1000003001,
|
||||
ERROR_CREATE_SPATIAL_ANCHOR_FAILED_MSFT = -1000039001,
|
||||
ERROR_SECONDARY_VIEW_CONFIGURATION_TYPE_NOT_ENABLED_MSFT = -1000053000,
|
||||
ERROR_CONTROLLER_MODEL_KEY_INVALID_MSFT = -1000055000,
|
||||
ERROR_REPROJECTION_MODE_UNSUPPORTED_MSFT = -1000066000,
|
||||
ERROR_COMPUTE_NEW_SCENE_NOT_COMPLETED_MSFT = -1000097000,
|
||||
ERROR_SCENE_COMPONENT_ID_INVALID_MSFT = -1000097001,
|
||||
ERROR_SCENE_COMPONENT_TYPE_MISMATCH_MSFT = -1000097002,
|
||||
ERROR_SCENE_MESH_BUFFER_ID_INVALID_MSFT = -1000097003,
|
||||
ERROR_SCENE_COMPUTE_FEATURE_INCOMPATIBLE_MSFT = -1000097004,
|
||||
ERROR_SCENE_COMPUTE_CONSISTENCY_MISMATCH_MSFT = -1000097005,
|
||||
ERROR_DISPLAY_REFRESH_RATE_UNSUPPORTED_FB = -1000101000,
|
||||
ERROR_COLOR_SPACE_UNSUPPORTED_FB = -1000108000,
|
||||
ERROR_SPACE_COMPONENT_NOT_SUPPORTED_FB = -1000113000,
|
||||
ERROR_SPACE_COMPONENT_NOT_ENABLED_FB = -1000113001,
|
||||
ERROR_SPACE_COMPONENT_STATUS_PENDING_FB = -1000113002,
|
||||
ERROR_SPACE_COMPONENT_STATUS_ALREADY_SET_FB = -1000113003,
|
||||
ERROR_UNEXPECTED_STATE_PASSTHROUGH_FB = -1000118000,
|
||||
ERROR_FEATURE_ALREADY_CREATED_PASSTHROUGH_FB = -1000118001,
|
||||
ERROR_FEATURE_REQUIRED_PASSTHROUGH_FB = -1000118002,
|
||||
ERROR_NOT_PERMITTED_PASSTHROUGH_FB = -1000118003,
|
||||
ERROR_INSUFFICIENT_RESOURCES_PASSTHROUGH_FB = -1000118004,
|
||||
ERROR_UNKNOWN_PASSTHROUGH_FB = -1000118050,
|
||||
ERROR_RENDER_MODEL_KEY_INVALID_FB = -1000119000,
|
||||
RENDER_MODEL_UNAVAILABLE_FB = 1000119020,
|
||||
ERROR_MARKER_NOT_TRACKED_VARJO = -1000124000,
|
||||
ERROR_MARKER_ID_INVALID_VARJO = -1000124001,
|
||||
ERROR_MARKER_DETECTOR_PERMISSION_DENIED_ML = -1000138000,
|
||||
ERROR_MARKER_DETECTOR_LOCATE_FAILED_ML = -1000138001,
|
||||
ERROR_MARKER_DETECTOR_INVALID_DATA_QUERY_ML = -1000138002,
|
||||
ERROR_MARKER_DETECTOR_INVALID_CREATE_INFO_ML = -1000138003,
|
||||
ERROR_MARKER_INVALID_ML = -1000138004,
|
||||
ERROR_LOCALIZATION_MAP_INCOMPATIBLE_ML = -1000139000,
|
||||
ERROR_LOCALIZATION_MAP_UNAVAILABLE_ML = -1000139001,
|
||||
ERROR_LOCALIZATION_MAP_FAIL_ML = -1000139002,
|
||||
ERROR_LOCALIZATION_MAP_IMPORT_EXPORT_PERMISSION_DENIED_ML = -1000139003,
|
||||
ERROR_LOCALIZATION_MAP_PERMISSION_DENIED_ML = -1000139004,
|
||||
ERROR_LOCALIZATION_MAP_ALREADY_EXISTS_ML = -1000139005,
|
||||
ERROR_LOCALIZATION_MAP_CANNOT_EXPORT_CLOUD_MAP_ML = -1000139006,
|
||||
ERROR_SPATIAL_ANCHOR_NAME_NOT_FOUND_MSFT = -1000142001,
|
||||
ERROR_SPATIAL_ANCHOR_NAME_INVALID_MSFT = -1000142002,
|
||||
SCENE_MARKER_DATA_NOT_STRING_MSFT = 1000147000,
|
||||
ERROR_SPACE_MAPPING_INSUFFICIENT_FB = -1000169000,
|
||||
ERROR_SPACE_LOCALIZATION_FAILED_FB = -1000169001,
|
||||
ERROR_SPACE_NETWORK_TIMEOUT_FB = -1000169002,
|
||||
ERROR_SPACE_NETWORK_REQUEST_FAILED_FB = -1000169003,
|
||||
ERROR_SPACE_CLOUD_STORAGE_DISABLED_FB = -1000169004,
|
||||
ERROR_PASSTHROUGH_COLOR_LUT_BUFFER_SIZE_MISMATCH_META = -1000266000,
|
||||
ENVIRONMENT_DEPTH_NOT_AVAILABLE_META = 1000291000,
|
||||
ERROR_HINT_ALREADY_SET_QCOM = -1000306000,
|
||||
ERROR_NOT_AN_ANCHOR_HTC = -1000319000,
|
||||
ERROR_SPACE_NOT_LOCATABLE_EXT = -1000429000,
|
||||
ERROR_PLANE_DETECTION_PERMISSION_DENIED_EXT = -1000429001,
|
||||
ERROR_FUTURE_PENDING_EXT = -1000469001,
|
||||
ERROR_FUTURE_INVALID_EXT = -1000469002,
|
||||
ERROR_EXTENSION_DEPENDENCY_NOT_ENABLED_KHR = ERROR_EXTENSION_DEPENDENCY_NOT_ENABLED,
|
||||
ERROR_PERMISSION_INSUFFICIENT_KHR = ERROR_PERMISSION_INSUFFICIENT,
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52865e17ab434793a960c1936684f6ec
|
||||
timeCreated: 1721813797
|
@ -0,0 +1,711 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Unity.XR.OpenXR.Features.PICOSupport;
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrFuturePollInfoEXT
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public ulong future;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrFuturePollResultEXT
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public PxrFutureState state;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSenseDataProviderCreateInfoBaseHeader
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSenseDataProviderStartCompletion
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public PxrResult futureResult;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSenseDataQueryCompletion
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public PxrResult futureResult;
|
||||
public ulong snapshotHandle;
|
||||
}
|
||||
|
||||
public struct PxrUuid
|
||||
{
|
||||
public ulong value0;
|
||||
public ulong value1;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSpatialAnchorCompletion
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public PxrResult futureResult;
|
||||
public ulong anchorHandle;
|
||||
public PxrUuid uuid;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSpatialAnchorPersistInfo
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public PxrPersistenceLocation location;
|
||||
public ulong anchorHandle;
|
||||
}
|
||||
|
||||
public enum PxrPersistenceLocation
|
||||
{
|
||||
Local = 0,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSenseDataQueryInfo
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public IntPtr filter; //PxrSenseDataQueryFilterBaseHeader
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSenseDataFilterUuid
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public uint uuidCount;
|
||||
public IntPtr uuidList; //=>PxrUuid[]
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSenseDataFilterSemantic
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public uint semanticCount;
|
||||
public IntPtr semantics; //=>PxrSemanticLabel[]
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrQueriedSenseDataGetInfo
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public ulong snapshotHandle;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrQueriedSenseData
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public uint queriedSpatialEntityCapacityInput;
|
||||
public uint queriedSpatialEntityCountOutput;
|
||||
public IntPtr queriedSpatialEntities;//PxrQueriedSpatialEntityInfo[]
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrQueriedSpatialEntityInfo
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public ulong spatialEntity;
|
||||
public ulong time;
|
||||
public PxrUuid uuid;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSpatialEntityAnchorRetrieveInfo
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public ulong spatialEntity;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSpaceLocation
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public ulong locationFlags; //PxrSpaceLocationFlags
|
||||
public PxrPosef pose;
|
||||
}
|
||||
public enum PxrSpaceLocationFlags
|
||||
{
|
||||
OrientationValid = 0x00000001,
|
||||
PositionValidBit = 0x00000002,
|
||||
OrientationTracked = 0x00000004,
|
||||
PositionTracked = 0x00000008
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSpatialAnchorUnpersistInfo
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public PxrPersistenceLocation location;
|
||||
public ulong anchorHandle;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSceneCaptureStartCompletion
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public PxrResult futureResult;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSpatialEntityComponentGetInfoBaseHeader
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public ulong entity;
|
||||
public PxrSceneComponentType componentType;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSpatialEntityComponentDataBaseHeader
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSpatialEntityGetInfo
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public ulong entity;
|
||||
public PxrSceneComponentType componentType;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSpatialEntitySemanticData
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public uint semanticCapacityInput;
|
||||
public uint semanticCountOutput;
|
||||
public IntPtr semanticLabels;//PxrSemanticLabel[]
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSpatialEntityLocationGetInfo
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public ulong entity;
|
||||
public PxrSceneComponentType componentType;
|
||||
public ulong baseSpace;
|
||||
public ulong time;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSpaceLocationData
|
||||
{
|
||||
public ulong locationFlags;
|
||||
public PxrPosef pose;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSpatialEntityLocationData
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public XrSpaceLocationData location;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSpatialEntityBoundingBox3DData
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public PxrBoxf box3D;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrBoxf
|
||||
{
|
||||
public PxrPosef center;
|
||||
public XrExtent3Df extents;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSpatialEntityBoundingBox2DData
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public PxrSceneBox2D box2D;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrSpatialEntityPolygonData
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public uint polygonCapacityInput;
|
||||
public uint polygonCountOutput;
|
||||
public IntPtr vertices; //PxrVector2f[]
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PxrTriangleMeshInfo
|
||||
{
|
||||
public XrStructureType type;
|
||||
public IntPtr next;
|
||||
public uint vertexCapacityInput;
|
||||
public uint vertexCountOutput;
|
||||
public IntPtr vertices;//PxrVector3f[];
|
||||
public uint indexCapacityInput;
|
||||
public uint indexCountOutput;
|
||||
public IntPtr indices;// uint16_t[]
|
||||
}
|
||||
public enum XrStructureType
|
||||
{
|
||||
XR_TYPE_UNKNOWN = 0,
|
||||
XR_TYPE_API_LAYER_PROPERTIES = 1,
|
||||
XR_TYPE_EXTENSION_PROPERTIES = 2,
|
||||
XR_TYPE_INSTANCE_CREATE_INFO = 3,
|
||||
XR_TYPE_SYSTEM_GET_INFO = 4,
|
||||
XR_TYPE_SYSTEM_PROPERTIES = 5,
|
||||
XR_TYPE_VIEW_LOCATE_INFO = 6,
|
||||
XR_TYPE_VIEW = 7,
|
||||
XR_TYPE_SESSION_CREATE_INFO = 8,
|
||||
XR_TYPE_SWAPCHAIN_CREATE_INFO = 9,
|
||||
XR_TYPE_SESSION_BEGIN_INFO = 10,
|
||||
XR_TYPE_VIEW_STATE = 11,
|
||||
XR_TYPE_FRAME_END_INFO = 12,
|
||||
XR_TYPE_HAPTIC_VIBRATION = 13,
|
||||
XR_TYPE_EVENT_DATA_BUFFER = 16,
|
||||
XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING = 17,
|
||||
XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED = 18,
|
||||
XR_TYPE_ACTION_STATE_BOOLEAN = 23,
|
||||
XR_TYPE_ACTION_STATE_FLOAT = 24,
|
||||
XR_TYPE_ACTION_STATE_VECTOR2F = 25,
|
||||
XR_TYPE_ACTION_STATE_POSE = 27,
|
||||
XR_TYPE_ACTION_SET_CREATE_INFO = 28,
|
||||
XR_TYPE_ACTION_CREATE_INFO = 29,
|
||||
XR_TYPE_INSTANCE_PROPERTIES = 32,
|
||||
XR_TYPE_FRAME_WAIT_INFO = 33,
|
||||
XR_TYPE_COMPOSITION_LAYER_PROJECTION = 35,
|
||||
XR_TYPE_COMPOSITION_LAYER_QUAD = 36,
|
||||
XR_TYPE_REFERENCE_SPACE_CREATE_INFO = 37,
|
||||
XR_TYPE_ACTION_SPACE_CREATE_INFO = 38,
|
||||
XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING = 40,
|
||||
XR_TYPE_VIEW_CONFIGURATION_VIEW = 41,
|
||||
XR_TYPE_SPACE_LOCATION = 42,
|
||||
XR_TYPE_SPACE_VELOCITY = 43,
|
||||
XR_TYPE_FRAME_STATE = 44,
|
||||
XR_TYPE_VIEW_CONFIGURATION_PROPERTIES = 45,
|
||||
XR_TYPE_FRAME_BEGIN_INFO = 46,
|
||||
XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW = 48,
|
||||
XR_TYPE_EVENT_DATA_EVENTS_LOST = 49,
|
||||
XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING = 51,
|
||||
XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED = 52,
|
||||
XR_TYPE_INTERACTION_PROFILE_STATE = 53,
|
||||
XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO = 55,
|
||||
XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO = 56,
|
||||
XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO = 57,
|
||||
XR_TYPE_ACTION_STATE_GET_INFO = 58,
|
||||
XR_TYPE_HAPTIC_ACTION_INFO = 59,
|
||||
XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO = 60,
|
||||
XR_TYPE_ACTIONS_SYNC_INFO = 61,
|
||||
XR_TYPE_BOUND_SOURCES_FOR_ACTION_ENUMERATE_INFO = 62,
|
||||
XR_TYPE_INPUT_SOURCE_LOCALIZED_NAME_GET_INFO = 63,
|
||||
XR_TYPE_SPACES_LOCATE_INFO = 1000471000,
|
||||
XR_TYPE_SPACE_LOCATIONS = 1000471001,
|
||||
XR_TYPE_SPACE_VELOCITIES = 1000471002,
|
||||
XR_TYPE_COMPOSITION_LAYER_CUBE_KHR = 1000006000,
|
||||
XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR = 1000008000,
|
||||
XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR = 1000010000,
|
||||
XR_TYPE_VULKAN_SWAPCHAIN_FORMAT_LIST_CREATE_INFO_KHR = 1000014000,
|
||||
XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT = 1000015000,
|
||||
XR_TYPE_COMPOSITION_LAYER_CYLINDER_KHR = 1000017000,
|
||||
XR_TYPE_COMPOSITION_LAYER_EQUIRECT_KHR = 1000018000,
|
||||
XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000019000,
|
||||
XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT = 1000019001,
|
||||
XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT = 1000019002,
|
||||
XR_TYPE_DEBUG_UTILS_LABEL_EXT = 1000019003,
|
||||
XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR = 1000023000,
|
||||
XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR = 1000023001,
|
||||
XR_TYPE_GRAPHICS_BINDING_OPENGL_XCB_KHR = 1000023002,
|
||||
XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR = 1000023003,
|
||||
XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR = 1000023004,
|
||||
XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR = 1000023005,
|
||||
XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR = 1000024001,
|
||||
XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR = 1000024002,
|
||||
XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR = 1000024003,
|
||||
XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR = 1000025000,
|
||||
XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR = 1000025001,
|
||||
XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR = 1000025002,
|
||||
XR_TYPE_GRAPHICS_BINDING_D3D11_KHR = 1000027000,
|
||||
XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR = 1000027001,
|
||||
XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR = 1000027002,
|
||||
XR_TYPE_GRAPHICS_BINDING_D3D12_KHR = 1000028000,
|
||||
XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR = 1000028001,
|
||||
XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR = 1000028002,
|
||||
XR_TYPE_SYSTEM_EYE_GAZE_INTERACTION_PROPERTIES_EXT = 1000030000,
|
||||
XR_TYPE_EYE_GAZE_SAMPLE_TIME_EXT = 1000030001,
|
||||
XR_TYPE_VISIBILITY_MASK_KHR = 1000031000,
|
||||
XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR = 1000031001,
|
||||
XR_TYPE_SESSION_CREATE_INFO_OVERLAY_EXTX = 1000033000,
|
||||
XR_TYPE_EVENT_DATA_MAIN_SESSION_VISIBILITY_CHANGED_EXTX = 1000033003,
|
||||
XR_TYPE_COMPOSITION_LAYER_COLOR_SCALE_BIAS_KHR = 1000034000,
|
||||
XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_MSFT = 1000039000,
|
||||
XR_TYPE_SPATIAL_ANCHOR_SPACE_CREATE_INFO_MSFT = 1000039001,
|
||||
XR_TYPE_COMPOSITION_LAYER_IMAGE_LAYOUT_FB = 1000040000,
|
||||
XR_TYPE_COMPOSITION_LAYER_ALPHA_BLEND_FB = 1000041001,
|
||||
XR_TYPE_VIEW_CONFIGURATION_DEPTH_RANGE_EXT = 1000046000,
|
||||
XR_TYPE_GRAPHICS_BINDING_EGL_MNDX = 1000048004,
|
||||
XR_TYPE_SPATIAL_GRAPH_NODE_SPACE_CREATE_INFO_MSFT = 1000049000,
|
||||
XR_TYPE_SPATIAL_GRAPH_STATIC_NODE_BINDING_CREATE_INFO_MSFT = 1000049001,
|
||||
XR_TYPE_SPATIAL_GRAPH_NODE_BINDING_PROPERTIES_GET_INFO_MSFT = 1000049002,
|
||||
XR_TYPE_SPATIAL_GRAPH_NODE_BINDING_PROPERTIES_MSFT = 1000049003,
|
||||
XR_TYPE_SYSTEM_HAND_TRACKING_PROPERTIES_EXT = 1000051000,
|
||||
XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT = 1000051001,
|
||||
XR_TYPE_HAND_JOINTS_LOCATE_INFO_EXT = 1000051002,
|
||||
XR_TYPE_HAND_JOINT_LOCATIONS_EXT = 1000051003,
|
||||
XR_TYPE_HAND_JOINT_VELOCITIES_EXT = 1000051004,
|
||||
XR_TYPE_SYSTEM_HAND_TRACKING_MESH_PROPERTIES_MSFT = 1000052000,
|
||||
XR_TYPE_HAND_MESH_SPACE_CREATE_INFO_MSFT = 1000052001,
|
||||
XR_TYPE_HAND_MESH_UPDATE_INFO_MSFT = 1000052002,
|
||||
XR_TYPE_HAND_MESH_MSFT = 1000052003,
|
||||
XR_TYPE_HAND_POSE_TYPE_INFO_MSFT = 1000052004,
|
||||
XR_TYPE_SECONDARY_VIEW_CONFIGURATION_SESSION_BEGIN_INFO_MSFT = 1000053000,
|
||||
XR_TYPE_SECONDARY_VIEW_CONFIGURATION_STATE_MSFT = 1000053001,
|
||||
XR_TYPE_SECONDARY_VIEW_CONFIGURATION_FRAME_STATE_MSFT = 1000053002,
|
||||
XR_TYPE_SECONDARY_VIEW_CONFIGURATION_FRAME_END_INFO_MSFT = 1000053003,
|
||||
XR_TYPE_SECONDARY_VIEW_CONFIGURATION_LAYER_INFO_MSFT = 1000053004,
|
||||
XR_TYPE_SECONDARY_VIEW_CONFIGURATION_SWAPCHAIN_CREATE_INFO_MSFT = 1000053005,
|
||||
XR_TYPE_CONTROLLER_MODEL_KEY_STATE_MSFT = 1000055000,
|
||||
XR_TYPE_CONTROLLER_MODEL_NODE_PROPERTIES_MSFT = 1000055001,
|
||||
XR_TYPE_CONTROLLER_MODEL_PROPERTIES_MSFT = 1000055002,
|
||||
XR_TYPE_CONTROLLER_MODEL_NODE_STATE_MSFT = 1000055003,
|
||||
XR_TYPE_CONTROLLER_MODEL_STATE_MSFT = 1000055004,
|
||||
XR_TYPE_VIEW_CONFIGURATION_VIEW_FOV_EPIC = 1000059000,
|
||||
XR_TYPE_HOLOGRAPHIC_WINDOW_ATTACHMENT_MSFT = 1000063000,
|
||||
XR_TYPE_COMPOSITION_LAYER_REPROJECTION_INFO_MSFT = 1000066000,
|
||||
XR_TYPE_COMPOSITION_LAYER_REPROJECTION_PLANE_OVERRIDE_MSFT = 1000066001,
|
||||
XR_TYPE_ANDROID_SURFACE_SWAPCHAIN_CREATE_INFO_FB = 1000070000,
|
||||
XR_TYPE_COMPOSITION_LAYER_SECURE_CONTENT_FB = 1000072000,
|
||||
XR_TYPE_BODY_TRACKER_CREATE_INFO_FB = 1000076001,
|
||||
XR_TYPE_BODY_JOINTS_LOCATE_INFO_FB = 1000076002,
|
||||
XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_FB = 1000076004,
|
||||
XR_TYPE_BODY_JOINT_LOCATIONS_FB = 1000076005,
|
||||
XR_TYPE_BODY_SKELETON_FB = 1000076006,
|
||||
XR_TYPE_INTERACTION_PROFILE_DPAD_BINDING_EXT = 1000078000,
|
||||
XR_TYPE_INTERACTION_PROFILE_ANALOG_THRESHOLD_VALVE = 1000079000,
|
||||
XR_TYPE_HAND_JOINTS_MOTION_RANGE_INFO_EXT = 1000080000,
|
||||
XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR = 1000089000,
|
||||
XR_TYPE_VULKAN_INSTANCE_CREATE_INFO_KHR = 1000090000,
|
||||
XR_TYPE_VULKAN_DEVICE_CREATE_INFO_KHR = 1000090001,
|
||||
XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR = 1000090003,
|
||||
XR_TYPE_COMPOSITION_LAYER_EQUIRECT2_KHR = 1000091000,
|
||||
XR_TYPE_SCENE_OBSERVER_CREATE_INFO_MSFT = 1000097000,
|
||||
XR_TYPE_SCENE_CREATE_INFO_MSFT = 1000097001,
|
||||
XR_TYPE_NEW_SCENE_COMPUTE_INFO_MSFT = 1000097002,
|
||||
XR_TYPE_VISUAL_MESH_COMPUTE_LOD_INFO_MSFT = 1000097003,
|
||||
XR_TYPE_SCENE_COMPONENTS_MSFT = 1000097004,
|
||||
XR_TYPE_SCENE_COMPONENTS_GET_INFO_MSFT = 1000097005,
|
||||
XR_TYPE_SCENE_COMPONENT_LOCATIONS_MSFT = 1000097006,
|
||||
XR_TYPE_SCENE_COMPONENTS_LOCATE_INFO_MSFT = 1000097007,
|
||||
XR_TYPE_SCENE_OBJECTS_MSFT = 1000097008,
|
||||
XR_TYPE_SCENE_COMPONENT_PARENT_FILTER_INFO_MSFT = 1000097009,
|
||||
XR_TYPE_SCENE_OBJECT_TYPES_FILTER_INFO_MSFT = 1000097010,
|
||||
XR_TYPE_SCENE_PLANES_MSFT = 1000097011,
|
||||
XR_TYPE_SCENE_PLANE_ALIGNMENT_FILTER_INFO_MSFT = 1000097012,
|
||||
XR_TYPE_SCENE_MESHES_MSFT = 1000097013,
|
||||
XR_TYPE_SCENE_MESH_BUFFERS_GET_INFO_MSFT = 1000097014,
|
||||
XR_TYPE_SCENE_MESH_BUFFERS_MSFT = 1000097015,
|
||||
XR_TYPE_SCENE_MESH_VERTEX_BUFFER_MSFT = 1000097016,
|
||||
XR_TYPE_SCENE_MESH_INDICES_UINT32_MSFT = 1000097017,
|
||||
XR_TYPE_SCENE_MESH_INDICES_UINT16_MSFT = 1000097018,
|
||||
XR_TYPE_SERIALIZED_SCENE_FRAGMENT_DATA_GET_INFO_MSFT = 1000098000,
|
||||
XR_TYPE_SCENE_DESERIALIZE_INFO_MSFT = 1000098001,
|
||||
XR_TYPE_EVENT_DATA_DISPLAY_REFRESH_RATE_CHANGED_FB = 1000101000,
|
||||
XR_TYPE_VIVE_TRACKER_PATHS_HTCX = 1000103000,
|
||||
XR_TYPE_EVENT_DATA_VIVE_TRACKER_CONNECTED_HTCX = 1000103001,
|
||||
XR_TYPE_SYSTEM_FACIAL_TRACKING_PROPERTIES_HTC = 1000104000,
|
||||
XR_TYPE_FACIAL_TRACKER_CREATE_INFO_HTC = 1000104001,
|
||||
XR_TYPE_FACIAL_EXPRESSIONS_HTC = 1000104002,
|
||||
XR_TYPE_SYSTEM_COLOR_SPACE_PROPERTIES_FB = 1000108000,
|
||||
XR_TYPE_HAND_TRACKING_MESH_FB = 1000110001,
|
||||
XR_TYPE_HAND_TRACKING_SCALE_FB = 1000110003,
|
||||
XR_TYPE_HAND_TRACKING_AIM_STATE_FB = 1000111001,
|
||||
XR_TYPE_HAND_TRACKING_CAPSULES_STATE_FB = 1000112000,
|
||||
XR_TYPE_SYSTEM_SPATIAL_ENTITY_PROPERTIES_FB = 1000113004,
|
||||
XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_FB = 1000113003,
|
||||
XR_TYPE_SPACE_COMPONENT_STATUS_SET_INFO_FB = 1000113007,
|
||||
XR_TYPE_SPACE_COMPONENT_STATUS_FB = 1000113001,
|
||||
XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB = 1000113005,
|
||||
XR_TYPE_EVENT_DATA_SPACE_SET_STATUS_COMPLETE_FB = 1000113006,
|
||||
XR_TYPE_FOVEATION_PROFILE_CREATE_INFO_FB = 1000114000,
|
||||
XR_TYPE_SWAPCHAIN_CREATE_INFO_FOVEATION_FB = 1000114001,
|
||||
XR_TYPE_SWAPCHAIN_STATE_FOVEATION_FB = 1000114002,
|
||||
XR_TYPE_FOVEATION_LEVEL_PROFILE_CREATE_INFO_FB = 1000115000,
|
||||
XR_TYPE_KEYBOARD_SPACE_CREATE_INFO_FB = 1000116009,
|
||||
XR_TYPE_KEYBOARD_TRACKING_QUERY_FB = 1000116004,
|
||||
XR_TYPE_SYSTEM_KEYBOARD_TRACKING_PROPERTIES_FB = 1000116002,
|
||||
XR_TYPE_TRIANGLE_MESH_CREATE_INFO_FB = 1000117001,
|
||||
XR_TYPE_SYSTEM_PASSTHROUGH_PROPERTIES_FB = 1000118000,
|
||||
XR_TYPE_PASSTHROUGH_CREATE_INFO_FB = 1000118001,
|
||||
XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_FB = 1000118002,
|
||||
XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_FB = 1000118003,
|
||||
XR_TYPE_GEOMETRY_INSTANCE_CREATE_INFO_FB = 1000118004,
|
||||
XR_TYPE_GEOMETRY_INSTANCE_TRANSFORM_FB = 1000118005,
|
||||
XR_TYPE_SYSTEM_PASSTHROUGH_PROPERTIES2_FB = 1000118006,
|
||||
XR_TYPE_PASSTHROUGH_STYLE_FB = 1000118020,
|
||||
XR_TYPE_PASSTHROUGH_COLOR_MAP_MONO_TO_RGBA_FB = 1000118021,
|
||||
XR_TYPE_PASSTHROUGH_COLOR_MAP_MONO_TO_MONO_FB = 1000118022,
|
||||
XR_TYPE_PASSTHROUGH_BRIGHTNESS_CONTRAST_SATURATION_FB = 1000118023,
|
||||
XR_TYPE_EVENT_DATA_PASSTHROUGH_STATE_CHANGED_FB = 1000118030,
|
||||
XR_TYPE_RENDER_MODEL_PATH_INFO_FB = 1000119000,
|
||||
XR_TYPE_RENDER_MODEL_PROPERTIES_FB = 1000119001,
|
||||
XR_TYPE_RENDER_MODEL_BUFFER_FB = 1000119002,
|
||||
XR_TYPE_RENDER_MODEL_LOAD_INFO_FB = 1000119003,
|
||||
XR_TYPE_SYSTEM_RENDER_MODEL_PROPERTIES_FB = 1000119004,
|
||||
XR_TYPE_RENDER_MODEL_CAPABILITIES_REQUEST_FB = 1000119005,
|
||||
XR_TYPE_BINDING_MODIFICATIONS_KHR = 1000120000,
|
||||
XR_TYPE_VIEW_LOCATE_FOVEATED_RENDERING_VARJO = 1000121000,
|
||||
XR_TYPE_FOVEATED_VIEW_CONFIGURATION_VIEW_VARJO = 1000121001,
|
||||
XR_TYPE_SYSTEM_FOVEATED_RENDERING_PROPERTIES_VARJO = 1000121002,
|
||||
XR_TYPE_COMPOSITION_LAYER_DEPTH_TEST_VARJO = 1000122000,
|
||||
XR_TYPE_SYSTEM_MARKER_TRACKING_PROPERTIES_VARJO = 1000124000,
|
||||
XR_TYPE_EVENT_DATA_MARKER_TRACKING_UPDATE_VARJO = 1000124001,
|
||||
XR_TYPE_MARKER_SPACE_CREATE_INFO_VARJO = 1000124002,
|
||||
XR_TYPE_FRAME_END_INFO_ML = 1000135000,
|
||||
XR_TYPE_GLOBAL_DIMMER_FRAME_END_INFO_ML = 1000136000,
|
||||
XR_TYPE_COORDINATE_SPACE_CREATE_INFO_ML = 1000137000,
|
||||
XR_TYPE_SYSTEM_MARKER_UNDERSTANDING_PROPERTIES_ML = 1000138000,
|
||||
XR_TYPE_MARKER_DETECTOR_CREATE_INFO_ML = 1000138001,
|
||||
XR_TYPE_MARKER_DETECTOR_ARUCO_INFO_ML = 1000138002,
|
||||
XR_TYPE_MARKER_DETECTOR_SIZE_INFO_ML = 1000138003,
|
||||
XR_TYPE_MARKER_DETECTOR_APRIL_TAG_INFO_ML = 1000138004,
|
||||
XR_TYPE_MARKER_DETECTOR_CUSTOM_PROFILE_INFO_ML = 1000138005,
|
||||
XR_TYPE_MARKER_DETECTOR_SNAPSHOT_INFO_ML = 1000138006,
|
||||
XR_TYPE_MARKER_DETECTOR_STATE_ML = 1000138007,
|
||||
XR_TYPE_MARKER_SPACE_CREATE_INFO_ML = 1000138008,
|
||||
XR_TYPE_LOCALIZATION_MAP_ML = 1000139000,
|
||||
XR_TYPE_EVENT_DATA_LOCALIZATION_CHANGED_ML = 1000139001,
|
||||
XR_TYPE_MAP_LOCALIZATION_REQUEST_INFO_ML = 1000139002,
|
||||
XR_TYPE_LOCALIZATION_MAP_IMPORT_INFO_ML = 1000139003,
|
||||
XR_TYPE_LOCALIZATION_ENABLE_EVENTS_INFO_ML = 1000139004,
|
||||
XR_TYPE_EVENT_DATA_HEADSET_FIT_CHANGED_ML = 1000472000,
|
||||
XR_TYPE_EVENT_DATA_EYE_CALIBRATION_CHANGED_ML = 1000472001,
|
||||
XR_TYPE_USER_CALIBRATION_ENABLE_EVENTS_INFO_ML = 1000472002,
|
||||
XR_TYPE_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT = 1000142000,
|
||||
XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT = 1000142001,
|
||||
XR_TYPE_SCENE_MARKERS_MSFT = 1000147000,
|
||||
XR_TYPE_SCENE_MARKER_TYPE_FILTER_MSFT = 1000147001,
|
||||
XR_TYPE_SCENE_MARKER_QR_CODES_MSFT = 1000147002,
|
||||
XR_TYPE_SPACE_QUERY_INFO_FB = 1000156001,
|
||||
XR_TYPE_SPACE_QUERY_RESULTS_FB = 1000156002,
|
||||
XR_TYPE_SPACE_STORAGE_LOCATION_FILTER_INFO_FB = 1000156003,
|
||||
XR_TYPE_SPACE_UUID_FILTER_INFO_FB = 1000156054,
|
||||
XR_TYPE_SPACE_COMPONENT_FILTER_INFO_FB = 1000156052,
|
||||
XR_TYPE_EVENT_DATA_SPACE_QUERY_RESULTS_AVAILABLE_FB = 1000156103,
|
||||
XR_TYPE_EVENT_DATA_SPACE_QUERY_COMPLETE_FB = 1000156104,
|
||||
XR_TYPE_SPACE_SAVE_INFO_FB = 1000158000,
|
||||
XR_TYPE_SPACE_ERASE_INFO_FB = 1000158001,
|
||||
XR_TYPE_EVENT_DATA_SPACE_SAVE_COMPLETE_FB = 1000158106,
|
||||
XR_TYPE_EVENT_DATA_SPACE_ERASE_COMPLETE_FB = 1000158107,
|
||||
XR_TYPE_SWAPCHAIN_IMAGE_FOVEATION_VULKAN_FB = 1000160000,
|
||||
XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB = 1000161000,
|
||||
XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB = 1000162000,
|
||||
XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB = 1000163000,
|
||||
XR_TYPE_SPACE_SHARE_INFO_FB = 1000169001,
|
||||
XR_TYPE_EVENT_DATA_SPACE_SHARE_COMPLETE_FB = 1000169002,
|
||||
XR_TYPE_COMPOSITION_LAYER_SPACE_WARP_INFO_FB = 1000171000,
|
||||
XR_TYPE_SYSTEM_SPACE_WARP_PROPERTIES_FB = 1000171001,
|
||||
XR_TYPE_HAPTIC_AMPLITUDE_ENVELOPE_VIBRATION_FB = 1000173001,
|
||||
XR_TYPE_SEMANTIC_LABELS_FB = 1000175000,
|
||||
XR_TYPE_ROOM_LAYOUT_FB = 1000175001,
|
||||
XR_TYPE_BOUNDARY_2D_FB = 1000175002,
|
||||
XR_TYPE_SEMANTIC_LABELS_SUPPORT_INFO_FB = 1000175010,
|
||||
XR_TYPE_DIGITAL_LENS_CONTROL_ALMALENCE = 1000196000,
|
||||
XR_TYPE_EVENT_DATA_SCENE_CAPTURE_COMPLETE_FB = 1000198001,
|
||||
XR_TYPE_SCENE_CAPTURE_REQUEST_INFO_FB = 1000198050,
|
||||
XR_TYPE_SPACE_CONTAINER_FB = 1000199000,
|
||||
XR_TYPE_FOVEATION_EYE_TRACKED_PROFILE_CREATE_INFO_META = 1000200000,
|
||||
XR_TYPE_FOVEATION_EYE_TRACKED_STATE_META = 1000200001,
|
||||
XR_TYPE_SYSTEM_FOVEATION_EYE_TRACKED_PROPERTIES_META = 1000200002,
|
||||
XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES_FB = 1000201004,
|
||||
XR_TYPE_FACE_TRACKER_CREATE_INFO_FB = 1000201005,
|
||||
XR_TYPE_FACE_EXPRESSION_INFO_FB = 1000201002,
|
||||
XR_TYPE_FACE_EXPRESSION_WEIGHTS_FB = 1000201006,
|
||||
XR_TYPE_EYE_TRACKER_CREATE_INFO_FB = 1000202001,
|
||||
XR_TYPE_EYE_GAZES_INFO_FB = 1000202002,
|
||||
XR_TYPE_EYE_GAZES_FB = 1000202003,
|
||||
XR_TYPE_SYSTEM_EYE_TRACKING_PROPERTIES_FB = 1000202004,
|
||||
XR_TYPE_PASSTHROUGH_KEYBOARD_HANDS_INTENSITY_FB = 1000203002,
|
||||
XR_TYPE_COMPOSITION_LAYER_SETTINGS_FB = 1000204000,
|
||||
XR_TYPE_HAPTIC_PCM_VIBRATION_FB = 1000209001,
|
||||
XR_TYPE_DEVICE_PCM_SAMPLE_RATE_STATE_FB = 1000209002,
|
||||
XR_TYPE_COMPOSITION_LAYER_DEPTH_TEST_FB = 1000212000,
|
||||
XR_TYPE_LOCAL_DIMMING_FRAME_END_INFO_META = 1000216000,
|
||||
XR_TYPE_PASSTHROUGH_PREFERENCES_META = 1000217000,
|
||||
XR_TYPE_SYSTEM_VIRTUAL_KEYBOARD_PROPERTIES_META = 1000219001,
|
||||
XR_TYPE_VIRTUAL_KEYBOARD_CREATE_INFO_META = 1000219002,
|
||||
XR_TYPE_VIRTUAL_KEYBOARD_SPACE_CREATE_INFO_META = 1000219003,
|
||||
XR_TYPE_VIRTUAL_KEYBOARD_LOCATION_INFO_META = 1000219004,
|
||||
XR_TYPE_VIRTUAL_KEYBOARD_MODEL_VISIBILITY_SET_INFO_META = 1000219005,
|
||||
XR_TYPE_VIRTUAL_KEYBOARD_ANIMATION_STATE_META = 1000219006,
|
||||
XR_TYPE_VIRTUAL_KEYBOARD_MODEL_ANIMATION_STATES_META = 1000219007,
|
||||
XR_TYPE_VIRTUAL_KEYBOARD_TEXTURE_DATA_META = 1000219009,
|
||||
XR_TYPE_VIRTUAL_KEYBOARD_INPUT_INFO_META = 1000219010,
|
||||
XR_TYPE_VIRTUAL_KEYBOARD_TEXT_CONTEXT_CHANGE_INFO_META = 1000219011,
|
||||
XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_COMMIT_TEXT_META = 1000219014,
|
||||
XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_BACKSPACE_META = 1000219015,
|
||||
XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_ENTER_META = 1000219016,
|
||||
XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_SHOWN_META = 1000219017,
|
||||
XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_HIDDEN_META = 1000219018,
|
||||
XR_TYPE_EXTERNAL_CAMERA_OCULUS = 1000226000,
|
||||
XR_TYPE_VULKAN_SWAPCHAIN_CREATE_INFO_META = 1000227000,
|
||||
XR_TYPE_PERFORMANCE_METRICS_STATE_META = 1000232001,
|
||||
XR_TYPE_PERFORMANCE_METRICS_COUNTER_META = 1000232002,
|
||||
XR_TYPE_SPACE_LIST_SAVE_INFO_FB = 1000238000,
|
||||
XR_TYPE_EVENT_DATA_SPACE_LIST_SAVE_COMPLETE_FB = 1000238001,
|
||||
XR_TYPE_SPACE_USER_CREATE_INFO_FB = 1000241001,
|
||||
XR_TYPE_SYSTEM_HEADSET_ID_PROPERTIES_META = 1000245000,
|
||||
XR_TYPE_RECOMMENDED_LAYER_RESOLUTION_META = 1000254000,
|
||||
XR_TYPE_RECOMMENDED_LAYER_RESOLUTION_GET_INFO_META = 1000254001,
|
||||
XR_TYPE_SYSTEM_PASSTHROUGH_COLOR_LUT_PROPERTIES_META = 1000266000,
|
||||
XR_TYPE_PASSTHROUGH_COLOR_LUT_CREATE_INFO_META = 1000266001,
|
||||
XR_TYPE_PASSTHROUGH_COLOR_LUT_UPDATE_INFO_META = 1000266002,
|
||||
XR_TYPE_PASSTHROUGH_COLOR_MAP_LUT_META = 1000266100,
|
||||
XR_TYPE_PASSTHROUGH_COLOR_MAP_INTERPOLATED_LUT_META = 1000266101,
|
||||
XR_TYPE_SPACE_TRIANGLE_MESH_GET_INFO_META = 1000269001,
|
||||
XR_TYPE_SPACE_TRIANGLE_MESH_META = 1000269002,
|
||||
XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES2_FB = 1000287013,
|
||||
XR_TYPE_FACE_TRACKER_CREATE_INFO2_FB = 1000287014,
|
||||
XR_TYPE_FACE_EXPRESSION_INFO2_FB = 1000287015,
|
||||
XR_TYPE_FACE_EXPRESSION_WEIGHTS2_FB = 1000287016,
|
||||
XR_TYPE_ENVIRONMENT_DEPTH_PROVIDER_CREATE_INFO_META = 1000291000,
|
||||
XR_TYPE_ENVIRONMENT_DEPTH_SWAPCHAIN_CREATE_INFO_META = 1000291001,
|
||||
XR_TYPE_ENVIRONMENT_DEPTH_SWAPCHAIN_STATE_META = 1000291002,
|
||||
XR_TYPE_ENVIRONMENT_DEPTH_IMAGE_ACQUIRE_INFO_META = 1000291003,
|
||||
XR_TYPE_ENVIRONMENT_DEPTH_IMAGE_VIEW_META = 1000291004,
|
||||
XR_TYPE_ENVIRONMENT_DEPTH_IMAGE_META = 1000291005,
|
||||
XR_TYPE_ENVIRONMENT_DEPTH_HAND_REMOVAL_SET_INFO_META = 1000291006,
|
||||
XR_TYPE_SYSTEM_ENVIRONMENT_DEPTH_PROPERTIES_META = 1000291007,
|
||||
XR_TYPE_PASSTHROUGH_CREATE_INFO_HTC = 1000317001,
|
||||
XR_TYPE_PASSTHROUGH_COLOR_HTC = 1000317002,
|
||||
XR_TYPE_PASSTHROUGH_MESH_TRANSFORM_INFO_HTC = 1000317003,
|
||||
XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_HTC = 1000317004,
|
||||
XR_TYPE_FOVEATION_APPLY_INFO_HTC = 1000318000,
|
||||
XR_TYPE_FOVEATION_DYNAMIC_MODE_INFO_HTC = 1000318001,
|
||||
XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC = 1000318002,
|
||||
XR_TYPE_SYSTEM_ANCHOR_PROPERTIES_HTC = 1000319000,
|
||||
XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_HTC = 1000319001,
|
||||
XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT = 1000373000,
|
||||
XR_TYPE_SYSTEM_FORCE_FEEDBACK_CURL_PROPERTIES_MNDX = 1000375000,
|
||||
XR_TYPE_FORCE_FEEDBACK_CURL_APPLY_LOCATIONS_MNDX = 1000375001,
|
||||
XR_TYPE_HAND_TRACKING_DATA_SOURCE_INFO_EXT = 1000428000,
|
||||
XR_TYPE_HAND_TRACKING_DATA_SOURCE_STATE_EXT = 1000428001,
|
||||
XR_TYPE_PLANE_DETECTOR_CREATE_INFO_EXT = 1000429001,
|
||||
XR_TYPE_PLANE_DETECTOR_BEGIN_INFO_EXT = 1000429002,
|
||||
XR_TYPE_PLANE_DETECTOR_GET_INFO_EXT = 1000429003,
|
||||
XR_TYPE_PLANE_DETECTOR_LOCATIONS_EXT = 1000429004,
|
||||
XR_TYPE_PLANE_DETECTOR_LOCATION_EXT = 1000429005,
|
||||
XR_TYPE_PLANE_DETECTOR_POLYGON_BUFFER_EXT = 1000429006,
|
||||
XR_TYPE_SYSTEM_PLANE_DETECTION_PROPERTIES_EXT = 1000429007,
|
||||
XR_TYPE_FUTURE_CANCEL_INFO_EXT = 1000469000,
|
||||
XR_TYPE_FUTURE_POLL_INFO_EXT = 1000469001,
|
||||
XR_TYPE_FUTURE_COMPLETION_EXT = 1000469002,
|
||||
XR_TYPE_FUTURE_POLL_RESULT_EXT = 1000469003,
|
||||
XR_TYPE_EVENT_DATA_USER_PRESENCE_CHANGED_EXT = 1000470000,
|
||||
XR_TYPE_SYSTEM_USER_PRESENCE_PROPERTIES_EXT = 1000470001,
|
||||
XR_TYPE_GRAPHICS_BINDING_VULKAN2_KHR = XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR,
|
||||
XR_TYPE_SWAPCHAIN_IMAGE_VULKAN2_KHR = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR,
|
||||
XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN2_KHR = XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR,
|
||||
XR_TYPE_DEVICE_PCM_SAMPLE_RATE_GET_INFO_FB = XR_TYPE_DEVICE_PCM_SAMPLE_RATE_STATE_FB,
|
||||
XR_TYPE_SPACES_LOCATE_INFO_KHR = XR_TYPE_SPACES_LOCATE_INFO,
|
||||
XR_TYPE_SPACE_LOCATIONS_KHR = XR_TYPE_SPACE_LOCATIONS,
|
||||
XR_TYPE_SPACE_VELOCITIES_KHR = XR_TYPE_SPACE_VELOCITIES,
|
||||
|
||||
//pico system
|
||||
XR_TYPE_EVENT_CONTROLLER_STATE_CHANGED_PICO = 1200006064,
|
||||
XR_TYPE_EVENT_SEETHROUGH_STATE_CHANGED = 1200006065,
|
||||
XR_TYPE_EVENT_KEY_EVENT = 1200006067,
|
||||
XR_TYPE_EVENT_MRC_STATUS_CHANGED = 1200006072,
|
||||
XR_TYPE_EVENT_LOG_LEVEL_CHANGE = 1200006086,
|
||||
|
||||
//motiontracking
|
||||
XR_TYPE_EVENT_MOTION_TRACKING_MDOE_CHANGED_EVENT_BD = 1200006403,
|
||||
XR_TYPE_EVENT_MOTION_TRACKER_KEY_EVENT_BD = 1200006404,
|
||||
XR_TYPE_EVENT_EXT_DEV_CONNECT_STATE_EVENT_BD = 1200006405,
|
||||
XR_TYPE_EVENT_EXT_DEV_BATTERY_STATE_EVENT_BD = 1200006406,
|
||||
XR_TYPE_EVENT_EXT_DEV_PASS_DATA_EVENT_BD = 1200006407,
|
||||
|
||||
//MR
|
||||
XR_TYPE_SPATIAL_ENTITY_LOCATION_GET_INFO = 1200389002,
|
||||
XR_TYPE_SPATIAL_ENTITY_LOCATION_DATA = 1200389003,
|
||||
XR_TYPE_SPATIAL_ENTITY_SEMANTIC_GET_INFO = 1200389004,
|
||||
XR_TYPE_SPATIAL_ENTITY_SEMANTIC_DATA = 1200389005,
|
||||
XR_TYPE_SPATIAL_ENTITY_BOUNDING_BOX_2D_GET_INFO = 1200389006,
|
||||
XR_TYPE_SPATIAL_ENTITY_BOUNDING_BOX_2D_DATA = 1200389007,
|
||||
XR_TYPE_SPATIAL_ENTITY_POLYGON_GET_INFO = 1200389008,
|
||||
XR_TYPE_SPATIAL_ENTITY_POLYGON_DATA = 1200389009,
|
||||
XR_TYPE_SPATIAL_ENTITY_BOUNDING_BOX_3D_GET_INFO = 1200389010,
|
||||
XR_TYPE_SPATIAL_ENTITY_BOUNDING_BOX_3D_DATA = 1200389011,
|
||||
XR_TYPE_SPATIAL_ENTITY_TRIANGLE_MESH_GET_INFO = 1200389012,
|
||||
XR_TYPE_SPATIAL_ENTITY_TRIANGLE_MESH_DATA = 1200389013,
|
||||
XR_TYPE_SENSE_DATA_PROVIDER_START_COMPLETION = 1200389014,
|
||||
XR_TYPE_EVENT_DATA_SENSE_DATA_PROVIDER_STATE_CHANGED = 1200389015,
|
||||
XR_TYPE_SENSE_DATA_FILTER_UUID = 1200389016,
|
||||
XR_TYPE_SENSE_DATA_FILTER_SEMANTIC = 1200389017,
|
||||
XR_TYPE_SENSE_DATA_QUERY_INFO = 1200389018,
|
||||
XR_TYPE_SENSE_DATA_QUERY_COMPLETION = 1200389019,
|
||||
XR_TYPE_QUERIED_SENSE_DATA_GET_INFO = 1200389020,
|
||||
XR_TYPE_EVENT_DATA_SENSE_DATA_UPDATED = 1200389023,
|
||||
XR_TYPE_SPATIAL_ENTITY_ANCHOR_RETRIEVE_INFO = 1200389025,
|
||||
XR_TYPE_SENSE_DATA_PROVIDER_CREATE_INFO_SPATIAL_ANCHOR = 1200390001,
|
||||
XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO = 1200390002,
|
||||
XR_TYPE_SPATIAL_ANCHOR_CREATE_COMPLETION = 1200390003,
|
||||
XR_TYPE_SPATIAL_ANCHOR_PERSIST_INFO = 1200390004,
|
||||
XR_TYPE_SPATIAL_ANCHOR_PERSIST_COMPLETION = 1200390005,
|
||||
XR_TYPE_SPATIAL_ANCHOR_UNPERSIST_INFO = 1200390006,
|
||||
XR_TYPE_SPATIAL_ANCHOR_UNPERSIST_COMPLETION = 1200390007,
|
||||
XR_TYPE_SCENE_CAPTURE_START_COMPLETION = 1200392002,
|
||||
XR_TYPE_SENSE_DATA_PROVIDER_CREATE_INFO_SCENE_CAPTURE = 1200392003,
|
||||
XR_TYPE_SENSE_DATA_PROVIDER_CREATE_INFO_SPATIAL_MESH = 1200393001,
|
||||
XR_TYPE_SENSE_DATA_PROVIDER_CREATE_INFO_AUTO_SCENE_CAPTURE = 1200394001,
|
||||
XR_TYPE_SENSE_DATA_PROVIDER_CREATE_INFO_SEMI_AUTO_SCENE_CAPTURE = 1200395001,
|
||||
|
||||
|
||||
XR_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
|
||||
}
|
||||
|
||||
public enum XrDeviceEventType
|
||||
{
|
||||
XR_DEVICE_CONNECTCHANGED = 0,
|
||||
XR_DEVICE_MAIN_CHANGED = 1,
|
||||
XR_DEVICE_VERSION = 2,
|
||||
XR_DEVICE_SN = 3,
|
||||
XR_DEVICE_BIND_STATUS = 4,
|
||||
XR_STATION_STATUS = 5,
|
||||
XR_DEVICE_IOBUSY = 6,
|
||||
XR_DEVICE_OTASTAUS = 7,
|
||||
XR_DEVICE_ID = 8,
|
||||
XR_DEVICE_OTASATAION_PROGRESS = 9,
|
||||
XR_DEVICE_OTASATAION_CODE = 10,
|
||||
XR_DEVICE_OTACONTROLLER_PROGRESS = 11,
|
||||
XR_DEVICE_OTACONTROLLER_CODE = 12,
|
||||
XR_DEVICE_OTA_SUCCESS = 13,
|
||||
XR_DEVICE_BLEMAC = 14,
|
||||
XR_DEVICE_HANDNESS_CHANGED = 15,
|
||||
XR_DEVICE_CHANNEL = 16,
|
||||
XR_DEVICE_LOSSRATE = 17,
|
||||
XR_DEVICE_THREAD_STARTED = 18,
|
||||
XR_DEVICE_MENUPRESSED_STATE =19,
|
||||
XR_DEVICE_HANDTRACKING_SETTING = 20,
|
||||
XR_DEVICE_INPUTDEVICE_CHANGED = 21,
|
||||
XR_DEVICE_SYSTEMGESTURE_STATE = 22,
|
||||
XR_DEVICE_FITNESSBAND_STATE = 23,
|
||||
XR_DEVICE_FITNESSBAND_BATTERY = 24,
|
||||
XR_DEVICE_BODYTRACKING_STATE_ERROR_CODE = 25,
|
||||
XR_DEVICE_BODYTRACKING_ACTION = 26
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4027bcf9e134f978996e95208fbfdf1
|
||||
timeCreated: 1721811878
|
Reference in New Issue
Block a user