上传修改

This commit is contained in:
Sora丶kong
2026-03-03 10:57:00 +08:00
parent fb16c80a59
commit 82130f6146
2894 changed files with 229 additions and 856196 deletions

View File

@@ -1,10 +0,0 @@
fileFormatVersion: 2
guid: 0e81046a8890fab4e90491fbd3317812
folderAsset: yes
timeCreated: 1604287454
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,97 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll information contained herein is, and remains the property of
PICO Technology Co., Ltd. The intellectual and technical concepts
contained herein are proprietary to PICO Technology Co., Ltd. and may be
covered by patents, patents in process, and are protected by trade secret or
copyright law. Dissemination of this information or reproduction of this
material is strictly forbidden unless prior written permission is obtained from
PICO Technology Co., Ltd.
*******************************************************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;
namespace Unity.XR.PXR
{
public class PXR_ControllerAnimator : MonoBehaviour
{
private Animator controllerAnimator;
public Transform primary2DAxisTran;
public Transform gripTran;
public Transform triggerTran;
public PXR_Input.Controller controller;
private InputDevice currentController;
private Vector2 axis2D = Vector2.zero;
private bool primaryButton;
private bool secondaryButton;
private bool menuButton;
private float grip;
private float trigger;
private Vector3 originalGrip;
private Vector3 originalTrigger;
private Vector3 originalJoystick;
public const string primary = "IsPrimaryDown";
public const string secondary = "IsSecondaryDown";
public const string media = "IsMediaDown";
public const string menu = "IsMenuDown";
void Start()
{
controllerAnimator = GetComponent<Animator>();
currentController = InputDevices.GetDeviceAtXRNode(controller == PXR_Input.Controller.LeftController
? XRNode.LeftHand
: XRNode.RightHand);
originalGrip = gripTran.localEulerAngles;
originalJoystick = primary2DAxisTran.localEulerAngles;
originalTrigger = triggerTran.localEulerAngles;
}
void Update()
{
currentController.TryGetFeatureValue(CommonUsages.primary2DAxis, out axis2D);
currentController.TryGetFeatureValue(CommonUsages.grip, out grip);
currentController.TryGetFeatureValue(CommonUsages.trigger, out trigger);
currentController.TryGetFeatureValue(CommonUsages.primaryButton, out primaryButton);
currentController.TryGetFeatureValue(CommonUsages.secondaryButton, out secondaryButton);
currentController.TryGetFeatureValue(CommonUsages.menuButton, out menuButton);
float x = Mathf.Clamp(axis2D.x * 10f, -10f, 10f);
float z = Mathf.Clamp(axis2D.y * 10f, -10f, 10f);
if (primary2DAxisTran != null)
{
if (controller == PXR_Input.Controller.LeftController)
{
primary2DAxisTran.localEulerAngles = new Vector3(-z, 0, x) + originalJoystick;
}
else
{
primary2DAxisTran.localEulerAngles = new Vector3(-z, 0, -x) + originalJoystick;
}
}
trigger *= -15;
if (triggerTran != null)
triggerTran.localEulerAngles = new Vector3(trigger, 0f, 0f) + originalTrigger;
grip *= 12;
if (gripTran != null)
gripTran.localEulerAngles = new Vector3(0f, grip, 0f) + originalGrip;
if (controllerAnimator != null)
{
controllerAnimator.SetBool(primary, primaryButton);
controllerAnimator.SetBool(secondary, secondaryButton);
if (controller == PXR_Input.Controller.LeftController)
controllerAnimator.SetBool(menu, menuButton);
else if(controller == PXR_Input.Controller.RightController)
controllerAnimator.SetBool(media, menuButton);
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 0551a3e12ecf0614fa83e84a93d87bb5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,78 +0,0 @@
/*******************************************************************************
Copyright ? 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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 UnityEngine;
using UnityEngine.XR;
namespace Unity.XR.PXR
{
public class PXR_ControllerG3Animator : MonoBehaviour
{
public Transform triggerTran;
public Transform menuTran;
public Transform touchPadTran;
public PXR_ControllerPower controllerPower;
private bool primaryAxisState = false;
private bool menuButtonState;
private float trigger;
private Vector3 menu;
private Vector3 originTrigger;
private Vector3 touchPadPos;
private InputDevice currentController;
private int handness;
void Start()
{
PXR_Input.GetControllerHandness(ref handness);
XRNode hand = handness == 0? XRNode.RightHand : XRNode.LeftHand;
if (controllerPower != null)
{
controllerPower.hand = handness == 0 ? PXR_Input.Controller.RightController : PXR_Input.Controller.LeftController;
}
currentController = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
menu = menuTran.localPosition;
originTrigger = triggerTran.localEulerAngles;
touchPadPos = touchPadTran.localPosition;
}
void Update()
{
currentController.TryGetFeatureValue(CommonUsages.primary2DAxisClick, out primaryAxisState);
currentController.TryGetFeatureValue(CommonUsages.menuButton, out menuButtonState);
currentController.TryGetFeatureValue(CommonUsages.trigger, out trigger);
if (triggerTran != null)
{
trigger *= -9.0f;
triggerTran.localEulerAngles = new Vector3(0f, 0f, Mathf.Clamp(trigger, -9f, 0f)) + originTrigger;
}
if (touchPadTran != null)
{
if (primaryAxisState)
touchPadTran.localPosition = touchPadPos + new Vector3(0f, -0.0005f, 0f);
else
touchPadTran.localPosition = touchPadPos;
}
if (menuButtonState)
menuTran.localPosition = new Vector3(0f, -0.00021f, 0f) + menu;
else
menuTran.localPosition = menu;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 13f010f629084af4fb20825efaab5fdd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,330 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll information contained herein is, and remains the property of
PICO Technology Co., Ltd. The intellectual and technical concepts
contained herein are proprietary to PICO Technology Co., Ltd. and may be
covered by patents, patents in process, and are protected by trade secret or
copyright law. Dissemination of this information or reproduction of this
material is strictly forbidden unless prior written permission is obtained from
PICO Technology Co., Ltd.
*******************************************************************************/
using System.Collections;
using System.IO;
using LitJson;
using UnityEngine;
namespace Unity.XR.PXR
{
public class PXR_ControllerLoader : MonoBehaviour
{
[SerializeField]
private PXR_Input.Controller hand;
public GameObject neo3L;
public GameObject neo3R;
public GameObject PICO_4L;
public GameObject PICO_4R;
public GameObject G3;
public GameObject PICO_4U_L;
public GameObject PICO_4U_R;
public Material legacyMaterial;
private Texture2D modelTexture2D;
private int controllerType = -1;
private JsonData curControllerData = null;
private int systemOrLocal = 0;
private bool loadModelSuccess = false;
private string modelName = "";
private string texFormat = "";
private string prePath = "";
private string modelFilePath = "/system/media/pxrRes/controller/";
private bool leftControllerState = false;
private bool rightControllerState = false;
private enum ControllerSimulationType
{
None,
Neo3,
PICO4,
G3,
PICO4U
}
#if UNITY_EDITOR
[SerializeField]
private ControllerSimulationType controllerSimulation = ControllerSimulationType.None;
#endif
public PXR_ControllerLoader(PXR_Input.Controller controller)
{
hand = controller;
}
void Awake()
{
#if UNITY_EDITOR
switch (controllerSimulation)
{
case ControllerSimulationType.Neo3:
{
Instantiate(hand == PXR_Input.Controller.LeftController ? neo3L : neo3R, transform, false);
break;
}
case ControllerSimulationType.PICO4:
{
Instantiate(hand == PXR_Input.Controller.LeftController ? PICO_4L : PICO_4R, transform, false);
break;
}
case ControllerSimulationType.G3:
{
Instantiate(G3, transform, false);
break;
}
case ControllerSimulationType.PICO4U:
{
Instantiate(hand == PXR_Input.Controller.LeftController ? PICO_4U_L : PICO_4U_R, transform, false);
break;
}
}
#endif
}
void Start()
{
controllerType = PXR_Plugin.Controller.UPxr_GetControllerType();
#if UNITY_ANDROID && !UNITY_EDITOR
LoadResFromJson();
#endif
leftControllerState = PXR_Input.IsControllerConnected(PXR_Input.Controller.LeftController);
rightControllerState = PXR_Input.IsControllerConnected(PXR_Input.Controller.RightController);
if (hand == PXR_Input.Controller.LeftController)
RefreshController(PXR_Input.Controller.LeftController);
if (hand == PXR_Input.Controller.RightController)
RefreshController(PXR_Input.Controller.RightController);
}
void Update()
{
if (hand == PXR_Input.Controller.LeftController)
{
if (PXR_Input.IsControllerConnected(PXR_Input.Controller.LeftController))
{
if (!leftControllerState)
{
controllerType = PXR_Plugin.Controller.UPxr_GetControllerType();
RefreshController(PXR_Input.Controller.LeftController);
leftControllerState = true;
}
}
else
{
if (leftControllerState)
{
DestroyLocalController();
leftControllerState = false;
}
}
}
if (hand == PXR_Input.Controller.RightController)
{
if (PXR_Input.IsControllerConnected(PXR_Input.Controller.RightController))
{
if (!rightControllerState)
{
controllerType = PXR_Plugin.Controller.UPxr_GetControllerType();
RefreshController(PXR_Input.Controller.RightController);
rightControllerState = true;
}
}
else
{
if (rightControllerState)
{
DestroyLocalController();
rightControllerState = false;
}
}
}
}
private void RefreshController(PXR_Input.Controller hand)
{
if (PXR_Input.IsControllerConnected(hand))
{
if (systemOrLocal == 0)
{
LoadControllerFromPrefab(hand);
if (!loadModelSuccess)
{
LoadControllerFromSystem((int)hand);
}
}
else
{
var isControllerExist = false;
foreach (Transform t in transform)
{
if (t.name == modelName)
{
isControllerExist = true;
}
}
if (!isControllerExist)
{
LoadControllerFromSystem((int)hand);
if (!loadModelSuccess)
{
LoadControllerFromPrefab(hand);
}
}
else
{
var currentController = transform.Find(modelName);
currentController.gameObject.SetActive(true);
}
}
}
}
private void LoadResFromJson()
{
string json = PXR_Plugin.System.UPxr_GetObjectOrArray("config.controller", (int)ResUtilsType.TypeObjectArray);
if (json != null)
{
JsonData jdata = JsonMapper.ToObject(json);
if (controllerType > 0)
{
if (jdata.Count >= controllerType)
{
curControllerData = jdata[controllerType - 1];
if (curControllerData != null)
{
modelFilePath = (string)curControllerData["base_path"];
modelName = (string)curControllerData["model_name"] + "_sys";
}
}
}
}
else
{
Debug.LogError("PXRLog LoadJsonFromSystem Error");
}
}
private void DestroyLocalController()
{
foreach (Transform t in transform)
{
Destroy(modelTexture2D);
Destroy(t.gameObject);
Resources.UnloadUnusedAssets();
loadModelSuccess = false;
}
}
private void LoadControllerFromPrefab(PXR_Input.Controller hand)
{
switch (controllerType)
{
case 5:
Instantiate(hand == PXR_Input.Controller.LeftController ? neo3L : neo3R, transform, false);
loadModelSuccess = true;
break;
case 6:
Instantiate(hand == PXR_Input.Controller.LeftController ? PICO_4L : PICO_4R, transform, false);
loadModelSuccess = true;
break;
case 7:
Instantiate(G3, transform, false);
loadModelSuccess = true;
break;
case 8:
Instantiate(hand == PXR_Input.Controller.LeftController ? PICO_4U_L : PICO_4U_R, transform, false);
loadModelSuccess = true;
break;
default:
loadModelSuccess = false;
break;
}
}
private void LoadControllerFromSystem(int id)
{
var sysControllerName = controllerType.ToString() + id.ToString() + ".obj";
var fullFilePath = modelFilePath + sysControllerName;
if (!File.Exists(fullFilePath))
{
Debug.Log("PXRLog Load Obj From Prefab");
}
else
{
GameObject go = new GameObject
{
name = modelName
};
MeshFilter meshFilter = go.AddComponent<MeshFilter>();
meshFilter.mesh = PXR_ObjImporter.Instance.ImportFile(fullFilePath);
go.transform.SetParent(transform);
go.transform.localPosition = Vector3.zero;
MeshRenderer meshRenderer = go.AddComponent<MeshRenderer>();
meshRenderer.material = legacyMaterial;
LoadTexture(meshRenderer, controllerType.ToString() + id.ToString(), false);
go.transform.localRotation = Quaternion.Euler(new Vector3(0, 180, 0));
go.transform.localScale = new Vector3(-0.01f, 0.01f, 0.01f);
loadModelSuccess = true;
}
}
private void LoadTexture(MeshRenderer mr,string controllerName, bool fromRes)
{
if (fromRes)
{
texFormat = "";
prePath = controllerName;
}
else
{
texFormat = "." + (string)curControllerData["tex_format"];
prePath = modelFilePath + controllerName;
}
var texturePath = prePath + "_idle" + texFormat;
mr.material.SetTexture("_MainTex", LoadOneTexture(texturePath, fromRes));
}
private Texture2D LoadOneTexture(string filepath, bool fromRes)
{
if (fromRes)
{
return Resources.Load<Texture2D>(filepath);
}
else
{
int tW = (int)curControllerData["tex_width"];
int tH = (int)curControllerData["tex_height"];
modelTexture2D = new Texture2D(tW, tH);
modelTexture2D.LoadImage(ReadPNG(filepath));
return modelTexture2D;
}
}
private byte[] ReadPNG(string path)
{
FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
fileStream.Seek(0, SeekOrigin.Begin);
byte[] binary = new byte[fileStream.Length];
fileStream.Read(binary, 0, (int)fileStream.Length);
fileStream.Close();
fileStream.Dispose();
return binary;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: c1ba2bcdb414e3b47aca41fdc1a87e64
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,117 +0,0 @@
/*******************************************************************************
Copyright ? 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll information contained herein is, and remains the property of
PICO Technology Co., Ltd. The intellectual and technical concepts
contained herein are proprietary to PICO Technology Co., Ltd. and may be
covered by patents, patents in process, and are protected by trade secret or
copyright law. Dissemination of this information or reproduction of this
material is strictly forbidden unless prior written permission is obtained from
PICO Technology Co., Ltd.
*******************************************************************************/
using System.Collections;
using System.Collections.Generic;
using Unity.XR.PXR;
using UnityEngine;
using UnityEngine.XR;
public class PXR_ControllerPower : MonoBehaviour
{
[SerializeField]
private Texture power1;
[SerializeField]
private Texture power2;
[SerializeField]
private Texture power3;
[SerializeField]
private Texture power4;
[SerializeField]
private Texture power5;
private Material powerMaterial;
private float interval = 2f;
public PXR_Input.Controller hand;
// Start is called before the first frame update
void Start()
{
if (GetComponent<MeshRenderer>() != null)
{
powerMaterial = GetComponent<MeshRenderer>().material;
}
else
{
powerMaterial = GetComponent<SkinnedMeshRenderer>().material;
}
}
// Update is called once per frame
void Update()
{
interval -= Time.deltaTime;
if (interval > 0) return;
interval = 2f;
var curBattery = 0f;
switch (hand)
{
case PXR_Input.Controller.LeftController:
{
InputDevices.GetDeviceAtXRNode(XRNode.LeftHand).TryGetFeatureValue(CommonUsages.batteryLevel, out curBattery);
}
break;
case PXR_Input.Controller.RightController:
{
InputDevices.GetDeviceAtXRNode(XRNode.RightHand).TryGetFeatureValue(CommonUsages.batteryLevel, out curBattery);
}
break;
}
switch ((int)curBattery)
{
case 1:
{
powerMaterial.SetTexture("_MainTex", power1);
powerMaterial.SetTexture("_EmissionMap", power1);
}
break;
case 2:
{
powerMaterial.SetTexture("_MainTex", power2);
powerMaterial.SetTexture("_EmissionMap", power2);
}
break;
case 3:
{
powerMaterial.SetTexture("_MainTex", power3);
powerMaterial.SetTexture("_EmissionMap", power3);
}
break;
case 4:
{
powerMaterial.SetTexture("_MainTex", power4);
powerMaterial.SetTexture("_EmissionMap", power4);
}
break;
case 5:
{
powerMaterial.SetTexture("_MainTex", power5);
powerMaterial.SetTexture("_EmissionMap", power5);
}
break;
default:
{
powerMaterial.SetTexture("_MainTex", power1);
powerMaterial.SetTexture("_EmissionMap", power1);
}
break;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 7cfc8380945cdad43ae2cacaadf47013
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,307 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;
using Unity.XR.PXR.Input;
namespace Unity.XR.PXR
{
public class PXR_ControllerWithHandAnimator : MonoBehaviour
{
public PXR_Input.Controller controller;
private Animator mAnimator;
private InputDevice mInputDevice;
private PXR_Controller mXRController;
private readonly float animation_time = 0.05f;
private float per_animation_step = 0.1f;
//trigger;
private readonly string trigger_Touch_LayerName = "trigger_touch";
private int trigger_Touch_LayerIndex;
private readonly string trigger_Value_LayerName = "trigger_press";
private int trigger_Value_LayerIndex;
private bool trigger_Touch;
private float trigger_Value;
private float trigger_Touch_Weight = 0f;
// A/X;
private readonly string X_A_Touch_LayerName = "X_A_touch";
private int X_A_Touch_LayerIndex;
private readonly string X_A_Press_LayerName = "X_A_press";
private int X_A_Press_LayerIndex;
private bool X_A_Press;
private bool X_A_Touch;
private float X_A_Touch_Weight = 0f;
// B/Y;
private readonly string Y_B_Touch_LayerName = "Y_B_touch";
private int Y_B_Touch_LayerIndex;
private readonly string Y_B_Press_LayerName = "Y_B_press";
private int Y_B_Press_LayerIndex;
private bool Y_B_Press;
private bool Y_B_Touch;
private float Y_B_Touch_Weight = 0f;
//Y/B or X/A
private readonly string X_A_Y_B_Press_LayerName = "X_A_Y_B_press";
private int X_A_Y_B_Press_LayerIndex;
//Y/B or X/A
private readonly string X_A_Y_B_Touch_LayerName = "X_A_Y_B_touch";
private int X_A_Y_B_Touch_LayerIndex;
private float X_A_Y_B_Touch_Weight = 0f;
//grip;
private readonly string grip_Value_LayerName = "grip_press";
private int grip_Value_LayerIndex;
private float grip_Value;
//rocker
private readonly string primary2DAxis_Touch_LayerName = "axis_touch";
private int primary2DAxis_Touch_LayerIndex;
private readonly string primary2DAxis_Vertical = "axis_vertical";
private int primary2DAxis_Vertical_Index;
private readonly string primary2DAxis_Horizontal = "axis_horizontal";
private int primary2DAxis_Horizontal_Index;
private Vector2 primary2DAxisVec2;
private bool primary2DAxis_Touch;
private float primary2DAxis_Touch_Weight = 0f;
//print screen
private readonly string menu_Press_LayerName = "thumbMenu";
private int menu_Press_LayerIndex;
private bool menu_Press;
private float menu_Press_Weight;
//home
private readonly string pico_Press_LayerName = "thumbPico";
private int pico_Press_LayerIndex;
private bool pico_Press;
private float pico_Press_Weight;
//thumb rest
private readonly string thumbstick_Touch_LayerName = "thumbstick_touch";
private int thumbstick_Touch_LayerIndex;
private bool thumbstick_Touch;
private float thumbstick_Touch_Weight;
// Start is called before the first frame update
void Start()
{
per_animation_step = 1.0f / animation_time;
mAnimator = GetComponent<Animator>();
mInputDevice = InputDevices.GetDeviceAtXRNode(controller == PXR_Input.Controller.LeftController ? XRNode.LeftHand : XRNode.RightHand);
mXRController = (controller == PXR_Input.Controller.LeftController ? PXR_Controller.leftHand : PXR_Controller.rightHand) as PXR_Controller;
if (mAnimator != null)
{
trigger_Touch_LayerIndex = mAnimator.GetLayerIndex(trigger_Touch_LayerName);
trigger_Value_LayerIndex = mAnimator.GetLayerIndex(trigger_Value_LayerName);
grip_Value_LayerIndex = mAnimator.GetLayerIndex(grip_Value_LayerName);
X_A_Touch_LayerIndex = mAnimator.GetLayerIndex(X_A_Touch_LayerName);
X_A_Press_LayerIndex = mAnimator.GetLayerIndex(X_A_Press_LayerName);
Y_B_Touch_LayerIndex = mAnimator.GetLayerIndex(Y_B_Touch_LayerName);
Y_B_Press_LayerIndex = mAnimator.GetLayerIndex(Y_B_Press_LayerName);
X_A_Y_B_Press_LayerIndex = mAnimator.GetLayerIndex(X_A_Y_B_Press_LayerName);
X_A_Y_B_Touch_LayerIndex = mAnimator.GetLayerIndex(X_A_Y_B_Touch_LayerName);
primary2DAxis_Touch_LayerIndex = mAnimator.GetLayerIndex(primary2DAxis_Touch_LayerName);
thumbstick_Touch_LayerIndex = mAnimator.GetLayerIndex(thumbstick_Touch_LayerName);
primary2DAxis_Vertical_Index = Animator.StringToHash(primary2DAxis_Vertical);
primary2DAxis_Horizontal_Index = Animator.StringToHash(primary2DAxis_Horizontal);
}
else
{
Debug.Log("Animator is null");
}
}
// Update is called once per frame
void Update()
{
mInputDevice.TryGetFeatureValue(CommonUsages.primaryButton, out X_A_Press);
mInputDevice.TryGetFeatureValue(CommonUsages.primaryTouch, out X_A_Touch);
mInputDevice.TryGetFeatureValue(CommonUsages.secondaryButton, out Y_B_Press);
mInputDevice.TryGetFeatureValue(CommonUsages.secondaryTouch, out Y_B_Touch);
mInputDevice.TryGetFeatureValue(CommonUsages.trigger, out trigger_Value);
mInputDevice.TryGetFeatureValue(PXR_Usages.triggerTouch, out trigger_Touch);
mInputDevice.TryGetFeatureValue(CommonUsages.grip, out grip_Value);
mInputDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out primary2DAxisVec2);
mInputDevice.TryGetFeatureValue(CommonUsages.primary2DAxisTouch, out primary2DAxis_Touch);
if (!primary2DAxis_Touch)
{
if (primary2DAxisVec2 != Vector2.zero)
primary2DAxis_Touch = true;
}
mInputDevice.TryGetFeatureValue(CommonUsages.menuButton, out menu_Press);
if (Y_B_Touch && primary2DAxisVec2 == Vector2.zero)
{
if (Y_B_Press)
{
Y_B_Touch_Weight = 1.0f;
mAnimator.SetLayerWeight(Y_B_Touch_LayerIndex, Y_B_Touch_Weight);
mAnimator.SetLayerWeight(Y_B_Press_LayerIndex, 1.0f);
mAnimator.SetLayerWeight(X_A_Y_B_Press_LayerIndex, X_A_Press ? 1.0f : 0.0f);
}
else
{
if (X_A_Touch)
{
if (X_A_Press)
{
X_A_Touch_Weight = 1.0f;
mAnimator.SetLayerWeight(X_A_Touch_LayerIndex, X_A_Touch_Weight);
}
else
{
if (X_A_Y_B_Touch_Weight < 0.9999f)
{
X_A_Y_B_Touch_Weight = Mathf.Min(mAnimator.GetLayerWeight(X_A_Y_B_Touch_LayerIndex) + Time.deltaTime * per_animation_step, 1.0f);
mAnimator.SetLayerWeight(X_A_Y_B_Touch_LayerIndex, X_A_Y_B_Touch_Weight);
}
}
mAnimator.SetLayerWeight(X_A_Press_LayerIndex, X_A_Press ? 1.0f : 0f);
}
else
{
if (Y_B_Touch_Weight < 0.9999f)
{
Y_B_Touch_Weight = Mathf.Min(mAnimator.GetLayerWeight(Y_B_Touch_LayerIndex) + Time.deltaTime * per_animation_step, 1.0f);
mAnimator.SetLayerWeight(Y_B_Touch_LayerIndex, Y_B_Touch_Weight);
}
if (X_A_Y_B_Touch_Weight > 0.0001f)
{
X_A_Y_B_Touch_Weight = Mathf.Max(mAnimator.GetLayerWeight(X_A_Y_B_Touch_LayerIndex) - Time.deltaTime * per_animation_step, 0.0f);
mAnimator.SetLayerWeight(X_A_Y_B_Touch_LayerIndex, X_A_Y_B_Touch_Weight);
}
if (X_A_Touch_Weight > 0.0001f)
{
X_A_Touch_Weight = Mathf.Max(mAnimator.GetLayerWeight(X_A_Touch_LayerIndex) - Time.deltaTime * per_animation_step, 0.0f);
mAnimator.SetLayerWeight(X_A_Touch_LayerIndex, X_A_Touch_Weight);
}
}
mAnimator.SetLayerWeight(Y_B_Press_LayerIndex, 0.0f);
mAnimator.SetLayerWeight(X_A_Y_B_Press_LayerIndex, 0.0f);
}
}
else
{
if (Y_B_Touch_Weight > 0.0001f)
{
Y_B_Touch_Weight = Mathf.Max(mAnimator.GetLayerWeight(Y_B_Touch_LayerIndex) - Time.deltaTime * per_animation_step, 0.0f);
mAnimator.SetLayerWeight(Y_B_Touch_LayerIndex, Y_B_Touch_Weight);
mAnimator.SetLayerWeight(Y_B_Press_LayerIndex, 0.0f);
mAnimator.SetLayerWeight(X_A_Y_B_Press_LayerIndex, 0.0f);
}
if (X_A_Y_B_Touch_Weight > 0.0001f)
{
X_A_Y_B_Touch_Weight = Mathf.Max(mAnimator.GetLayerWeight(X_A_Y_B_Touch_LayerIndex) - Time.deltaTime * per_animation_step, 0.0f);
mAnimator.SetLayerWeight(X_A_Y_B_Touch_LayerIndex, X_A_Y_B_Touch_Weight);
mAnimator.SetLayerWeight(Y_B_Press_LayerIndex, 0.0f);
mAnimator.SetLayerWeight(X_A_Y_B_Press_LayerIndex, 0.0f);
}
if (X_A_Touch && primary2DAxisVec2 == Vector2.zero)
{
if (X_A_Press)
{
X_A_Touch_Weight = 1.0f;
mAnimator.SetLayerWeight(X_A_Touch_LayerIndex, X_A_Touch_Weight);
}
else
{
if (X_A_Touch_Weight < 0.9999f)
{
X_A_Touch_Weight = Mathf.Min(mAnimator.GetLayerWeight(X_A_Touch_LayerIndex) + Time.deltaTime * per_animation_step, 1.0f);
mAnimator.SetLayerWeight(X_A_Touch_LayerIndex, X_A_Touch_Weight);
}
}
mAnimator.SetLayerWeight(X_A_Press_LayerIndex, X_A_Press ? 1.0f : 0f);
mAnimator.SetFloat(primary2DAxis_Vertical_Index, 0f);
mAnimator.SetFloat(primary2DAxis_Horizontal_Index, 0f);
}
else
{
if (X_A_Touch_Weight > 0.0001f)
{
X_A_Touch_Weight = Mathf.Max(mAnimator.GetLayerWeight(X_A_Touch_LayerIndex) - Time.deltaTime * per_animation_step, 0.0f);
mAnimator.SetLayerWeight(X_A_Touch_LayerIndex, X_A_Touch_Weight);
mAnimator.SetLayerWeight(X_A_Press_LayerIndex, 0f);
}
if (primary2DAxis_Touch)
{
if (primary2DAxis_Touch_Weight < 0.9999f)
{
primary2DAxis_Touch_Weight = Mathf.Min(mAnimator.GetLayerWeight(primary2DAxis_Touch_LayerIndex) + Time.deltaTime * per_animation_step, 1.0f);
mAnimator.SetLayerWeight(primary2DAxis_Touch_LayerIndex, primary2DAxis_Touch_Weight);
}
mAnimator.SetFloat(primary2DAxis_Vertical_Index, primary2DAxisVec2.y);
mAnimator.SetFloat(primary2DAxis_Horizontal_Index, primary2DAxisVec2.x);
}
else
{
if (primary2DAxis_Touch_Weight > 0.0001f)
{
primary2DAxis_Touch_Weight = Mathf.Max(mAnimator.GetLayerWeight(primary2DAxis_Touch_LayerIndex) - Time.deltaTime * per_animation_step, 0.0f);
mAnimator.SetLayerWeight(primary2DAxis_Touch_LayerIndex, primary2DAxis_Touch_Weight);
mAnimator.SetFloat(primary2DAxis_Vertical_Index, 0f);
mAnimator.SetFloat(primary2DAxis_Horizontal_Index, 0f);
}
if (thumbstick_Touch)
{
if (thumbstick_Touch_Weight < 0.9999f)
{
thumbstick_Touch_Weight = Mathf.Min(mAnimator.GetLayerWeight(thumbstick_Touch_LayerIndex) + Time.deltaTime * per_animation_step, 1.0f);
mAnimator.SetLayerWeight(thumbstick_Touch_LayerIndex, thumbstick_Touch_Weight);
}
}
else
{
if (thumbstick_Touch_Weight > 0.0001f)
{
thumbstick_Touch_Weight = Mathf.Max(mAnimator.GetLayerWeight(thumbstick_Touch_LayerIndex) - Time.deltaTime * per_animation_step, 0.0f);
mAnimator.SetLayerWeight(thumbstick_Touch_LayerIndex, thumbstick_Touch_Weight);
}
}
}
}
}
if (trigger_Touch)
{
if (trigger_Touch_Weight < 0.9999f)
{
trigger_Touch_Weight = Mathf.Min(mAnimator.GetLayerWeight(trigger_Touch_LayerIndex) + Time.deltaTime * per_animation_step, 1.0f);
mAnimator.SetLayerWeight(trigger_Touch_LayerIndex, trigger_Touch_Weight);
}
mAnimator.SetLayerWeight(trigger_Value_LayerIndex, trigger_Value);
}
else
{
if (trigger_Touch_Weight > 0.0001f)
{
trigger_Touch_Weight = Mathf.Max(mAnimator.GetLayerWeight(trigger_Touch_LayerIndex) - Time.deltaTime * per_animation_step, 0.0f);
mAnimator.SetLayerWeight(trigger_Touch_LayerIndex, trigger_Touch_Weight);
}
}
mAnimator.SetLayerWeight(grip_Value_LayerIndex, grip_Value);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: ad904341cd701b544911a03d77412e1d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,10 +0,0 @@
fileFormatVersion: 2
guid: ba33a065da87db540a48c95b1795a99f
folderAsset: yes
timeCreated: 1593498988
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,181 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll information contained herein is, and remains the property of
PICO Technology Co., Ltd. The intellectual and technical concepts
contained herein are proprietary to PICO Technology Co., Ltd. and may be
covered by patents, patents in process, and are protected by trade secret or
copyright law. Dissemination of this information or reproduction of this
material is strictly forbidden unless prior written permission is obtained from
PICO Technology Co., Ltd.
*******************************************************************************/
using System;
using UnityEngine;
namespace Unity.XR.PXR
{
public class PXR_Boundary
{
/// <summary>
/// Sets the boundary as visible or invisible. Note: The setting defined in this function can be overridden by system settings (e.g., proximity trigger) or user settings (e.g., disabling the boundary system).
/// </summary>
/// <param name="value">Whether to set the boundary as visible or invisble:
/// - `true`: visible
/// - `false`: invisible</param>
public static void SetVisible(bool value)
{
PXR_Plugin.Boundary.UPxr_SetBoundaryVisiable(value);
}
/// <summary>
/// Gets whether the boundary is visible.
/// </summary>
/// <returns>
/// - `true`: visible
/// - `false`: invisible</returns>
public static bool GetVisible()
{
return PXR_Plugin.Boundary.UPxr_GetBoundaryVisiable();
}
/// <summary>
/// Checks whether the boundary is configured. Boundary-related functions are available for use only if the boundary is configured.
/// </summary>
/// <returns>
/// - `true`: configured
/// - `false`: not configured</returns>
public static bool GetConfigured()
{
return PXR_Plugin.Boundary.UPxr_GetBoundaryConfigured();
}
/// <summary>
/// Checks whether the boundary is enabled.
/// </summary>
/// <returns>
/// - `true`: enabled
/// - `false`: not enabled</returns>
public static bool GetEnabled()
{
return PXR_Plugin.Boundary.UPxr_GetBoundaryEnabled();
}
/// <summary>
/// Checks whether a tracked node (Left hand, Right hand, Head) will trigger the boundary.
/// </summary>
/// <param name="node">The node to track: HandLeft-left controller; HandRight-right controller; Head-HMD.</param>
/// <param name="boundaryType">The boundary type: `OuterBoundary`-boundary (custom boundary or in-site fast boundary); `PlayArea`-the maximum rectangle in the custom boundary (no such a rectangle in the in-site fast boundary).</param>
/// <returns>
/// A struct that contains the following details:
/// - `IsTriggering`: bool, whether the boundary is triggered;
/// - `ClosestDistance`: float, the minimum distance between the tracked node and the boundary;
/// - `ClosestPoint`: vector3, the closest point between the tracked node and the boundary;
/// - `ClosestPointNormal`: vector3, the normal line of the closest point;
/// - `valid`: bool, whether the result returned is valid.
/// </returns>
public static PxrBoundaryTriggerInfo TestNode(BoundaryTrackingNode node, BoundaryType boundaryType)
{
return PXR_Plugin.Boundary.UPxr_TestNodeIsInBoundary(node, boundaryType);
}
/// <summary>
/// Checks whether a tracked point will trigger the boundary.
/// </summary>
/// <param name="point">The coordinate of the point.</param>
/// <param name="boundaryType">The boundary type: `OuterBoundary`-boundary (custom boundary or in-site fast boundary); `PlayArea`-customize the maximum rectangle in the custom boundary (no such rectangle for in-site fast boundary).</param>
/// <returns>
/// A struct that contains the following details:
/// - `IsTriggering`: bool, whether the boundary is triggered;
/// - `ClosestDistance`: float, the minimum distance between the tracked node and the boundary;
/// - `ClosestPoint`: vector3, the closest point between the tracked node and the boundary;
/// - `ClosestPointNormal`: vector3, the normal line of the closest point;
/// - `valid`: bool, whether the result returned is valid.
/// </returns>
public static PxrBoundaryTriggerInfo TestPoint(PxrVector3f point, BoundaryType boundaryType)
{
return PXR_Plugin.Boundary.UPxr_TestPointIsInBoundary(point, boundaryType);
}
/// <summary>
/// Gets the collection of boundary points.
/// </summary>
/// <param name="boundaryType">The boundary type:
/// - `OuterBoundary`: custom boundary or in-site fast boundary.
/// - `PlayArea`: customize the maximum rectangle in the custom boundary (no such rectangle for in-site fast boundary).</param>
/// <returns>A collection of boundary points.
/// - If you pass `OuterBoundary`, the actual calibrated vertex array of the boundary will be returned.
/// - If you pass `PlayArea`, the boundary points array of the maximum rectangle within the calibrated play area will be returned. The boundary points array is calculated by the algorithm.
/// For stationary boundary, passing `PlayArea` returns nothing.
/// </returns>
public static Vector3[] GetGeometry(BoundaryType boundaryType)
{
return PXR_Plugin.Boundary.UPxr_GetBoundaryGeometry(boundaryType);
}
/// <summary>
/// Gets the size of the play area for the custom boundary.
/// </summary>
/// <param name="boundaryType">You can only pass `PlayArea` (customize the maximum rectangle in the custom boundary). **Note**: There is no such rectangle for stationary boundary.</param>
/// <returns>The lengths of the X and Z axis of the maximum rectangle within the custom calibrated play area. The lengths are calculated by the algorithm. The length of the Y axis is always 1.
/// If the current user calibrates the stationary boundary, (0,1,0) will be returned.
/// </returns>
public static Vector3 GetDimensions(BoundaryType boundaryType)
{
return PXR_Plugin.Boundary.UPxr_GetBoundaryDimensions(boundaryType);
}
/// <summary>
/// Gets the camera image of the device and use it as the environmental background. Before calling this function, make sure you have set the clear flags of the camera to solid color and have set the background color of the camera to 0 for the alpha channel.
/// @note If the app is paused, this function will cease. Therefore, you need to call this function again after the app has been resumed.
/// </summary>
/// <param name="value">Whether to enable SeeThrough: `true`-enable; `false`-do not enable.</param>
public static void EnableSeeThroughManual(bool value)
{
PXR_Plugin.Boundary.UPxr_SetSeeThroughBackground(value);
}
/// <summary>
/// Gets the current status of seethrough tracking.
/// </summary>
/// <returns>Returns `PxrTrackingState`. Below are the enumerations:
/// * `LostNoReason`: no reason
/// * `LostCamera`: camera calibration data error
/// * `LostHighLight`: environment lighting too bright
/// * `LostLowLight`: environment lighting too dark
/// * `LostLowFeatureCount`: few environmental features
/// * `LostReLocation`: relocation in progress
/// * `LostInitialization`: initialization in progress
/// * `LostNoCamera`: camera data error
/// * `LostNoIMU`: IMU data error
/// * `LostIMUJitter`: IMU data jitter
/// * `LostUnknown`: unknown error
/// </returns>
public static PxrTrackingState GetSeeThroughTrackingState() {
return PXR_Plugin.Boundary.UPxr_GetSeeThroughTrackingState();
}
/// <summary>
/// disable or enable boundary
/// </summary>
/// <param name="value"></param>
public static void SetGuardianSystemDisable(bool value)
{
PXR_Plugin.Boundary.UPxr_SetGuardianSystemDisable(value);
}
/// <summary>
/// Uses the global pose.
/// </summary>
/// <param name="value">Specifies whether to use the global pose.
/// * `true`: use
/// * `false`: do not use
/// </param>
public static void UseGlobalPose(bool value)
{
PXR_Plugin.Boundary.UPxr_SetSeeThroughState(value);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 617aa04623edd024a9298a3b21656d4c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 815321e0da90723458db60e729bdebde
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,91 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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 UnityEngine;
namespace Unity.XR.PXR
{
public class PXR_FoveationRendering
{
private static PXR_FoveationRendering instance = null;
public static PXR_FoveationRendering Instance
{
get
{
if (instance == null)
{
instance = new PXR_FoveationRendering();
}
return instance;
}
}
/// <summary>
/// Sets a foveated rendering level.
/// </summary>
/// <param name="level">Select a foveated rendering level:
/// * `None`: disable foveated rendering
/// * `Low`
/// * `Med`
/// * `High`
/// * `TopHigh`
/// </param>
/// <param name="isETFR">
/// Describe if the foveated rendering mode is eye tracked foveated rendering (ETFR):
/// * `true`: ETFR
/// * `false`: not ETFR
/// </param>
/// <returns>
/// * `true`: success
/// * `false`: failure
/// </returns>
public static bool SetFoveationLevel(FoveationLevel level, bool isETFR)
{
if (isETFR)
{
return PXR_Plugin.Render.UPxr_SetEyeFoveationLevel(level);
}
else
{
return PXR_Plugin.Render.UPxr_SetFoveationLevel(level);
}
}
/// <summary>
/// Gets the current foveated rendering level.
/// </summary>
/// <returns>The current foveated rendering level:
/// * `None` (`-1`): foveated rendering disabled
/// * `Low`
/// * `Med`
/// * `High`
/// * `TopHigh`
/// </returns>
public static FoveationLevel GetFoveationLevel()
{
return PXR_Plugin.Render.UPxr_GetFoveationLevel();
}
/// <summary>
/// Sets foveated rendering parameters.
/// </summary>
/// <param name="foveationGainX">Set the reduction rate of peripheral pixels in the X-axis direction. Value range: [1.0, 10.0], the greater the value, the higher the reduction rate.</param>
/// <param name="foveationGainY">Set the reduction rate of peripheral pixels in the Y-axis direction. Value range: [1.0, 10.0], the greater the value, the higher the reduction rate.</param>
/// <param name="foveationArea">Set the range of foveated area whose resolution is not to be reduced. Value range: [0.0, 4.0], the higher the value, the bigger the high-quality central area.</param>
/// <param name="foveationMinimum">Set the minimum pixel density. Recommended values: 1/32, 1/16, 1/8, 1/4, 1/2. The actual pixel density will be greater than or equal to the value set here.</param>
public static void SetFoveationParameters(float foveationGainX, float foveationGainY, float foveationArea, float foveationMinimum)
{
PXR_Plugin.Render.UPxr_SetFoveationParameters(foveationGainX, foveationGainY, foveationArea, foveationMinimum);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 9d0598bf64df1a34e9a5ec19775188d5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,423 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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.Runtime.InteropServices;
using UnityEngine;
#if PICO_LIVE_PREVIEW && UNITY_EDITOR
using Unity.XR.PICO.LivePreview;
#endif
namespace Unity.XR.PXR
{
/// <summary>
/// Hand types.
/// </summary>
public enum HandType
{
/// <summary>
/// Left hand.
/// </summary>
HandLeft = 0,
/// <summary>
/// Right hand.
/// </summary>
HandRight = 1,
}
/// <summary>
/// The current active input device.
/// </summary>
public enum ActiveInputDevice
{
/// <summary>
/// HMD
/// </summary>
HeadActive = 0,
/// <summary>
/// Controllers
/// </summary>
ControllerActive = 1,
/// <summary>
/// Hands
/// </summary>
HandTrackingActive = 2,
}
public struct Vector3f
{
public float x;
public float y;
public float z;
public Vector3 ToVector3()
{
return new Vector3() { x = x, y = y, z = -z };
}
}
public struct Quatf
{
public float x;
public float y;
public float z;
public float w;
public Quaternion ToQuat()
{
return new Quaternion() { x = x, y = y, z = -z, w = -w };
}
}
/// <summary>
/// The location of hand joint.
/// </summary>
public struct Posef
{
/// <summary>
/// The orientation of hand joint.
/// </summary>
public Quatf Orientation;
/// <summary>
/// The position of hand joint.
/// </summary>
public Vector3f Position;
public override string ToString()
{
return string.Format("Orientation :{0}, {1}, {2}, {3} Position: {4}, {5}, {6}",
Orientation.x, Orientation.y, Orientation.z, Orientation.w,
Position.x, Position.y, Position.z);
}
}
/// <summary>
/// The status of ray and fingers.
/// </summary>
public enum HandAimStatus : ulong
{
/// <summary>
/// Whether the data is valid.
/// </summary>
AimComputed = 0x00000001,
/// <summary>
/// Whether the ray appears.
/// </summary>
AimRayValid = 0x00000002,
/// <summary>
/// Whether the index finger pinches.
/// </summary>
AimIndexPinching = 0x00000004,
/// <summary>
/// Whether the middle finger pinches.
/// </summary>
AimMiddlePinching = 0x00000008,
/// <summary>
/// Whether the ring finger pinches.
/// </summary>
AimRingPinching = 0x00000010,
/// <summary>
/// Whether the little finger pinches.
/// </summary>
AimLittlePinching = 0x00000020,
/// <summary>
/// Whether the ray touches.
/// </summary>
AimRayTouched = 0x00000200
}
/// <summary>
/// The data about the poses of ray and fingers.
/// </summary>
public struct HandAimState
{
/// <summary>
/// The status of hand tracking. If it is not `tracked`, confidence will be `0`.
/// </summary>
public HandAimStatus aimStatus;
/// <summary>
/// The pose of the ray.
/// </summary>
public Posef aimRayPose;
/// <summary>
/// The strength of index finger's pinch.
/// </summary>
private float pinchStrengthIndex;
/// <summary>
/// The strength of middle finger's pinch.
/// </summary>
private float pinchStrengthMiddle;
/// <summary>
/// The strength of ring finger's pinch.
/// </summary>
private float pinchStrengthRing;
/// <summary>
/// The strength of little finger's pinch.
/// </summary>
private float pinchStrengthLittle;
/// <summary>
/// The strength of ray's touch.
/// </summary>
public float touchStrengthRay;
}
/// <summary>
/// The data about the status of hand joint location.
/// </summary>
public enum HandLocationStatus : ulong
{
/// <summary>
/// Whether the joint's orientation is valid.
/// </summary>
OrientationValid = 0x00000001,
/// <summary>
/// Whether the joint's position is valid.
/// </summary>
PositionValid = 0x00000002,
/// <summary>
/// Whether the joint's orientation is being tracked.
/// </summary>
OrientationTracked = 0x00000004,
/// <summary>
/// Whether the joint's position is being tracked.
/// </summary>
PositionTracked = 0x00000008
}
public enum HandJoint
{
JointPalm = 0,
JointWrist = 1,
JointThumbMetacarpal = 2,
JointThumbProximal = 3,
JointThumbDistal = 4,
JointThumbTip = 5,
JointIndexMetacarpal = 6,
JointIndexProximal = 7,
JointIndexIntermediate = 8,
JointIndexDistal = 9,
JointIndexTip = 10,
JointMiddleMetacarpal = 11,
JointMiddleProximal = 12,
JointMiddleIntermediate = 13,
JointMiddleDistal = 14,
JointMiddleTip = 15,
JointRingMetacarpal = 16,
JointRingProximal = 17,
JointRingIntermediate = 18,
JointRingDistal = 19,
JointRingTip = 20,
JointLittleMetacarpal = 21,
JointLittleProximal = 22,
JointLittleIntermediate = 23,
JointLittleDistal = 24,
JointLittleTip = 25,
JointMax = 26
}
/// <summary>
/// The data about the location of hand joint.
/// </summary>
public struct HandJointLocation
{
/// <summary>
/// The status of hand joint location.
/// </summary>
public HandLocationStatus locationStatus;
/// <summary>
/// The orientation and position of hand joint.
/// </summary>
public Posef pose;
/// <summary>
/// The radius of hand joint.
/// </summary>
public float radius;
}
/// <summary>
/// The data about hand tracking.
/// </summary>
public struct HandJointLocations
{
/// <summary>
/// The quality level of hand tracking:
/// `0`: low
/// `1`: high
/// </summary>
public uint isActive;
/// <summary>
/// The number of hand joints that the SDK supports. Currenty returns `26`.
/// </summary>
public uint jointCount;
/// <summary>
/// The scale of the hand.
/// </summary>
public float handScale;
/// <summary>
/// The locations (orientation and position) of hand joints.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)HandJoint.JointMax)]
public HandJointLocation[] jointLocations;
}
public enum HandFinger
{
Thumb = 0,
Index = 1,
Middle = 2,
Ring = 3,
Pinky = 4
}
public static class PXR_HandTracking
{
/// <summary>Gets whether hand tracking is enabled or disabled.</summary>
/// <returns>
/// * `true`: enabled
/// * `false`: disabled
/// </returns>
public static bool GetSettingState()
{
#if PICO_LIVE_PREVIEW && UNITY_EDITOR
return PXR_PTApi.UPxr_GetSettingState();
#endif
return PXR_Plugin.HandTracking.UPxr_GetHandTrackerSettingState();
}
/// <summary>Gets the current active input device.</summary>
/// <returns>The current active input device:
/// * `HeadActive`: HMD
/// * `ControllerActive`: controllers
/// * `HandTrackingActive`: hands
/// </returns>
public static ActiveInputDevice GetActiveInputDevice()
{
#if PICO_LIVE_PREVIEW && UNITY_EDITOR
return PXR_PTApi.UPxr_GetGetHandTrackerActiveState() ? ActiveInputDevice.HandTrackingActive : ActiveInputDevice.ControllerActive;
#endif
return PXR_Plugin.HandTracking.UPxr_GetHandTrackerActiveInputType();
}
/// <summary>Gets the data about the pose of a specified hand, including the status of the ray and fingers, the strength of finger pinch and ray touch.</summary>
/// <param name="hand">The hand to get data for:
/// * `HandLeft`: left hand
/// * `HandRight`: right hand
/// </param>
/// <param name="aimState">`HandAimState` contains the data about the poses of ray and fingers.
/// If you use PICO hand prefabs without changing any of their default settings, you will get the following data:
/// ```csharp
/// public class PXR_Hand
/// {
/// // Whether the data is valid.
/// public bool Computed { get; private set; }
/// // The ray pose.
/// public Posef RayPose { get; private set; }
/// // Whether the ray was displayed.
/// public bool RayValid { get; private set; }
/// // Whether the ray pinched.
/// public bool Pinch { get; private set; }
/// // The strength of ray pinch.
/// public float PinchStrength { get; private set; }
/// ```
/// </param>
/// <returns>
/// * `true`: success
/// * `false`: failure
/// </returns>
public static bool GetAimState(HandType hand, ref HandAimState aimState)
{
if (!PXR_ProjectSetting.GetProjectConfig().handTracking)
return false;
#if PICO_LIVE_PREVIEW && UNITY_EDITOR
PICO.LivePreview.HandAimState lPHandAimState = new PICO.LivePreview.HandAimState();
PXR_PTApi.UPxr_GetHandTrackerAimState((int)hand, ref lPHandAimState);
aimState.aimStatus = (HandAimStatus)lPHandAimState.aimStatus;
aimState.touchStrengthRay = lPHandAimState.touchStrengthRay;
aimState.aimRayPose.Position.x = lPHandAimState.aimRayPose.Position.x;
aimState.aimRayPose.Position.y = lPHandAimState.aimRayPose.Position.y;
aimState.aimRayPose.Position.z = lPHandAimState.aimRayPose.Position.z;
aimState.aimRayPose.Orientation.x = lPHandAimState.aimRayPose.Orientation.x;
aimState.aimRayPose.Orientation.y = lPHandAimState.aimRayPose.Orientation.y;
aimState.aimRayPose.Orientation.z = lPHandAimState.aimRayPose.Orientation.z;
aimState.aimRayPose.Orientation.w = lPHandAimState.aimRayPose.Orientation.w;
return true;
#endif
return PXR_Plugin.HandTracking.UPxr_GetHandTrackerAimState(hand, ref aimState);
}
/// <summary>Gets the locations of joints for a specified hand.</summary>
/// <param name="hand">The hand to get joint locations for:
/// * `HandLeft`: left hand
/// * `HandRight`: right hand
/// </param>
/// <param name="jointLocations">Contains data about the locations of the joints in the specified hand.</param>
/// <returns>
/// * `true`: success
/// * `false`: failure
/// </returns>
public static bool GetJointLocations(HandType hand, ref HandJointLocations jointLocations)
{
if (!PXR_ProjectSetting.GetProjectConfig().handTracking)
return false;
#if PICO_LIVE_PREVIEW && UNITY_EDITOR
PICO.LivePreview.HandJointLocations lPHandJointLocations = new PICO.LivePreview.HandJointLocations();
PXR_PTApi.UPxr_GetHandTrackerJointLocations((int)hand,ref lPHandJointLocations);
jointLocations.handScale = lPHandJointLocations.handScale;
jointLocations.isActive = lPHandJointLocations.isActive;
jointLocations.jointCount = lPHandJointLocations.jointCount;
jointLocations.jointLocations = new HandJointLocation[lPHandJointLocations.jointCount];
for (int i = 0; i < lPHandJointLocations.jointCount; i++)
{
jointLocations.jointLocations[i].locationStatus = (HandLocationStatus)lPHandJointLocations.jointLocations[i].locationStatus;
jointLocations.jointLocations[i].radius = lPHandJointLocations.jointLocations[i].radius;
jointLocations.jointLocations[i].pose.Position.x = lPHandJointLocations.jointLocations[i].pose.Position.x;
jointLocations.jointLocations[i].pose.Position.y = lPHandJointLocations.jointLocations[i].pose.Position.y;
jointLocations.jointLocations[i].pose.Position.z = lPHandJointLocations.jointLocations[i].pose.Position.z;
jointLocations.jointLocations[i].pose.Orientation.x = lPHandJointLocations.jointLocations[i].pose.Orientation.x;
jointLocations.jointLocations[i].pose.Orientation.y = lPHandJointLocations.jointLocations[i].pose.Orientation.y;
jointLocations.jointLocations[i].pose.Orientation.z = lPHandJointLocations.jointLocations[i].pose.Orientation.z;
jointLocations.jointLocations[i].pose.Orientation.w = lPHandJointLocations.jointLocations[i].pose.Orientation.w;
}
return true;
#endif
return PXR_Plugin.HandTracking.UPxr_GetHandTrackerJointLocations(hand, ref jointLocations);
}
/// <summary>
/// Gets the scaling ratio of the hand model.
/// </summary>
/// <param name="hand">Specifies the hand to get scaling ratio for:
/// * `HandLeft`: left hand
/// * `HandRight`: right hand
/// </param>
/// <param name="scale">Returns the scaling ratio for the specified hand.</param>
/// <returns>
/// * `true`: success
/// * `false`: failure
/// </returns>
public static bool GetHandScale(HandType hand,ref float scale)
{
return PXR_Plugin.HandTracking.UPxr_GetHandScale((int)hand, ref scale);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: a6243041ddd1c214c84a8c5abef6c24a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: ce57129cda8427d4eaacb7990f5f40de
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,86 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.XR;
namespace Unity.XR.PXR
{
[Serializable]
public class PXR_LateLatching : MonoBehaviour
{
#if UNITY_2020_3_OR_NEWER
private Camera m_LateLatchingCamera;
static XRDisplaySubsystem s_DisplaySubsystem = null;
static List<XRDisplaySubsystem> s_DisplaySubsystems = new List<XRDisplaySubsystem>();
private void Awake()
{
m_LateLatchingCamera = GetComponent<Camera>();
}
private void OnEnable()
{
List<XRDisplaySubsystem> displaySubsystems = new List<XRDisplaySubsystem>();
SubsystemManager.GetInstances(displaySubsystems);
Debug.Log("PXR_U OnEnable() displaySubsystems.Count = " + displaySubsystems.Count);
for (int i = 0; i < displaySubsystems.Count; i++)
{
s_DisplaySubsystem = displaySubsystems[i];
}
}
private void OnDisable()
{
}
void Update()
{
if (s_DisplaySubsystem == null)
{
List<XRDisplaySubsystem> displaySubsystems = new List<XRDisplaySubsystem>();
SubsystemManager.GetInstances(displaySubsystems);
if (displaySubsystems.Count > 0)
{
s_DisplaySubsystem = displaySubsystems[0];
}
}
if (null == s_DisplaySubsystem)
return;
s_DisplaySubsystem.MarkTransformLateLatched(m_LateLatchingCamera.transform, XRDisplaySubsystem.LateLatchNode.Head);
}
#if !UNITY_EDITOR
private void OnPreRender()
{
s_DisplaySubsystem.BeginRecordingIfLateLatched(m_LateLatchingCamera);
}
private void OnPostRender()
{
s_DisplaySubsystem.EndRecordingIfLateLatched(m_LateLatchingCamera);
}
#endif
private void FixedUpdate()
{
}
private void LateUpdate()
{
}
#endif
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: b0d77cf58f760874892e934648a878f2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 2d6132037afd3fe4abfa4282efd18bd4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 575693a8c0449a04f82b773bf343dcef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,842 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll information contained herein is, and remains the property of
PICO Technology Co., Ltd. The intellectual and technical concepts
contained herein are proprietary to PICO Technology Co., Ltd. and may be
covered by patents, patents in process, and are protected by trade secret or
copyright law. Dissemination of this information or reproduction of this
material is strictly forbidden unless prior written permission is obtained from
PICO Technology Co., Ltd.
*******************************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEditor;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
using UnityEngine.XR;
namespace Unity.XR.PXR
{
public class PXR_OverLay : MonoBehaviour, IComparable<PXR_OverLay>
{
private const string TAG = "[PXR_CompositeLayers]";
public static List<PXR_OverLay> Instances = new List<PXR_OverLay>();
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.ExternalSurface;
public Transform overlayTransform;
public Camera xrRig;
public Texture[] layerTextures = new Texture[2] { null, null };
public bool isPremultipliedAlpha = false;
public bool isDynamic = false;
public int[] overlayTextureIds = new int[2];
public Matrix4x4[] mvMatrixs = new Matrix4x4[2];
public Vector3[] modelScales = new Vector3[2];
public Quaternion[] modelRotations = new Quaternion[2];
public Vector3[] modelTranslations = new Vector3[2];
public Quaternion[] cameraRotations = new Quaternion[2];
public Vector3[] cameraTranslations = new Vector3[2];
public Camera[] overlayEyeCamera = new Camera[2];
public bool overrideColorScaleAndOffset = false;
public Vector4 colorScale = Vector4.one;
public Vector4 colorOffset = Vector4.zero;
// Eac
public Vector3 offsetPosLeft = Vector3.zero;
public Vector3 offsetPosRight = Vector3.zero;
public Vector4 offsetRotLeft = new Vector4(0, 0, 0, 1);
public Vector4 offsetRotRight = new Vector4(0, 0, 0, 1);
public EACModelType eacModelType = EACModelType.Eac360;
public float overlapFactor = 1.0f;
public ulong timestamp = 0;
private Vector4 overlayLayerColorScaleDefault = Vector4.one;
private Vector4 overlayLayerColorOffsetDefault = Vector4.zero;
public bool isExternalAndroidSurface = false;
public bool isExternalAndroidSurfaceDRM = false;
public Surface3DType externalAndroidSurface3DType = Surface3DType.Single;
#region Blurred Quad
public BlurredQuadMode blurredQuadMode = BlurredQuadMode.SmallWindow;
public float blurredQuadScale = 0.5f;
public float blurredQuadShift = 0.01f;
public float blurredQuadFOV = 70.0f;
public float blurredQuadIPD = 0.064f;
#endregion
public IntPtr externalAndroidSurfaceObject = IntPtr.Zero;
public delegate void ExternalAndroidSurfaceObjectCreated();
public ExternalAndroidSurfaceObjectCreated externalAndroidSurfaceObjectCreated = null;
// 360
public float radius = 0; // >0
// ImageRect
public bool useImageRect = false;
public TextureRect textureRect = TextureRect.StereoScopic;
public DestinationRect destinationRect = DestinationRect.Default;
public Rect srcRectLeft = new Rect(0, 0, 1, 1);
public Rect srcRectRight = new Rect(0, 0, 1, 1);
public Rect dstRectLeft = new Rect(0, 0, 1, 1);
public Rect dstRectRight = new Rect(0, 0, 1, 1);
public PxrRecti imageRectLeft;
public PxrRecti imageRectRight;
// LayerBlend
public bool useLayerBlend = false;
public PxrBlendFactor srcColor = PxrBlendFactor.PxrBlendFactorOne;
public PxrBlendFactor dstColor = PxrBlendFactor.PxrBlendFactorOne;
public PxrBlendFactor srcAlpha = PxrBlendFactor.PxrBlendFactorOne;
public PxrBlendFactor dstAlpha = PxrBlendFactor.PxrBlendFactorOne;
public float[] colorMatrix = new float[18] {
1,0,0, // left
0,1,0,
0,0,1,
1,0,0, // right
0,1,0,
0,0,1,
};
public bool isClones = false;
public bool isClonesToNew = false;
public bool enableSubmitLayer = true;
public PXR_OverLay originalOverLay;
public IntPtr layerSubmitPtr = IntPtr.Zero;
public APIExecutionStatus Quad2Status = APIExecutionStatus.None;
public APIExecutionStatus Cylinder2Status = APIExecutionStatus.None;
public APIExecutionStatus Equirect2Status = APIExecutionStatus.None;
private bool toCreateSwapChain = false;
private bool toCopyRT = false;
private bool copiedRT = false;
private int eyeCount = 2;
private UInt32 imageCounts = 0;
private PxrLayerParam overlayParam = new PxrLayerParam();
private struct NativeTexture
{
public Texture[] textures;
};
private NativeTexture[] nativeTextures;
private static Material cubeM;
private IntPtr leftPtr = IntPtr.Zero;
private IntPtr rightPtr = IntPtr.Zero;
private static Material textureM;
public HDRFlags hdr = HDRFlags.None;
public int CompareTo(PXR_OverLay other)
{
return layerDepth.CompareTo(other.layerDepth);
}
protected void Awake()
{
xrRig = Camera.main;
Instances.Add(this);
if (null == xrRig.gameObject.GetComponent<PXR_OverlayManager>())
{
xrRig.gameObject.AddComponent<PXR_OverlayManager>();
}
overlayEyeCamera[0] = xrRig;
overlayEyeCamera[1] = xrRig;
overlayTransform = GetComponent<Transform>();
#if UNITY_ANDROID && !UNITY_EDITOR
if (overlayTransform != null)
{
MeshRenderer render = overlayTransform.GetComponent<MeshRenderer>();
if (render != null)
{
render.enabled = false;
}
}
#endif
if (!isClones)
{
InitializeBuffer();
}
}
private void Start()
{
if (isClones)
{
InitializeBuffer();
}
if (PXR_Manager.Instance == null)
{
return;
}
Camera[] cam = PXR_Manager.Instance.GetEyeCamera();
if (cam[0] != null && cam[0].enabled)
{
RefreshCamera(cam[0], cam[0]);
}
else if (cam[1] != null && cam[2] != null)
{
RefreshCamera(cam[1], cam[2]);
}
}
public void RefreshCamera(Camera leftCamera, Camera rightCamera)
{
overlayEyeCamera[0] = leftCamera;
overlayEyeCamera[1] = rightCamera;
}
private void InitializeBuffer()
{
if (!isExternalAndroidSurface && !isClones)
{
if (null == layerTextures[0] && null == layerTextures[1])
{
PLog.e(TAG, " The left and right images are all empty!");
return;
}
else if (null == layerTextures[0] && null != layerTextures[1])
{
layerTextures[0] = layerTextures[1];
}
else if (null != layerTextures[0] && null == layerTextures[1])
{
layerTextures[1] = layerTextures[0];
}
overlayParam.width = (uint)layerTextures[1].width;
overlayParam.height = (uint)layerTextures[1].height;
}
else
{
overlayParam.width = 1024;
overlayParam.height = 1024;
}
overlayID++;
overlayIndex = overlayID;
overlayParam.layerId = overlayIndex;
overlayParam.layerShape = overlayShape == 0 ? OverlayShape.Quad : overlayShape;
overlayParam.layerType = overlayType;
overlayParam.arraySize = 1;
overlayParam.mipmapCount = 1;
overlayParam.sampleCount = 1;
overlayParam.layerFlags = 0;
if (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 (OverlayShape.Cubemap == overlayShape)
{
overlayParam.faceCount = 6;
if (cubeM == null)
cubeM = new Material(Shader.Find("PXR_SDK/PXR_CubemapBlit"));
}
else
{
overlayParam.faceCount = 1;
if (textureM == null)
textureM = new Material(Shader.Find("PXR_SDK/PXR_Texture2DBlit"));
}
if (isClones)
{
if (null != originalOverLay)
{
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlagSharedImagesBetweenLayers;
leftPtr = Marshal.AllocHGlobal(Marshal.SizeOf(originalOverLay.overlayIndex));
rightPtr = Marshal.AllocHGlobal(Marshal.SizeOf(originalOverLay.overlayIndex));
Marshal.WriteInt64(leftPtr, originalOverLay.overlayIndex);
Marshal.WriteInt64(rightPtr, originalOverLay.overlayIndex);
overlayParam.leftExternalImages = leftPtr;
overlayParam.rightExternalImages = rightPtr;
isExternalAndroidSurface = originalOverLay.isExternalAndroidSurface;
isDynamic = originalOverLay.isDynamic;
overlayParam.width = (UInt32)Mathf.Min(overlayParam.width, originalOverLay.overlayParam.width);
overlayParam.height = (UInt32)Mathf.Min(overlayParam.height, originalOverLay.overlayParam.height);
}
else
{
PLog.e(TAG, "In clone state, originalOverLay cannot be empty!");
}
}
if (isExternalAndroidSurface)
{
if (isExternalAndroidSurfaceDRM)
{
overlayParam.layerFlags |= (UInt32)(PxrLayerCreateFlags.PxrLayerFlagAndroidSurface | PxrLayerCreateFlags.PxrLayerFlagProtectedContent);
}
else
{
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlagAndroidSurface;
}
if (Surface3DType.LeftRight == externalAndroidSurface3DType)
{
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlag3DLeftRightSurface;
}
else if (Surface3DType.TopBottom == externalAndroidSurface3DType)
{
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlag3DTopBottomSurface;
}
overlayParam.layerLayout = LayerLayout.Mono;
PLog.i(TAG, $"UPxr_CreateLayer() overlayParam.layerId={overlayParam.layerId}, layerShape={overlayParam.layerShape}, layerType={overlayParam.layerType}, width={overlayParam.width}, height={overlayParam.height}, layerFlags={overlayParam.layerFlags}, format={overlayParam.format}, layerLayout={overlayParam.layerLayout}.");
IntPtr layerParamPtr = Marshal.AllocHGlobal(Marshal.SizeOf(overlayParam));
Marshal.StructureToPtr(overlayParam, layerParamPtr, false);
PXR_Plugin.Render.UPxr_CreateLayer(layerParamPtr);
Marshal.FreeHGlobal(layerParamPtr);
}
else
{
if (!isDynamic)
{
overlayParam.layerFlags |= (UInt32)PxrLayerCreateFlags.PxrLayerFlagStaticImage;
}
if ((layerTextures[0] != null && layerTextures[1] != null && layerTextures[0] == layerTextures[1]) || null == layerTextures[1])
{
eyeCount = 1;
overlayParam.layerLayout = LayerLayout.Mono;
}
else
{
eyeCount = 2;
overlayParam.layerLayout = LayerLayout.Stereo;
}
PXR_Plugin.Render.UPxr_CreateLayerParam(overlayParam);
toCreateSwapChain = true;
CreateTexture();
}
}
public void CreateExternalSurface(PXR_OverLay overlayInstance)
{
#if UNITY_ANDROID && !UNITY_EDITOR
if (IntPtr.Zero != overlayInstance.externalAndroidSurfaceObject)
{
return;
}
PXR_Plugin.Render.UPxr_GetLayerAndroidSurface(overlayInstance.overlayIndex, 0, ref overlayInstance.externalAndroidSurfaceObject);
PLog.i(TAG, string.Format("CreateExternalSurface: Overlay Type:{0}, LayerDepth:{1}, SurfaceObject:{2}", overlayInstance.overlayType, overlayInstance.overlayIndex, overlayInstance.externalAndroidSurfaceObject));
if (IntPtr.Zero == overlayInstance.externalAndroidSurfaceObject || null == overlayInstance.externalAndroidSurfaceObjectCreated)
{
return;
}
overlayInstance.externalAndroidSurfaceObjectCreated();
#endif
}
public void UpdateCoords()
{
if (null == overlayTransform || !overlayTransform.gameObject.activeSelf || null == overlayEyeCamera[0] || null == overlayEyeCamera[1])
{
return;
}
for (int i = 0; i < mvMatrixs.Length; i++)
{
mvMatrixs[i] = overlayEyeCamera[i].worldToCameraMatrix * overlayTransform.localToWorldMatrix;
if (overlayTransform is RectTransform uiTransform)
{
var rect = uiTransform.rect;
var lossyScale = overlayTransform.lossyScale;
modelScales[i] = new Vector3(rect.width * lossyScale.x,
rect.height * lossyScale.y, 1);
modelTranslations[i] = uiTransform.TransformPoint(rect.center);
}
else
{
modelScales[i] = overlayTransform.lossyScale;
modelTranslations[i] = overlayTransform.position;
}
modelRotations[i] = overlayTransform.rotation;
cameraRotations[i] = overlayEyeCamera[i].transform.rotation;
cameraTranslations[i] = overlayEyeCamera[i].transform.position;
}
}
public bool CreateTexture()
{
if (!toCreateSwapChain)
{
return false;
}
if (null == nativeTextures)
nativeTextures = new NativeTexture[eyeCount];
for (int i = 0; i < eyeCount; i++)
{
int ret = PXR_Plugin.Render.UPxr_GetLayerImageCount(overlayIndex, (EyeType)i, ref imageCounts);
if (ret != 0 || imageCounts < 1)
{
return false;
}
if (null == nativeTextures[i].textures)
{
nativeTextures[i].textures = new Texture[imageCounts];
}
for (int j = 0; j < imageCounts; j++)
{
IntPtr ptr = IntPtr.Zero;
PXR_Plugin.Render.UPxr_GetLayerImagePtr(overlayIndex, (EyeType)i, j, ref ptr);
if (IntPtr.Zero == ptr)
{
return false;
}
Texture texture;
if (OverlayShape.Cubemap == overlayShape)
{
texture = Cubemap.CreateExternalTexture((int)overlayParam.width, TextureFormat.RGBA32, false, ptr);
}
else
{
texture = Texture2D.CreateExternalTexture((int)overlayParam.width, (int)overlayParam.height, TextureFormat.RGBA32, false, true, ptr);
}
if (null == texture)
{
return false;
}
nativeTextures[i].textures[j] = texture;
}
}
toCreateSwapChain = false;
toCopyRT = true;
copiedRT = false;
FreePtr();
return true;
}
public bool CopyRT()
{
if (isClones)
{
return true;
}
if (!toCopyRT)
{
return copiedRT;
}
if (!isDynamic && copiedRT)
{
return copiedRT;
}
if (null == nativeTextures)
{
return false;
}
if (GraphicsDeviceType.Vulkan != SystemInfo.graphicsDeviceType)
{
if (enableSubmitLayer)
{
PXR_Plugin.Render.UPxr_GetLayerNextImageIndexByRender(overlayIndex, ref imageIndex);
}
}
for (int i = 0; i < eyeCount; i++)
{
Texture nativeTexture = nativeTextures[i].textures[imageIndex];
if (null == nativeTexture || null == layerTextures[i])
continue;
RenderTexture texture = layerTextures[i] as RenderTexture;
if (OverlayShape.Cubemap == overlayShape && null == layerTextures[i] as Cubemap)
{
return false;
}
for (int f = 0; f < (int)overlayParam.faceCount; f++)
{
if (QualitySettings.activeColorSpace == ColorSpace.Gamma && texture != null && texture.format == RenderTextureFormat.ARGB32)
{
Graphics.CopyTexture(layerTextures[i], f, 0, nativeTexture, f, 0);
}
else
{
RenderTextureDescriptor rtDes = new RenderTextureDescriptor((int)overlayParam.width, (int)overlayParam.height, RenderTextureFormat.ARGB32, 0);
rtDes.msaaSamples = (int)overlayParam.sampleCount;
rtDes.useMipMap = true;
rtDes.autoGenerateMips = false;
rtDes.sRGB = true;
RenderTexture renderTexture = RenderTexture.GetTemporary(rtDes);
if (!renderTexture.IsCreated())
{
renderTexture.Create();
}
renderTexture.DiscardContents();
if (OverlayShape.Cubemap == overlayShape)
{
cubeM.SetInt("_d", f);
Graphics.Blit(layerTextures[i], renderTexture, cubeM);
}
else
{
textureM.mainTexture = texture;
textureM.SetPass(0);
textureM.SetInt("_premultiply", isPremultipliedAlpha ? 1 : 0);
Graphics.Blit(layerTextures[i], renderTexture, textureM);
}
Graphics.CopyTexture(renderTexture, 0, 0, nativeTexture, f, 0);
RenderTexture.ReleaseTemporary(renderTexture);
}
}
copiedRT = true;
}
return copiedRT;
}
public void SetTexture(Texture texture, bool dynamic)
{
if (isExternalAndroidSurface)
{
PLog.w(TAG, "Not support setTexture !");
return;
}
if (isClones)
{
return;
}
else
{
foreach (PXR_OverLay overlay in PXR_OverLay.Instances)
{
if (overlay.isClones && null != overlay.originalOverLay && overlay.originalOverLay.overlayIndex == overlayIndex)
{
overlay.DestroyLayer();
overlay.isClonesToNew = true;
}
}
}
toCopyRT = false;
PXR_Plugin.Render.UPxr_DestroyLayerByRender(overlayIndex);
ClearTexture();
for (int i = 0; i < layerTextures.Length; i++)
{
layerTextures[i] = texture;
}
isDynamic = dynamic;
InitializeBuffer();
if (!isClones)
{
foreach (PXR_OverLay overlay in PXR_OverLay.Instances)
{
if (overlay.isClones && overlay.isClonesToNew)
{
overlay.originalOverLay = this;
overlay.InitializeBuffer();
overlay.isClonesToNew = false;
}
}
}
}
private void FreePtr()
{
if (leftPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(leftPtr);
leftPtr = IntPtr.Zero;
}
if (rightPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(rightPtr);
rightPtr = IntPtr.Zero;
}
if (layerSubmitPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(layerSubmitPtr);
layerSubmitPtr = IntPtr.Zero;
}
}
public void OnDestroy()
{
DestroyLayer();
Instances.Remove(this);
}
public void DestroyLayer()
{
if (isExternalAndroidSurface)
{
PXR_Plugin.Render.UPxr_DestroyLayer(overlayIndex);
externalAndroidSurfaceObject = IntPtr.Zero;
ClearTexture();
return;
}
if (!isClones)
{
List<PXR_OverLay> toDestroyClones = new List<PXR_OverLay>();
foreach (PXR_OverLay overlay in Instances)
{
if (overlay.isClones && null != overlay.originalOverLay && overlay.originalOverLay.overlayIndex == overlayIndex)
{
toDestroyClones.Add(overlay);
}
}
foreach (PXR_OverLay overLay in toDestroyClones)
{
PXR_Plugin.Render.UPxr_DestroyLayerByRender(overLay.overlayIndex);
ClearTexture();
}
PXR_Plugin.Render.UPxr_DestroyLayerByRender(overlayIndex);
}
else
{
if (null != originalOverLay && Instances.Contains(originalOverLay))
{
PXR_Plugin.Render.UPxr_DestroyLayerByRender(overlayIndex);
}
}
ClearTexture();
}
private void ClearTexture()
{
FreePtr();
if (isExternalAndroidSurface || null == nativeTextures || isClones)
{
return;
}
for (int i = 0; i < eyeCount; i++)
{
if (null == nativeTextures[i].textures)
{
continue;
}
for (int j = 0; j < imageCounts; j++)
DestroyImmediate(nativeTextures[i].textures[j]);
}
nativeTextures = null;
}
public void SetLayerColorScaleAndOffset(Vector4 scale, Vector4 offset)
{
colorScale = scale;
colorOffset = offset;
}
public void SetEACOffsetPosAndRot(Vector3 leftPos, Vector3 rightPos, Vector4 leftRot, Vector4 rightRot)
{
offsetPosLeft = leftPos;
offsetPosRight = rightPos;
offsetRotLeft = leftRot;
offsetRotRight = rightRot;
}
public void SetEACFactor(float factor)
{
overlapFactor = factor;
}
public Vector4 GetLayerColorScale()
{
if (!overrideColorScaleAndOffset)
{
return overlayLayerColorScaleDefault;
}
return colorScale;
}
public Vector4 GetLayerColorOffset()
{
if (!overrideColorScaleAndOffset)
{
return overlayLayerColorOffsetDefault;
}
return colorOffset;
}
public PxrRecti getPxrRectiLeft(bool left)
{
if (left)
{
imageRectLeft.x = (int)(overlayParam.width * srcRectLeft.x);
imageRectLeft.y = (int)(overlayParam.height * srcRectLeft.y);
imageRectLeft.width = (int)(overlayParam.width * Mathf.Min(srcRectLeft.width, 1 - srcRectLeft.x));
imageRectLeft.height = (int)(overlayParam.height * Mathf.Min(srcRectLeft.height, 1 - srcRectLeft.y));
return imageRectLeft;
}
else
{
imageRectRight.x = (int)(overlayParam.width * srcRectRight.x);
imageRectRight.y = (int)(overlayParam.height * srcRectRight.y);
imageRectRight.width = (int)(overlayParam.width * Mathf.Min(srcRectRight.width, 1 - srcRectRight.x));
imageRectRight.height = (int)(overlayParam.height * Mathf.Min(srcRectRight.height, 1 - srcRectRight.y));
return imageRectRight;
}
}
public UInt32 getHDRFlags()
{
UInt32 hdrFlags = 0;
if (!isExternalAndroidSurface)
{
return hdrFlags;
}
switch (hdr)
{
case HDRFlags.HdrPQ:
hdrFlags |= (UInt32)PxrLayerSubmitFlags.PxrLayerFlagColorSpaceHdrPQ;
break;
case HDRFlags.HdrHLG:
hdrFlags |= (UInt32)PxrLayerSubmitFlags.PxrLayerFlagColorSpaceHdrHLG;
break;
default:
break;
}
return hdrFlags;
}
public enum HDRFlags
{
None,
HdrPQ,
HdrHLG,
}
public enum OverlayShape
{
Quad = 1,
Cylinder = 2,
Equirect = 3,
Cubemap = 5,
Eac = 6,
Fisheye = 7,
BlurredQuad = 9
}
public enum OverlayType
{
Overlay = 0,
Underlay = 1
}
public enum TextureType
{
ExternalSurface,
DynamicTexture,
StaticTexture
}
public enum LayerLayout
{
Stereo = 0,
DoubleWide = 1,
Array = 2,
Mono = 3
}
public enum Surface3DType
{
Single = 0,
LeftRight,
TopBottom
}
public enum TextureRect
{
MonoScopic,
StereoScopic,
Custom
}
public enum DestinationRect
{
Default,
Custom
}
public enum EACModelType
{
Eac360 = 0,
Eac360ViewPort = 1,
Eac180 = 4,
Eac180ViewPort = 5,
}
public enum ColorForamt
{
VK_FORMAT_R8G8B8A8_UNORM = 37,
VK_FORMAT_R8G8B8A8_SRGB = 43,
GL_SRGB8_ALPHA8 = 0x8c43,
GL_RGBA8 = 0x8058
}
public enum APIExecutionStatus
{
None,
True,
False
}
public enum BlurredQuadMode
{
SmallWindow,
Immersion
}
}
}

View File

@@ -1,13 +0,0 @@
fileFormatVersion: 2
guid: daeec670ce18c8d488f9f5b2e51c817b
timeCreated: 1590405833
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,214 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll information contained herein is, and remains the property of
PICO Technology Co., Ltd. The intellectual and technical concepts
contained herein are proprietary to PICO Technology Co., Ltd. and may be
covered by patents, patents in process, and are protected by trade secret or
copyright law. Dissemination of this information or reproduction of this
material is strictly forbidden unless prior written permission is obtained from
PICO Technology Co., Ltd.
*******************************************************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Unity.XR.PXR
{
public class PXR_ScreenFade : MonoBehaviour
{
[Tooltip("The gradient of time.")]
public float gradientTime = 5.0f;
[Tooltip("Basic color.")]
public Color fadeColor = new Color(0.0f, 0.0f, 0.0f, 1.0f);
[Tooltip("The default value is 4000.")]
private int renderQueue = 4000;
private MeshRenderer gradientMeshRenderer;
private MeshFilter gradientMeshFilter;
private Material gradientMaterial = null;
private bool isGradient = false;
private float currentAlpha;
private float nowFadeAlpha;
private List<Vector3> verts;
private List<int> indices;
private int N = 5;
void Awake()
{
CreateFadeMesh();
SetCurrentAlpha(0);
}
void OnEnable()
{
StartCoroutine(ScreenFade());
}
void OnDestroy()
{
DestoryGradientMesh();
}
private void CreateFadeMesh()
{
verts = new List<Vector3>();
indices = new List<int>();
gradientMaterial = new Material(Shader.Find("PXR_SDK/PXR_Fade"));
gradientMeshFilter = gameObject.AddComponent<MeshFilter>();
gradientMeshRenderer = gameObject.AddComponent<MeshRenderer>();
CreateModel();
}
public void SetCurrentAlpha(float alpha)
{
currentAlpha = alpha;
SetAlpha();
}
IEnumerator ScreenFade()
{
float nowTime = 0.0f;
while (nowTime < gradientTime)
{
nowTime += Time.deltaTime;
nowFadeAlpha = Mathf.Lerp(1.0f, 0, Mathf.Clamp01(nowTime / gradientTime));
SetAlpha();
yield return null;
}
}
private void SetAlpha()
{
Color color = fadeColor;
color.a = Mathf.Max(currentAlpha, nowFadeAlpha);
isGradient = color.a > 0;
if (gradientMaterial != null)
{
gradientMaterial.color = color;
gradientMaterial.renderQueue = renderQueue;
gradientMeshRenderer.material = gradientMaterial;
gradientMeshRenderer.enabled = isGradient;
}
}
void CreateModel()
{
for (float i = -N / 2f; i <= N / 2f; i++)
{
for (float j = -N / 2f; j <= N / 2f; j++)
{
verts.Add(new Vector3(i, j, -N / 2f));
}
}
for (float i = -N / 2f; i <= N / 2f; i++)
{
for (float j = -N / 2f; j <= N / 2f; j++)
{
verts.Add(new Vector3(N / 2f, j, i));
}
}
for (float i = -N / 2f; i <= N / 2f; i++)
{
for (float j = -N / 2f; j <= N / 2f; j++)
{
verts.Add(new Vector3(i, N / 2f, j));
}
}
for (float i = -N / 2f; i <= N / 2f; i++)
{
for (float j = -N / 2f; j <= N / 2f; j++)
{
verts.Add(new Vector3(-N / 2f, j, i));
}
}
for (float i = -N / 2f; i <= N / 2f; i++)
{
for (float j = -N / 2f; j <= N / 2f; j++)
{
verts.Add(new Vector3(i, j, N / 2f));
}
}
for (float i = -N / 2f; i <= N / 2f; i++)
{
for (float j = -N / 2f; j <= N / 2f; j++)
{
verts.Add(new Vector3(i, -N / 2f, j));
}
}
for (int i = 0; i < verts.Count; i++)
{
verts[i] = verts[i].normalized * 0.7f;
}
CreateMakePos(0);
CreateMakePos(1);
CreateMakePos(2);
OtherMakePos(3);
OtherMakePos(4);
OtherMakePos(5);
Mesh mesh = new Mesh();
mesh.vertices = verts.ToArray();
mesh.triangles = indices.ToArray();
mesh.RecalculateNormals();
mesh.RecalculateBounds();
Vector3[] normals = mesh.normals;
for (int i = 0; i < normals.Length; i++)
{
normals[i] = -normals[i];
}
mesh.normals = normals;
int[] triangles = mesh.triangles;
for (int i = 0; i < triangles.Length; i += 3)
{
int t = triangles[i];
triangles[i] = triangles[i + 2];
triangles[i + 2] = t;
}
mesh.triangles = triangles;
gradientMeshFilter.mesh = mesh;
}
public void CreateMakePos(int num)
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
int index = j * (N + 1) + (N + 1) * (N + 1) * num + i;
int up = (j + 1) * (N + 1) + (N + 1) * (N + 1) * num + i;
indices.AddRange(new int[] { index, index + 1, up + 1 });
indices.AddRange(new int[] { index, up + 1, up });
}
}
}
public void OtherMakePos(int num)
{
for (int i = 0; i < N + 1; i++)
{
for (int j = 0; j < N + 1; j++)
{
if (i != N && j != N)
{
int index = j * (N + 1) + (N + 1) * (N + 1) * num + i;
int up = (j + 1) * (N + 1) + (N + 1) * (N + 1) * num + i;
indices.AddRange(new int[] { index, up + 1, index + 1 });
indices.AddRange(new int[] { index, up, up + 1 });
}
}
}
}
private void DestoryGradientMesh()
{
if (gradientMeshRenderer != null)
Destroy(gradientMeshRenderer);
if (gradientMaterial != null)
Destroy(gradientMaterial);
if (gradientMeshFilter != null)
Destroy(gradientMeshFilter);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 9ee8dd1042c84fa4fa2411e8c4ebcc01
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,421 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll information contained herein is, and remains the property of
PICO Technology Co., Ltd. The intellectual and technical concepts
contained herein are proprietary to PICO Technology Co., Ltd. and may be
covered by patents, patents in process, and are protected by trade secret or
copyright law. Dissemination of this information or reproduction of this
material is strictly forbidden unless prior written permission is obtained from
PICO Technology Co., Ltd.
*******************************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Unity.XR.PXR
{
public delegate void EventDataBufferCallBack(ref PxrEventDataBuffer dataBuffer);
public class PXR_System
{
/// <summary>
/// Gets the SDK version.
/// </summary>
/// <returns>The SDK version.</returns>
public static string GetSDKVersion()
{
return PXR_Plugin.System.UPxr_GetSDKVersion();
}
/// <summary>
/// Gets the predicted time a frame will be displayed after being rendered.
/// </summary>
/// <returns>The predicted time (in miliseconds).</returns>
public static double GetPredictedDisplayTime()
{
return PXR_Plugin.System.UPxr_GetPredictedDisplayTime();
}
/// <summary>
/// Sets the extra latency mode. Note: Call this function once only.
/// </summary>
/// <param name="mode">The latency mode:
/// * `0`: ExtraLatencyModeOff (Disable ExtraLatencyMode mode. This option will display the latest rendered frame for display)
/// * `1`: ExtraLatencyModeOn (Enable ExtraLatencyMode mode. This option will display one frame prior to the latest rendered frame)
/// * `2`: ExtraLatencyModeDynamic (Use system default setup)
/// </param>
/// <returns>Whether the extra latency mode has been set:
/// * `true`: success
/// * `false`: failure
/// </returns>
public static bool SetExtraLatencyMode(int mode)
{
return PXR_Plugin.System.UPxr_SetExtraLatencyMode(mode);
}
/// <summary>
/// Gets the sensor's status.
/// </summary>
/// <returns>The sensor's status:
/// * `0`: null
/// * `1`: 3DoF
/// * `3`: 6DoF
/// </returns>
public static int GetSensorStatus()
{
return PXR_Plugin.System.UPxr_GetSensorStatus();
}
/// <summary>
/// Sets the system display frequency rate.
/// </summary>
/// <param name="rate">The frequency rate: `72`; `90`; `120`. Other values are invalid.</param>
public static void SetSystemDisplayFrequency(float rate)
{
PXR_Plugin.System.UPxr_SetSystemDisplayFrequency(rate);
}
/// <summary>
/// Gets the system display frequency rate.
/// </summary>
/// <returns>The system display frequency rate.</returns>
public static float GetSystemDisplayFrequency()
{
return PXR_Plugin.System.UPxr_GetSystemDisplayFrequency();
}
/// <summary>
/// Gets the predicted status of the sensor.
/// </summary>
/// <param name="sensorState">Sensor's coordinate:
/// * `pose`: in-app coordinate
/// * `globalPose`: global coordinate
/// </param>
/// <param name="sensorFrameIndex">Sensor frame index.</param>
/// <returns>The predicted status of the sensor.</returns>
public static int GetPredictedMainSensorStateNew(ref PxrSensorState2 sensorState, ref int sensorFrameIndex) {
return PXR_Plugin.System.UPxr_GetPredictedMainSensorStateNew(ref sensorState, ref sensorFrameIndex);
}
/// <summary>
/// Enables/disables content protection.
/// </summary>
/// <param name="data">Specifies whether to enable/disable content protection:
/// * `0`: disable
/// * `1`: enable
/// </param>
/// <returns>Whether content protection is successfully enabled/disabled:
/// * `0`: success
/// * `1`: failure
/// </returns>
public static int ContentProtect(int data) {
return PXR_Plugin.System.UPxr_ContentProtect(data);
}
/// <summary>
/// Enables/disables face tracking.
/// @note Only supported by PICO 4 Pro and PICO 4 Enterprise.
/// </summary>
/// <param name="enable">Whether to enable/disable face tracking:
/// * `true`: enable
/// * `false`: disable
/// </param>
public static void EnableFaceTracking(bool enable) {
PXR_Plugin.System.UPxr_EnableFaceTracking(enable);
}
/// <summary>
/// Enables/disables lipsync.
/// @note Only supported by PICO 4 Pro and PICO 4 Enterprise.
/// </summary>
/// <param name="enable">Whether to enable/disable lipsync:
/// * `true`: enable
/// * `false`: disable
/// </param>
public static void EnableLipSync(bool enable){
PXR_Plugin.System.UPxr_EnableLipSync(enable);
}
/// <summary>
/// Gets face tracking data.
/// @note Only supported by PICO 4 Pro and PICO 4 Enterprise.
/// </summary>
/// <param name="ts">(Optional) A reserved parameter, pass `0`.</param>
/// <param name="flags">The face tracking mode to retrieve data for. Enumertions:
/// * `PXR_GET_FACE_DATA_DEFAULT` (invalid, only for making it compatible with older SDK version)
/// * `PXR_GET_FACE_DATA`: face only
/// * `PXR_GET_LIP_DATA`: lipsync only
/// * `PXR_GET_FACELIP_DATA`: hybrid (both face and lipsync)
/// </param>
/// <param name="faceTrackingInfo">Returns the `PxrFaceTrackingInfo` struct that contains the following face tracking data:
/// * `timestamp`: Int64, reserved field
/// * `blendShapeWeight`: float[], pass `0`.
/// * `videoInputValid`: float[], the input validity of the upper and lower parts of the face.
/// * `laughingProb`: float[], the coefficient of laughter.
/// * `emotionProb`: float[], the emotion factor.
/// * `reserved`: float[], reserved field.
/// </param>
public static void GetFaceTrackingData(Int64 ts, GetDataType flags, ref PxrFaceTrackingInfo faceTrackingInfo) {
PXR_Plugin.System.UPxr_GetFaceTrackingData( ts, (int)flags, ref faceTrackingInfo);
}
/// <summary>Sets a GPU or CPU level for the device.</summary>
/// <param name="which">Choose to set a GPU or CPU level:
/// * `CPU`
/// * `GPU`
/// </param>
/// <param name="level">Select a level from the following:
/// * `POWER_SAVINGS`: power-saving level
/// * `SUSTAINED_LOW`: low level
/// * `SUSTAINED_HIGH`: high level
/// * `BOOST`: top-high level, be careful to use this level
/// </param>
/// <returns>
/// * `0`: success
/// * `1`: failure
/// </returns>
public static int SetPerformanceLevels(PxrPerfSettings which, PxrSettingsLevel level)
{
return PXR_Plugin.System.UPxr_SetPerformanceLevels(which, level);
}
/// <summary>Gets the device's GPU or CPU level.</summary>
/// <param name="which">Choose to get GPU or CPU level:
/// * `CPU`
/// * `GPU`
/// </param>
/// <returns>
/// Returns one of the following levels:
/// * `POWER_SAVINGS`: power-saving level
/// * `SUSTAINED_LOW`: low level
/// * `SUSTAINED_HIGH`: high level
/// * `BOOST`: top-high level, be careful to use this level
/// </returns>
public static PxrSettingsLevel GetPerformanceLevels(PxrPerfSettings which)
{
return PXR_Plugin.System.UPxr_GetPerformanceLevels(which);
}
/// <summary>Sets FOV in four directions (left, right, up, and down) for specified eye(s).</summary>
/// <param name="eye">The eye to set FOV for:
/// * `LeftEye`
/// * `RightEye`
/// * `BothEye`
/// </param>
/// <param name="fovLeft">The horizontal FOV (in degrees) for the left part of the eye, for example, `47.5`.</param>
/// <param name="fovRight">The horizontal FOV (in degrees) for the right part of the eye..</param>
/// <param name="fovUp">The vertical FOV (in degrees) for the upper part of the eye.</param>
/// <param name="fovDown">The vertical FOV (in degrees) for the lower part of the eye.</param>
/// <returns>
/// * `0`: success
/// * `1`: failure
/// </returns>
public static int SetEyeFOV(EyeType eye, float fovLeft, float fovRight, float fovUp, float fovDown)
{
return PXR_Plugin.Render.UPxr_SetEyeFOV(eye, fovLeft, fovRight, fovUp, fovDown);
}
/// <summary>
/// Switches the face tracking mode.
/// @note Only supported by PICO 4 Pro and PICO 4 Enterprise.
/// </summary>
/// <param name="value">
/// `STOP_FT`: to stop the "Face Only" mode.
/// `STOP_LIPSYNC`: to stop the "Lipsync Only" mode.
/// `START_FT`: to start the "Face Only" mode.
/// `START_LIPSYNC`: to start the "Lipsync Only" mode.
/// </param>
/// <returns>
/// `0`: success
/// `1`: failure
/// </returns>
public static int SetFaceTrackingStatus(PxrFtLipsyncValue value) {
return PXR_Plugin.System.UPxr_SetFaceTrackingStatus(value);
}
/// <summary>
/// Sets a tracking origin mode for the app.
/// When the user moves in the virtual scene, the system tracks and calculates the user's positional changes based on the origin.
/// </summary>
/// <param name="originMode">Selects a tracking origin mode from the following:
/// * `TrackingOriginModeFlags.Device`: Device mode. The system sets the device's initial position as the origin. The device's height from the floor is not calculated.
/// * `TrackingOriginModeFlags.Floor`: Floor mode. The system sets an origin based on the device's original position and the device's height from the floor.
/// </param>
public static void SetTrackingOrigin(PxrTrackingOrigin originMode)
{
PXR_Plugin.System.UPxr_SetTrackingOrigin(originMode);
}
/// <summary>
/// Gets the tracking origin mode of the app.
/// </summary>
/// <param name="originMode">Returns the app's tracking origin mode:
/// * `TrackingOriginModeFlags.Device`: Device mode
/// * `TrackingOriginModeFlags.Floor`: Floor mode
/// For the description of each mode, refer to `SetTrackingOrigin`.
/// </param>
public static void GetTrackingOrigin(out PxrTrackingOrigin originMode)
{
originMode = PxrTrackingOrigin.Eye;
PXR_Plugin.System.UPxr_GetTrackingOrigin(ref originMode);
}
/// <summary>
/// Turns on the power service for a specified object.
/// </summary>
/// <param name="objName">The name of the object to turn on the power service for.</param>
/// <returns>Whether the power service has been turned on:
/// * `true`: success
/// * `false`: failure
/// </returns>
public static bool StartBatteryReceiver(string objName)
{
return PXR_Plugin.System.UPxr_StartBatteryReceiver(objName);
}
/// <summary>
/// Turns off the power service.
/// </summary>
/// <returns>Whether the power service has been turned off:
/// * `true`: success
/// * `false`: failure
/// </returns>
public static bool StopBatteryReceiver()
{
return PXR_Plugin.System.UPxr_StopBatteryReceiver();
}
/// <summary>
/// Sets the brightness for the current HMD.
/// </summary>
/// <param name="brightness">Target brightness. Value range: [0,255].</param>
/// <returns>Whether the brightness has been set successfully:
/// * `true`: success
/// * `false`: failure
/// </returns>
public static bool SetCommonBrightness(int brightness)
{
return PXR_Plugin.System.UPxr_SetBrightness(brightness);
}
/// <summary>
/// Gets the brightness of the current HMD.
/// </summary>
/// <returns>An int value that indicates the brightness. Value range: [0,255].</returns>
public static int GetCommonBrightness()
{
return PXR_Plugin.System.UPxr_GetCurrentBrightness();
}
/// <summary>
/// Gets the brightness level of the current screen.
/// </summary>
/// <returns>An int array. The first bit is the total brightness level supported, the second bit is the current brightness level, and it is the interval value of the brightness level from the third bit to the end bit.</returns>
public static int[] GetScreenBrightnessLevel()
{
return PXR_Plugin.System.UPxr_GetScreenBrightnessLevel();
}
/// <summary>
/// Sets a brightness level for the current screen.
/// </summary>
/// <param name="brightness">Brightness mode:
/// * `0`: system default brightness setting.
/// * `1`: custom brightness setting, you can then set param `level`.
/// </param>
/// <param name="level">Brightness level. Value range: [1,255].</param>
public static void SetScreenBrightnessLevel(int brightness, int level)
{
PXR_Plugin.System.UPxr_SetScreenBrightnessLevel(brightness, level);
}
/// <summary>
/// Turns on the volume service for a specified object.
/// </summary>
/// <param name="objName">The name of the object to turn on the volume service for.</param>
/// <returns>Whether the volume service has been turned on:
/// * `true`: success
/// * `false`: failure
/// </returns>
public static bool StartAudioReceiver(string objName)
{
return PXR_Plugin.System.UPxr_StartAudioReceiver(objName);
}
/// <summary>
/// Turns off the volume service.
/// </summary>
/// <returns>Whether the volume service has been turned off:
/// * `true`: success
/// * `false`: failure
/// </returns>
public static bool StopAudioReceiver()
{
return PXR_Plugin.System.UPxr_StopAudioReceiver();
}
/// <summary>
/// Gets the maximum volume.
/// </summary>
/// <returns>An int value that indicates the maximum volume.</returns>
public static int GetMaxVolumeNumber()
{
return PXR_Plugin.System.UPxr_GetMaxVolumeNumber();
}
/// <summary>
/// Gets the current volume.
/// </summary>
/// <returns>An int value that indicates the current volume. Value range: [0,15].</returns>
public static int GetCurrentVolumeNumber()
{
return PXR_Plugin.System.UPxr_GetCurrentVolumeNumber();
}
/// <summary>
/// Increases the volume.
/// </summary>
/// <returns>Whether the volume has been increased:
/// * `true`: success
/// * `false`: failure
/// </returns>
public static bool VolumeUp()
{
return PXR_Plugin.System.UPxr_VolumeUp();
}
/// <summary>
/// Decreases the volume.
/// </summary>
/// <returns>Whether the volume has been decreased:
/// * `true`: success
/// * `false`: failure
/// </returns>
public static bool VolumeDown()
{
return PXR_Plugin.System.UPxr_VolumeDown();
}
/// <summary>
/// Sets a volume.
/// </summary>
/// <param name="volume">The target volume. Value range: [0,15].</param>
/// <returns>Whether the target volume has been set:
/// * `true`: success
/// * `false`: failure
/// </returns>
public static bool SetVolumeNum(int volume)
{
return PXR_Plugin.System.UPxr_SetVolumeNum(volume);
}
public static string GetProductName()
{
return PXR_Plugin.System.ProductName;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 00e4f0103b06c774b9ba07b7c06221b6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 52e3f8f00271b644caef0444a6ba66c6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,157 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll information contained herein is, and remains the property of
PICO Technology Co., Ltd. The intellectual and technical concepts
contained herein are proprietary to PICO Technology Co., Ltd. and may be
covered by patents, patents in process, and are protected by trade secret or
copyright law. Dissemination of this information or reproduction of this
material is strictly forbidden unless prior written permission is obtained from
PICO Technology Co., Ltd.
*******************************************************************************/
using System.Collections.Generic;
using UnityEngine;
using Unity.XR.PXR;
public class PXR_Hand : MonoBehaviour
{
public HandType handType;
public Transform Basemesh;
[HideInInspector]
public List<Transform> handJoints = new List<Transform>(new Transform[(int)HandJoint.JointMax]);
public bool Computed { get; private set; }
public Posef RayPose { get; private set; }
public bool RayValid { get; private set; }
public bool Pinch { get; private set; }
public float PinchStrength { get; private set; }
private HandJointLocations handJointLocations = new HandJointLocations();
private HandAimState aimState = new HandAimState();
[SerializeField]
private Transform rayPose;
[SerializeField]
private GameObject defaultRay;
private SkinnedMeshRenderer[] touchRenders;
private bool isaAdaptiveScales = false;
PXR_VstModelPosCheck mOffsetPos=null;
private void Awake()
{
mOffsetPos= GetComponent<PXR_VstModelPosCheck>();
}
private void Start()
{
isaAdaptiveScales = PXR_ProjectSetting.GetProjectConfig().adaptiveHand;
if (defaultRay != null)
{
touchRenders = defaultRay.GetComponentsInChildren<SkinnedMeshRenderer>();
}
}
protected void OnEnable() => Application.onBeforeRender += OnBeforeRender;
protected void OnDisable() => Application.onBeforeRender -= OnBeforeRender;
private void OnBeforeRender()
{
UpdateHandJoints();
UpdateAimState();
UpdateRayPose();
}
private void UpdateHandJoints()
{
if (PXR_HandTracking.GetJointLocations(handType, ref handJointLocations))
{
if (handJointLocations.isActive == 0) return;
if (isaAdaptiveScales)
{
float scale = 0;
PXR_HandTracking.GetHandScale(handType,ref scale);
Basemesh.localScale = Vector3.one*scale;
}
for (int i = 0; i < handJoints.Count; ++i)
{
if (handJoints[i] == null) continue;
if (i == (int)HandJoint.JointWrist)
{
handJoints[i].localPosition = handJointLocations.jointLocations[i].pose.Position.ToVector3();
handJoints[i].localRotation = handJointLocations.jointLocations[i].pose.Orientation.ToQuat();
}
else
{
Pose parentPose = Pose.identity;
if (i == (int)HandJoint.JointPalm ||
i == (int)HandJoint.JointThumbMetacarpal ||
i == (int)HandJoint.JointIndexMetacarpal ||
i == (int)HandJoint.JointMiddleMetacarpal ||
i == (int)HandJoint.JointRingMetacarpal ||
i == (int)HandJoint.JointLittleMetacarpal)
{
parentPose = new Pose(handJointLocations.jointLocations[1].pose.Position.ToVector3(), handJointLocations.jointLocations[1].pose.Orientation.ToQuat());
}
else
{
parentPose = new Pose(handJointLocations.jointLocations[i-1].pose.Position.ToVector3(), handJointLocations.jointLocations[i-1].pose.Orientation.ToQuat());
}
var inverseParentRotation = Quaternion.Inverse(parentPose.rotation);
handJoints[i].localRotation = inverseParentRotation * handJointLocations.jointLocations[i].pose.Orientation.ToQuat();
}
}
if (mOffsetPos)
{
Basemesh.localPosition = handJointLocations.jointLocations[(int)Unity.XR.PXR.HandJoint.JointWrist].pose.Position.ToVector3()+ mOffsetPos.GetHandPosOffset();
}
}
}
private void UpdateAimState()
{
if (PXR_HandTracking.GetAimState(handType, ref aimState))
{
Computed = (aimState.aimStatus&HandAimStatus.AimComputed) != 0;
RayPose = aimState.aimRayPose;
RayValid = (aimState.aimStatus&HandAimStatus.AimRayValid) != 0;
Pinch = (aimState.aimStatus&HandAimStatus.AimRayTouched) != 0;
PinchStrength = aimState.touchStrengthRay;
}
}
private void UpdateRayPose()
{
if (rayPose == null) return;
if (RayValid)
{
rayPose.gameObject.SetActive(true);
rayPose.localPosition = RayPose.Position.ToVector3();
rayPose.localRotation = RayPose.Orientation.ToQuat();
if (defaultRay != null)
{
foreach (var touchRender in touchRenders)
{
touchRender.SetBlendShapeWeight(0, aimState.touchStrengthRay*100);
}
}
}
else
{
rayPose.gameObject.SetActive(false);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: f753f52cc8c63524f9ace6fcab377a5b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,568 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll information contained herein is, and remains the property of
PICO Technology Co., Ltd. The intellectual and technical concepts
contained herein are proprietary to PICO Technology Co., Ltd. and may be
covered by patents, patents in process, and are protected by trade secret or
copyright law. Dissemination of this information or reproduction of this
material is strictly forbidden unless prior written permission is obtained from
PICO Technology Co., Ltd.
*******************************************************************************/
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using System;
using UnityEngine.XR;
namespace Unity.XR.PXR
{
public class PXR_HandPose : MonoBehaviour
{
public TrackType trackType;
public PXR_HandPoseConfig config;
public UnityEvent handPoseStart;
public UpdateEvent handPoseUpdate;
public UnityEvent handPoseEnd;
private List<Vector3> leftJointPos = new List<Vector3>(new Vector3[(int)HandJoint.JointMax]);
private List<Vector3> rightJointPos = new List<Vector3>(new Vector3[(int)HandJoint.JointMax]);
private HandJointLocations leftHandJointLocations = new HandJointLocations();
private HandJointLocations rightHandJointLocations = new HandJointLocations();
private bool poseStateHold;
private bool poseStateActive;
private float poseStateHoldTime;
public enum TrackType
{
Any,
Left,
Right
}
private void HandPoseEventCheck()
{
switch (trackType)
{
case TrackType.Any:
poseStateActive = (leftShapesActive && leftBonesActive && leftTransActive) || (rightShapesActive && rightBonesActive && rightTransActive);
break;
case TrackType.Left:
poseStateActive = leftShapesActive && leftBonesActive && leftTransActive;
break;
case TrackType.Right:
poseStateActive = rightShapesActive && rightBonesActive && rightTransActive;
break;
default:
break;
}
if (poseStateHold != poseStateActive)
{
poseStateHold = poseStateActive;
if (poseStateHold)
{
poseStateActive = true;
if (handPoseStart != null)
{
handPoseStart.Invoke();
}
}
else
{
poseStateActive = false;
if (handPoseStart != null)
{
handPoseEnd.Invoke();
}
}
poseStateHoldTime = 0f;
}
else
{
if (poseStateHold)
{
poseStateHoldTime += Time.deltaTime;
handPoseUpdate.Invoke(poseStateHoldTime);
}
}
}
private bool HoldCheck(bool holdState, float holdDuration, bool resultState, ref float holdTime)
{
if (resultState != holdState)
{
holdTime += Time.deltaTime;
if (holdTime >= holdDuration)
{
resultState = holdState;
}
}
else
{
holdTime = 0;
}
return resultState;
}
private void Start()
{
shapesHoldDuration = config.shapesRecognizer.holdDuration;
bones = config.bonesRecognizer.Bones;
bonesHoldDuration = config.bonesRecognizer.holdDuration;
transTrackAxis = config.transRecognizer.trackAxis;
transSpaceType = config.transRecognizer.spaceType;
transTrackTarget = config.transRecognizer.trackTarget;
transHoldDuration = config.transRecognizer.holdDuration;
transAngleThreshold = config.transRecognizer.angleThreshold;
transThresholdWidth = config.transRecognizer.thresholdWidth;
}
private void Update()
{
if (config == null) return;
InputDevices.GetDeviceAtXRNode(XRNode.Head).TryGetFeatureValue(CommonUsages.devicePosition, out HMDpose);
if (trackType == TrackType.Right || trackType == TrackType.Any)
{
PXR_HandTracking.GetJointLocations(HandType.HandRight, ref rightHandJointLocations);
for (int i = 0; i < rightJointPos.Count; ++i)
{
if (rightHandJointLocations.jointLocations == null) break;
rightJointPos[i] = rightHandJointLocations.jointLocations[i].pose.Position.ToVector3();
if (i == (int)HandJoint.JointWrist)
{
rightWirstPos = rightHandJointLocations.jointLocations[i].pose.Position.ToVector3();
rightWirstRot = rightHandJointLocations.jointLocations[i].pose.Orientation.ToQuat();
}
}
rightShapesHold = ShapesRecognizerCheck(rightJointPos, rightWirstRot * Vector3.left, rightWirstRot * Vector3.back);
rightShapesActive = HoldCheck(rightShapesHold, shapesHoldDuration, rightShapesActive, ref rightShapesHoldTime);
rightBonesHold = BonesCheck(HandType.HandRight);
rightBonesActive = HoldCheck(rightBonesHold, bonesHoldDuration, rightBonesActive, ref rightBonesHoldTime);
rightTransHold = TransCheck(TrackType.Right, rightWirstPos, rightWirstRot, HMDpose, rightTransHold);
rightTransActive = HoldCheck(rightTransHold, transHoldDuration, rightTransActive, ref rightTransHoldTime);
}
if (trackType == TrackType.Left || trackType == TrackType.Any)
{
PXR_HandTracking.GetJointLocations(HandType.HandLeft, ref leftHandJointLocations);
for (int i = 0; i < leftJointPos.Count; ++i)
{
if (leftHandJointLocations.jointLocations == null) break;
leftJointPos[i] = leftHandJointLocations.jointLocations[i].pose.Position.ToVector3();
if (i == (int)HandJoint.JointWrist)
{
leftWirstPos = leftHandJointLocations.jointLocations[i].pose.Position.ToVector3();
leftWirstRot = leftHandJointLocations.jointLocations[i].pose.Orientation.ToQuat();
}
}
leftShapesHold = ShapesRecognizerCheck(leftJointPos, leftWirstRot * Vector3.right, leftWirstRot * Vector3.forward, -1);
leftShapesActive = HoldCheck(leftShapesHold, shapesHoldDuration, leftShapesActive, ref leftShapesHoldTime);
leftBonesHold = BonesCheck(HandType.HandLeft);
leftBonesActive = HoldCheck(leftBonesHold, bonesHoldDuration, leftBonesActive, ref leftBonesHoldTime);
leftTransHold = TransCheck(TrackType.Left, leftWirstPos, leftWirstRot, HMDpose, leftTransHold);
leftTransActive = HoldCheck(leftTransHold, transHoldDuration, leftTransActive, ref leftTransHoldTime);
}
HandPoseEventCheck();
}
#region ShapesRecognizer
private float shapesHoldDuration = 0.09f;
private bool leftShapesHold;
private bool leftShapesActive;
private float leftShapesHoldTime;
private bool rightShapesActive;
private bool rightShapesHold;
private float rightShapesHoldTime;
private bool angleCheckValid = false;
private bool abducCheckOpen = false;
private Vector3 leftWirstPos;
private Vector3 rightWirstPos;
private Quaternion leftWirstRot;
private Quaternion rightWirstRot;
private Vector3 thumb0, thumb1, thumb2, thumb3;
private Vector3 index0, index1, index2, index3;
private Vector3 middle0, middle1, middle2, middle3;
private Vector3 ring0, ring1, ring2, ring3;
private Vector3 pinky0, pinky1, pinky2, pinky3;
private bool thumbFlex, indexFlex, middleFlex, ringFlex, pinkyFlex;
private bool thumbCurl, indexCurl, middleCurl, ringCurl, pinkyCurl;
private bool thumbAbduc, indexAbduc, middleAbduc, ringAbduc, pinkyAbduc;
private bool ShapesRecognizerCheck(List<Vector3> jointPos, Vector3 wirstRight, Vector3 wirstForward, int wirstDirect = 1)
{
thumb0 = jointPos[(int)HandJoint.JointThumbTip];
thumb1 = jointPos[(int)HandJoint.JointThumbDistal];
thumb2 = jointPos[(int)HandJoint.JointThumbProximal];
thumb3 = jointPos[(int)HandJoint.JointThumbMetacarpal];
index0 = jointPos[(int)HandJoint.JointIndexTip];
index1 = jointPos[(int)HandJoint.JointIndexDistal];
index2 = jointPos[(int)HandJoint.JointIndexIntermediate];
index3 = jointPos[(int)HandJoint.JointIndexProximal];
middle0 = jointPos[(int)HandJoint.JointMiddleTip];
middle1 = jointPos[(int)HandJoint.JointMiddleDistal];
middle2 = jointPos[(int)HandJoint.JointMiddleIntermediate];
middle3 = jointPos[(int)HandJoint.JointMiddleProximal];
ring0 = jointPos[(int)HandJoint.JointRingTip];
ring1 = jointPos[(int)HandJoint.JointRingDistal];
ring2 = jointPos[(int)HandJoint.JointRingIntermediate];
ring3 = jointPos[(int)HandJoint.JointRingProximal];
pinky0 = jointPos[(int)HandJoint.JointLittleTip];
pinky1 = jointPos[(int)HandJoint.JointLittleDistal];
pinky2 = jointPos[(int)HandJoint.JointLittleIntermediate];
pinky3 = jointPos[(int)HandJoint.JointLittleProximal];
thumbFlex = FlexionCheck(config.shapesRecognizer.thumb, wirstDirect * wirstRight, wirstDirect * wirstForward);
indexFlex = FlexionCheck(config.shapesRecognizer.index, wirstRight, wirstForward);
middleFlex = FlexionCheck(config.shapesRecognizer.middle, wirstRight, wirstForward);
ringFlex = FlexionCheck(config.shapesRecognizer.ring, wirstRight, wirstForward);
pinkyFlex = FlexionCheck(config.shapesRecognizer.pinky, wirstRight, wirstForward);
thumbCurl = CurlCheck(config.shapesRecognizer.thumb);
indexCurl = CurlCheck(config.shapesRecognizer.index);
middleCurl = CurlCheck(config.shapesRecognizer.middle);
ringCurl = CurlCheck(config.shapesRecognizer.ring);
pinkyCurl = CurlCheck(config.shapesRecognizer.pinky);
thumbAbduc = AbductionCheck(config.shapesRecognizer.thumb);
indexAbduc = AbductionCheck(config.shapesRecognizer.index);
middleAbduc = AbductionCheck(config.shapesRecognizer.middle);
ringAbduc = AbductionCheck(config.shapesRecognizer.ring);
pinkyAbduc = AbductionCheck(config.shapesRecognizer.pinky);
return thumbFlex && indexFlex && middleFlex && ringFlex && pinkyFlex
&& thumbCurl && indexCurl && middleCurl && ringCurl && pinkyCurl
&& thumbAbduc && indexAbduc && middleAbduc && ringAbduc && pinkyAbduc;
}
private bool FlexionCheck(ShapesRecognizer.Finger finger, Vector3 wirstRight, Vector3 wirstForward)
{
if (finger.flexion == ShapesRecognizer.Flexion.Any) return true;
else
{
float flexAngle = 0;
switch (finger.handFinger)
{
case HandFinger.Thumb:
Vector3 thumb23 = (thumb2 - thumb3);
Vector3 thumb23_project = Vector3.ProjectOnPlane(thumb23, wirstRight);
flexAngle = Vector3.Angle(thumb23_project, wirstForward);
break;
case HandFinger.Index:
Vector3 index23 = (index2 - index3);
Vector3 index_project = Vector3.ProjectOnPlane(index23, wirstForward);
flexAngle = Vector3.Angle(index_project, wirstRight);
break;
case HandFinger.Middle:
Vector3 middle23 = (middle2 - middle3);
Vector3 middle_project = Vector3.ProjectOnPlane(middle23, wirstForward);
flexAngle = Vector3.Angle(middle_project, wirstRight);
break;
case HandFinger.Ring:
Vector3 ring23 = (ring2 - ring3);
Vector3 ring_project = Vector3.ProjectOnPlane(ring23, wirstForward);
flexAngle = Vector3.Angle(ring_project, wirstRight);
break;
case HandFinger.Pinky:
Vector3 pinky23 = (pinky2 - pinky3);
Vector3 pinky_project = Vector3.ProjectOnPlane(pinky23, wirstForward);
flexAngle = Vector3.Angle(pinky_project, wirstRight);
break;
default:
break;
}
return AngleCheck(flexAngle, finger.fingerConfigs.flexionConfigs.min, finger.fingerConfigs.flexionConfigs.max, finger.fingerConfigs.flexionConfigs.width,
ShapesRecognizer.flexionMin, ShapesRecognizer.flexionMax);
}
}
private bool CurlCheck(ShapesRecognizer.Finger finger)
{
if (finger.curl == ShapesRecognizer.Curl.Any) return true;
else
{
float curlAngle = 0;
switch (finger.handFinger)
{
case HandFinger.Thumb:
Vector3 thumb01 = (thumb0 - thumb1);
Vector3 thumb32 = (thumb3 - thumb2);
curlAngle = Vector3.Angle(thumb01, thumb32);
break;
case HandFinger.Index:
Vector3 index01 = (index0 - index1);
Vector3 index32 = (index3 - index2);
curlAngle = Vector3.Angle(index32, index01);
break;
case HandFinger.Middle:
Vector3 middle01 = (middle0 - middle1);
Vector3 middle32 = (middle3 - middle2);
curlAngle = Vector3.Angle(middle32, middle01);
break;
case HandFinger.Ring:
Vector3 ring01 = (ring0 - ring1);
Vector3 ring32 = (ring3 - ring2);
curlAngle = Vector3.Angle(ring32, ring01);
break;
case HandFinger.Pinky:
Vector3 pinky01 = (pinky0 - pinky1);
Vector3 pinky32 = (pinky3 - pinky2);
curlAngle = Vector3.Angle(pinky32, pinky01);
break;
default:
break;
}
return AngleCheck(curlAngle, finger.fingerConfigs.curlConfigs.min, finger.fingerConfigs.curlConfigs.max, finger.fingerConfigs.curlConfigs.width,
ShapesRecognizer.curlMin, ShapesRecognizer.curlMax);
}
}
private bool AbductionCheck(ShapesRecognizer.Finger finger)
{
if (finger.abduction == ShapesRecognizer.Abduction.Any) return true;
else
{
float abducAngle = 0;
Vector3 thumb12 = (thumb1 - thumb2);
Vector3 index23 = (index2 - index3);
Vector3 middle23 = (middle2 - middle3);
Vector3 ring23 = (ring2 - ring3);
Vector3 pinky23 = (pinky2 - pinky3);
switch (finger.handFinger)
{
case HandFinger.Thumb:
abducAngle = Vector3.Angle(thumb12, index23);
break;
case HandFinger.Index:
abducAngle = Vector3.Angle(index23, middle23);
break;
case HandFinger.Middle:
abducAngle = Vector3.Angle(middle23, ring23);
break;
case HandFinger.Ring:
abducAngle = Vector3.Angle(ring23, pinky23);
break;
case HandFinger.Pinky:
abducAngle = Vector3.Angle(pinky23, ring23);
break;
default:
break;
}
bool result = false;
if (finger.abduction == ShapesRecognizer.Abduction.Open)
{
result = AbducCheck(abducAngle, finger.fingerConfigs.abductionConfigs.mid, finger.fingerConfigs.abductionConfigs.width); ;
}
else if (finger.abduction == ShapesRecognizer.Abduction.Close)
{
result = !AbducCheck(abducAngle, finger.fingerConfigs.abductionConfigs.mid, finger.fingerConfigs.abductionConfigs.width); ;
}
return result;
}
}
private bool AngleCheck(float angle, float min, float max, float width, float rangeMin, float rangeMax)
{
if (angle > min && angle < max)
{
angleCheckValid = true;
}
if (min - rangeMin <= 1f)
{
angleCheckValid = angle < max;
}
else if (angle < (min - width))
{
angleCheckValid = false;
}
if (rangeMax - max <= 1f)
{
angleCheckValid = angle > min;
}
else if ((angle > (max + width)))
{
angleCheckValid = false;
}
return angleCheckValid;
}
private bool AbducCheck(float angle, float mid, float width)
{
if (angle > mid + width / 2)
{
abducCheckOpen = true;
}
if (angle < mid - width / 2)
{
abducCheckOpen = false;
}
return abducCheckOpen;
}
#endregion
#region BonesRecognizer
private List<BonesRecognizer.BonesGroup> bones;
private bool leftBonesHold;
private bool leftBonesActive;
private float leftBonesHoldTime;
private bool rightBonesHold;
private bool rightBonesActive;
private float rightBonesHoldTime;
private float bonesHoldDuration;
private bool BonesCheck(HandType handType)
{
for (int i = 0; i < bones.Count; i++)
{
float distance = Vector3.Distance(GetHandJoint(handType, bones[i].bone1), GetHandJoint(handType, bones[i].bone2));
if (distance < bones[i].distance - bones[i].thresholdWidth / 2)
{
bones[i].activeState = true;
}
else if (distance > bones[i].distance + bones[i].thresholdWidth / 2)
{
bones[i].activeState = false;
}
if (!bones[i].activeState)
{
return false;
}
}
return true;
}
private Vector3 GetHandJoint(HandType hand, BonesRecognizer.HandBones bone)
{
if (hand == HandType.HandLeft)
{
return leftHandJointLocations.jointLocations[(int)bone].pose.Position.ToVector3();
}
else
{
return rightHandJointLocations.jointLocations[(int)bone].pose.Position.ToVector3();
}
}
#endregion
#region TransRecognizer
private bool leftTransHold;
private bool leftTransActive;
private float leftTransHoldTime;
private bool rightTransHold;
private bool rightTransActive;
private float rightTransHoldTime;
private TransRecognizer.TrackAxis transTrackAxis;
private TransRecognizer.SpaceType transSpaceType;
private TransRecognizer.TrackTarget transTrackTarget;
private float transAngleThreshold;
private float transThresholdWidth;
private float transHoldDuration;
private Vector3 HMDpose;
private Vector3 palmPos;
private Vector3 palmAxis;
private Vector3 targetPos;
private bool TransCheck(TrackType trackType, Vector3 wristPos, Quaternion wristRot, Vector3 headPose, bool holdState)
{
GetTrackAxis(trackType, wristRot);
GetProjectedTarget(headPose, wristRot, wristPos);
float errorAngle = Vector3.Angle(palmAxis, targetPos);
if (errorAngle < transAngleThreshold - transThresholdWidth / 2)
{
holdState = true;
}
if (errorAngle > transAngleThreshold + transThresholdWidth / 2)
{
holdState = false;
}
return holdState;
}
private Vector3 GetTrackAxis(TrackType trackType, Quaternion wristRot)
{
switch (transTrackAxis)
{
case TransRecognizer.TrackAxis.Fingers:
palmAxis = wristRot * Vector3.forward;
break;
case TransRecognizer.TrackAxis.Palm:
palmAxis = wristRot * Vector3.down;
break;
case TransRecognizer.TrackAxis.Thumb:
palmAxis = trackType == TrackType.Right ? wristRot * Vector3.left : wristRot * Vector3.right;
break;
}
return palmAxis;
}
private Vector3 GetProjectedTarget(Vector3 headPose, Quaternion wristRot, Vector3 wristPos)
{
palmPos = wristRot * (trackType == TrackType.Right ? new Vector3(0.08f, 0, 0) : new Vector3(-0.08f, 0, 0)) + wristPos;
switch (transTrackTarget)
{
case TransRecognizer.TrackTarget.TowardsFace:
targetPos = headPose;
break;
case TransRecognizer.TrackTarget.AwayFromFace:
targetPos = palmPos * 2 - headPose;
break;
case TransRecognizer.TrackTarget.WorldUp:
targetPos = palmPos + Vector3.up;
break;
case TransRecognizer.TrackTarget.WorldDown:
targetPos = palmPos + Vector3.down;
break;
}
targetPos -= palmPos;
switch (transSpaceType)
{
case TransRecognizer.SpaceType.WorldSpace:
break;
case TransRecognizer.SpaceType.LocalXY:
targetPos = Vector3.ProjectOnPlane(targetPos, wristRot * Vector3.forward);
break;
case TransRecognizer.SpaceType.LocalXZ:
targetPos = Vector3.ProjectOnPlane(targetPos, wristRot * Vector3.up);
break;
case TransRecognizer.SpaceType.LocalYZ:
targetPos = Vector3.ProjectOnPlane(targetPos, wristRot * Vector3.right);
break;
}
return targetPos;
}
#endregion
[Serializable]
public class UpdateEvent : UnityEvent<float> { }
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 35bed5e2884b6cb4a8f47d89e0bc7401
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,274 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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 UnityEngine;
namespace Unity.XR.PXR
{
[Serializable]
public class PXR_HandPoseConfig : ScriptableObject
{
[DisplayOnly]
public ShapesRecognizer shapesRecognizer;
[DisplayOnly]
public BonesRecognizer bonesRecognizer;
[DisplayOnly]
public TransRecognizer transRecognizer;
}
[Serializable]
public class ShapesRecognizer
{
public Finger thumb = new Finger(HandFinger.Thumb);
public Finger index = new Finger(HandFinger.Index);
public Finger middle = new Finger(HandFinger.Middle);
public Finger ring = new Finger(HandFinger.Ring);
public Finger pinky = new Finger(HandFinger.Pinky);
public float holdDuration = 0.09f;
[Serializable]
public class Finger
{
[HideInInspector]
public HandFinger handFinger;
public Flexion flexion;
public Curl curl;
public Abduction abduction;
public FingerConfigs fingerConfigs;
public Finger(HandFinger finger)
{
handFinger = finger;
flexion = Flexion.Any;
curl = Curl.Any;
abduction = Abduction.Any;
fingerConfigs = new FingerConfigs(finger);
}
}
[Serializable]
public class FingerConfigs
{
public RangeConfigs flexionConfigs;
public RangeConfigs curlConfigs;
public RangeConfigsAbduction abductionConfigs;
public FingerConfigs(HandFinger finger)
{
flexionConfigs = new RangeConfigs(flexionMin, flexionMax, defaultFlexionWidth);
if (finger == HandFinger.Thumb)
{
curlConfigs = new RangeConfigs(curlThumbMin, curlThumbMax, defaultCurlWidth);
abductionConfigs = new RangeConfigsAbduction(abductionThumbMid, abductionThumbWidth);
}
else
{
curlConfigs = new RangeConfigs(curlMin, curlMax, defaultCurlWidth);
abductionConfigs = new RangeConfigsAbduction(abductionMid, abductionWidth);
}
}
}
public enum ShapeType
{
flexion,
curl,
abduction
}
public enum Flexion
{
Any,
Open,
Close,
//Custom
}
public enum Curl
{
Any,
Open,
Close,
//Custom
}
public enum Abduction
{
Any,
Open,
Close,
}
[Serializable]
public class RangeConfigs
{
public float min;
public float max;
public float width;
public RangeConfigs(float n, float m, float w)
{
min = n;
max = m;
width =w;
}
}
[Serializable]
public class RangeConfigsAbduction
{
public float mid;
public float width;
public RangeConfigsAbduction(float m, float w)
{
mid = m;
width = w;
}
}
public const float defaultFlexionWidth = 10f;
public const float flexionThumbOpenMin = 155f;
public const float flexionThumbOpenMax = 180f;
public const float flexionThumbCloseMin = 90f;
public const float flexionThumbCloseMax = 120f;
public const float flexionOpenMin = 144f;
public const float flexionOpenMax = 180f;
public const float flexionCloseMin = 90f;
public const float flexionCloseMax = 126f;
public const float flexionMin = 90f;
public const float flexionMax = 180f;
public const float defaultCurlWidth = 20f;
public const float curlThumbOpenMin = 90f;
public const float curlThumbOpenMax = 180f;
public const float curlThumbCloseMin = 45f;
public const float curlThumbCloseMax = 90f;
public const float curlThumbMin = 45f;
public const float curlThumbMax = 180f;
public const float curlOpenMin = 107f;
public const float curlOpenMax = 180f;
public const float curlCloseMin = 0f;
public const float curlCloseMax = 73f;
public const float curlMin = 0f;
public const float curlMax = 180f;
public const float abductionThumbMid = 13f;
public const float abductionThumbWidth = 6f;
public const float abductionMid = 10f;
public const float abductionWidth = 6f;
public const float abductionMin = 0f;
public const float abductionMax = 90f;
}
[Serializable]
public class BonesRecognizer
{
public List<BonesGroup> Bones = new List<BonesGroup>();
public float holdDuration = 0.022f;
[Serializable]
public class BonesGroup
{
[LabelAttribute("Joint 1")]
public HandBones bone1 = HandBones.Wrist;
[LabelAttribute("Joint 2")]
public HandBones bone2 = HandBones.Wrist;
public float distance = 0.025f;
[LabelAttribute("Margin")]
public float thresholdWidth = 0.003f;
[HideInInspector]
public bool activeState;
}
public enum HandBones
{
Palm = 0,
Wrist = 1,
Thumb_Metacarpal = 2,
Thumb_Proximal = 3,
Thumb_Distal = 4,
Thumb_Tip = 5,
Index_Metacarpal = 6,
Index_Proximal = 7,
Index_Intermediate = 8,
Index_Distal = 9,
Index_Tip = 10,
Middle_Metacarpal = 11,
Middle_Proximal = 12,
Middle_Intermediate = 13,
Middle_Distal = 14,
Middle_Tip = 15,
Ring_Metacarpal = 16,
Ring_Proximal = 17,
Ring_Intermediate = 18,
Ring_Distal = 19,
Ring_Tip = 20,
Little_Metacarpal = 21,
Little_Proximal = 22,
Little_Intermediate = 23,
Little_Distal = 24,
Little_Tip = 25
}
}
[Serializable]
public class TransRecognizer
{
public TrackAxis trackAxis;
public SpaceType spaceType;
public TrackTarget trackTarget;
public enum SpaceType
{
WorldSpace,
LocalXY,
LocalYZ,
LocalXZ
}
public enum TrackAxis
{
Fingers, Palm, Thumb
}
public enum TrackTarget
{
TowardsFace,
AwayFromFace,
WorldUp,
WorldDown,
}
public float angleThreshold = 35f;
public float thresholdWidth = 10f;
public float holdDuration = 0.022f;
}
public class DisplayOnly : PropertyAttribute { }
public class LabelAttribute : PropertyAttribute
{
public string name;
public LabelAttribute(string name)
{
this.name = name;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 0fea894361bde054fbfc4de741aa3483
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,47 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll information contained herein is, and remains the property of
PICO Technology Co., Ltd. The intellectual and technical concepts
contained herein are proprietary to PICO Technology Co., Ltd. and may be
covered by patents, patents in process, and are protected by trade secret or
copyright law. Dissemination of this information or reproduction of this
material is strictly forbidden unless prior written permission is obtained from
PICO Technology Co., Ltd.
*******************************************************************************/
using System.Collections.Generic;
using UnityEngine;
namespace Unity.XR.PXR
{
public class PXR_HandPoseGenerator : MonoBehaviour
{
public PXR_HandPoseConfig config;
public PXR_HandPosePreview preview;
//Shapes
public ShapesRecognizer.Finger thumb = new ShapesRecognizer.Finger(HandFinger.Thumb);
public ShapesRecognizer.Finger index = new ShapesRecognizer.Finger(HandFinger.Index);
public ShapesRecognizer.Finger middle = new ShapesRecognizer.Finger(HandFinger.Middle);
public ShapesRecognizer.Finger ring = new ShapesRecognizer.Finger(HandFinger.Ring);
public ShapesRecognizer.Finger pinky = new ShapesRecognizer.Finger(HandFinger.Pinky);
public float shapesholdDuration = 0.09f;
//Bones
public List<BonesRecognizer.BonesGroup> Bones = new List<BonesRecognizer.BonesGroup>();
public float bonesHoldDuration = 0.022f;
//Trans
public TransRecognizer.TrackAxis trackAxis;
public TransRecognizer.SpaceType spaceType;
public TransRecognizer.TrackTarget trackTarget;
public float angleThreshold = 35f;
public float thresholdWidth = 10f;
public float transHoldDuration = 0.022f;
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 5cbe7cced81af1f46a0aef054af159be
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,361 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll information contained herein is, and remains the property of
PICO Technology Co., Ltd. The intellectual and technical concepts
contained herein are proprietary to PICO Technology Co., Ltd. and may be
covered by patents, patents in process, and are protected by trade secret or
copyright law. Dissemination of this information or reproduction of this
material is strictly forbidden unless prior written permission is obtained from
PICO Technology Co., Ltd.
*******************************************************************************/
using System.Collections.Generic;
using UnityEngine;
using Unity.XR.PXR;
using System;
[ExecuteInEditMode]
public class PXR_HandPosePreview : MonoBehaviour
{
[HideInInspector]public List<Transform> handJoints = new List<Transform>(new Transform[(int)HandJoint.JointMax]);
[HideInInspector] public Vector3[] jointAngles = new Vector3[(int)HandJoint.JointMax];
[HideInInspector] public Transform posePreviewX;
[HideInInspector] public Transform posePreviewY;
[HideInInspector] public Transform handModel;
[HideInInspector] public SkinnedMeshRenderer handAxis;
[HideInInspector] public Transform headModel;
[HideInInspector] public Transform handShadow;
[HideInInspector] public ModelFinger modelThumb = new ModelFinger(ModelFinger.FingerType.thumb);
[HideInInspector] public ModelFinger modelIndex = new ModelFinger(ModelFinger.FingerType.index);
[HideInInspector] public ModelFinger modelMiddle = new ModelFinger(ModelFinger.FingerType.middle);
[HideInInspector] public ModelFinger modelRing = new ModelFinger(ModelFinger.FingerType.ring);
[HideInInspector] public ModelFinger modelLittle = new ModelFinger(ModelFinger.FingerType.little);
[HideInInspector] public Material openMaterial;
[HideInInspector] public Material anyMaterial;
[HideInInspector] public Material openFadeMaterial;
[HideInInspector] public Material anyFadeMaterial;
[HideInInspector] public Material highLightMaterial;
private Vector4 highLightBlendPower;
private int blendPower = Shader.PropertyToID("_BlendPower");
public void UpdateShapeState(ShapesRecognizer shapesConfig)
{
var thumb = shapesConfig.thumb;
var index = shapesConfig.index;
var middle = shapesConfig.middle;
var ring = shapesConfig.ring;
var little = shapesConfig.pinky;
int joint = 0;
Vector3 angle = Vector3.zero;
//thumb
joint = (int)HandJoint.JointThumbProximal;
angle =
thumb.flexion == ShapesRecognizer.Flexion.Close ? new Vector3(52f, -37, -8) :
thumb.abduction == ShapesRecognizer.Abduction.Close ? new Vector3(58f, 16, 1) : jointAngles[joint];
handJoints[joint].localEulerAngles = angle;
joint = (int)HandJoint.JointThumbDistal;
angle =
thumb.curl == ShapesRecognizer.Curl.Close ? new Vector3(36, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
handJoints[joint].localEulerAngles = angle;
modelThumb.HighlightModelJoints(this,thumb.flexion, thumb.curl);
//index
joint = (int)HandJoint.JointIndexProximal;
angle =
index.flexion == ShapesRecognizer.Flexion.Close ? new Vector3(jointAngles[joint].x + 68, jointAngles[joint].y, jointAngles[joint].z) :
index.abduction == ShapesRecognizer.Abduction.Close ? new Vector3(jointAngles[joint].x, 18, jointAngles[joint].z) : jointAngles[joint];
handJoints[joint].localEulerAngles = angle;
joint = (int)HandJoint.JointIndexIntermediate;
angle = index.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 60, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
handJoints[joint].localEulerAngles = angle;
joint = (int)HandJoint.JointIndexDistal;
angle = index.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 65, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
handJoints[joint].localEulerAngles = angle;
modelIndex.HighlightModelJoints(this, index.flexion, index.curl);
//middle
joint = (int)HandJoint.JointMiddleProximal;
angle =
middle.flexion == ShapesRecognizer.Flexion.Close ? new Vector3(jointAngles[joint].x + 68, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
handJoints[joint].localEulerAngles = angle;
joint = (int)HandJoint.JointMiddleIntermediate;
angle = middle.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 60, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
handJoints[joint].localEulerAngles = angle;
joint = (int)HandJoint.JointMiddleDistal;
angle = middle.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 65, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
handJoints[joint].localEulerAngles = angle;
modelMiddle.HighlightModelJoints(this, middle.flexion, middle.curl);
//ring
joint = (int)HandJoint.JointRingProximal;
angle =
ring.flexion == ShapesRecognizer.Flexion.Close ? new Vector3(jointAngles[joint].x + 68, jointAngles[joint].y, jointAngles[joint].z) :
middle.abduction == ShapesRecognizer.Abduction.Close ? new Vector3(jointAngles[joint].x, -18, jointAngles[joint].z) : jointAngles[joint];
handJoints[joint].localEulerAngles = angle;
joint = (int)HandJoint.JointRingIntermediate;
angle = ring.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 60, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
handJoints[joint].localEulerAngles = angle;
joint = (int)HandJoint.JointRingDistal;
angle = ring.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 65, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
handJoints[joint].localEulerAngles = angle;
modelRing.HighlightModelJoints(this, ring.flexion, ring.curl);
//little
joint = (int)HandJoint.JointLittleProximal;
angle =
little.flexion == ShapesRecognizer.Flexion.Close ? new Vector3(jointAngles[joint].x + 68, jointAngles[joint].y, jointAngles[joint].z) :
ring.abduction == ShapesRecognizer.Abduction.Close ? new Vector3(jointAngles[joint].x, -18, jointAngles[joint].z) : jointAngles[joint];
handJoints[joint].localEulerAngles = angle;
joint = (int)HandJoint.JointLittleIntermediate;
angle = little.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 60, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
handJoints[joint].localEulerAngles = angle;
joint = (int)HandJoint.JointLittleDistal;
angle = little.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 65, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
handJoints[joint].localEulerAngles = angle;
modelLittle.HighlightModelJoints(this, little.flexion, little.curl);
//abduction highlight
highLightBlendPower.w = thumb.abduction == ShapesRecognizer.Abduction.Any ? 0 : 1;
highLightBlendPower.x = index.abduction == ShapesRecognizer.Abduction.Any ? 0 : 1;
highLightBlendPower.y = middle.abduction == ShapesRecognizer.Abduction.Any ? 0 : 1;
highLightBlendPower.z = ring.abduction == ShapesRecognizer.Abduction.Any ? 0 : 1;
highLightMaterial.SetVector(blendPower, highLightBlendPower);
}
public void ResetShapeState()
{
for (int i = 0; i < handJoints.Count; i++)
{
handJoints[i].localEulerAngles = jointAngles[i];
}
modelThumb.HighlightModelJoints(this, ShapesRecognizer.Flexion.Any, ShapesRecognizer.Curl.Any);
modelIndex.HighlightModelJoints(this, ShapesRecognizer.Flexion.Any, ShapesRecognizer.Curl.Any);
modelMiddle.HighlightModelJoints(this, ShapesRecognizer.Flexion.Any, ShapesRecognizer.Curl.Any);
modelRing.HighlightModelJoints(this, ShapesRecognizer.Flexion.Any, ShapesRecognizer.Curl.Any);
modelLittle.HighlightModelJoints(this, ShapesRecognizer.Flexion.Any, ShapesRecognizer.Curl.Any);
highLightMaterial.SetVector(blendPower, Vector4.zero);
}
public void ResetTransformState()
{
headModel.gameObject.SetActive(false);
handAxis.gameObject.SetActive(false);
handModel.localEulerAngles = new Vector3(-90, 180, 0);
}
public void UpdateTransformState(TransRecognizer transRecognizer)
{
handAxis.gameObject.SetActive(true);
switch (transRecognizer.trackAxis)
{
case TransRecognizer.TrackAxis.Fingers:
handAxis.SetBlendShapeWeight(0, 100);
handAxis.SetBlendShapeWeight(1, 0);
handAxis.SetBlendShapeWeight(2, 0);
break;
case TransRecognizer.TrackAxis.Palm:
handAxis.SetBlendShapeWeight(0, 0);
handAxis.SetBlendShapeWeight(1, 0);
handAxis.SetBlendShapeWeight(2, 100);
break;
case TransRecognizer.TrackAxis.Thumb:
handAxis.SetBlendShapeWeight(0, 0);
handAxis.SetBlendShapeWeight(1, 100);
handAxis.SetBlendShapeWeight(2, 0);
break;
default:
break;
}
switch (transRecognizer.trackTarget)
{
case TransRecognizer.TrackTarget.TowardsFace:
headModel.gameObject.SetActive(true);
headModel.localPosition = new Vector3(0, 0.05f, -0.24f);
headModel.localEulerAngles = Vector3.zero;
handModel.localEulerAngles =
transRecognizer.trackAxis == TransRecognizer.TrackAxis.Fingers ? new Vector3(0, 180, 0) :
transRecognizer.trackAxis == TransRecognizer.TrackAxis.Palm ? new Vector3(-90, 180, 0) : new Vector3(-90, 0, -90);
break;
case TransRecognizer.TrackTarget.AwayFromFace:
headModel.gameObject.SetActive(true);
headModel.localPosition = new Vector3(0, 0.05f, 0.24f);
headModel.localEulerAngles = new Vector3(0, 180, 0);
handModel.localEulerAngles =
transRecognizer.trackAxis == TransRecognizer.TrackAxis.Fingers ? new Vector3(0, 180, 0) :
transRecognizer.trackAxis == TransRecognizer.TrackAxis.Palm ? new Vector3(-90, 180, 0) : new Vector3(-90, 0, -90);
break;
case TransRecognizer.TrackTarget.WorldUp:
headModel.gameObject.SetActive(false);
handModel.localEulerAngles =
transRecognizer.trackAxis == TransRecognizer.TrackAxis.Fingers ? new Vector3(-90, 0, 0) :
transRecognizer.trackAxis == TransRecognizer.TrackAxis.Palm ? new Vector3(0, 0, 180) : new Vector3(0, 0, -90);
break;
case TransRecognizer.TrackTarget.WorldDown:
headModel.gameObject.SetActive(false);
handModel.localEulerAngles =
transRecognizer.trackAxis == TransRecognizer.TrackAxis.Fingers ? new Vector3(90, 0, 0) :
transRecognizer.trackAxis == TransRecognizer.TrackAxis.Palm ? Vector3.zero : new Vector3(0, 0, 90);
break;
default:
break;
}
if (handModel.localEulerAngles.x == 0)
{
handShadow.GetChild(0).gameObject.SetActive(false);
handShadow.GetChild(1).gameObject.SetActive(true);
}
else
{
handShadow.GetChild(0).gameObject.SetActive(true);
handShadow.GetChild(1).gameObject.SetActive(false);
}
}
[Serializable]
public class ModelFinger
{
public FingerType Type;
public List<Transform> flexionTransforms = new List<Transform>();
public List<MeshRenderer> flexionMeshRenderers = new List<MeshRenderer>();
public List<Transform> curlTransforms = new List<Transform>();
public List<MeshRenderer> curlMeshRenderers = new List<MeshRenderer>();
public enum ModelJoint
{
metacarpal = 0,
proximal = 1,
intermediate = 2,
distal = 3,
tip = 4
}
public enum FingerType
{
thumb,
index,
middle,
ring,
little
}
public ModelFinger(FingerType type)
{
Type = type;
}
public void RefreshModelJoints(Transform transform)
{
if (flexionTransforms.Count == 0 || curlTransforms.Count == 0)
{
flexionTransforms.Clear();
curlTransforms.Clear();
flexionMeshRenderers.Clear();
curlMeshRenderers.Clear();
var baseTransform = transform.GetChild(1);
for (int i = 0; i < baseTransform.childCount; i++)
{
if (baseTransform.GetChild(i).name.EndsWith($"{Type}_{ModelJoint.metacarpal}"))
{
baseTransform = baseTransform.GetChild(i);
break;
}
}
flexionTransforms.Add(GetModelJoint(baseTransform, ModelJoint.proximal));
curlTransforms.Add(GetModelJoint(baseTransform, ModelJoint.intermediate));
if (Type != FingerType.thumb)
{
curlTransforms.Add(GetModelJoint(baseTransform, ModelJoint.distal));
}
foreach (var flexionTransform in flexionTransforms)
{
flexionMeshRenderers.Add(flexionTransform.Find("Bone").GetComponent<MeshRenderer>());
flexionMeshRenderers.Add(flexionTransform.Find("Pointer").GetComponent<MeshRenderer>());
flexionMeshRenderers.Add(flexionTransform.parent.Find("Bone").GetComponent<MeshRenderer>());
}
foreach (var curlTransform in curlTransforms)
{
var mesh = curlTransform.Find("Bone").GetComponent<MeshRenderer>();
if (!curlMeshRenderers.Contains(mesh)) curlMeshRenderers.Add(mesh);
mesh = curlTransform.Find("Pointer").GetComponent<MeshRenderer>();
if (!curlMeshRenderers.Contains(mesh)) curlMeshRenderers.Add(mesh);
mesh = curlTransform.parent.Find("Bone").GetComponent<MeshRenderer>();
if (!curlMeshRenderers.Contains(mesh)) curlMeshRenderers.Add(mesh);
}
if (Type != FingerType.thumb)
{
var m = GetModelJoint(baseTransform, ModelJoint.tip).Find("Pointer")
.GetComponent<MeshRenderer>();
if (!curlMeshRenderers.Contains(m)) curlMeshRenderers.Add(m);
}
else
{
var m = GetModelJoint(baseTransform, ModelJoint.distal).Find("Pointer")
.GetComponent<MeshRenderer>();
if (!curlMeshRenderers.Contains(m)) curlMeshRenderers.Add(m);
}
}
}
public void HighlightModelJoints(PXR_HandPosePreview handPosePreview, ShapesRecognizer.Flexion flexion, ShapesRecognizer.Curl curl)
{
foreach (var mesh in flexionMeshRenderers)
{
mesh.material = flexion != ShapesRecognizer.Flexion.Any ? handPosePreview.openMaterial : handPosePreview.anyMaterial;
}
foreach (var mesh in curlMeshRenderers)
{
mesh.material = curl != ShapesRecognizer.Curl.Any ? handPosePreview.openMaterial : handPosePreview.anyMaterial;
}
flexionMeshRenderers[2].material = flexion != ShapesRecognizer.Flexion.Any ? handPosePreview.openFadeMaterial : handPosePreview.anyFadeMaterial;
}
private Transform GetModelJoint(Transform tran, ModelJoint type)
{
for (int i = 0; i < (int)type; i++)
{
tran = tran.GetChild(2);
}
return tran;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: ea4ea412f6917124397eeba0f097ec6f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,602 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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 Unity.Collections;
using UnityEngine;
using UnityEngine.Scripting;
using System.Runtime.CompilerServices;
using UnityEngine.XR.Management;
using UnityEngine.InputSystem;
using UnityEngine.XR;
using System.Collections.Generic;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.XR;
#if XR_HANDS
using UnityEngine.XR.Hands;
using UnityEngine.XR.Hands.ProviderImplementation;
namespace Unity.XR.PXR
{
[Preserve]
/// <summary>
/// Implement Unity XRHandSubSystem
/// Reference: https://docs.unity3d.com/Packages/com.unity.xr.hands@1.1/manual/implement-a-provider.html
/// </summary>
public class PXR_HandSubSystem : XRHandSubsystem
{
XRHandProviderUtility.SubsystemUpdater m_Updater;
// This method registers the subsystem descriptor with the SubsystemManager
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
static void RegisterDescriptor()
{
var handsSubsystemCinfo = new XRHandSubsystemDescriptor.Cinfo
{
id = "PICO Hands",
providerType = typeof(PXRHandSubsystemProvider),
subsystemTypeOverride = typeof(PXR_HandSubSystem)
};
XRHandSubsystemDescriptor.Register(handsSubsystemCinfo);
}
protected override void OnCreate()
{
base.OnCreate();
m_Updater = new XRHandProviderUtility.SubsystemUpdater(this);
}
protected override void OnStart()
{
Debug.Log("PXR_HandSubSystem Start");
m_Updater.Start();
base.OnStart();
}
protected override void OnStop()
{
m_Updater.Stop();
base.OnStop();
}
protected override void OnDestroy()
{
m_Updater.Destroy();
m_Updater = null;
base.OnDestroy();
}
class PXRHandSubsystemProvider : XRHandSubsystemProvider
{
HandJointLocations jointLocations = new HandJointLocations();
readonly HandLocationStatus AllStatus = HandLocationStatus.PositionTracked | HandLocationStatus.PositionValid |
HandLocationStatus.OrientationTracked | HandLocationStatus.OrientationValid;
bool isValid = false;
public override void Start()
{
CreateHands();
}
public override void Stop()
{
DestroyHands();
}
public override void Destroy()
{
}
/// <summary>
/// Mapping the PICO Joint Index To Unity Joint Index
/// </summary>
static int[] pxrJointIndexToUnityJointIndexMapping;
static void Initialize()
{
if (pxrJointIndexToUnityJointIndexMapping == null)
{
pxrJointIndexToUnityJointIndexMapping = new int[(int)HandJoint.JointMax];
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointPalm] = XRHandJointID.Palm.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointWrist] = XRHandJointID.Wrist.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointThumbMetacarpal] = XRHandJointID.ThumbMetacarpal.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointThumbProximal] = XRHandJointID.ThumbProximal.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointThumbDistal] = XRHandJointID.ThumbDistal.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointThumbTip] = XRHandJointID.ThumbTip.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointIndexMetacarpal] = XRHandJointID.IndexMetacarpal.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointIndexProximal] = XRHandJointID.IndexProximal.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointIndexIntermediate] = XRHandJointID.IndexIntermediate.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointIndexDistal] = XRHandJointID.IndexDistal.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointIndexTip] = XRHandJointID.IndexTip.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointMiddleMetacarpal] = XRHandJointID.MiddleMetacarpal.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointMiddleProximal] = XRHandJointID.MiddleProximal.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointMiddleIntermediate] = XRHandJointID.MiddleIntermediate.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointMiddleDistal] = XRHandJointID.MiddleDistal.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointMiddleTip] = XRHandJointID.MiddleTip.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointRingMetacarpal] = XRHandJointID.RingMetacarpal.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointRingProximal] = XRHandJointID.RingProximal.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointRingIntermediate] = XRHandJointID.RingIntermediate.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointRingDistal] = XRHandJointID.RingDistal.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointRingTip] = XRHandJointID.RingTip.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointLittleMetacarpal] = XRHandJointID.LittleMetacarpal.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointLittleProximal] = XRHandJointID.LittleProximal.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointLittleIntermediate] = XRHandJointID.LittleIntermediate.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointLittleDistal] = XRHandJointID.LittleDistal.ToIndex();
pxrJointIndexToUnityJointIndexMapping[(int)HandJoint.JointLittleTip] = XRHandJointID.LittleTip.ToIndex();
}
}
/// <summary>
/// Gets the layout of hand joints for this provider, by having the
/// provider mark each index corresponding to a <see cref="XRHandJointID"/>
/// get marked as <see langword="true"/> if the provider attempts to track
/// that joint.
/// </summary>
/// <remarks>
/// Called once on creation so that before the subsystem is even started,
/// so the user can immediately create a valid hierarchical structure as
/// soon as they get a reference to the subsystem without even needing to
/// start it.
/// </remarks>
/// <param name="handJointsInLayout">
/// Each index corresponds to a <see cref="XRHandJointID"/>. For each
/// joint that the provider will attempt to track, mark that spot as
/// <see langword="true"/> by calling <c>.ToIndex()</c> on that ID.
/// </param>
public override void GetHandLayout(NativeArray<bool> handJointsInLayout)
{
Initialize();
handJointsInLayout[XRHandJointID.Palm.ToIndex()] = true;
handJointsInLayout[XRHandJointID.Wrist.ToIndex()] = true;
handJointsInLayout[XRHandJointID.ThumbMetacarpal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.ThumbProximal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.ThumbDistal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.ThumbTip.ToIndex()] = true;
handJointsInLayout[XRHandJointID.IndexMetacarpal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.IndexProximal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.IndexIntermediate.ToIndex()] = true;
handJointsInLayout[XRHandJointID.IndexDistal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.IndexTip.ToIndex()] = true;
handJointsInLayout[XRHandJointID.MiddleMetacarpal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.MiddleProximal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.MiddleIntermediate.ToIndex()] = true;
handJointsInLayout[XRHandJointID.MiddleDistal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.MiddleTip.ToIndex()] = true;
handJointsInLayout[XRHandJointID.RingMetacarpal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.RingProximal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.RingIntermediate.ToIndex()] = true;
handJointsInLayout[XRHandJointID.RingDistal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.RingTip.ToIndex()] = true;
handJointsInLayout[XRHandJointID.LittleMetacarpal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.LittleProximal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.LittleIntermediate.ToIndex()] = true;
handJointsInLayout[XRHandJointID.LittleDistal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.LittleTip.ToIndex()] = true;
isValid = true;
}
/// <summary>
/// Attempts to retrieve current hand-tracking data from the provider.
/// </summary>
public override UpdateSuccessFlags TryUpdateHands(
UpdateType updateType,
ref Pose leftHandRootPose,
NativeArray<XRHandJoint> leftHandJoints,
ref Pose rightHandRootPose,
NativeArray<XRHandJoint> rightHandJoints)
{
if (!isValid)
return UpdateSuccessFlags.None;
UpdateSuccessFlags ret = UpdateSuccessFlags.None;
const int handRootIndex = (int)HandJoint.JointWrist;
if (PXR_HandTracking.GetJointLocations(HandType.HandLeft, ref jointLocations))
{
if (jointLocations.isActive != 0U)
{
for (int index = 0, jointCount = (int)jointLocations.jointCount; index < jointCount; ++index)
{
ref HandJointLocation joint = ref jointLocations.jointLocations[index];
int unityHandJointIndex = pxrJointIndexToUnityJointIndexMapping[index];
leftHandJoints[unityHandJointIndex] = CreateXRHandJoint(Handedness.Left, unityHandJointIndex, joint);
if (index == handRootIndex)
{
leftHandRootPose = PXRPosefToUnityPose(joint.pose);
ret |= UpdateSuccessFlags.LeftHandRootPose;
}
}
if (PicoAimHand.left.UpdateHand(HandType.HandLeft, (ret & UpdateSuccessFlags.LeftHandRootPose) != 0))
{
ret |= UpdateSuccessFlags.LeftHandJoints;
}
}
}
if (PXR_HandTracking.GetJointLocations(HandType.HandRight, ref jointLocations))
{
if (jointLocations.isActive != 0U)
{
for (int index = 0, jointCount = (int)jointLocations.jointCount; index < jointCount; ++index)
{
ref HandJointLocation joint = ref jointLocations.jointLocations[index];
int unityHandJointIndex = pxrJointIndexToUnityJointIndexMapping[index];
rightHandJoints[unityHandJointIndex] = CreateXRHandJoint(Handedness.Right, unityHandJointIndex, joint);
if (index == handRootIndex)
{
rightHandRootPose = PXRPosefToUnityPose(joint.pose);
ret |= UpdateSuccessFlags.RightHandRootPose;
}
}
if (PicoAimHand.right.UpdateHand(HandType.HandRight, (ret & UpdateSuccessFlags.RightHandRootPose) != 0))
{
ret |= UpdateSuccessFlags.RightHandJoints;
}
}
}
return ret;
}
void CreateHands()
{
if (PicoAimHand.left == null)
PicoAimHand.left = PicoAimHand.CreateHand(InputDeviceCharacteristics.Left);
if (PicoAimHand.right == null)
PicoAimHand.right = PicoAimHand.CreateHand(InputDeviceCharacteristics.Right);
}
void DestroyHands()
{
if (PicoAimHand.left != null)
{
InputSystem.RemoveDevice(PicoAimHand.left);
PicoAimHand.left = null;
}
if (PicoAimHand.right != null)
{
InputSystem.RemoveDevice(PicoAimHand.right);
PicoAimHand.right = null;
}
}
/// <summary>
/// Create Unity XRHandJoint From PXR HandJointLocation
/// </summary>
/// <param name="handedness"></param>
/// <param name="unityHandJointIndex"></param>
/// <param name="joint"></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
XRHandJoint CreateXRHandJoint(Handedness handedness, int unityHandJointIndex, in HandJointLocation joint)
{
Pose pose = Pose.identity;
XRHandJointTrackingState state = XRHandJointTrackingState.None;
if ((joint.locationStatus & AllStatus) == AllStatus)
{
state = (XRHandJointTrackingState.Pose | XRHandJointTrackingState.Radius);
pose = PXRPosefToUnityPose(joint.pose);
}
return XRHandProviderUtility.CreateJoint(handedness,
state,
XRHandJointIDUtility.FromIndex(unityHandJointIndex),
pose, joint.radius
);
}
/// <summary>
/// PXR's Posef to Unity'Pose
/// </summary>
/// <param name="pxrPose"></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
Pose PXRPosefToUnityPose(in Posef pxrPose)
{
Vector3 position = pxrPose.Position.ToVector3();
Quaternion orientation = pxrPose.Orientation.ToQuat();
return new Pose(position, orientation);
}
}
}
/// <remarks>
/// The <see cref="TrackedDevice.devicePosition"/> and
/// <see cref="TrackedDevice.deviceRotation"/> inherited from <see cref="TrackedDevice"/>
/// represent the aim pose. You can use these values to discover the target for pinch gestures,
/// when appropriate.
///
/// Use the [XROrigin](xref:Unity.XR.CoreUtils.XROrigin) in the scene to position and orient
/// the device properly. If you are using this data to set the Transform of a GameObject in
/// the scene hierarchy, you can set the local position and rotation of the Transform and make
/// it a child of the <c>CameraOffset</c> object below the <c>XROrigin</c>. Otherwise, you can use the
/// Transform of the <c>CameraOffset</c> to transform the data into world space.
/// </remarks>
#if UNITY_EDITOR
[UnityEditor.InitializeOnLoad]
#endif
[Preserve, InputControlLayout(displayName = "Pico Aim Hand", commonUsages = new[] { "LeftHand", "RightHand" })]
public partial class PicoAimHand : TrackedDevice
{
/// <summary>
/// The left-hand <see cref="InputDevice"/> that contains
/// <see cref="InputControl"/>s that surface data in the Pico Hand
/// Tracking Aim extension.
/// </summary>
/// <remarks>
/// It is recommended that you treat this as read-only, and do not set
/// it yourself. It will be set for you if hand-tracking has been
/// enabled and if you are running with either the OpenXR or Oculus
/// plug-in.
/// </remarks>
public static PicoAimHand left { get; set; }
/// <summary>
/// The right-hand <see cref="InputDevice"/> that contains
/// <see cref="InputControl"/>s that surface data in the Pico Hand
/// Tracking Aim extension.
/// </summary>
/// <remarks>
/// It is recommended that you treat this as read-only, and do not set
/// it yourself. It will be set for you if hand-tracking has been
/// enabled and if you are running with either the OpenXR or Oculus
/// plug-in.
/// </remarks>
public static PicoAimHand right { get; set; }
/// <summary>
/// The pinch amount required to register as being pressed for the
/// purposes of <see cref="indexPressed"/>, <see cref="middlePressed"/>,
/// <see cref="ringPressed"/>, and <see cref="littlePressed"/>.
/// </summary>
public const float pressThreshold = 0.8f;
/// <summary>
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl)
/// that represents whether the pinch between the index finger and
/// the thumb is mostly pressed (greater than a threshold of <c>0.8</c>
/// contained in <see cref="pressThreshold"/>).
/// </summary>
[Preserve, InputControl(offset = 0)]
public ButtonControl indexPressed { get; private set; }
/// <summary>
/// Cast the result of reading this to <see cref="PicoAimFlags"/> to examine the value.
/// </summary>
[Preserve, InputControl]
public IntegerControl aimFlags { get; private set; }
/// <summary>
/// An [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl)
/// that represents the pinch strength between the index finger and
/// the thumb.
/// </summary>
/// <remarks>
/// A value of <c>0</c> denotes no pinch at all, while a value of
/// <c>1</c> denotes a full pinch.
/// </remarks>
[Preserve, InputControl]
public AxisControl pinchStrengthIndex { get; private set; }
/// <summary>
/// Perform final initialization tasks after the control hierarchy has been put into place.
/// </summary>
protected override void FinishSetup()
{
base.FinishSetup();
indexPressed = GetChildControl<ButtonControl>(nameof(indexPressed));
aimFlags = GetChildControl<IntegerControl>(nameof(aimFlags));
pinchStrengthIndex = GetChildControl<AxisControl>(nameof(pinchStrengthIndex));
var deviceDescriptor = XRDeviceDescriptor.FromJson(description.capabilities);
if (deviceDescriptor != null)
{
if ((deviceDescriptor.characteristics & InputDeviceCharacteristics.Left) != 0)
InputSystem.SetDeviceUsage(this, UnityEngine.InputSystem.CommonUsages.LeftHand);
else if ((deviceDescriptor.characteristics & InputDeviceCharacteristics.Right) != 0)
InputSystem.SetDeviceUsage(this, UnityEngine.InputSystem.CommonUsages.RightHand);
}
}
/// <summary>
/// Creates a <see cref="PicoAimHand"/> and adds it to the Input System.
/// </summary>
/// <param name="extraCharacteristics">
/// Additional characteristics to build the hand device with besides
/// <see cref="InputDeviceCharacteristics.HandTracking"/> and <see cref="InputDeviceCharacteristics.TrackedDevice"/>.
/// </param>
/// <returns>
/// A <see cref="PicoAimHand"/> retrieved from
/// <see cref="InputSystem.AddDevice(InputDeviceDescription)"/>.
/// </returns>
/// <remarks>
/// It is recommended that you do not call this yourself. It will be
/// called for you at the appropriate time if hand-tracking has been
/// enabled and if you are running with either the OpenXR or Oculus
/// plug-in.
/// </remarks>
public static PicoAimHand CreateHand(InputDeviceCharacteristics extraCharacteristics)
{
var desc = new InputDeviceDescription
{
product = k_PicoAimHandDeviceProductName,
capabilities = new XRDeviceDescriptor
{
characteristics = InputDeviceCharacteristics.HandTracking | InputDeviceCharacteristics.TrackedDevice | extraCharacteristics,
inputFeatures = new List<XRFeatureDescriptor>
{
new XRFeatureDescriptor
{
name = "index_pressed",
featureType = FeatureType.Binary
},
new XRFeatureDescriptor
{
name = "aim_flags",
featureType = FeatureType.DiscreteStates
},
new XRFeatureDescriptor
{
name = "aim_pose_position",
featureType = FeatureType.Axis3D
},
new XRFeatureDescriptor
{
name = "aim_pose_rotation",
featureType = FeatureType.Rotation
},
new XRFeatureDescriptor
{
name = "pinch_strength_index",
featureType = FeatureType.Axis1D
}
}
}.ToJson()
};
return InputSystem.AddDevice(desc) as PicoAimHand;
}
/// <summary>
/// Queues update events in the Input System based on the supplied hand.
/// It is not recommended that you call this directly. This will be called
/// for you when appropriate.
/// </summary>
/// <param name="isHandRootTracked">
/// Whether the hand root pose is valid.
/// </param>
/// <param name="aimFlags">
/// The aim flags to update in the Input System.
/// </param>
/// <param name="aimPose">
/// The aim pose to update in the Input System. Used if the hand root is tracked.
/// </param>
/// <param name="pinchIndex">
/// The pinch strength for the index finger to update in the Input System.
/// </param>
public void UpdateHand(bool isHandRootTracked, HandAimStatus aimFlags, Posef aimPose, float pinchIndex)
{
if (aimFlags != m_PreviousFlags)
{
InputSystem.QueueDeltaStateEvent(this.aimFlags, (int)aimFlags);
m_PreviousFlags = aimFlags;
}
bool isIndexPressed = pinchIndex > pressThreshold;
if (isIndexPressed != m_WasIndexPressed)
{
InputSystem.QueueDeltaStateEvent(indexPressed, isIndexPressed);
m_WasIndexPressed = isIndexPressed;
}
InputSystem.QueueDeltaStateEvent(pinchStrengthIndex, pinchIndex);
if ((aimFlags & HandAimStatus.AimComputed) == 0)
{
if (m_WasTracked)
{
InputSystem.QueueDeltaStateEvent(isTracked, false);
InputSystem.QueueDeltaStateEvent(trackingState, InputTrackingState.None);
m_WasTracked = false;
}
return;
}
if (isHandRootTracked)
{
InputSystem.QueueDeltaStateEvent(devicePosition, aimPose.Position.ToVector3());
InputSystem.QueueDeltaStateEvent(deviceRotation, aimPose.Orientation.ToQuat());
if (!m_WasTracked)
{
InputSystem.QueueDeltaStateEvent(trackingState, InputTrackingState.Position | InputTrackingState.Rotation);
InputSystem.QueueDeltaStateEvent(isTracked, true);
}
m_WasTracked = true;
}
else if (m_WasTracked)
{
InputSystem.QueueDeltaStateEvent(trackingState, InputTrackingState.None);
InputSystem.QueueDeltaStateEvent(isTracked, false);
m_WasTracked = false;
}
}
internal bool UpdateHand(HandType handType, bool isHandRootTracked)
{
HandAimState handAimState = new HandAimState();
PXR_HandTracking.GetAimState(handType, ref handAimState);
UpdateHand(
isHandRootTracked,
handAimState.aimStatus,
handAimState.aimRayPose,
handAimState.touchStrengthRay);
return (handAimState.aimStatus&HandAimStatus.AimComputed) != 0;
}
#if UNITY_EDITOR
static PicoAimHand() => RegisterLayout();
#endif
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
static void RegisterLayout()
{
InputSystem.RegisterLayout<PicoAimHand>(
matches: new InputDeviceMatcher()
.WithProduct(k_PicoAimHandDeviceProductName));
}
const string k_PicoAimHandDeviceProductName = "Pico Aim Hand Tracking";
HandAimStatus m_PreviousFlags;
bool m_WasTracked;
bool m_WasIndexPressed;
}
}
#endif //XR_HANDS

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d52208075b354ec4b91ede460034a741
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,626 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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 UnityEngine;
using UnityEngine.XR.Management;
using UnityEngine.XR;
using AOT;
#if UNITY_INPUT_SYSTEM
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.XR;
using Unity.XR.PXR.Input;
using System.Linq;
#endif
#if UNITY_EDITOR
using UnityEditor;
#endif
#if AR_FOUNDATION
using UnityEngine.XR.ARSubsystems;
#endif
#if XR_HANDS
using UnityEngine.XR.Hands;
#endif
namespace Unity.XR.PXR
{
#if UNITY_INPUT_SYSTEM
#if UNITY_EDITOR
[InitializeOnLoad]
#endif
static class InputLayoutLoader
{
static InputLayoutLoader()
{
RegisterInputLayouts();
}
public static void RegisterInputLayouts()
{
InputSystem.RegisterLayout<PXR_HMD>(matches: new InputDeviceMatcher().WithInterface(XRUtilities.InterfaceMatchAnyVersion).WithProduct(@"^(PICO HMD)|^(PICO Neo)|^(PICO G)"));
InputSystem.RegisterLayout<PXR_Controller>(matches: new InputDeviceMatcher().WithInterface(XRUtilities.InterfaceMatchAnyVersion).WithProduct(@"^(PICO Controller)"));
}
}
#endif
public class PXR_Loader : XRLoaderHelper
#if UNITY_EDITOR
, IXRLoaderPreInit
#endif
{
private const string TAG = "PXR_Loader";
private static List<XRDisplaySubsystemDescriptor> displaySubsystemDescriptors = new List<XRDisplaySubsystemDescriptor>();
private static List<XRInputSubsystemDescriptor> inputSubsystemDescriptors = new List<XRInputSubsystemDescriptor>();
private static List<XRMeshSubsystemDescriptor> meshSubsystemDescriptors = new List<XRMeshSubsystemDescriptor>();
#if XR_HANDS
private static List<XRHandSubsystemDescriptor> handSubsystemDescriptors = new List<XRHandSubsystemDescriptor>();
#endif
#if AR_FOUNDATION
private static List<XRSessionSubsystemDescriptor> sessionSubsystemDescriptors = new List<XRSessionSubsystemDescriptor>();
private static List<XRCameraSubsystemDescriptor> cameraSubsystemDescriptors = new List<XRCameraSubsystemDescriptor>();
private static List<XRFaceSubsystemDescriptor> faceSubsystemDescriptors = new List<XRFaceSubsystemDescriptor>();
private static List<XRHumanBodySubsystemDescriptor> humanBodySubsystemDescriptors = new List<XRHumanBodySubsystemDescriptor>();
private static List<XRAnchorSubsystemDescriptor> anchorSubsystemDescriptors = new List<XRAnchorSubsystemDescriptor>();
#endif
public delegate Quaternion ConvertRotationWith2VectorDelegate(Vector3 from, Vector3 to);
public XRDisplaySubsystem displaySubsystem
{
get
{
return GetLoadedSubsystem<XRDisplaySubsystem>();
}
}
public XRInputSubsystem inputSubsystem
{
get
{
return GetLoadedSubsystem<XRInputSubsystem>();
}
}
public XRMeshSubsystem meshSubsystem
{
get
{
return GetLoadedSubsystem<XRMeshSubsystem>();
}
}
internal enum LoaderState
{
Uninitialized,
InitializeAttempted,
Initialized,
StartAttempted,
Started,
StopAttempted,
Stopped,
DeinitializeAttempted
}
internal LoaderState currentLoaderState { get; private set; } = LoaderState.Uninitialized;
List<LoaderState> validLoaderInitStates = new List<LoaderState> { LoaderState.Uninitialized, LoaderState.InitializeAttempted };
List<LoaderState> validLoaderStartStates = new List<LoaderState> { LoaderState.Initialized, LoaderState.StartAttempted, LoaderState.Stopped };
List<LoaderState> validLoaderStopStates = new List<LoaderState> { LoaderState.StartAttempted, LoaderState.Started, LoaderState.StopAttempted };
List<LoaderState> validLoaderDeinitStates = new List<LoaderState> { LoaderState.InitializeAttempted, LoaderState.Initialized, LoaderState.Stopped, LoaderState.DeinitializeAttempted };
List<LoaderState> runningStates = new List<LoaderState>()
{
LoaderState.Initialized,
LoaderState.StartAttempted,
LoaderState.Started
};
public override bool Initialize()
{
Debug.Log($"{TAG} Initialize() currentLoaderState={currentLoaderState}");
#if UNITY_INPUT_SYSTEM
InputLayoutLoader.RegisterInputLayouts();
#endif
#if UNITY_ANDROID && !UNITY_EDITOR
PXR_Settings settings = GetSettings();
if (settings != null)
{
UserDefinedSettings userDefinedSettings = new UserDefinedSettings
{
stereoRenderingMode = settings.GetStereoRenderingMode(),
colorSpace = (ushort)((QualitySettings.activeColorSpace == ColorSpace.Linear) ? 1 : 0),
useContentProtect = Convert.ToUInt16(PXR_ProjectSetting.GetProjectConfig().useContentProtect),
systemDisplayFrequency = settings.GetSystemDisplayFrequency(),
optimizeBufferDiscards = settings.GetOptimizeBufferDiscards(),
enableAppSpaceWarp = Convert.ToUInt16(settings.enableAppSpaceWarp),
enableSubsampled = Convert.ToUInt16(PXR_ProjectSetting.GetProjectConfig().enableSubsampled),
lateLatchingDebug = Convert.ToUInt16(PXR_ProjectSetting.GetProjectConfig().latelatchingDebug),
enableStageMode = Convert.ToUInt16(PXR_ProjectSetting.GetProjectConfig().stageMode),
enableSuperResolution = Convert.ToUInt16(PXR_ProjectSetting.GetProjectConfig().superResolution),
normalSharpening = Convert.ToUInt16(PXR_ProjectSetting.GetProjectConfig().normalSharpening),
qualitySharpening = Convert.ToUInt16(PXR_ProjectSetting.GetProjectConfig().qualitySharpening),
fixedFoveatedSharpening = Convert.ToUInt16(PXR_ProjectSetting.GetProjectConfig().fixedFoveatedSharpening),
selfAdaptiveSharpening = Convert.ToUInt16(PXR_ProjectSetting.GetProjectConfig().selfAdaptiveSharpening),
spatialMeshLod = Convert.ToUInt16(PXR_ProjectSetting.GetProjectConfig().meshLod),
};
PXR_Plugin.System.UPxr_Construct(ConvertRotationWith2Vector);
PXR_Plugin.System.UPxr_SetEventDataBufferCallBack(EventDataBufferFunction);
PXR_Plugin.System.UPxr_SetUserDefinedSettings(userDefinedSettings);
}
#endif
PXR_Plugin.System.ProductName = PXR_Plugin.System.UPxr_GetProductName();
if (currentLoaderState == LoaderState.Initialized)
return true;
if (!validLoaderInitStates.Contains(currentLoaderState))
return false;
if (displaySubsystem == null)
{
CreateSubsystem<XRDisplaySubsystemDescriptor, XRDisplaySubsystem>(displaySubsystemDescriptors, "PICO Display");
if (displaySubsystem == null)
return false;
}
if (inputSubsystem == null)
{
CreateSubsystem<XRInputSubsystemDescriptor, XRInputSubsystem>(inputSubsystemDescriptors, "PICO Input");
if (inputSubsystem == null)
return false;
}
if (PXR_ProjectSetting.GetProjectConfig().spatialMesh)
{
CreateSubsystem<XRMeshSubsystemDescriptor, XRMeshSubsystem>(meshSubsystemDescriptors, "PICO Mesh");
}
#if XR_HANDS
CreateSubsystem<XRHandSubsystemDescriptor, XRHandSubsystem>(handSubsystemDescriptors, "PICO Hands");
#endif
#if AR_FOUNDATION
if (PXR_ProjectSetting.GetProjectConfig().arFoundation)
{
CreateSubsystem<XRSessionSubsystemDescriptor, XRSessionSubsystem>(sessionSubsystemDescriptors, PXR_SessionSubsystem.k_SubsystemId);
CreateSubsystem<XRCameraSubsystemDescriptor, XRCameraSubsystem>(cameraSubsystemDescriptors, PXR_CameraSubsystem.k_SubsystemId);
if (PXR_ProjectSetting.GetProjectConfig().faceTracking)
{
CreateSubsystem<XRFaceSubsystemDescriptor, XRFaceSubsystem>(faceSubsystemDescriptors, PXR_FaceSubsystem.k_SubsystemId);
}
if (PXR_ProjectSetting.GetProjectConfig().bodyTracking)
{
CreateSubsystem<XRHumanBodySubsystemDescriptor, XRHumanBodySubsystem>(humanBodySubsystemDescriptors, PXR_HumanBodySubsystem.k_SubsystemId);
}
if (PXR_ProjectSetting.GetProjectConfig().spatialAnchor)
{
CreateSubsystem<XRAnchorSubsystemDescriptor, XRAnchorSubsystem>(anchorSubsystemDescriptors, PXR_AnchorSubsystem.k_SubsystemId);
}
}
#endif
if (displaySubsystem == null && inputSubsystem == null)
{
Debug.LogError("PXRLog Unable to start PICO Plugin.");
}
else if (displaySubsystem == null)
{
Debug.LogError("PXRLog Failed to load display subsystem.");
}
else if (inputSubsystem == null)
{
Debug.LogError("PXRLog Failed to load input subsystem.");
}
else
{
PXR_Plugin.System.UPxr_InitializeFocusCallback();
}
#if XR_HANDS
var handSubSystem = GetLoadedSubsystem<XRHandSubsystem>();
if (handSubSystem == null)
{
Debug.LogError("PXRLog Failed to load XRHandSubsystem.");
}
#endif
if (PXR_ProjectSetting.GetProjectConfig().spatialAnchor)
{
PXR_Plugin.MixedReality.UPxr_CreateSpatialAnchorSenseDataProvider();
}
if (PXR_ProjectSetting.GetProjectConfig().sceneCapture)
{
PXR_Plugin.MixedReality.UPxr_CreateSceneCaptureSenseDataProvider();
}
currentLoaderState = LoaderState.Initialized;
return displaySubsystem != null;
}
public override bool Start()
{
Debug.Log($"{TAG} Start() currentLoaderState={currentLoaderState}");
if (currentLoaderState == LoaderState.Started)
return true;
if (!validLoaderStartStates.Contains(currentLoaderState))
return false;
currentLoaderState = LoaderState.StartAttempted;
StartSubsystem<XRDisplaySubsystem>();
StartSubsystem<XRInputSubsystem>();
#if XR_HANDS
StartSubsystem<XRHandSubsystem>();
#endif
#if AR_FOUNDATION
if (PXR_ProjectSetting.GetProjectConfig().arFoundation)
{
StartSubsystem<XRCameraSubsystem>();
if (PXR_ProjectSetting.GetProjectConfig().bodyTracking)
{
StartSubsystem<XRHumanBodySubsystem>();
}
if (PXR_ProjectSetting.GetProjectConfig().faceTracking)
{
StartSubsystem<XRFaceSubsystem>();
}
}
if (PXR_ProjectSetting.GetProjectConfig().spatialAnchor)
{
StartSubsystem<XRAnchorSubsystem>();
}
#endif
if (!displaySubsystem?.running ?? false)
{
StartSubsystem<XRDisplaySubsystem>();
}
if (!inputSubsystem?.running ?? false)
{
StartSubsystem<XRInputSubsystem>();
}
currentLoaderState = LoaderState.Started;
return true;
}
public override bool Stop()
{
Debug.Log($"{TAG} Stop() currentLoaderState={currentLoaderState}");
if (currentLoaderState == LoaderState.Stopped)
return true;
if (!validLoaderStopStates.Contains(currentLoaderState))
return false;
currentLoaderState = LoaderState.StopAttempted;
var inputRunning = inputSubsystem?.running ?? false;
var displayRunning = displaySubsystem?.running ?? false;
if (inputRunning)
{
StopSubsystem<XRInputSubsystem>();
}
if (displayRunning)
{
StopSubsystem<XRDisplaySubsystem>();
}
#if XR_HANDS
StopSubsystem<XRHandSubsystem>();
#endif
#if AR_FOUNDATION
if (PXR_ProjectSetting.GetProjectConfig().arFoundation)
{
StopSubsystem<XRCameraSubsystem>();
if (PXR_ProjectSetting.GetProjectConfig().bodyTracking)
{
StopSubsystem<XRHumanBodySubsystem>();
}
if (PXR_ProjectSetting.GetProjectConfig().faceTracking)
{
StopSubsystem<XRFaceSubsystem>();
}
}
if (PXR_ProjectSetting.GetProjectConfig().spatialAnchor)
{
StopSubsystem<XRAnchorSubsystem>();
}
#endif
currentLoaderState = LoaderState.Stopped;
return true;
}
public override bool Deinitialize()
{
Debug.Log($"{TAG} Deinitialize() currentLoaderState={currentLoaderState}");
if (currentLoaderState == LoaderState.Uninitialized)
return true;
if (!validLoaderDeinitStates.Contains(currentLoaderState))
{
return false;
}
currentLoaderState = LoaderState.DeinitializeAttempted;
DestroySubsystem<XRDisplaySubsystem>();
DestroySubsystem<XRInputSubsystem>();
if (PXR_ProjectSetting.GetProjectConfig().spatialMesh)
{
if (meshSubsystem.running)
{
StopSubsystem<XRMeshSubsystem>();
}
PXR_Plugin.MixedReality.UPxr_DisposeMesh();
DestroySubsystem<XRMeshSubsystem>();
}
#if XR_HANDS
DestroySubsystem<XRHandSubsystem>();
#endif
#if AR_FOUNDATION
if (PXR_ProjectSetting.GetProjectConfig().arFoundation)
{
DestroySubsystem<XRCameraSubsystem>();
if (PXR_ProjectSetting.GetProjectConfig().bodyTracking)
{
DestroySubsystem<XRHumanBodySubsystem>();
}
if (PXR_ProjectSetting.GetProjectConfig().faceTracking)
{
DestroySubsystem<XRFaceSubsystem>();
}
}
#endif
PXR_Plugin.System.UPxr_DeinitializeFocusCallback();
if (PXR_ProjectSetting.GetProjectConfig().spatialAnchor)
{
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));
}
if (PXR_ProjectSetting.GetProjectConfig().sceneCapture)
{
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));
}
currentLoaderState = LoaderState.Uninitialized;
return true;
}
[MonoPInvokeCallback(typeof(ConvertRotationWith2VectorDelegate))]
static Quaternion ConvertRotationWith2Vector(Vector3 from, Vector3 to)
{
return Quaternion.FromToRotation(from, to);
}
[MonoPInvokeCallback(typeof(EventDataBufferCallBack))]
static void EventDataBufferFunction(ref PxrEventDataBuffer eventDB)
{
int status, action;
switch (eventDB.type)
{
case PxrStructureType.SessionStateChanged:
int state = BitConverter.ToInt32(eventDB.data, 0);
if (PXR_Plugin.System.SessionStateChanged != null)
{
PXR_Plugin.System.SessionStateChanged(state);
}
#if AR_FOUNDATION
PXR_SessionSubsystem.instance?.OnSessionStateChange(state);
#endif
break;
case PxrStructureType.Controller:
PxrDeviceEventType eventType = (PxrDeviceEventType)eventDB.data[0];
status = eventDB.data[5];
action = eventDB.data[6];
PLog.d(TAG, $"Controller eventType={eventType}, status={status}, action={action}");
switch (eventType)
{
case PxrDeviceEventType.INPUTDEVICE_CHANGED:
if (PXR_Plugin.System.InputDeviceChanged != null)
{
PXR_Plugin.System.InputDeviceChanged(status);
}
break;
case PxrDeviceEventType.MOTION_TRACKER_STATE:
if (status == 0 || status == 1)
{
if (PXR_MotionTracking.MotionTrackerNumberOfConnections != null)
{
PXR_MotionTracking.MotionTrackerNumberOfConnections(status, action);
}
}
else if (status == 2)
{
if (PXR_MotionTracking.BodyTrackingAbnormalCalibrationData != null)
{
PXR_MotionTracking.BodyTrackingAbnormalCalibrationData(status, action);
}
}
break;
case PxrDeviceEventType.MOTION_TRACKER_BATTERY:
if (PXR_MotionTracking.MotionTrackerBatteryLevel != null)
{
PXR_MotionTracking.MotionTrackerBatteryLevel(status, action);
}
break;
case PxrDeviceEventType.BODYTRACKING_STATE_ERROR_CODE:
if (PXR_MotionTracking.BodyTrackingStateError != null)
{
PXR_MotionTracking.BodyTrackingStateError((BodyTrackingStatusCode)status, (BodyTrackingErrorCode)action);
}
break;
case PxrDeviceEventType.BODYTRACKING_ACTION:
if (PXR_MotionTracking.BodyTrackingAction != null)
{
if ((action & (int)BodyActionList.PxrTouchGround) != 0)
{
PXR_MotionTracking.BodyTrackingAction(status, BodyActionList.PxrTouchGround);
}
if ((action & (int)BodyActionList.PxrKeepStatic) != 0)
{
PXR_MotionTracking.BodyTrackingAction(status, BodyActionList.PxrKeepStatic);
}
if ((action & (int)BodyActionList.PxrTouchGroundToe) != 0)
{
PXR_MotionTracking.BodyTrackingAction(status, BodyActionList.PxrTouchGroundToe);
}
if ((action & (int)BodyActionList.PxrFootDownAction) != 0)
{
PXR_MotionTracking.BodyTrackingAction(status, BodyActionList.PxrFootDownAction);
}
}
break;
}
break;
case PxrStructureType.SeethroughStateChanged:
status = BitConverter.ToInt32(eventDB.data, 0);
PXR_Plugin.Boundary.seeThroughState = status;
if (PXR_Plugin.Boundary.SeethroughStateChangedAction != null)
{
PXR_Plugin.Boundary.SeethroughStateChangedAction(status);
}
PLog.i(TAG, $"SeethroughStateChanged status ={status}");
break;
case PxrStructureType.RefreshRateChanged:
float drRate = BitConverter.ToSingle(eventDB.data, 0);
if (PXR_Plugin.System.DisplayRefreshRateChangedAction != null)
{
PXR_Plugin.System.DisplayRefreshRateChangedAction(drRate);
}
PLog.i(TAG, $"RefreshRateChanged value ={drRate}");
break;
case PxrStructureType.SDKLoglevelChanged:
status = BitConverter.ToInt32(eventDB.data, 0);
PLog.logLevel = (PLog.LogLevel)status;
PLog.i(TAG, $"SDKLoglevelChanged logLevel ={status}");
break;
case PxrStructureType.MotionTrackerKeyEvent:
if (PXR_MotionTracking.MotionTrackerKeyAction != null)
{
MotionTrackerEventData result = new MotionTrackerEventData();
result.trackerSN.value = System.Text.Encoding.ASCII.GetString(eventDB.data.Take(24).ToArray());
result.code = BitConverter.ToInt32(eventDB.data, 24);
result.action = BitConverter.ToInt32(eventDB.data, 28);
result.repeat = BitConverter.ToInt32(eventDB.data, 32);
result.shortPress = BitConverter.ToBoolean(eventDB.data, 36);
PLog.i(TAG, $" code={result.code}, action={result.action}, repeat={result.repeat}, shortPress={result.shortPress},trackerSN={result.trackerSN.value} ");
PXR_MotionTracking.MotionTrackerKeyAction(result);
}
break;
case PxrStructureType.EXTDevConnectStateEvent:
if (PXR_MotionTracking.ExtDevConnectAction != null)
{
ExtDevConnectEventData result = new ExtDevConnectEventData();
result.trackerSN.value = System.Text.Encoding.ASCII.GetString(eventDB.data.Take(24).ToArray());
result.state = BitConverter.ToInt32(eventDB.data, 24);
PLog.i(TAG, $" state={result.state},trackerSN={result.trackerSN.value} ");
PXR_MotionTracking.ExtDevConnectAction(result);
}
break;
case PxrStructureType.EXTDevBatteryStateEvent:
if (PXR_MotionTracking.ExtDevBatteryAction != null)
{
ExtDevBatteryEventData result = new ExtDevBatteryEventData();
result.trackerSN.value = System.Text.Encoding.ASCII.GetString(eventDB.data.Take(24).ToArray());
result.battery = BitConverter.ToInt32(eventDB.data, 24);
result.charger = BitConverter.ToInt32(eventDB.data, 28);
PLog.i(TAG, $" state={result.battery}, charger={result.charger}, trackerSN={result.trackerSN.value} ");
PXR_MotionTracking.ExtDevBatteryAction(result);
}
break;
case PxrStructureType.MotionTrackingModeChangedEvent:
if (PXR_MotionTracking.MotionTrackingModeChangedAction != null)
{
status = BitConverter.ToInt32(eventDB.data, 0);
PLog.i(TAG, $" status={status} ");
PXR_MotionTracking.MotionTrackingModeChangedAction((MotionTrackerMode)status);
}
break;
case PxrStructureType.EXTDevPassDataEvent:
if (PXR_MotionTracking.ExtDevPassDataAction != null)
{
status = BitConverter.ToInt32(eventDB.data, 0);
PLog.i(TAG, $" state={status}");
PXR_MotionTracking.ExtDevPassDataAction(status);
}
break;
default:
break;
}
}
public PXR_Settings GetSettings()
{
PXR_Settings settings = null;
#if UNITY_EDITOR
UnityEditor.EditorBuildSettings.TryGetConfigObject<PXR_Settings>("Unity.XR.PXR.Settings", out settings);
#endif
#if UNITY_ANDROID && !UNITY_EDITOR
settings = PXR_Settings.settings;
#endif
return settings;
}
#if UNITY_EDITOR
public string GetPreInitLibraryName(BuildTarget buildTarget, BuildTargetGroup buildTargetGroup)
{
return "PxrPlatform";
}
#endif
#if UNITY_ANDROID && !UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
static void RuntimeLoadPicoPlugin()
{
PXR_Plugin.System.UPxr_LoadPICOPlugin();
string version = "UnityXR_" + PXR_Plugin.System.UPxr_GetSDKVersion() + "_" + Application.unityVersion;
PXR_Plugin.System.UPxr_SetConfigString( ConfigType.EngineVersion, version );
}
#endif
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 563682312a45bbe4bbd8d243e5e14608
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: fd9f82377aeb9704193bd866d119aaa5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,708 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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.PXR
{
public class PXR_OverlayManager : 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()
{
// external surface
if (PXR_OverLay.Instances.Count > 0)
{
foreach (var overlay in PXR_OverLay.Instances)
{
if (overlay.isExternalAndroidSurface)
{
overlay.CreateExternalSurface(overlay);
}
}
}
}
private void BeginRendering(ScriptableRenderContext arg1, Camera[] arg2)
{
foreach (Camera cam in arg2)
{
if (cam != null && Camera.main == cam)
{
OnPreRenderCallBack(cam);
}
}
}
private void EndRendering(ScriptableRenderContext arg1, Camera[] arg2)
{
foreach (Camera cam in arg2)
{
if (cam != null && Camera.main == cam)
{
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
int boundaryState = PXR_Plugin.Boundary.seeThroughState;
if (null == PXR_OverLay.Instances) return;
if (PXR_OverLay.Instances.Count > 0 && boundaryState != 2)
{
foreach (var overlay in PXR_OverLay.Instances)
{
if (!overlay.isActiveAndEnabled) continue;
if (null == overlay.layerTextures) continue;
if (!overlay.isClones && overlay.layerTextures[0] == null && overlay.layerTextures[1] == null && !overlay.isExternalAndroidSurface) continue;
if (overlay.overlayTransform != null && !overlay.overlayTransform.gameObject.activeSelf) continue;
overlay.CreateTexture();
if (GraphicsDeviceType.Vulkan == SystemInfo.graphicsDeviceType)
{
if (overlay.enableSubmitLayer)
{
PXR_Plugin.Render.UPxr_GetLayerNextImageIndex(overlay.overlayIndex, ref overlay.imageIndex);
}
}
}
}
}
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;
int boundaryState = PXR_Plugin.Boundary.seeThroughState;
if (null == PXR_OverLay.Instances) return;
if (PXR_OverLay.Instances.Count > 0 && boundaryState != 2)
{
PXR_OverLay.Instances.Sort();
foreach (var compositeLayer in PXR_OverLay.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 && !compositeLayer.isExternalAndroidSurface) 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 = false;
if (compositeLayer.overlayTransform != null && compositeLayer.overlayTransform.parent == transform)
{
isHeadLocked = true;
}
if (!compositeLayer.isExternalAndroidSurface && !compositeLayer.CopyRT()) continue;
if (null == compositeLayer.cameraRotations || null == compositeLayer.modelScales || null == compositeLayer.modelTranslations) continue;
// set color matrics
PXR_Plugin.Render.UPxr_SetConfigFloatArray(ConfigType.SetSubmitLayerEXTItemColorMatrix, compositeLayer.colorMatrix, 18);
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
{
poseLeft.orientation.x = compositeLayer.modelRotations[0].x;
poseLeft.orientation.y = compositeLayer.modelRotations[0].y;
poseLeft.orientation.z = -compositeLayer.modelRotations[0].z;
poseLeft.orientation.w = -compositeLayer.modelRotations[0].w;
poseLeft.position.x = compositeLayer.modelTranslations[0].x;
poseLeft.position.y = compositeLayer.modelTranslations[0].y;
poseLeft.position.z = -compositeLayer.modelTranslations[0].z;
poseRight.orientation.x = compositeLayer.modelRotations[0].x;
poseRight.orientation.y = compositeLayer.modelRotations[0].y;
poseRight.orientation.z = -compositeLayer.modelRotations[0].z;
poseRight.orientation.w = -compositeLayer.modelRotations[0].w;
poseRight.position.x = compositeLayer.modelTranslations[0].x;
poseRight.position.y = compositeLayer.modelTranslations[0].y;
poseRight.position.z = -compositeLayer.modelTranslations[0].z;
header.layerFlags = (UInt32)(
PxrLayerSubmitFlags.PxrLayerFlagUseExternalHeadPose |
PxrLayerSubmitFlags.PxrLayerFlagLayerPoseNotInTrackingSpace);
}
header.layerFlags |= compositeLayer.getHDRFlags();
if (compositeLayer.isPremultipliedAlpha)
{
header.layerFlags |= (UInt32)PxrLayerSubmitFlags.PxrLayerFlagPremultipliedAlpha;
}
if (!compositeLayer.enableSubmitLayer)
{
header.layerFlags |= (UInt32)(PxrLayerSubmitFlags.PxrLayerFlagFixLayer);
}
if (compositeLayer.overlayShape == PXR_OverLay.OverlayShape.Quad)
{
if (PXR_OverLay.APIExecutionStatus.None == compositeLayer.Quad2Status)
{
PxrLayerQuad2 layer = new PxrLayerQuad2();
layer.header.layerId = -1;
if (PXR_Plugin.Render.UPxr_SubmitLayerQuad2(layer))
{
compositeLayer.Quad2Status = PXR_OverLay.APIExecutionStatus.False;
PLog.i("OverlayManager", "Quad2Status:UPxr_SubmitLayerQuad ");
}
else
{
compositeLayer.Quad2Status = PXR_OverLay.APIExecutionStatus.True;
PLog.i("OverlayManager", "Quad2Status:UPxr_SubmitLayerQuad2 ");
}
}
PxrLayerQuad2 layerSubmit2 = new PxrLayerQuad2();
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)
{
Vector3 lPos = new Vector3();
Vector3 rPos = new Vector3();
Quaternion quaternion = new Quaternion(compositeLayer.modelRotations[0].x, compositeLayer.modelRotations[0].y, -compositeLayer.modelRotations[0].z, -compositeLayer.modelRotations[0].w);
lPos.x = compositeLayer.modelScales[0].x * (-0.5f + compositeLayer.dstRectLeft.x + 0.5f * Mathf.Min(compositeLayer.dstRectLeft.width, 1 - compositeLayer.dstRectLeft.x));
lPos.y = compositeLayer.modelScales[0].y * (-0.5f + compositeLayer.dstRectLeft.y + 0.5f * Mathf.Min(compositeLayer.dstRectLeft.height, 1 - compositeLayer.dstRectLeft.y));
lPos.z = 0;
lPos = quaternion * lPos;
layerSubmit2.poseLeft.position.x += lPos.x;
layerSubmit2.poseLeft.position.y += lPos.y;
layerSubmit2.poseLeft.position.z += lPos.z;
rPos.x = compositeLayer.modelScales[0].x * (-0.5f + compositeLayer.dstRectRight.x + 0.5f * Mathf.Min(compositeLayer.dstRectRight.width, 1 - compositeLayer.dstRectRight.x));
rPos.y = compositeLayer.modelScales[0].y * (-0.5f + compositeLayer.dstRectRight.y + 0.5f * Mathf.Min(compositeLayer.dstRectRight.height, 1 - compositeLayer.dstRectRight.y));
rPos.z = 0;
rPos = quaternion * rPos;
layerSubmit2.poseRight.position.x += rPos.x;
layerSubmit2.poseRight.position.y += rPos.y;
layerSubmit2.poseRight.position.z += rPos.z;
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);
if (PXR_OverLay.APIExecutionStatus.True == compositeLayer.Quad2Status)
{
PXR_Plugin.Render.UPxr_SubmitLayerQuad2ByRender(compositeLayer.layerSubmitPtr);
}
else
{
PxrLayerQuad layerSubmit = new PxrLayerQuad();
layerSubmit.header.layerId = compositeLayer.overlayIndex;
layerSubmit.header.colorScaleX = colorScale.x;
layerSubmit.header.colorScaleY = colorScale.y;
layerSubmit.header.colorScaleZ = colorScale.z;
layerSubmit.header.colorScaleW = colorScale.w;
layerSubmit.header.colorBiasX = colorBias.x;
layerSubmit.header.colorBiasY = colorBias.y;
layerSubmit.header.colorBiasZ = colorBias.z;
layerSubmit.header.colorBiasW = colorBias.w;
layerSubmit.header.compositionDepth = compositeLayer.layerDepth;
layerSubmit.header.headPose.orientation.x = compositeLayer.cameraRotations[0].x;
layerSubmit.header.headPose.orientation.y = compositeLayer.cameraRotations[0].y;
layerSubmit.header.headPose.orientation.z = -compositeLayer.cameraRotations[0].z;
layerSubmit.header.headPose.orientation.w = -compositeLayer.cameraRotations[0].w;
layerSubmit.header.headPose.position.x = (compositeLayer.cameraTranslations[0].x + compositeLayer.cameraTranslations[1].x) / 2;
layerSubmit.header.headPose.position.y = (compositeLayer.cameraTranslations[0].y + compositeLayer.cameraTranslations[1].y) / 2;
layerSubmit.header.headPose.position.z = -(compositeLayer.cameraTranslations[0].z + compositeLayer.cameraTranslations[1].z) / 2;
if (isHeadLocked)
{
layerSubmit.pose.orientation.x = compositeLayer.overlayTransform.localRotation.x;
layerSubmit.pose.orientation.y = compositeLayer.overlayTransform.localRotation.y;
layerSubmit.pose.orientation.z = -compositeLayer.overlayTransform.localRotation.z;
layerSubmit.pose.orientation.w = -compositeLayer.overlayTransform.localRotation.w;
layerSubmit.pose.position.x = compositeLayer.overlayTransform.localPosition.x;
layerSubmit.pose.position.y = compositeLayer.overlayTransform.localPosition.y;
layerSubmit.pose.position.z = -compositeLayer.overlayTransform.localPosition.z;
layerSubmit.header.layerFlags = (UInt32)(
PxrLayerSubmitFlags.PxrLayerFlagLayerPoseNotInTrackingSpace |
PxrLayerSubmitFlags.PxrLayerFlagHeadLocked);
}
else
{
layerSubmit.pose.orientation.x = compositeLayer.modelRotations[0].x;
layerSubmit.pose.orientation.y = compositeLayer.modelRotations[0].y;
layerSubmit.pose.orientation.z = -compositeLayer.modelRotations[0].z;
layerSubmit.pose.orientation.w = -compositeLayer.modelRotations[0].w;
layerSubmit.pose.position.x = compositeLayer.modelTranslations[0].x;
layerSubmit.pose.position.y = compositeLayer.modelTranslations[0].y;
layerSubmit.pose.position.z = -compositeLayer.modelTranslations[0].z;
layerSubmit.header.layerFlags = (UInt32)(
PxrLayerSubmitFlags.PxrLayerFlagUseExternalHeadPose |
PxrLayerSubmitFlags.PxrLayerFlagLayerPoseNotInTrackingSpace);
}
layerSubmit.width = compositeLayer.modelScales[0].x;
layerSubmit.height = compositeLayer.modelScales[0].y;
if (compositeLayer.layerSubmitPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(compositeLayer.layerSubmitPtr);
compositeLayer.layerSubmitPtr = IntPtr.Zero;
}
compositeLayer.layerSubmitPtr = Marshal.AllocHGlobal(Marshal.SizeOf(layerSubmit));
Marshal.StructureToPtr(layerSubmit, compositeLayer.layerSubmitPtr, false);
PXR_Plugin.Render.UPxr_SubmitLayerQuadByRender(compositeLayer.layerSubmitPtr);
}
}
else if (compositeLayer.overlayShape == PXR_OverLay.OverlayShape.Cylinder)
{
if (PXR_OverLay.APIExecutionStatus.None == compositeLayer.Cylinder2Status)
{
PxrLayerCylinder2 layer = new PxrLayerCylinder2();
layer.header.layerId = -1;
if (PXR_Plugin.Render.UPxr_SubmitLayerCylinder2(layer))
{
compositeLayer.Cylinder2Status = PXR_OverLay.APIExecutionStatus.False;
PLog.i("OverlayManager", "Quad2Status:UPxr_SubmitLayerCylinder ");
}
else
{
compositeLayer.Cylinder2Status = PXR_OverLay.APIExecutionStatus.True;
PLog.i("OverlayManager", "Quad2Status:UPxr_SubmitLayerCylinder2 ");
}
}
PxrLayerCylinder2 layerSubmit2 = new PxrLayerCylinder2();
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
{
Debug.LogError("PXRLog 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);
if (PXR_OverLay.APIExecutionStatus.True == compositeLayer.Cylinder2Status)
{
PXR_Plugin.Render.UPxr_SubmitLayerCylinder2ByRender(compositeLayer.layerSubmitPtr);
}
else
{
PxrLayerCylinder layerSubmit = new PxrLayerCylinder();
layerSubmit.header.layerId = compositeLayer.overlayIndex;
layerSubmit.header.colorScaleX = colorScale.x;
layerSubmit.header.colorScaleY = colorScale.y;
layerSubmit.header.colorScaleZ = colorScale.z;
layerSubmit.header.colorScaleW = colorScale.w;
layerSubmit.header.colorBiasX = colorBias.x;
layerSubmit.header.colorBiasY = colorBias.y;
layerSubmit.header.colorBiasZ = colorBias.z;
layerSubmit.header.colorBiasW = colorBias.w;
layerSubmit.header.compositionDepth = compositeLayer.layerDepth;
layerSubmit.header.headPose.orientation.x = compositeLayer.cameraRotations[0].x;
layerSubmit.header.headPose.orientation.y = compositeLayer.cameraRotations[0].y;
layerSubmit.header.headPose.orientation.z = -compositeLayer.cameraRotations[0].z;
layerSubmit.header.headPose.orientation.w = -compositeLayer.cameraRotations[0].w;
layerSubmit.header.headPose.position.x = (compositeLayer.cameraTranslations[0].x + compositeLayer.cameraTranslations[1].x) / 2;
layerSubmit.header.headPose.position.y = (compositeLayer.cameraTranslations[0].y + compositeLayer.cameraTranslations[1].y) / 2;
layerSubmit.header.headPose.position.z = -(compositeLayer.cameraTranslations[0].z + compositeLayer.cameraTranslations[1].z) / 2;
if (isHeadLocked)
{
layerSubmit.pose.orientation.x = compositeLayer.overlayTransform.localRotation.x;
layerSubmit.pose.orientation.y = compositeLayer.overlayTransform.localRotation.y;
layerSubmit.pose.orientation.z = -compositeLayer.overlayTransform.localRotation.z;
layerSubmit.pose.orientation.w = -compositeLayer.overlayTransform.localRotation.w;
layerSubmit.pose.position.x = compositeLayer.overlayTransform.localPosition.x;
layerSubmit.pose.position.y = compositeLayer.overlayTransform.localPosition.y;
layerSubmit.pose.position.z = -compositeLayer.overlayTransform.localPosition.z;
layerSubmit.header.layerFlags = (UInt32)(
PxrLayerSubmitFlags.PxrLayerFlagLayerPoseNotInTrackingSpace |
PxrLayerSubmitFlags.PxrLayerFlagHeadLocked);
}
else
{
layerSubmit.pose.orientation.x = compositeLayer.modelRotations[0].x;
layerSubmit.pose.orientation.y = compositeLayer.modelRotations[0].y;
layerSubmit.pose.orientation.z = -compositeLayer.modelRotations[0].z;
layerSubmit.pose.orientation.w = -compositeLayer.modelRotations[0].w;
layerSubmit.pose.position.x = compositeLayer.modelTranslations[0].x;
layerSubmit.pose.position.y = compositeLayer.modelTranslations[0].y;
layerSubmit.pose.position.z = -compositeLayer.modelTranslations[0].z;
layerSubmit.header.layerFlags = (UInt32)(
PxrLayerSubmitFlags.PxrLayerFlagUseExternalHeadPose |
PxrLayerSubmitFlags.PxrLayerFlagLayerPoseNotInTrackingSpace);
}
if (compositeLayer.modelScales[0].z != 0)
{
layerSubmit.centralAngle = compositeLayer.modelScales[0].x / compositeLayer.modelScales[0].z;
}
else
{
Debug.LogError("PXRLog scale.z is 0");
}
layerSubmit.height = compositeLayer.modelScales[0].y;
layerSubmit.radius = compositeLayer.modelScales[0].z;
if (compositeLayer.layerSubmitPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(compositeLayer.layerSubmitPtr);
compositeLayer.layerSubmitPtr = IntPtr.Zero;
}
compositeLayer.layerSubmitPtr = Marshal.AllocHGlobal(Marshal.SizeOf(layerSubmit));
Marshal.StructureToPtr(layerSubmit, compositeLayer.layerSubmitPtr, false);
PXR_Plugin.Render.UPxr_SubmitLayerCylinderByRender(compositeLayer.layerSubmitPtr);
}
}
else if (compositeLayer.overlayShape == PXR_OverLay.OverlayShape.Equirect)
{
if (PXR_OverLay.APIExecutionStatus.None == compositeLayer.Equirect2Status)
{
PxrLayerEquirect2 layer = new PxrLayerEquirect2();
layer.header.layerId = -1;
if (PXR_Plugin.Render.UPxr_SubmitLayerEquirect2(layer))
{
compositeLayer.Equirect2Status = PXR_OverLay.APIExecutionStatus.False;
PLog.i("OverlayManager", "Equirect2Status:UPxr_SubmitLayerEquirect ");
}
else
{
compositeLayer.Equirect2Status = PXR_OverLay.APIExecutionStatus.True;
PLog.i("OverlayManager", "Equirect2Status:UPxr_SubmitLayerEquirect2 ");
}
}
PxrLayerEquirect2 layerSubmit2 = new PxrLayerEquirect2();
layerSubmit2.header = header;
layerSubmit2.poseLeft = poseLeft;
layerSubmit2.poseRight = poseRight;
layerSubmit2.header.layerShape = (PXR_OverLay.OverlayShape)4;
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);
if (PXR_OverLay.APIExecutionStatus.True == compositeLayer.Equirect2Status)
{
PXR_Plugin.Render.UPxr_SubmitLayerEquirect2ByRender(compositeLayer.layerSubmitPtr);
}
else
{
PxrLayerEquirect layerSubmit = new PxrLayerEquirect();
layerSubmit.header = header;
layerSubmit.poseLeft = poseLeft;
layerSubmit.poseRight = poseRight;
layerSubmit.header.layerShape = PXR_OverLay.OverlayShape.Equirect;
layerSubmit.radiusLeft = compositeLayer.radius;
layerSubmit.radiusRight = compositeLayer.radius;
layerSubmit.scaleXLeft = 1 / compositeLayer.dstRectLeft.width;
layerSubmit.scaleXRight = 1 / compositeLayer.dstRectRight.width;
layerSubmit.scaleYLeft = 1 / compositeLayer.dstRectLeft.height;
layerSubmit.scaleYRight = 1 / compositeLayer.dstRectRight.height;
layerSubmit.biasXLeft = -compositeLayer.dstRectLeft.x / compositeLayer.dstRectLeft.width;
layerSubmit.biasXRight = -compositeLayer.dstRectRight.x / compositeLayer.dstRectRight.width;
layerSubmit.biasYLeft = 1 + (compositeLayer.dstRectLeft.y - 1) / compositeLayer.dstRectLeft.height;
layerSubmit.biasYRight = 1 + (compositeLayer.dstRectRight.y - 1) / compositeLayer.dstRectRight.height;
if (compositeLayer.layerSubmitPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(compositeLayer.layerSubmitPtr);
compositeLayer.layerSubmitPtr = IntPtr.Zero;
}
compositeLayer.layerSubmitPtr = Marshal.AllocHGlobal(Marshal.SizeOf(layerSubmit));
Marshal.StructureToPtr(layerSubmit, compositeLayer.layerSubmitPtr, false);
PXR_Plugin.Render.UPxr_SubmitLayerEquirectByRender(compositeLayer.layerSubmitPtr);
}
}
else if (compositeLayer.overlayShape == PXR_OverLay.OverlayShape.Cubemap)
{
PxrLayerCube2 layerSubmit2 = new PxrLayerCube2();
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);
PXR_Plugin.Render.UPxr_SubmitLayerCube2ByRender(compositeLayer.layerSubmitPtr);
}
else if (compositeLayer.overlayShape == PXR_OverLay.OverlayShape.Eac)
{
PxrLayerEac2 layerSubmit2 = new PxrLayerEac2();
layerSubmit2.header = header;
layerSubmit2.poseLeft = poseLeft;
layerSubmit2.poseRight = poseRight;
layerSubmit2.offsetPosLeft.x = compositeLayer.offsetPosLeft.x;
layerSubmit2.offsetPosLeft.y = compositeLayer.offsetPosLeft.y;
layerSubmit2.offsetPosLeft.z = compositeLayer.offsetPosLeft.z;
layerSubmit2.offsetPosRight.x = compositeLayer.offsetPosRight.x;
layerSubmit2.offsetPosRight.y = compositeLayer.offsetPosRight.y;
layerSubmit2.offsetPosRight.z = compositeLayer.offsetPosRight.z;
layerSubmit2.offsetRotLeft.x = compositeLayer.offsetRotLeft.x;
layerSubmit2.offsetRotLeft.y = compositeLayer.offsetRotLeft.y;
layerSubmit2.offsetRotLeft.z = compositeLayer.offsetRotLeft.z;
layerSubmit2.offsetRotLeft.w = compositeLayer.offsetRotLeft.w;
layerSubmit2.offsetRotRight.x = compositeLayer.offsetRotRight.x;
layerSubmit2.offsetRotRight.y = compositeLayer.offsetRotRight.y;
layerSubmit2.offsetRotRight.z = compositeLayer.offsetRotRight.z;
layerSubmit2.offsetRotRight.w = compositeLayer.offsetRotRight.w;
layerSubmit2.degreeType = (uint)compositeLayer.eacModelType;
layerSubmit2.overlapFactor = compositeLayer.overlapFactor;
layerSubmit2.timestamp = compositeLayer.timestamp;
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);
PXR_Plugin.Render.UPxr_SubmitLayerEac2ByRender(compositeLayer.layerSubmitPtr);
}
else if (compositeLayer.overlayShape == PXR_OverLay.OverlayShape.Fisheye)
{
PxrLayerFisheye layerSubmit = new PxrLayerFisheye();
layerSubmit.header = header;
layerSubmit.poseLeft = poseLeft;
layerSubmit.poseRight = poseRight;
layerSubmit.header.layerShape = PXR_OverLay.OverlayShape.Fisheye;
layerSubmit.radiusLeft = compositeLayer.radius;
layerSubmit.radiusRight = compositeLayer.radius;
layerSubmit.scaleXLeft = 1 / compositeLayer.dstRectLeft.width;
layerSubmit.scaleXRight = 1 / compositeLayer.dstRectRight.width;
layerSubmit.scaleYLeft = 1 / compositeLayer.dstRectLeft.height;
layerSubmit.scaleYRight = 1 / compositeLayer.dstRectRight.height;
layerSubmit.biasXLeft = -compositeLayer.dstRectLeft.x / compositeLayer.dstRectLeft.width;
layerSubmit.biasXRight = -compositeLayer.dstRectRight.x / compositeLayer.dstRectRight.width;
layerSubmit.biasYLeft = 1 + (compositeLayer.dstRectLeft.y - 1) / compositeLayer.dstRectLeft.height;
layerSubmit.biasYRight = 1 + (compositeLayer.dstRectRight.y - 1) / compositeLayer.dstRectRight.height;
if (compositeLayer.layerSubmitPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(compositeLayer.layerSubmitPtr);
compositeLayer.layerSubmitPtr = IntPtr.Zero;
}
compositeLayer.layerSubmitPtr = Marshal.AllocHGlobal(Marshal.SizeOf(layerSubmit));
Marshal.StructureToPtr(layerSubmit, compositeLayer.layerSubmitPtr, false);
PXR_Plugin.Render.UPxr_SubmitLayerFisheyeByRender(compositeLayer.layerSubmitPtr);
}
else if (compositeLayer.overlayShape == PXR_OverLay.OverlayShape.BlurredQuad)
{
PxrLayerQuad2 layerSubmit2 = new PxrLayerQuad2();
float blurredQuadEXTAlpha = 0.0f;
if (PXR_OverLay.BlurredQuadMode.SmallWindow == compositeLayer.blurredQuadMode)
{
header.layerFlags |= (UInt32)PxrLayerSubmitFlags.PxrLayerFlagBlurredQuadModeSmallWindow;
blurredQuadEXTAlpha = 1.0f;
}
else if (PXR_OverLay.BlurredQuadMode.Immersion == compositeLayer.blurredQuadMode)
{
header.layerFlags |= (UInt32)PxrLayerSubmitFlags.PxrLayerFlagBlurredQuadModeImmersion;
blurredQuadEXTAlpha = 0.0f;
}
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)
{
Vector3 lPos = new Vector3();
Vector3 rPos = new Vector3();
Quaternion quaternion = new Quaternion(compositeLayer.modelRotations[0].x, compositeLayer.modelRotations[0].y, -compositeLayer.modelRotations[0].z, -compositeLayer.modelRotations[0].w);
lPos.x = compositeLayer.modelScales[0].x * (-0.5f + compositeLayer.dstRectLeft.x + 0.5f * Mathf.Min(compositeLayer.dstRectLeft.width, 1 - compositeLayer.dstRectLeft.x));
lPos.y = compositeLayer.modelScales[0].y * (-0.5f + compositeLayer.dstRectLeft.y + 0.5f * Mathf.Min(compositeLayer.dstRectLeft.height, 1 - compositeLayer.dstRectLeft.y));
lPos.z = 0;
lPos = quaternion * lPos;
layerSubmit2.poseLeft.position.x += lPos.x;
layerSubmit2.poseLeft.position.y += lPos.y;
layerSubmit2.poseLeft.position.z += lPos.z;
rPos.x = compositeLayer.modelScales[0].x * (-0.5f + compositeLayer.dstRectRight.x + 0.5f * Mathf.Min(compositeLayer.dstRectRight.width, 1 - compositeLayer.dstRectRight.x));
rPos.y = compositeLayer.modelScales[0].y * (-0.5f + compositeLayer.dstRectRight.y + 0.5f * Mathf.Min(compositeLayer.dstRectRight.height, 1 - compositeLayer.dstRectRight.y));
rPos.z = 0;
rPos = quaternion * rPos;
layerSubmit2.poseRight.position.x += rPos.x;
layerSubmit2.poseRight.position.y += rPos.y;
layerSubmit2.poseRight.position.z += rPos.z;
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);
PXR_Plugin.Render.UPxr_SubmitLayerBlurredQuad2ByRender(compositeLayer.layerSubmitPtr, compositeLayer.blurredQuadScale, compositeLayer.blurredQuadShift, compositeLayer.blurredQuadFOV, compositeLayer.blurredQuadIPD, blurredQuadEXTAlpha);
}
}
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: ae23a5b0f5d5d7c4e9cb27caee9c7572
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,13 +0,0 @@
fileFormatVersion: 2
guid: e46169b3ebf1d5e45aa4a01a9ac54017
timeCreated: 1590461192
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,110 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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.IO;
using UnityEngine;
namespace Unity.XR.PXR
{
[System.Serializable]
public class PXR_ProjectSetting : ScriptableObject
{
public bool useContentProtect;
public bool handTracking;
public bool adaptiveHand;
public bool highFrequencyHand;
public bool openMRC;
public bool faceTracking;
public bool lipsyncTracking;
public bool eyeTracking;
public bool eyetrackingCalibration;
public bool enableETFR;
public bool latelatching;
public bool latelatchingDebug;
public bool enableSubsampled;
public bool bodyTracking;
public bool adaptiveResolution;
public bool stageMode;
public bool videoSeeThrough;
public bool spatialAnchor;
public bool sceneCapture;
public bool sharedAnchor;
public bool spatialMesh;
public PxrMeshLod meshLod;
public bool superResolution;
public bool normalSharpening;
public bool qualitySharpening;
public bool fixedFoveatedSharpening;
public bool selfAdaptiveSharpening;
public bool arFoundation;
public bool mrSafeguard;
public bool enableRecommendMSAA;
public bool recommendSubsamping;
public bool recommendMSAA;
public static PXR_ProjectSetting GetProjectConfig()
{
PXR_ProjectSetting projectConfig = Resources.Load<PXR_ProjectSetting>("PXR_ProjectSetting");
#if UNITY_EDITOR
if (projectConfig == null)
{
projectConfig = CreateInstance<PXR_ProjectSetting>();
projectConfig.useContentProtect = false;
projectConfig.handTracking = false;
projectConfig.adaptiveHand = false;
projectConfig.highFrequencyHand = false;
projectConfig.openMRC = true;
projectConfig.faceTracking = false;
projectConfig.lipsyncTracking = false;
projectConfig.eyeTracking = false;
projectConfig.eyetrackingCalibration = false;
projectConfig.enableETFR = false;
projectConfig.latelatching = false;
projectConfig.latelatchingDebug = false;
projectConfig.enableSubsampled = false;
projectConfig.bodyTracking = false;
projectConfig.adaptiveResolution = false;
projectConfig.stageMode = false;
projectConfig.videoSeeThrough = false;
projectConfig.spatialAnchor = false;
projectConfig.sceneCapture = false;
projectConfig.sharedAnchor = false;
projectConfig.spatialMesh = false;
projectConfig.superResolution = false;
projectConfig.normalSharpening = false;
projectConfig.qualitySharpening = false;
projectConfig.fixedFoveatedSharpening = false;
projectConfig.selfAdaptiveSharpening = false;
projectConfig.arFoundation = false;
projectConfig.mrSafeguard = false;
projectConfig.enableRecommendMSAA = false;
projectConfig.recommendSubsamping = false;
projectConfig.recommendMSAA = false;
projectConfig.meshLod = PxrMeshLod.Low;
string path = Application.dataPath + "/Resources";
if (!Directory.Exists(path))
{
UnityEditor.AssetDatabase.CreateFolder("Assets", "Resources");
UnityEditor.AssetDatabase.CreateAsset(projectConfig, "Assets/Resources/PXR_ProjectSetting.asset");
}
else
{
UnityEditor.AssetDatabase.CreateAsset(projectConfig, "Assets/Resources/PXR_ProjectSetting.asset");
}
}
#endif
return projectConfig;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 261e5777ad4ae374eb318821653de6aa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,118 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll information contained herein is, and remains the property of
PICO Technology Co., Ltd. The intellectual and technical concepts
contained herein are proprietary to PICO Technology Co., Ltd. and may be
covered by patents, patents in process, and are protected by trade secret or
copyright law. Dissemination of this information or reproduction of this
material is strictly forbidden unless prior written permission is obtained from
PICO Technology Co., Ltd.
*******************************************************************************/
using System;
using UnityEngine;
using UnityEngine.XR.Management;
#if UNITY_EDITOR
using System.IO;
using UnityEditor;
#endif
namespace Unity.XR.PXR
{
[Serializable]
[XRConfigurationData("PICO", "Unity.XR.PXR.Settings")]
public class PXR_Settings : ScriptableObject
{
public enum StereoRenderingModeAndroid
{
MultiPass,
Multiview
}
public enum SystemDisplayFrequency
{
Default,
RefreshRate72,
RefreshRate90,
RefreshRate120,
}
[SerializeField, Tooltip("Set the Stereo Rendering Method")]
public StereoRenderingModeAndroid stereoRenderingModeAndroid;
[SerializeField, Tooltip("Set the system display frequency")]
public SystemDisplayFrequency systemDisplayFrequency;
[SerializeField, Tooltip("if enabled,will always discarding depth and resolving MSAA color to improve performance on tile-based architectures. This only affects Vulkan. Note that this may break user content")]
public bool optimizeBufferDiscards = true;
[SerializeField, Tooltip("Enable Application SpaceWarp")]
public bool enableAppSpaceWarp;
[SerializeField, Tooltip("Set the system splash screen picture in PNG format. [width,height] < [1024, 1024]")]
public Texture2D systemSplashScreen;
private string splashPath = string.Empty;
public ushort GetStereoRenderingMode()
{
return (ushort)stereoRenderingModeAndroid;
}
public ushort GetSystemDisplayFrequency()
{
return (ushort)systemDisplayFrequency;
}
public ushort GetOptimizeBufferDiscards()
{
return optimizeBufferDiscards ? (ushort)1 : (ushort)0;
}
#if UNITY_ANDROID && !UNITY_EDITOR
public static PXR_Settings settings;
public void Awake()
{
settings = this;
}
#elif UNITY_EDITOR
private void OnValidate()
{
if (systemSplashScreen == null)
{
return;
}
if(systemSplashScreen.width > 1024 || systemSplashScreen.height > 1024)
{
systemSplashScreen = null;
splashPath = string.Empty;
Debug.LogError("The width and height of the System Splash Screen are invalid. They should be at least 1024 pixels in width and height.");
return;
}
splashPath = AssetDatabase.GetAssetPath(systemSplashScreen);
if (!string.Equals(Path.GetExtension(splashPath), ".png", StringComparison.OrdinalIgnoreCase))
{
systemSplashScreen = null;
Debug.LogError("Invalid file format of System Splash Screen, only PNG format is supported. The asset path: " + splashPath);
splashPath = string.Empty;
}
}
public string GetSystemSplashScreen(string path)
{
if (systemSplashScreen == null || splashPath == string.Empty)
{
return "0";
}
string targetPath = Path.Combine(path, "src/main/assets/pico_splash.png");
FileUtil.ReplaceFile(splashPath, targetPath);
return "1";
}
#endif
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 1c52faa1787e89a4eaf8abdae2e6ae25
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,43 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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 UnityEngine;
using UnityEngine.XR;
namespace Unity.XR.PXR
{
public static class PXR_Usages
{
public static InputFeatureUsage<Vector3> combineEyePoint = new InputFeatureUsage<Vector3>("CombinedEyeGazePoint");
public static InputFeatureUsage<Vector3> combineEyeVector = new InputFeatureUsage<Vector3>("CombinedEyeGazeVector");
public static InputFeatureUsage<Vector3> leftEyePoint = new InputFeatureUsage<Vector3>("LeftEyeGazePoint");
public static InputFeatureUsage<Vector3> leftEyeVector = new InputFeatureUsage<Vector3>("LeftEyeGazeVector");
public static InputFeatureUsage<Vector3> rightEyePoint = new InputFeatureUsage<Vector3>("RightEyeGazePoint");
public static InputFeatureUsage<Vector3> rightEyeVector = new InputFeatureUsage<Vector3>("RightEyeGazeVector");
public static InputFeatureUsage<float> leftEyeOpenness = new InputFeatureUsage<float>("LeftEyeOpenness");
public static InputFeatureUsage<float> rightEyeOpenness = new InputFeatureUsage<float>("RightEyeOpenness");
public static InputFeatureUsage<uint> leftEyePoseStatus = new InputFeatureUsage<uint>("LeftEyePoseStatus");
public static InputFeatureUsage<uint> rightEyePoseStatus = new InputFeatureUsage<uint>("RightEyePoseStatus");
public static InputFeatureUsage<uint> combinedEyePoseStatus = new InputFeatureUsage<uint>("CombinedEyePoseStatus");
public static InputFeatureUsage<float> leftEyePupilDilation = new InputFeatureUsage<float>("LeftEyePupilDilation");
public static InputFeatureUsage<float> rightEyePupilDilation = new InputFeatureUsage<float>("RightEyePupilDilation");
public static InputFeatureUsage<Vector3> leftEyePositionGuide = new InputFeatureUsage<Vector3>("LeftEyePositionGuide");
public static InputFeatureUsage<Vector3> rightEyePositionGuide = new InputFeatureUsage<Vector3>("RightEyePositionGuide");
public static InputFeatureUsage<Vector3> foveatedGazeDirection = new InputFeatureUsage<Vector3>("FoveatedGazeDirection");
public static InputFeatureUsage<uint> foveatedGazeTrackingState = new InputFeatureUsage<uint>("FoveatedGazeTrackingState");
public static InputFeatureUsage<bool> triggerTouch = new InputFeatureUsage<bool>("TriggerTouch");
public static InputFeatureUsage<float> grip1DAxis = new InputFeatureUsage<float>("Grip1DAxis");
public static InputFeatureUsage<bool> controllerStatus = new InputFeatureUsage<bool>("ControllerStatus");
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: c90eeb81b7becad43a8ab4b12f0df19e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: ad2a35d484cb9454187475efb4bf740f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,274 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.XR;
using UnityEngine.XR.Management;
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;
private int objectPoolMaxSize = 200;
private Queue<GameObject> meshObjectsPool;
/// <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>();
PXR_Manager.EnableVideoSeeThrough = true;
InitializePool();
}
void Update()
{
DrawMesh();
}
void OnEnable()
{
if (XRGeneralSettings.Instance != null && XRGeneralSettings.Instance.Manager != null)
{
var pxrLoader = XRGeneralSettings.Instance.Manager.ActiveLoaderAs<PXR_Loader>();
if (pxrLoader != null)
{
subsystem = pxrLoader.meshSubsystem;
if (subsystem != null)
{
subsystem.Start();
if (subsystem.running)
{
PXR_Manager.SpatialMeshDataUpdated += SpatialMeshDataUpdated;
}
}
else
{
enabled = false;
}
}
}
}
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 / 15f);
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++)
{
int flag = (int)block.labels[i];
normalizedColors[i] = MeshColor[flag];
}
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 readonly Color[] MeshColor = {
Color.black,
Color.red,
Color.green,
Color.blue,
Color.white,
Color.yellow,
Color.cyan,
Color.magenta,
Color.gray,
Color.grey,
new Color(0.8f,0.2f,0.6f)
};
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 551d50f46be2e15418380110aaeeb3ba
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,10 +0,0 @@
fileFormatVersion: 2
guid: b3e65a1172a9c3043b159b685b902103
folderAsset: yes
timeCreated: 1590581218
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 2e80d58020bdd4b42b9c135992067180
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,60 +0,0 @@
#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);
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: e1ef0f496c0fb5146b7aa4877024fa79
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d3ae25b6b7cd44b40a54c07476a52456
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,65 +0,0 @@
#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)
{
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 81e400e6b0dcff7418936a822864e3a6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,987 +0,0 @@
#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 ();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 2e63e0f11bef8d6429a261ce53a94f70
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,105 +0,0 @@
#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) {}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: eccf65801d671bc41b6df3f29c184857
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,478 +0,0 @@
#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]);
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: a9e68f25477380e49b9cc15cf5aeabe4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,484 +0,0 @@
#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;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: a4dd365314ca7114282641abfb814cdb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,912 +0,0 @@
#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;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: aadd9cba7eae43a42b4cc217ba457e54
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,24 +0,0 @@
#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

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: dd46d201658351647a556d32b2cd1edb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,44 +0,0 @@
#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
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 6e84bd194d881f84e81d978238a310ea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,72 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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.
*******************************************************************************/
#if UNITY_ANDROID && !UNITY_EDITOR
using System.Runtime.InteropServices;
#endif
using UnityEngine;
namespace Unity.XR.PXR
{
public class PLog
{
// 7--all print, 4--info to fatal, 3--warning to fatal,
// 2--error to fatal, 1--only fatal print
public static LogLevel logLevel = LogLevel.LogWarn;
public enum LogLevel
{
LogFatal = 1,
LogError = 2,
LogWarn = 3,
LogInfo = 4,
LogDebug = 5,
LogVerbose,
}
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));
}
}
}

View File

@@ -1,13 +0,0 @@
fileFormatVersion: 2
guid: 18f15a8b3150c6f4e9eacdcae94a826e
timeCreated: 1590473667
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,246 +0,0 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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 UnityEngine;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Unity.XR.PXR
{
public class PXR_ObjImporter : MonoBehaviour
{
private static PXR_ObjImporter instance;
public static PXR_ObjImporter Instance
{
get { return instance ?? (instance = new PXR_ObjImporter()); }
}
private List<int> triangles;
private List<Vector3> vertices;
private List<Vector2> uv;
private List<Vector3> normals;
private List<PxrVector3Int> faceData;
private List<int> intArray;
private const int MinPow10 = -16;
private const int MaxPow10 = 16;
private const int NumPows10 = MaxPow10 - MinPow10 + 1;
private static readonly float[] pow10 = GenerateLookupTable();
public Mesh ImportFile(string filePath)
{
triangles = new List<int>();
vertices = new List<Vector3>();
uv = new List<Vector2>();
normals = new List<Vector3>();
faceData = new List<PxrVector3Int>();
intArray = new List<int>();
LoadMeshData(filePath);
Vector3[] newVerts = new Vector3[faceData.Count];
Vector2[] newUVs = new Vector2[faceData.Count];
Vector3[] newNormals = new Vector3[faceData.Count];
for (int i = 0; i < faceData.Count; i++)
{
newVerts[i] = vertices[faceData[i].x - 1];
if (faceData[i].y >= 1)
newUVs[i] = uv[faceData[i].y - 1];
if (faceData[i].z >= 1)
newNormals[i] = normals[faceData[i].z - 1];
}
Mesh mesh = new Mesh();
mesh.vertices = newVerts;
mesh.uv = newUVs;
mesh.normals = newNormals;
mesh.triangles = triangles.ToArray();
mesh.RecalculateBounds();
return mesh;
}
private void LoadMeshData(string fileName)
{
StringBuilder sb = new StringBuilder();
string text = File.ReadAllText(fileName);
int start = 0;
string objectName = null;
int faceDataCount = 0;
StringBuilder sbFloat = new StringBuilder();
for (int i = 0; i < text.Length; i++)
{
if (text[i] == '\n')
{
sb.Remove(0, sb.Length);
sb.Append(text, start + 1, i - start);
start = i;
if (sb[0] == 'o' && sb[1] == ' ')
{
sbFloat.Remove(0, sbFloat.Length);
int j = 2;
while (j < sb.Length)
{
objectName += sb[j];
j++;
}
}
else if (sb[0] == 'v' && sb[1] == ' ') // Vertices
{
int splitStart = 2;
vertices.Add(new Vector3(GetFloat(sb, ref splitStart, ref sbFloat),
GetFloat(sb, ref splitStart, ref sbFloat), GetFloat(sb, ref splitStart, ref sbFloat)));
}
else if (sb[0] == 'v' && sb[1] == 't' && sb[2] == ' ') // UV
{
int splitStart = 3;
uv.Add(new Vector2(GetFloat(sb, ref splitStart, ref sbFloat),
GetFloat(sb, ref splitStart, ref sbFloat)));
}
else if (sb[0] == 'v' && sb[1] == 'n' && sb[2] == ' ') // Normals
{
int splitStart = 3;
normals.Add(new Vector3(GetFloat(sb, ref splitStart, ref sbFloat),
GetFloat(sb, ref splitStart, ref sbFloat), GetFloat(sb, ref splitStart, ref sbFloat)));
}
else if (sb[0] == 'f' && sb[1] == ' ')
{
int splitStart = 2;
int j = 1;
intArray.Clear();
int info = 0;
while (splitStart < sb.Length && char.IsDigit(sb[splitStart]))
{
faceData.Add(new PxrVector3Int(GetInt(sb, ref splitStart, ref sbFloat),
GetInt(sb, ref splitStart, ref sbFloat), GetInt(sb, ref splitStart, ref sbFloat)));
j++;
intArray.Add(faceDataCount);
faceDataCount++;
}
info += j;
j = 1;
while (j + 2 < info)
{
triangles.Add(intArray[0]);
triangles.Add(intArray[j]);
triangles.Add(intArray[j + 1]);
j++;
}
}
}
}
}
private float GetFloat(StringBuilder sb, ref int start, ref StringBuilder sbFloat)
{
sbFloat.Remove(0, sbFloat.Length);
while (start < sb.Length &&
(char.IsDigit(sb[start]) || sb[start] == '-' || sb[start] == '.'))
{
sbFloat.Append(sb[start]);
start++;
}
start++;
return ParseFloat(sbFloat);
}
private int GetInt(StringBuilder sb, ref int start, ref StringBuilder sbInt)
{
sbInt.Remove(0, sbInt.Length);
while (start < sb.Length &&
(char.IsDigit(sb[start])))
{
sbInt.Append(sb[start]);
start++;
}
start++;
return IntParseFast(sbInt);
}
private static float[] GenerateLookupTable()
{
var result = new float[(-MinPow10 + MaxPow10) * 10];
for (int i = 0; i < result.Length; i++)
result[i] = (float)((i / NumPows10) *
Mathf.Pow(10, i % NumPows10 + MinPow10));
return result;
}
private float ParseFloat(StringBuilder value)
{
float result = 0;
bool negate = false;
int len = value.Length;
int decimalIndex = value.Length;
for (int i = len - 1; i >= 0; i--)
if (value[i] == '.')
{ decimalIndex = i; break; }
int offset = -MinPow10 + decimalIndex;
for (int i = 0; i < decimalIndex; i++)
if (i != decimalIndex && value[i] != '-')
result += pow10[(value[i] - '0') * NumPows10 + offset - i - 1];
else if (value[i] == '-')
negate = true;
for (int i = decimalIndex + 1; i < len; i++)
if (i != decimalIndex)
result += pow10[(value[i] - '0') * NumPows10 + offset - i];
if (negate)
result = -result;
return result;
}
private int IntParseFast(StringBuilder value)
{
int result = 0;
for (int i = 0; i < value.Length; i++)
{
result = 10 * result + (value[i] - 48);
}
return result;
}
}
public sealed class PxrVector3Int
{
public int x { get; set; }
public int y { get; set; }
public int z { get; set; }
public PxrVector3Int() { }
public PxrVector3Int(int intX, int intY, int intZ)
{
x = intX;
y = intY;
z = intZ;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: f2847360a92ba0f40ad7692cff1514b6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,19 +0,0 @@
using System.Collections;
using System.IO;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor.AssetImporters;
using UnityEditor.Experimental.AssetImporters;
[ScriptedImporter(1, ".phf")]
public class PXR_PhfFile : ScriptedImporter
{
public override void OnImportAsset(AssetImportContext ctx)
{
var phfTxt = File.ReadAllText(ctx.assetPath);
var assetText = new TextAsset(phfTxt);
ctx.AddObjectToAsset("main obj", assetText);
ctx.SetMainObject(assetText);
}
}
#endif

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d59d7e2845e58ed429e0d9a183c3b9bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,72 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using Unity.XR.PXR;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
public class PXR_VstModelPosCheck : MonoBehaviour
{
public bool IsController = false;
private Transform mMainCamTrans;
private XRBaseController mXRBaseController;
private PXR_Hand mPXR_Hand;
private float mVirtualWorldOffset = 0.03f;
private readonly Vector3 mStartDirection = new Vector3(0f, 0f, 1.0f);
private Quaternion mHeadRotation;
private Vector3 mOffsetDirection;
private Vector3 mOffsetPos;
// Start is called before the first frame update
void Start()
{
if (IsController)
{
if (mXRBaseController == null)
mXRBaseController = GetComponent<XRBaseController>();
}
else
{
if (mPXR_Hand == null)
mPXR_Hand = GetComponent<PXR_Hand>();
}
mMainCamTrans = Camera.main.transform;
mVirtualWorldOffset = PXR_Plugin.System.UPxr_VstModelOffset();
}
private void OnEnable()
{
Application.onBeforeRender += CheckPos;
}
private void OnDisable()
{
Application.onBeforeRender -= CheckPos;
}
private void UpdatePos()
{
mHeadRotation = mMainCamTrans.localRotation;
mOffsetDirection = mHeadRotation * (-1f * mStartDirection);
mOffsetPos = mOffsetDirection * mVirtualWorldOffset;
}
private void CheckPos()
{
if (IsController)
{
UpdatePos();
transform.localPosition = mXRBaseController.currentControllerState.position + mOffsetPos;
}
}
public Vector3 GetHandPosOffset()
{
UpdatePos();
return mOffsetPos;
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 53189b8d17e53d940a4049ff51959815
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: