Init
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af2e07e443067b947ba9416c54fd673f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4a172f3ddf65b643aee5a7bdd3e5015
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eac9288513d6ab14fbb83c358e066e68
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,17 @@
|
||||
using Unity.XR.CoreUtils.Capabilities;
|
||||
using UnityEngine;
|
||||
using Unity.XR.PXR;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
class PXR_OpenXR_SDKCapability : CapabilityProfile, ICapabilityModifier
|
||||
{
|
||||
static CapabilityDictionary m_CurrentCapabilities = new CapabilityDictionary();
|
||||
|
||||
|
||||
public bool TryGetCapabilityValue(string capabilityKey, out bool capabilityValue)
|
||||
{
|
||||
return m_CurrentCapabilities.TryGetValue(capabilityKey, out capabilityValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 37f17ef263b31984bbb562a0f1f1918f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
using Unity.XR.CoreUtils.Capabilities;
|
||||
using UnityEngine;
|
||||
using Unity.XR.PXR;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
class PXR_SDKCapability : CapabilityProfile, ICapabilityModifier
|
||||
{
|
||||
static CapabilityDictionary m_CurrentCapabilities = new CapabilityDictionary();
|
||||
|
||||
public bool TryGetCapabilityValue(string capabilityKey, out bool capabilityValue)
|
||||
{
|
||||
return m_CurrentCapabilities.TryGetValue(capabilityKey, out capabilityValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2b340d6b5858d6439e4b03f2c397afa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ce500e2a00603a46a6aed7bd3f4385a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,65 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
#if UNITY_EDITOR
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.XR.PXR.Debugger
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public class PXR_PicoDebuggerSetup
|
||||
{
|
||||
static PXR_PicoDebuggerSetup()
|
||||
{
|
||||
EditorApplication.update += Init_PXR_PicoDebuggerSetup;
|
||||
}
|
||||
static void Init_PXR_PicoDebuggerSetup()
|
||||
{
|
||||
string currentPanelPath = $"{PXR_DebuggerConst.sdkPackageName}Assets/Debugger/Prefabs/DebuggerPanel.prefab";
|
||||
string targetPanelPath = "Assets/Resources/PXR_DebuggerPanel.prefab";
|
||||
string currentEntryPath = $"{PXR_DebuggerConst.sdkPackageName}Assets/Debugger/Prefabs/PICODebugger.prefab";
|
||||
string targetEntryPath = "Assets/Resources/PXR_PICODebugger.prefab";
|
||||
if(!File.Exists(targetEntryPath)){
|
||||
if (!Directory.Exists("Assets/Resources"))
|
||||
{
|
||||
AssetDatabase.CreateFolder("Assets", "Resources");
|
||||
}
|
||||
|
||||
if (AssetDatabase.LoadAssetAtPath<GameObject>(currentEntryPath) == null)
|
||||
{
|
||||
Debug.LogError("Prefab not found at path: " + currentEntryPath);
|
||||
}
|
||||
|
||||
AssetDatabase.CopyAsset(currentEntryPath, targetEntryPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
if(!File.Exists(targetPanelPath)){
|
||||
if (!Directory.Exists("Assets/Resources"))
|
||||
{
|
||||
AssetDatabase.CreateFolder("Assets", "Resources");
|
||||
}
|
||||
|
||||
if (AssetDatabase.LoadAssetAtPath<GameObject>(currentPanelPath) == null)
|
||||
{
|
||||
Debug.LogError("Prefab not found at path: " + currentPanelPath);
|
||||
}
|
||||
|
||||
AssetDatabase.CopyAsset(currentPanelPath, targetPanelPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
// EditorApplication.update -= Init_PXR_PicoDebuggerSetup;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c809738d124f34369b66513743555f59
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,109 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using System;
|
||||
namespace Unity.XR.PXR.Debugger
|
||||
{
|
||||
// Generate a setting item in the editor project settings screen
|
||||
static class SettingToolEditor
|
||||
{
|
||||
[SettingsProvider]
|
||||
public static SettingsProvider CreateMyCustomSettingsProvider()
|
||||
{
|
||||
var config = PXR_PicoDebuggerSO.Instance;
|
||||
|
||||
var provider = new SettingsProvider("Project/PICO Debugger", SettingsScope.Project)
|
||||
{
|
||||
label = "PICO Debugger",
|
||||
activateHandler = (obj, rootElement) =>
|
||||
{
|
||||
var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>($"{PXR_Utils.sdkPackageName}Assets/Debugger/UI/PICODebuggerPanel.uxml");
|
||||
var rootVisualElement = visualTree.Instantiate();
|
||||
rootElement.Add(rootVisualElement);
|
||||
|
||||
var isOpenToggle = rootVisualElement.Q<Toggle>("IsOpen");
|
||||
var debuggerlaucherButtonDropdown = rootVisualElement.Q<DropdownField>("DebuggerLaucherButton");
|
||||
var startPositionDropdown = rootVisualElement.Q<DropdownField>("StartPosition");
|
||||
var maxInfoCountSlider = rootVisualElement.Q<Slider>("MaxInfoCount");
|
||||
var rulerClearButtonDropdown = rootVisualElement.Q<DropdownField>("RulerClearButton");
|
||||
|
||||
isOpenToggle.value = config.isOpen;
|
||||
isOpenToggle.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
config.isOpen = evt.newValue;
|
||||
EditorUtility.SetDirty(config); // Mark as dirty to save the changes
|
||||
if(config.isOpen){
|
||||
PXR_AppLog.PXR_OnEvent($"{PXR_AppLog.strPICODebugger}", PXR_AppLog.strPICODebugger_Enable,"enable");
|
||||
}
|
||||
});
|
||||
|
||||
debuggerlaucherButtonDropdown.choices = Enum.GetNames(typeof(LauncherButton)).ToList();
|
||||
debuggerlaucherButtonDropdown.choices = Enum.GetNames(typeof(LauncherButton)).Where(name => name != config.rulerClearButton.ToString()).ToList();
|
||||
debuggerlaucherButtonDropdown.index = (int)config.debuggerLauncherButton;
|
||||
debuggerlaucherButtonDropdown.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
config.debuggerLauncherButton = (LauncherButton)Enum.Parse(typeof(LauncherButton), evt.newValue);
|
||||
rulerClearButtonDropdown.choices = Enum.GetNames(typeof(LauncherButton)).Where(name => name != config.debuggerLauncherButton.ToString()).ToList();
|
||||
EditorUtility.SetDirty(config);
|
||||
PXR_AppLog.PXR_OnEvent($"{PXR_AppLog.strPICODebugger}", PXR_AppLog.strPICODebugger_LauncherButton,$"{config.debuggerLauncherButton}");
|
||||
});
|
||||
|
||||
|
||||
startPositionDropdown.choices = Enum.GetNames(typeof(StartPosiion)).ToList();
|
||||
startPositionDropdown.index = (int)config.startPosition;
|
||||
startPositionDropdown.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
config.startPosition = (StartPosiion)Enum.Parse(typeof(StartPosiion), evt.newValue);
|
||||
EditorUtility.SetDirty(config);
|
||||
PXR_AppLog.PXR_OnEvent($"{PXR_AppLog.strPICODebugger}",$"{PXR_AppLog.strPICODebugger_InitialPosition}",$"{config.startPosition}");
|
||||
});
|
||||
|
||||
// var isFollowingToggle = rootVisualElement.Q<Toggle>("isFollowing");
|
||||
// var isFollowingProperty = settings.FindProperty("isFollowing");
|
||||
|
||||
// var isLookAtCameraToggle = rootVisualElement.Q<Toggle>("isLookAtCamera");
|
||||
// var isLookAtCameraProperty = settings.FindProperty("isLookAtCamera");
|
||||
|
||||
|
||||
maxInfoCountSlider.value = config.maxInfoCount;
|
||||
maxInfoCountSlider.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
config.maxInfoCount = Mathf.RoundToInt(evt.newValue);
|
||||
EditorUtility.SetDirty(config);
|
||||
PXR_AppLog.PXR_OnEvent($"{PXR_AppLog.strPICODebugger}",$"{PXR_AppLog.strPICODebugger_MaxLogCount}", $"{config.maxInfoCount}");
|
||||
});
|
||||
|
||||
|
||||
rulerClearButtonDropdown.choices = Enum.GetNames(typeof(LauncherButton)).Where(name => name != config.debuggerLauncherButton.ToString()).ToList();
|
||||
rulerClearButtonDropdown.index = (int)config.rulerClearButton;
|
||||
rulerClearButtonDropdown.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
config.rulerClearButton = (LauncherButton)Enum.Parse(typeof(LauncherButton), evt.newValue);
|
||||
debuggerlaucherButtonDropdown.choices = Enum.GetNames(typeof(LauncherButton)).Where(name => name != config.rulerClearButton.ToString()).ToList();
|
||||
EditorUtility.SetDirty(config);
|
||||
PXR_AppLog.PXR_OnEvent($"{PXR_AppLog.strPICODebugger}",$"{PXR_AppLog.strPICODebugger_RulerResetButton}", $"{config.rulerClearButton}");
|
||||
});
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
},
|
||||
keywords = new HashSet<string>(new[] { "PICO", "Debugger Tool" })
|
||||
};
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16a4fd861d5a241dd806c0390ca67f73
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,107 @@
|
||||
using Unity.XR.PXR;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(PXR_ARCameraEffectManager))]
|
||||
public class PXR_ARCameraEffectManagerEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
PXR_ARCameraEffectManager manager = (PXR_ARCameraEffectManager)target;
|
||||
PXR_ProjectSetting projectConfig = PXR_ProjectSetting.GetProjectConfig();
|
||||
var guiContent = new GUIContent();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
// camera effect
|
||||
guiContent.text = "Camera Effect";
|
||||
manager.enableCameraEffect = EditorGUILayout.Toggle(guiContent, manager.enableCameraEffect);
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
if (manager.enableCameraEffect)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
guiContent.text = "Colortemp";
|
||||
manager.colortempValue = EditorGUILayout.Slider(guiContent, manager.colortempValue, -50, 50);
|
||||
|
||||
guiContent.text = "Brightness";
|
||||
manager.brightnessValue = EditorGUILayout.Slider(guiContent, manager.brightnessValue, -50, 50);
|
||||
|
||||
guiContent.text = "Saturation";
|
||||
manager.saturationValue = EditorGUILayout.Slider(guiContent, manager.saturationValue, -50, 50);
|
||||
|
||||
guiContent.text = "Contrast";
|
||||
manager.contrastValue = EditorGUILayout.Slider(guiContent, manager.contrastValue, -50, 50);
|
||||
|
||||
EditorGUILayout.LabelField("LUT");
|
||||
var textureControlRect = EditorGUILayout.GetControlRect(GUILayout.Width(100), GUILayout.Height(100));
|
||||
manager.lutTex1 = (Texture2D)EditorGUI.ObjectField(new Rect(textureControlRect.x, textureControlRect.y, 100, textureControlRect.height), manager.lutTex1, typeof(Texture), false);
|
||||
ValidateTexture(manager.lutTex1);
|
||||
|
||||
manager.lutTex2 = (Texture2D)EditorGUI.ObjectField(new Rect(textureControlRect.x + textureControlRect.width, textureControlRect.y, textureControlRect.width, textureControlRect.height), manager.lutTex2, typeof(Texture), false);
|
||||
ValidateTexture(manager.lutTex2);
|
||||
|
||||
manager.lutTex3 = (Texture2D)EditorGUI.ObjectField(new Rect(textureControlRect.x + 2*textureControlRect.width, textureControlRect.y, textureControlRect.width, textureControlRect.height), manager.lutTex3, typeof(Texture), false);
|
||||
ValidateTexture(manager.lutTex3);
|
||||
|
||||
manager.lutTex4 = (Texture2D)EditorGUI.ObjectField(new Rect(textureControlRect.x + 3 * textureControlRect.width, textureControlRect.y, textureControlRect.width, textureControlRect.height), manager.lutTex4, typeof(Texture), false);
|
||||
ValidateTexture(manager.lutTex4);
|
||||
|
||||
manager.lutTex5 = (Texture2D)EditorGUI.ObjectField(new Rect(textureControlRect.x + 4 * textureControlRect.width, textureControlRect.y, textureControlRect.width, textureControlRect.height), manager.lutTex5, typeof(Texture), false);
|
||||
ValidateTexture(manager.lutTex5);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
Camera camera = manager.gameObject.GetComponent<Camera>();
|
||||
if (camera)
|
||||
{
|
||||
camera.clearFlags = CameraClearFlags.SolidColor;
|
||||
camera.backgroundColor = new Color(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
EditorUtility.SetDirty(projectConfig);
|
||||
EditorUtility.SetDirty(manager);
|
||||
}
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEngine.SceneManagement.SceneManager.GetActiveScene());
|
||||
}
|
||||
}
|
||||
|
||||
private static void ValidateTexture(Texture2D lutTex)
|
||||
{
|
||||
if (lutTex != null)
|
||||
{
|
||||
// Validate texture format
|
||||
if (lutTex.format != TextureFormat.RGBA32)
|
||||
{
|
||||
Debug.LogError("Unsupported texture format! Please provide a texture in RGBA32 format.");
|
||||
lutTex = null; // Reset texture if format is incorrect
|
||||
}
|
||||
|
||||
// Validate texture size
|
||||
if (lutTex.width > 512 || lutTex.height > 512)
|
||||
{
|
||||
Debug.LogError("The texture size must not exceed 512x512 pixels!");
|
||||
lutTex = null; // Reset texture if size is incorrect
|
||||
}
|
||||
|
||||
// Set read/write flag
|
||||
if (!lutTex.isReadable)
|
||||
{
|
||||
string assetPath = AssetDatabase.GetAssetPath(lutTex);
|
||||
TextureImporter importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
|
||||
if (importer != null)
|
||||
{
|
||||
importer.isReadable = true;
|
||||
AssetDatabase.ImportAsset(assetPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c1e9fbaf94f2922449415352deff41f0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,306 @@
|
||||
using LitJson;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
public class PXR_AppLog
|
||||
{
|
||||
public static string APPName = "PICO_UnitySDK";
|
||||
public static int APPID = 722442;
|
||||
public static int productLineID = 843;
|
||||
|
||||
|
||||
public static string strXRSDK = "unity_xr_sdk";
|
||||
public static string strOpenXRSDK = "unity_openxr_sdk";
|
||||
#region Portal
|
||||
public static string strPortal = "portal"; // param
|
||||
public static string strPortal_Enter = "enter";
|
||||
|
||||
public static string strPortal_Configs_Open = "configs_open";
|
||||
public static string strPortal_Configs_RequiredPICOXRPluginApplied = "configs_required_picoxr_plugin_applied";
|
||||
public static string strPortal_Configs_RequiredBuildTargetAndroidApplied = "configs_required_build_target_android_applied";
|
||||
public static string strPortal_Configs_RequiredAndroidSdkVersionsApplied = "configs_required_android_api_level29_applied";
|
||||
public static string strPortal_Configs_ToApplyAllApplied = "configs_to_apply_all_applied";
|
||||
public static string strPortal_Configs_ProjectValidation = "configs_project_validation";
|
||||
public static string strPortal_Configs_OpenPICOXRProjectSetting = "configs_open_picoxr_project_setting";
|
||||
|
||||
public static string strPortal_Tools_Open = "tools_open";
|
||||
public static string strPortal_Tools_ProjectValidation_Documentation = "tools_project_validation_documentation";
|
||||
public static string strPortal_Tools_ProjectValidation_Open = "tools_project_validation_open";
|
||||
public static string strPortal_Tools_BuildingBlocks = "tools_building_blocks_documentation";
|
||||
public static string strPortal_Tools_PICOXRToolkitMR = "tools_picoxr_toolkit_mr_documentation";
|
||||
public static string strPortal_Tools_XRProfilingToolkit = "tools_xr_profiling_toolkit_documentation";
|
||||
public static string strPortal_Tools_PICODeveloperCenter = "tools_pico_developer_center_documentation";
|
||||
public static string strPortal_Tools_Emulator = "tools_emulator_documentation";
|
||||
public static string strPortal_Tools_MoreDeveloperTools = "tools_more_developer_tools_documentation";
|
||||
|
||||
public static string strPortal_Sample_Open = "samples_open";
|
||||
public static string strPortal_Samples_MixedRealitySample_Documentation = "samples_mixed_reality_sample_documentation";
|
||||
public static string strPortal_Samples_MixedRealitySample_GitHub = "samples_mixed_reality_sample_github";
|
||||
|
||||
public static string strPortal_Samples_InteractionSample_Documentation = "samples_interaction_sample_documentation";
|
||||
public static string strPortal_Samples_InteractionSample_GitHub = "samples_interaction_sample_github";
|
||||
|
||||
public static string strPortal_Samples_MotionTrackerSample_Documentation = "samples_motion_tracker_sample_documentation";
|
||||
public static string strPortal_Samples_MotionTrackerSample_GitHub = "samples_motion_tracker_sample_github";
|
||||
|
||||
public static string strPortal_Samples_PlatformServicesSample_Documentation = "samples_platform_services_sample_documentation";
|
||||
public static string strPortal_Samples_PlatformServicesSample_GitHub = "samples_platform_services_sample_github";
|
||||
|
||||
public static string strPortal_Samples_SpatialAudioSample_Documentation = "samples_spatial_audio_sample_documentation";
|
||||
public static string strPortal_Samples_SpatialAudioSample_GitHub = "samples_spatial_audio_sample_github";
|
||||
|
||||
public static string strPortal_Samples_ARFoundationSample_Documentation = "samples_arfoundation_sample_documentation";
|
||||
public static string strPortal_Samples_ARFoundationSample_GitHub = "samples_arfoundation_sample_github";
|
||||
|
||||
public static string strPortal_Samples_AdaptiveResolutionSample_Documentation = "samples_adaptive_resolution_sample_documentation";
|
||||
public static string strPortal_Samples_AdaptiveResolutionSample_GitHub = "samples_adaptive_resolution_sample_github";
|
||||
|
||||
public static string strPortal_Samples_ToonWorldSample_Documentation = "samples_toon_world_sample_documentation";
|
||||
public static string strPortal_Samples_ToonWorldSample_GitHub = "samples_toon_world_sample_github";
|
||||
|
||||
public static string strPortal_Samples_MicroWarSample_Documentation = "samples_micro_war_sample_documentation";
|
||||
public static string strPortal_Samples_MicroWarSample_GitHub = "samples_micro_war_sample_github";
|
||||
|
||||
public static string strPortal_Samples_PICOAvatarSample_Documentation = "samples_pico_avatar_sample_documentation";
|
||||
public static string strPortal_Samples_PICOAvatarSample_GitHub = "samples_pico_avatar_sample_github";
|
||||
|
||||
public static string strPortal_Samples_URPFork_Documentation = "samples_urp_fork_documentation";
|
||||
public static string strPortal_Samples_URPFork_GitHub = "samples_urp_fork_github";
|
||||
|
||||
|
||||
public static string strPortal_About_Open = "about_open";
|
||||
public static string strPortal_About_Documentation = "about_documentation";
|
||||
public static string strPortal_About_Installation = "about_installation";
|
||||
#endregion
|
||||
|
||||
#region ProjectValidation
|
||||
public static string strProjectValidation = "project_validation"; // param
|
||||
public static string strProjectValidation_AndroidAPIMinSdkVersion = "android_api_min_sdk_version";
|
||||
public static string strProjectValidation_ARM64 = "arm64";
|
||||
public static string strProjectValidation_OneMainCamera = "one_main_camera";
|
||||
public static string strProjectValidation_OneAudioListener = "one_audio_listener";
|
||||
public static string strProjectValidation_BuildTargetPlatformAndroid = "build_target_platform_android";
|
||||
public static string strProjectValidation_PICOXRPlugin = "picoxr_plugin";
|
||||
public static string strProjectValidation_GraphicsAPIOrderForAndroid = "graphics_api_order_for_android";
|
||||
public static string strProjectValidation_Unity2022NoDevelopmentBuild = "unity2022_no_development_build";
|
||||
public static string strProjectValidation_Unity2022114URPLinearMSAA4OpenglesCrash = "unity2022114_urp_linear_msaa4_opengles_crash";
|
||||
public static string strProjectValidation_AddPXRManager = "add_pxr_manager";
|
||||
public static string strProjectValidation_ETFRUseOpenGLES3 = "etfr_use_opengles3";
|
||||
public static string strProjectValidation_FTUnsafeCode = "ft_unsafe_code";
|
||||
public static string strProjectValidation_URPNoHDR = "urp_no_hdr";
|
||||
public static string strProjectValidation_URPGraphicsQuality = "urp_graphics_quality";
|
||||
public static string strProjectValidation_MRARM64 = "mr_arm64";
|
||||
public static string strProjectValidation_OneXROrigin = "one_xr_origin";
|
||||
public static string strProjectValidation_ProjectKeystore = "project_keystore";
|
||||
public static string strProjectValidation_ProjectKey = "project_key";
|
||||
public static string strProjectValidation_UIOrientationLandscapeLeft = "ui_orientation_landscape_left";
|
||||
public static string strProjectValidation_UseActivity = "use_activity";
|
||||
public static string strProjectValidation_TargetAPILevelAuto = "target_api_level_auto";
|
||||
public static string strProjectValidation_InstallLocationAuto = "install_location_auto";
|
||||
public static string strProjectValidation_ContactOffset001 = "context_offset_001";
|
||||
public static string strProjectValidation_SleepThreshold0005 = "sleep_threshold_0005";
|
||||
public static string strProjectValidation_SolverIteration8 = "solver_iteration8";
|
||||
public static string strProjectValidation_MaximumPixelLights = "maximum_pixel_lights";
|
||||
public static string strProjectValidation_TextureQualitytoFullRes = "texture_quality_to_full_res";
|
||||
public static string strProjectValidation_AnisotropicFiltering = "anisotropic_filtering";
|
||||
public static string strProjectValidation_ETC2 = "etc2";
|
||||
public static string strProjectValidation_ColorSpaceLinear = "color_space_linear";
|
||||
public static string strProjectValidation_DisableGraphicsJobs = "disable_graphics_jobs";
|
||||
public static string strProjectValidation_Multithreaded = "multithreaded";
|
||||
public static string strProjectValidation_DisplayBufferFormat = "display_buffer_format";
|
||||
public static string strProjectValidation_RenderingPathToForward = "rendering_path_to_forward";
|
||||
public static string strProjectValidation_Multiview = "multiview";
|
||||
public static string strProjectValidation_URPIntermediatetexturetoAuto = "urp_intermediate_texture_to_auto";
|
||||
public static string strProjectValidation_URPDisableSSAO = "urp_disable_ssao";
|
||||
public static string strProjectValidation_FFRSubsampling = "ffr_subsampling";
|
||||
public static string strProjectValidation_MSAA = "msaa";
|
||||
public static string strProjectValidation_APPSWNoContentProtect = "appsw_no_content_protect";
|
||||
public static string strProjectValidation_TrackingOriginModeDevice = "tracking_origin_mode_device";
|
||||
public static string strProjectValidation_DisableRealtimeGI = "disable_realtime_gi";
|
||||
public static string strProjectValidation_GPUSkinning = "gpu_skinning";
|
||||
public static string strProjectValidation_EyeTrackingCalibration = "eye_tracking_calibration";
|
||||
public static string strProjectValidation_WritePermissionAndroid14 = "write_permission_android14";
|
||||
public static string strProjectValidation_Unity2020321Unity6 = "unity2020321_unity6";
|
||||
public static string strProjectValidation_URPNoUseToDelete = "urp_no_use_to_delete";
|
||||
public static string strProjectValidation_URPVSTNoPostProcessing = "urp_vst_no_post_processing";
|
||||
public static string strProjectValidation_URPNoETFRAndFFR = "urp_no_etfr_and_ffr";
|
||||
public static string strProjectValidation_APPSWNeed = "appsw_need";
|
||||
public static string strProjectValidation_LateLatchingNeed = "late_latching_need";
|
||||
public static string strProjectValidation_LateLatchingOrOverlay = "late_latching_or_overlay";
|
||||
public static string strProjectValidation_Overlay7 = "overlay7";
|
||||
public static string strProjectValidation_SuperResolutionOrSubsampling = "super_resolution_or_subsampling";
|
||||
public static string strProjectValidation_SharpeningOrSubsampling = "sharpening_or_subsampling";
|
||||
public static string strProjectValidation_Unity6URPOpenGLESMultiPassNoMSAA = "unity6_urp_opengles_multi_pass_no_msaa";
|
||||
public static string strProjectValidation_Overlay4 = "overlay4";
|
||||
public static string strProjectValidation_Unity6RunInBackground = "unity6_run_in_background";
|
||||
public static string strProjectValidation_MRC = "mrc";
|
||||
public static string strProjectValidation_DisplayRefreshRatesDefault = "display_refresh_rates_default";
|
||||
public static string strProjectValidation_VKOptimizeBufferDiscards = "vk_optimize_buffer_discards";
|
||||
|
||||
// 3.3.0 new add
|
||||
public static string strProjectValidation_SubsamplingOpenXR182Earlier = "subsampling_openxr_182_earlier";
|
||||
#endregion
|
||||
|
||||
#region BuildingBlocks
|
||||
public static string strBuildingBlocks = "building_blocks"; // param
|
||||
public static string strBuildingBlocks_PICOControllerTracking = "pico_controller_tracking";
|
||||
public static string strBuildingBlocks_ControllerCanvasInteraction = "controller_canvas_interaction";
|
||||
public static string strBuildingBlocks_PICOHandTracking = "pico_hand_tracking";
|
||||
public static string strBuildingBlocks_XRHandTracking = "xr_hand_tracking";
|
||||
public static string strBuildingBlocks_XRIHandInteraction = "xri_hand_interaction";
|
||||
public static string strBuildingBlocks_XRIGrabInteraction = "xri_grab_interaction";
|
||||
public static string strBuildingBlocks_XRIPokeInteraction = "xri_poke_interaction";
|
||||
public static string strBuildingBlocks_PICOVideoSeethrough = "pico_video_seethrough";
|
||||
public static string strBuildingBlocks_PICOVideoSeethroughEffect = "pico_video_seethrough_effect";
|
||||
public static string strBuildingBlocks_PICOBodyTracking = "pico_body_tracking";
|
||||
public static string strBuildingBlocks_PICOBodyTrackingDebug = "pico_body_tracking_debug";
|
||||
public static string strBuildingBlocks_PICOObjectTracking = "pico_object_tracking";
|
||||
public static string strBuildingBlocks_PICOSpatialAudioFreeField = "pico_spatial_audio_free_field";
|
||||
public static string strBuildingBlocks_PICOSpatialAudioAmbisonics = "pico_spatial_audio_ambisonics";
|
||||
// 3.3.0 new add
|
||||
public static string strBuildingBlocks_PICOSpatialAnchorSample = "pico_spatial_anchor_sample";
|
||||
public static string strBuildingBlocks_PICOSpatialMesh = "pico_spatial_mesh";
|
||||
public static string strBuildingBlocks_PICOSceneCapture = "pico_scene_capture";
|
||||
public static string strBuildingBlocks_PICOCompositionLayerOverlay = "pico_composition_layer_overlay";
|
||||
public static string strBuildingBlocks_PICOCompositionLayerUnderlay = "pico_composition_layer_underlay";
|
||||
#endregion
|
||||
|
||||
#region PICO Debugger
|
||||
public static string strPICODebugger = "XRSDK_PICO_debugger";
|
||||
|
||||
public static string strPICODebugger_Enable = strPICODebugger + "_enable";
|
||||
public static string strPICODebugger_LauncherButton = strPICODebugger + "_launcher_button";
|
||||
public static string strPICODebugger_InitialPosition = strPICODebugger + "_initial_position";
|
||||
public static string strPICODebugger_MaxLogCount = strPICODebugger + "_max_log_count";
|
||||
public static string strPICODebugger_RulerResetButton = strPICODebugger + "_ruler_reset_button";
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
private static bool isInited = false;
|
||||
private static void TryInitAppLog()
|
||||
{
|
||||
#if UNITY_EDITOR_WIN
|
||||
if (isInited)
|
||||
{
|
||||
return;
|
||||
}
|
||||
isInited = true;
|
||||
|
||||
Debug.Log($"TryInitAppLog ");
|
||||
AppLog_init("722442", "PICO_UnitySDK");
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call the buried point collection wherever it is required, and pass in the name and parameters of the buried point (in a dictionary structure).
|
||||
/// </summary>
|
||||
/// <param name="eventName"></param>
|
||||
/// <param name="properties"></param>
|
||||
public static void PXR_OnEvent(string param, string value)
|
||||
{
|
||||
#if UNITY_EDITOR_WIN
|
||||
if (PXR_ProjectSetting.GetProjectConfig().isDataCollectionDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Debug.Log($"PXR_OnEvent eventName:{strXRSDK}, param:{param}, value:{value}");
|
||||
try
|
||||
{
|
||||
var contentData = new JsonData()
|
||||
{
|
||||
[param] = value,
|
||||
|
||||
};
|
||||
TryInitAppLog();
|
||||
AppLog_onEvent(strXRSDK, contentData.ToJson());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//Debug.LogError($"PXR_OnEvent param:{param}, value={value}, e={e}.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call the buried point collection wherever it is required, and pass in the name and parameters of the buried point (in a dictionary structure).
|
||||
/// </summary>
|
||||
/// <param name="eventName"></param>
|
||||
/// <param name="properties"></param>
|
||||
public static void PXR_OnEvent(string eventName, string param, string value = "1")
|
||||
{
|
||||
#if UNITY_EDITOR_WIN
|
||||
if (PXR_ProjectSetting.GetProjectConfig().isDataCollectionDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//Debug.Log($"PXR_OnEvent eventName:{eventName}, param:{param}, value:{value}");
|
||||
try
|
||||
{
|
||||
var contentData = new JsonData()
|
||||
{
|
||||
[param] = value,
|
||||
|
||||
};
|
||||
TryInitAppLog();
|
||||
AppLog_onEvent(eventName, contentData.ToJson());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//Debug.LogError($"PXR_OnEvent param:{param}, value={value}, e={e}.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void PXR_SetLogEnabled(bool enable)
|
||||
{
|
||||
#if UNITY_EDITOR_WIN
|
||||
Debug.Log($"PXR_SetLogEnabled start enable={enable}");
|
||||
if (enable)
|
||||
{
|
||||
AppLog_setLogEnabled(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
AppLog_setLogEnabled(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void PXR_AppLogDestroy(DestroyCallback observer)
|
||||
{
|
||||
#if UNITY_EDITOR_WIN
|
||||
AppLog_destroy(observer);
|
||||
#endif
|
||||
}
|
||||
|
||||
private const string DllName = "applogrs";
|
||||
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void AppLog_init(string appid, string channel);
|
||||
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void AppLog_setEventVerifyEnabled(uint enabled);
|
||||
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void AppLog_setLogEnabled(uint enabled);
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern UInt64 AppLog_getDeviceId();
|
||||
|
||||
public delegate void LoggerCallback(string message);
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void AppLog_setLogger(LoggerCallback observer);
|
||||
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void AppLog_onEvent(string eventName, string param);
|
||||
public delegate void DestroyCallback();
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void AppLog_destroy(DestroyCallback destory_callback);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0ece506a9761df4d8274c9f5e04b5bf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,689 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEditor.Android;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
using UnityEditor;
|
||||
using UnityEditor.XR.Management;
|
||||
using UnityEngine.XR.Management;
|
||||
#if UNITY_OPENXR
|
||||
#if XR_HAND
|
||||
using UnityEngine.XR.Hands.OpenXR;
|
||||
#endif
|
||||
#if PICO_OPENXR_SDK
|
||||
//using UnityEngine.XR.Hands.OpenXR;
|
||||
using Unity.XR.OpenXR.Features.PICOSupport;
|
||||
using UnityEngine.XR.OpenXR;
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace Unity.XR.PXR.Editor
|
||||
{
|
||||
public class PXR_BuildProcessor : XRBuildHelper<PXR_Settings>
|
||||
{
|
||||
public override string BuildSettingsKey { get { return "Unity.XR.PXR.Settings"; } }
|
||||
|
||||
public static bool IsLoaderExists(bool isPlatform = false)
|
||||
{
|
||||
XRGeneralSettings generalSettings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(BuildTargetGroup.Android);
|
||||
if (generalSettings == null) return false;
|
||||
var assignedSettings = generalSettings.AssignedSettings;
|
||||
if (assignedSettings == null) return false;
|
||||
|
||||
bool isPxrOpenXRFeatureEnabled = false;
|
||||
bool isPxrOpenXRExtensionsEnabled = false;
|
||||
#if UNITY_2021_1_OR_NEWER
|
||||
foreach (XRLoader loader in assignedSettings.activeLoaders)
|
||||
{
|
||||
if (loader is PXR_Loader) return true;
|
||||
#if PICO_OPENXR_SDK
|
||||
if (loader is OpenXRLoader)
|
||||
{
|
||||
var settings = OpenXRSettings.GetSettingsForBuildTargetGroup(BuildTargetGroup.Android);
|
||||
foreach (var feature in settings.GetFeatures<OpenXRFeature>())
|
||||
{
|
||||
if (feature is PICOFeature)
|
||||
{
|
||||
isPxrOpenXRFeatureEnabled = feature.enabled;
|
||||
if (!isPlatform)
|
||||
{
|
||||
return isPxrOpenXRFeatureEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
if (feature is OpenXRExtensions)
|
||||
{
|
||||
isPxrOpenXRExtensionsEnabled = feature.enabled;
|
||||
if (isPlatform)
|
||||
{
|
||||
return isPxrOpenXRExtensionsEnabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
foreach (XRLoader loader in assignedSettings.loaders)
|
||||
{
|
||||
if (loader is PXR_Loader) return true;
|
||||
#if PICO_OPENXR_SDK
|
||||
if (loader is OpenXRLoader)
|
||||
{
|
||||
Debug.Log("PXRLog [Build Check]OpenXR is enabled");
|
||||
var settings = OpenXRSettings.GetSettingsForBuildTargetGroup(BuildTargetGroup.Android);
|
||||
foreach (var feature in settings.GetFeatures<OpenXRFeature>())
|
||||
{
|
||||
if (feature is PXR_OpenXRFeature)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (feature is PXR_OpenXRFeature)
|
||||
{
|
||||
isPxrOpenXRFeatureEnabled = feature.enabled;
|
||||
if (!isPlatform)
|
||||
{
|
||||
return isPxrOpenXRFeatureEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
if (feature is PXR_OpenXRExtensions)
|
||||
{
|
||||
isPxrOpenXRExtensionsEnabled = feature.enabled;
|
||||
if (isPlatform)
|
||||
{
|
||||
return isPxrOpenXRExtensionsEnabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
private PXR_Settings PxrSettings
|
||||
{
|
||||
get
|
||||
{
|
||||
return SettingsForBuildTargetGroup(BuildTargetGroup.Android) as PXR_Settings;
|
||||
}
|
||||
}
|
||||
private void SetRequiredPluginInBuild()
|
||||
{
|
||||
PluginImporter[] plugins = PluginImporter.GetAllImporters();
|
||||
foreach (PluginImporter plugin in plugins)
|
||||
{
|
||||
if (plugin.assetPath.Contains("PxrPlatform.aar"))
|
||||
{
|
||||
plugin.SetIncludeInBuildDelegate((path) =>
|
||||
{
|
||||
return IsLoaderExists(true);
|
||||
});
|
||||
}
|
||||
if (plugin.assetPath.Contains(".ForUnitySDK.aar"))
|
||||
{
|
||||
Debug.Log("PXRLog [Build Check]OpenXR is enabled");
|
||||
plugin.SetIncludeInBuildDelegate((path) =>
|
||||
{
|
||||
#if PICO_OPENXR_SDK
|
||||
var settings = OpenXRSettings.GetSettingsForBuildTargetGroup(BuildTargetGroup.Android);
|
||||
foreach (var feature in settings.GetFeatures<OpenXRFeature>())
|
||||
{
|
||||
if (feature is PICOFeature)
|
||||
{
|
||||
return feature.enabled;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
#else
|
||||
return IsLoaderExists(true);
|
||||
#endif
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnPreprocessBuild(BuildReport report)
|
||||
{
|
||||
SetRequiredPluginInBuild();
|
||||
if (report.summary.platformGroup != BuildTargetGroup.Android)
|
||||
return;
|
||||
if (!IsLoaderExists())
|
||||
return;
|
||||
GraphicsDeviceType firstGfxType =
|
||||
PlayerSettings.GetGraphicsAPIs(EditorUserBuildSettings.activeBuildTarget)[0];
|
||||
if (firstGfxType != GraphicsDeviceType.OpenGLES3 && firstGfxType != GraphicsDeviceType.Vulkan && firstGfxType != GraphicsDeviceType.OpenGLES2)
|
||||
throw new BuildFailedException($"PICO Plugin on mobile platforms nonsupport the {firstGfxType}");
|
||||
if (PxrSettings.stereoRenderingModeAndroid == PXR_Settings.StereoRenderingModeAndroid.Multiview && firstGfxType == GraphicsDeviceType.OpenGLES2)
|
||||
PlayerSettings.SetGraphicsAPIs(BuildTarget.Android, new GraphicsDeviceType[] { GraphicsDeviceType.OpenGLES3 });
|
||||
if (PlayerSettings.Android.minSdkVersion < AndroidSdkVersions.AndroidApiLevel29)
|
||||
throw new BuildFailedException("Android Minimum API must be set to 29 or higher for PICO Plugin.");
|
||||
base.OnPreprocessBuild(report);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_2021_3_OR_NEWER
|
||||
internal class PXR_BuildHooks : IPreprocessBuildWithReport, IPostprocessBuildWithReport
|
||||
{
|
||||
public int callbackOrder { get; }
|
||||
|
||||
private static readonly Dictionary<string, string> AndroidBootConfigVars = new Dictionary<string, string>()
|
||||
{
|
||||
{ "xr-usable-core-mask-enabled", "1"},
|
||||
{ "xr-require-backbuffer-textures", "0" },
|
||||
{ "xr-hide-memoryless-render-texture", "1" },
|
||||
{ "xr-vulkan-extension-fragment-density-map-enabled", "1"}
|
||||
};
|
||||
|
||||
public void OnPreprocessBuild(BuildReport report)
|
||||
{
|
||||
|
||||
if (report.summary.platformGroup == BuildTargetGroup.Android)
|
||||
{
|
||||
|
||||
var bootConfig = new BootConfig(report);
|
||||
bootConfig.ReadBootConfig();
|
||||
|
||||
foreach (var entry in AndroidBootConfigVars)
|
||||
{
|
||||
bootConfig.SetValueForKey(entry.Key, entry.Value);
|
||||
}
|
||||
|
||||
bootConfig.WriteBootConfig();
|
||||
|
||||
var issues = PXR_ProjectValidationRequired.GetValidationIssues();
|
||||
foreach (var issue in issues)
|
||||
{
|
||||
if (issue.error)
|
||||
{
|
||||
Debug.LogError($"PXR SDK validation failed: {issue.description}");
|
||||
throw new BuildFailedException($"There are unresolved PXR configuration errors");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPostprocessBuild(BuildReport report)
|
||||
{
|
||||
if (report.summary.platformGroup == BuildTargetGroup.Android)
|
||||
{
|
||||
BootConfig bootConfig = new BootConfig(report);
|
||||
bootConfig.ReadBootConfig();
|
||||
|
||||
foreach (KeyValuePair<string, string> entry in AndroidBootConfigVars)
|
||||
{
|
||||
bootConfig.ClearEntryForKeyAndValue(entry.Key, entry.Value);
|
||||
}
|
||||
|
||||
bootConfig.WriteBootConfig();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Small utility class for reading, updating and writing boot config.
|
||||
/// </summary>
|
||||
internal class BootConfig
|
||||
{
|
||||
private const string XrBootSettingsKey = "xr-boot-settings";
|
||||
|
||||
private readonly Dictionary<string, string> bootConfigSettings;
|
||||
private readonly string buildTargetName;
|
||||
|
||||
public BootConfig(BuildReport report)
|
||||
{
|
||||
bootConfigSettings = new Dictionary<string, string>();
|
||||
buildTargetName = BuildPipeline.GetBuildTargetName(report.summary.platform);
|
||||
}
|
||||
|
||||
public void ReadBootConfig()
|
||||
{
|
||||
bootConfigSettings.Clear();
|
||||
|
||||
string xrBootSettings = EditorUserBuildSettings.GetPlatformSettings(buildTargetName, XrBootSettingsKey);
|
||||
if (!string.IsNullOrEmpty(xrBootSettings))
|
||||
{
|
||||
var bootSettings = xrBootSettings.Split(';');
|
||||
foreach (var bootSetting in bootSettings)
|
||||
{
|
||||
var setting = bootSetting.Split(':');
|
||||
if (setting.Length == 2 && !string.IsNullOrEmpty(setting[0]) && !string.IsNullOrEmpty(setting[1]))
|
||||
{
|
||||
bootConfigSettings.Add(setting[0], setting[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetValueForKey(string key, string value) => bootConfigSettings[key] = value;
|
||||
|
||||
public bool TryGetValue(string key, out string value) => bootConfigSettings.TryGetValue(key, out value);
|
||||
|
||||
public void ClearEntryForKeyAndValue(string key, string value)
|
||||
{
|
||||
if (bootConfigSettings.TryGetValue(key, out string dictValue) && dictValue == value)
|
||||
{
|
||||
bootConfigSettings.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteBootConfig()
|
||||
{
|
||||
bool firstEntry = true;
|
||||
var sb = new System.Text.StringBuilder();
|
||||
foreach (var kvp in bootConfigSettings)
|
||||
{
|
||||
if (!firstEntry)
|
||||
{
|
||||
sb.Append(";");
|
||||
}
|
||||
|
||||
sb.Append($"{kvp.Key}:{kvp.Value}");
|
||||
firstEntry = false;
|
||||
}
|
||||
|
||||
EditorUserBuildSettings.SetPlatformSettings(buildTargetName, XrBootSettingsKey, sb.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if UNITY_ANDROID
|
||||
internal class PXR_Manifest : IPostGenerateGradleAndroidProject
|
||||
{
|
||||
public void OnPostGenerateGradleAndroidProject(string path)
|
||||
{
|
||||
if (!PXR_BuildProcessor.IsLoaderExists())
|
||||
return;
|
||||
string originManifestPath = path + "/src/main/AndroidManifest.xml";
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(originManifestPath);
|
||||
string manifestTagPath = "/manifest";
|
||||
string applicationTagPath = manifestTagPath + "/application";
|
||||
string metaDataTagPath = applicationTagPath + "/meta-data";
|
||||
string usesPermissionTagName = "uses-permission";
|
||||
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","pvr.app.type"}},new Dictionary<string, string>{{"value","vr"}});
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","pxr.sdk.version_code"}},new Dictionary<string, string>{{"value", "5140"}});
|
||||
doc.InsertAttributeInTargetTag(applicationTagPath,null, new Dictionary<string, string>() {{"requestLegacyExternalStorage", "true"}});
|
||||
#if PICO_OPENXR_SDK
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","use.pxr.sdk"}},new Dictionary<string, string>{{"value", "2"}});
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","pvr.sdk.version"}},new Dictionary<string, string>{{"value","Unity OpenXR "+PXR_Constants.SDKVersion}});
|
||||
var settings = OpenXRSettings.GetSettingsForBuildTargetGroup(BuildTargetGroup.Android);
|
||||
bool mrPermission = false;
|
||||
|
||||
foreach (var feature in settings.GetFeatures<OpenXRFeature>())
|
||||
{
|
||||
if (feature is PICOSceneCapture)
|
||||
{
|
||||
if (feature.enabled)
|
||||
{
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "enable_scene_anchor" } },
|
||||
new Dictionary<string, string> { { "value", "1" } });
|
||||
mrPermission = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
doc.RemoveAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "enable_scene_anchor" } });
|
||||
}
|
||||
}
|
||||
|
||||
if (feature is PICOSpatialAnchor)
|
||||
{
|
||||
if (feature.enabled)
|
||||
{
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "enable_spatial_anchor" } },
|
||||
new Dictionary<string, string> { { "value", "1" } });
|
||||
mrPermission = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
doc.RemoveAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "enable_spatial_anchor" } });
|
||||
}
|
||||
}
|
||||
|
||||
if (feature is PICOSpatialMesh)
|
||||
{
|
||||
if (feature.enabled)
|
||||
{
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "enable_mesh_anchor" } },
|
||||
new Dictionary<string, string> { { "value", "1" } });
|
||||
mrPermission = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
doc.RemoveAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "enable_mesh_anchor" } });
|
||||
}
|
||||
}
|
||||
#if XR_HAND
|
||||
if (feature is HandTracking)
|
||||
{
|
||||
if (feature.enabled)
|
||||
{
|
||||
if (PXR_OpenXRProjectSetting.GetProjectConfig().isHandTracking)
|
||||
{
|
||||
doc.CreateElementInTag(manifestTagPath, usesPermissionTagName,
|
||||
new Dictionary<string, string> { { "name", "com.picovr.permission.HAND_TRACKING" } });
|
||||
|
||||
if (PXR_OpenXRProjectSetting.GetProjectConfig().handTrackingSupportType == HandTrackingSupport.HandsOnly)
|
||||
{
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "handtracking" } },
|
||||
new Dictionary<string, string> { { "value", "1" } });
|
||||
doc.RemoveAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "controller" } });
|
||||
}
|
||||
else
|
||||
{
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "handtracking" } },
|
||||
new Dictionary<string, string> { { "value", "1" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "controller" } },
|
||||
new Dictionary<string, string> { { "value", "1" } });
|
||||
}
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "Hand_Tracking_HighFrequency" } },
|
||||
new Dictionary<string, string> { { "value", PXR_OpenXRProjectSetting.GetProjectConfig().highFrequencyHand ? "1" : "0" } });
|
||||
}
|
||||
else
|
||||
{
|
||||
doc.RemoveNameValueElementInTag(manifestTagPath, usesPermissionTagName,
|
||||
"android:name", "com.picovr.permission.HAND_TRACKING");
|
||||
doc.RemoveAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "handtracking" } });
|
||||
doc.RemoveAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "Hand_Tracking_HighFrequency" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "controller" } },
|
||||
new Dictionary<string, string> { { "value", "1" } });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
doc.RemoveNameValueElementInTag(manifestTagPath, usesPermissionTagName,
|
||||
"android:name", "com.picovr.permission.HAND_TRACKING");
|
||||
doc.RemoveAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "handtracking" } });
|
||||
doc.RemoveAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "Hand_Tracking_HighFrequency" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "controller" } },
|
||||
new Dictionary<string, string> { { "value", "1" } });
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
}
|
||||
|
||||
doc.RemoveNameValueElementInTag(manifestTagPath, usesPermissionTagName,
|
||||
"android:name", "com.picovr.permission.HAND_TRACKING");
|
||||
doc.RemoveAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "handtracking" } });
|
||||
doc.RemoveAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "Hand_Tracking_HighFrequency" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "controller" } },
|
||||
new Dictionary<string, string> { { "value", "1" } });
|
||||
|
||||
#endif
|
||||
if (PXR_OpenXRProjectSetting.GetProjectConfig().isEyeTracking)
|
||||
{
|
||||
doc.CreateElementInTag(manifestTagPath, usesPermissionTagName,
|
||||
new Dictionary<string, string> { { "name", "com.picovr.permission.EYE_TRACKING" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "picovr.software.eye_tracking" } },
|
||||
new Dictionary<string, string> { { "value", "1" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "eyetracking_calibration" } },
|
||||
new Dictionary<string, string> { { "value", PXR_OpenXRProjectSetting.GetProjectConfig().isEyeTrackingCalibration ? "true" : "false" } });
|
||||
}
|
||||
else
|
||||
{
|
||||
doc.RemoveNameValueElementInTag(manifestTagPath, usesPermissionTagName,
|
||||
"android:name", "com.picovr.permission.EYE_TRACKING");
|
||||
doc.RemoveAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "picovr.software.eye_tracking" } });
|
||||
doc.RemoveAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "eyetracking_calibration" } });
|
||||
}
|
||||
|
||||
if (PXR_OpenXRProjectSetting.GetProjectConfig().MRSafeguard)
|
||||
{
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "enable_mr_safeguard" } },
|
||||
new Dictionary<string, string> { { "value", PXR_OpenXRProjectSetting.GetProjectConfig().MRSafeguard ? "1" : "0" } });
|
||||
}
|
||||
else
|
||||
{
|
||||
doc.RemoveAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "enable_mr_safeguard" } });
|
||||
}
|
||||
|
||||
if (mrPermission)
|
||||
{
|
||||
doc.CreateElementInTag(manifestTagPath, usesPermissionTagName,
|
||||
new Dictionary<string, string> { { "name", "com.picovr.permission.SPATIAL_DATA" } });
|
||||
}
|
||||
else
|
||||
{
|
||||
doc.RemoveNameValueElementInTag(manifestTagPath, usesPermissionTagName,
|
||||
"android:name", "com.picovr.permission.SPATIAL_DATA");
|
||||
}
|
||||
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "pvr.app.splash" } },
|
||||
new Dictionary<string, string> { { "value", PXR_OpenXRProjectSetting.GetProjectConfig().GetSystemSplashScreen(path) } });
|
||||
|
||||
#else
|
||||
var settings = PXR_XmlTools.GetSettings();
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","use.pxr.sdk"}},new Dictionary<string, string>{{"value", "1"}});
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","pvr.sdk.version"}},new Dictionary<string, string>{{"value","XR Platform_"+PXR_Constants.SDKVersion}});
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","enable_cpt"}},new Dictionary<string, string>{{"value",PXR_ProjectSetting.GetProjectConfig().useContentProtect ? "1" : "0"}});
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","Enable_AdaptiveHandModel"}},new Dictionary<string, string> {{"value",PXR_ProjectSetting.GetProjectConfig().adaptiveHand ? "1" : "0" }});
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","Hand_Tracking_HighFrequency"}},new Dictionary<string, string> {{"value",PXR_ProjectSetting.GetProjectConfig().highFrequencyHand ? "1" : "0" }});
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","rendering_mode"}},new Dictionary<string, string>{{"value",((int)settings.stereoRenderingModeAndroid).ToString()}});
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","display_rate"}},new Dictionary<string, string>{{"value",((int)settings.systemDisplayFrequency).ToString()}});
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","color_Space"}},new Dictionary<string, string>{{"value",QualitySettings.activeColorSpace == ColorSpace.Linear ? "1" : "0"}});
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","MRCsupport"}},new Dictionary<string, string>{{"value",PXR_ProjectSetting.GetProjectConfig().openMRC ? "1" : "0" }});
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","pvr.LateLatching"}}, new Dictionary<string, string> {{"value",PXR_ProjectSetting.GetProjectConfig().latelatching ? "1" : "0" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","pvr.LateLatchingDebug"}}, new Dictionary<string, string> {{"value", PXR_ProjectSetting.GetProjectConfig().latelatching && PXR_ProjectSetting.GetProjectConfig().latelatchingDebug ? "1" : "0" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","pvr.app.splash"} },new Dictionary<string, string>{{"value",settings.GetSystemSplashScreen(path)}});
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","PICO.swift.feature"}},new Dictionary<string, string>{{"value",PXR_ProjectSetting.GetProjectConfig().bodyTracking ? "1" : "0" }});
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath,new Dictionary<string, string>{{"name","adaptive_resolution"}},new Dictionary<string, string>{{"value",PXR_ProjectSetting.GetProjectConfig().adaptiveResolution ? "1" : "0" }});
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "enable_mr_safeguard" } }, new Dictionary<string, string> { { "value", PXR_ProjectSetting.GetProjectConfig().mrSafeguard ? "1" : "0" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "enable_vst" } }, new Dictionary<string, string> { { "value", PXR_ProjectSetting.GetProjectConfig().videoSeeThrough ? "1" : "0" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "enable_anchor" } }, new Dictionary<string, string> { { "value", PXR_ProjectSetting.GetProjectConfig().spatialAnchor ? "1" : "0" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "mr_map_mgr_auto_start" } }, new Dictionary<string, string> { { "value", PXR_ProjectSetting.GetProjectConfig().spatialAnchor ? "1" : "0" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "enable_spatial_anchor" } }, new Dictionary<string, string> { { "value", PXR_ProjectSetting.GetProjectConfig().spatialAnchor ? "1" : "0" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "enable_cloud_anchor" } }, new Dictionary<string, string> { { "value", PXR_ProjectSetting.GetProjectConfig().sharedAnchor ? "1" : "0" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "enable_mesh_anchor" } }, new Dictionary<string, string> { { "value", PXR_ProjectSetting.GetProjectConfig().spatialMesh ? "1" : "0" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "enable_scene_anchor" } }, new Dictionary<string, string> { { "value", PXR_ProjectSetting.GetProjectConfig().sceneCapture ? "1" : "0" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "pvr.SuperResolution" } }, new Dictionary<string, string> { { "value", PXR_ProjectSetting.GetProjectConfig().superResolution ? "1" : "0" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "pvr.NormalSharpening" } }, new Dictionary<string, string> { { "value", PXR_ProjectSetting.GetProjectConfig().normalSharpening ? "1" : "0" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "pvr.QualitySharpening" } }, new Dictionary<string, string> { { "value", PXR_ProjectSetting.GetProjectConfig().qualitySharpening ? "1" : "0" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "pvr.FixedFoveatedSharpening" } }, new Dictionary<string, string> { { "value", PXR_ProjectSetting.GetProjectConfig().fixedFoveatedSharpening ? "1" : "0" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "pvr.SelfAdaptiveSharpening" } }, new Dictionary<string, string> { { "value", PXR_ProjectSetting.GetProjectConfig().selfAdaptiveSharpening ? "1" : "0" } });
|
||||
doc.CreateElementInTag(manifestTagPath,usesPermissionTagName,new Dictionary<string, string>{{"name","android.permission.WRITE_SETTINGS"}});
|
||||
|
||||
if (PXR_ProjectSetting.GetProjectConfig().eyeTracking || PXR_ProjectSetting.GetProjectConfig().enableETFR)
|
||||
{
|
||||
doc.CreateElementInTag(manifestTagPath, usesPermissionTagName, new Dictionary<string, string> { { "name", "com.picovr.permission.EYE_TRACKING" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "picovr.software.eye_tracking" } }, new Dictionary<string, string> { { "value", "1" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "eyetracking_calibration" } }, new Dictionary<string, string> { { "value", PXR_ProjectSetting.GetProjectConfig().eyetrackingCalibration ? "true" : "false" } });
|
||||
}
|
||||
|
||||
if (PXR_ProjectSetting.GetProjectConfig().spatialAnchor || PXR_ProjectSetting.GetProjectConfig().sceneCapture || PXR_ProjectSetting.GetProjectConfig().spatialMesh || PXR_ProjectSetting.GetProjectConfig().sharedAnchor)
|
||||
{
|
||||
doc.CreateElementInTag(manifestTagPath, usesPermissionTagName,
|
||||
new Dictionary<string, string> { { "name", "com.picovr.permission.SPATIAL_DATA" } });
|
||||
}
|
||||
|
||||
if (PXR_ProjectSetting.GetProjectConfig().handTracking)
|
||||
{
|
||||
if (PXR_ProjectSetting.GetProjectConfig().handTrackingSupportType==HandTrackingSupport.HandsOnly)
|
||||
{
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "handtracking" } },
|
||||
new Dictionary<string, string> { { "value", "1" } });
|
||||
doc.RemoveAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "controller" } });
|
||||
|
||||
doc.CreateElementInTag(manifestTagPath, usesPermissionTagName,
|
||||
new Dictionary<string, string> { { "name", "com.picovr.permission.HAND_TRACKING" } });
|
||||
}
|
||||
else
|
||||
{
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "handtracking" } },
|
||||
new Dictionary<string, string> { { "value", "1" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "controller" } },
|
||||
new Dictionary<string, string> { { "value", "1" } });
|
||||
doc.CreateElementInTag(manifestTagPath, usesPermissionTagName,
|
||||
new Dictionary<string, string> { { "name", "com.picovr.permission.HAND_TRACKING" } });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
doc.RemoveAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "handtracking" } });
|
||||
doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "controller" } },
|
||||
new Dictionary<string, string> { { "value", "1" } });
|
||||
doc.RemoveNameValueElementInTag(manifestTagPath, usesPermissionTagName,
|
||||
"android:name", "com.picovr.permission.HAND_TRACKING");
|
||||
}
|
||||
|
||||
if (PXR_ProjectSetting.GetProjectConfig().faceTracking) { doc.CreateElementInTag(manifestTagPath, usesPermissionTagName, new Dictionary<string, string> { { "name", "com.picovr.permission.FACE_TRACKING" } }); }
|
||||
if (PXR_ProjectSetting.GetProjectConfig().lipsyncTracking) { doc.CreateElementInTag(manifestTagPath, usesPermissionTagName, new Dictionary<string, string> { { "name", "android.permission.RECORD_AUDIO" } }); }
|
||||
if (PXR_ProjectSetting.GetProjectConfig().faceTracking) { doc.InsertAttributeInTargetTag(metaDataTagPath, new Dictionary<string, string> { { "name", "picovr.software.face_tracking" } }, new Dictionary<string, string> { { "value", "false/true" } }); }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
doc.Save(originManifestPath);
|
||||
}
|
||||
public int callbackOrder { get { return 10000; } }
|
||||
}
|
||||
#endif
|
||||
|
||||
public static class PXR_XmlTools
|
||||
{
|
||||
static readonly string androidURI = "http://schemas.android.com/apk/res/android";
|
||||
public static void InsertAttributeInTargetTag(this XmlDocument doc, string tagPath, Dictionary<string, string> filterDic, Dictionary<string, string> attributeDic)
|
||||
{
|
||||
XmlElement targetElement = null;
|
||||
if (filterDic == null)
|
||||
targetElement = doc.SelectSingleNode(tagPath) as XmlElement;
|
||||
else
|
||||
{
|
||||
XmlNodeList nodeList = doc.SelectNodes(tagPath);
|
||||
if (nodeList != null)
|
||||
{
|
||||
foreach (XmlNode node in nodeList)
|
||||
{
|
||||
if (FilterCheck(node as XmlElement, filterDic))
|
||||
{
|
||||
targetElement = node as XmlElement;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (targetElement == null)
|
||||
{
|
||||
string parentPath = tagPath.Substring(0, tagPath.LastIndexOf("/"));
|
||||
string tagName = tagPath.Substring(tagPath.LastIndexOf("/") + 1);
|
||||
foreach (var item in attributeDic)
|
||||
filterDic.Add(item.Key, item.Value);
|
||||
doc.CreateElementInTag(parentPath, tagName, filterDic);
|
||||
}
|
||||
else UpdateOrCreateAttribute(targetElement, attributeDic);
|
||||
}
|
||||
public static void RemoveAttributeInTargetTag(this XmlDocument doc, string tagPath, Dictionary<string, string> filterDic)
|
||||
{
|
||||
if (filterDic != null)
|
||||
{
|
||||
XmlNodeList nodeList = doc.SelectNodes(tagPath);
|
||||
if (nodeList != null)
|
||||
{
|
||||
foreach (XmlNode node in nodeList)
|
||||
{
|
||||
if (FilterCheck(node as XmlElement, filterDic))
|
||||
{
|
||||
node.ParentNode?.RemoveChild(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveNameValueElementInTag(this XmlDocument doc, string parentPath, string tag, string name,
|
||||
string value)
|
||||
{
|
||||
var xmlNodeList = doc.SelectNodes(parentPath + "/" + tag);
|
||||
|
||||
foreach (XmlNode node in xmlNodeList)
|
||||
{
|
||||
var attributeList = ((XmlElement)node).Attributes;
|
||||
|
||||
foreach (XmlAttribute attrib in attributeList)
|
||||
{
|
||||
if (attrib.Name == name && attrib.Value == value)
|
||||
{
|
||||
node.ParentNode?.RemoveChild(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void CreateElementInTag(this XmlDocument doc, string parentPath, string tagName,
|
||||
Dictionary<string, string> attributeDic)
|
||||
{
|
||||
XmlNode parentNode = doc.SelectSingleNode(parentPath);
|
||||
if (parentNode == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (XmlNode childNode in parentNode.ChildNodes)
|
||||
{
|
||||
if (childNode.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
if (FilterCheck((XmlElement)childNode, attributeDic))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
XmlElement newElement = doc.CreateElement(tagName);
|
||||
UpdateOrCreateAttribute(newElement, attributeDic);
|
||||
parentNode.AppendChild(newElement);
|
||||
}
|
||||
private static bool FilterCheck(XmlElement element, Dictionary<string, string> filterDic)
|
||||
{
|
||||
foreach (var filterCase in filterDic)
|
||||
{
|
||||
string caseValue = element.GetAttribute(filterCase.Key, androidURI);
|
||||
if (String.IsNullOrEmpty(caseValue) || caseValue != filterCase.Value)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private static void UpdateOrCreateAttribute(XmlElement element, Dictionary<string, string> attributeDic)
|
||||
{
|
||||
foreach (var attributeItem in attributeDic)
|
||||
{
|
||||
element.SetAttribute(attributeItem.Key, androidURI, attributeItem.Value);
|
||||
}
|
||||
}
|
||||
public static 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4ebbee757f020441995246fa9243022
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,500 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Unity.XR.PXR.Editor
|
||||
{
|
||||
[CanEditMultipleObjects]
|
||||
[CustomEditor(typeof(PXR_CompositionLayer))]
|
||||
public class PXR_CompositionLayerEditor : UnityEditor.Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
var guiContent = new GUIContent();
|
||||
foreach (PXR_CompositionLayer overlayTarget in targets)
|
||||
{
|
||||
EditorGUILayout.LabelField("Composition Layer Settings", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
guiContent.text = "Type";
|
||||
overlayTarget.overlayType = (PXR_CompositionLayer.OverlayType)EditorGUILayout.EnumPopup(guiContent, overlayTarget.overlayType);
|
||||
guiContent.text = "Shape";
|
||||
overlayTarget.overlayShape = (PXR_CompositionLayer.OverlayShape)EditorGUILayout.EnumPopup(guiContent, overlayTarget.overlayShape);
|
||||
guiContent.text = "Depth";
|
||||
overlayTarget.layerDepth = EditorGUILayout.IntField(guiContent, overlayTarget.layerDepth);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
guiContent.text = "Clones";
|
||||
overlayTarget.isClones = EditorGUILayout.Toggle(guiContent, overlayTarget.isClones);
|
||||
if (overlayTarget.isClones)
|
||||
{
|
||||
overlayTarget.originalOverLay = EditorGUILayout.ObjectField("Original OverLay", overlayTarget.originalOverLay, typeof(PXR_CompositionLayer), true) as PXR_CompositionLayer;
|
||||
|
||||
GUIStyle firstLevelStyle = new GUIStyle(GUI.skin.label);
|
||||
firstLevelStyle.alignment = TextAnchor.UpperLeft;
|
||||
firstLevelStyle.fontStyle = FontStyle.Bold;
|
||||
firstLevelStyle.fontSize = 12;
|
||||
firstLevelStyle.wordWrap = true;
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
EditorGUILayout.LabelField("Note:", firstLevelStyle);
|
||||
EditorGUILayout.LabelField("Original OverLay cannot be empty or itself!");
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUILayout.LabelField("Composition Layer Textures", EditorStyles.boldLabel);
|
||||
guiContent.text = "Texture Type";
|
||||
overlayTarget.textureType = (PXR_CompositionLayer.TextureType)EditorGUILayout.EnumPopup(guiContent, overlayTarget.textureType);
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
if (overlayTarget.overlayShape == PXR_CompositionLayer.OverlayShape.BlurredQuad)
|
||||
{
|
||||
overlayTarget.textureType = PXR_CompositionLayer.TextureType.ExternalSurface;
|
||||
}
|
||||
|
||||
if (overlayTarget.textureType == PXR_CompositionLayer.TextureType.ExternalSurface)
|
||||
{
|
||||
overlayTarget.isExternalAndroidSurface = true;
|
||||
overlayTarget.isDynamic = false;
|
||||
}
|
||||
else if (overlayTarget.textureType == PXR_CompositionLayer.TextureType.DynamicTexture)
|
||||
{
|
||||
overlayTarget.isExternalAndroidSurface = false;
|
||||
overlayTarget.isDynamic = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.isExternalAndroidSurface = false;
|
||||
overlayTarget.isDynamic = false;
|
||||
}
|
||||
|
||||
if (overlayTarget.isExternalAndroidSurface)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
guiContent.text = "DRM";
|
||||
overlayTarget.isExternalAndroidSurfaceDRM = EditorGUILayout.Toggle(guiContent, overlayTarget.isExternalAndroidSurfaceDRM);
|
||||
|
||||
guiContent.text = "3D Surface Type";
|
||||
guiContent.tooltip = "The functions of '3D Surface Type' and 'Source Rects' are similar, and only one of them can be used. ";
|
||||
overlayTarget.externalAndroidSurface3DType = (PXR_CompositionLayer.Surface3DType)EditorGUILayout.EnumPopup(guiContent, overlayTarget.externalAndroidSurface3DType);
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
if (overlayTarget.overlayShape == PXR_CompositionLayer.OverlayShape.BlurredQuad)
|
||||
{
|
||||
EditorGUILayout.LabelField("Blurred Quad");
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
guiContent.text = "Mode";
|
||||
overlayTarget.blurredQuadMode = (PXR_CompositionLayer.BlurredQuadMode)EditorGUILayout.EnumPopup(guiContent, overlayTarget.blurredQuadMode);
|
||||
|
||||
guiContent.text = "Scale";
|
||||
overlayTarget.blurredQuadScale = EditorGUILayout.FloatField(guiContent, Mathf.Abs(overlayTarget.blurredQuadScale));
|
||||
|
||||
guiContent.text = "Shift";
|
||||
overlayTarget.blurredQuadShift = EditorGUILayout.Slider(guiContent, overlayTarget.blurredQuadShift, -1, 1);
|
||||
|
||||
guiContent.text = "FOV";
|
||||
overlayTarget.blurredQuadFOV = EditorGUILayout.Slider(guiContent, overlayTarget.blurredQuadFOV, 0, 180f);
|
||||
|
||||
guiContent.text = "IPD";
|
||||
overlayTarget.blurredQuadIPD = EditorGUILayout.Slider(guiContent, overlayTarget.blurredQuadIPD, 0.01f, 1.0f);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
guiContent.tooltip = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.LabelField("Texture");
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
|
||||
var labelControlRect = EditorGUILayout.GetControlRect();
|
||||
EditorGUI.LabelField(new Rect(labelControlRect.x, labelControlRect.y, labelControlRect.width / 2, labelControlRect.height), new GUIContent("Left", "Texture used for the left eye"));
|
||||
EditorGUI.LabelField(new Rect(labelControlRect.x + labelControlRect.width / 2, labelControlRect.y, labelControlRect.width / 2, labelControlRect.height), new GUIContent("Right", "Texture used for the right eye"));
|
||||
|
||||
var textureControlRect = EditorGUILayout.GetControlRect(GUILayout.Height(64));
|
||||
overlayTarget.layerTextures[0] = (Texture)EditorGUI.ObjectField(new Rect(textureControlRect.x, textureControlRect.y, 64, textureControlRect.height), overlayTarget.layerTextures[0], typeof(Texture), false);
|
||||
overlayTarget.layerTextures[1] = (Texture)EditorGUI.ObjectField(new Rect(textureControlRect.x + textureControlRect.width / 2, textureControlRect.y, 64, textureControlRect.height), overlayTarget.layerTextures[1] != null ? overlayTarget.layerTextures[1] : overlayTarget.layerTextures[0], typeof(Texture), false);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
if (overlayTarget.overlayShape == PXR_CompositionLayer.OverlayShape.Equirect ||
|
||||
overlayTarget.overlayShape == PXR_CompositionLayer.OverlayShape.Fisheye)
|
||||
{
|
||||
guiContent.text = "Radius";
|
||||
overlayTarget.radius = EditorGUILayout.FloatField(guiContent, Mathf.Abs(overlayTarget.radius));
|
||||
}
|
||||
}
|
||||
|
||||
if (overlayTarget.overlayShape == PXR_CompositionLayer.OverlayShape.Quad ||
|
||||
overlayTarget.overlayShape == PXR_CompositionLayer.OverlayShape.Cylinder ||
|
||||
overlayTarget.overlayShape == PXR_CompositionLayer.OverlayShape.Equirect ||
|
||||
overlayTarget.overlayShape == PXR_CompositionLayer.OverlayShape.Eac ||
|
||||
overlayTarget.overlayShape == PXR_CompositionLayer.OverlayShape.Fisheye)
|
||||
{
|
||||
guiContent.text = "Texture Rects";
|
||||
overlayTarget.useImageRect = EditorGUILayout.Toggle(guiContent, overlayTarget.useImageRect);
|
||||
if (overlayTarget.useImageRect)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
if (PXR_CompositionLayer.Surface3DType.Single != overlayTarget.externalAndroidSurface3DType)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
}
|
||||
guiContent.text = "Source Rects";
|
||||
guiContent.tooltip = "The functions of '3D Surface Type' and 'Source Rects' are similar, and only one of them can be used. ";
|
||||
overlayTarget.textureRect = (PXR_CompositionLayer.TextureRect)EditorGUILayout.EnumPopup(guiContent, overlayTarget.textureRect);
|
||||
|
||||
if (PXR_CompositionLayer.Surface3DType.Single == overlayTarget.externalAndroidSurface3DType)
|
||||
{
|
||||
if (overlayTarget.textureRect == PXR_CompositionLayer.TextureRect.Custom)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Left Rect");
|
||||
EditorGUILayout.LabelField("Right Rect");
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
overlayTarget.srcRectLeft = ClampRect(EditorGUILayout.RectField(overlayTarget.srcRectLeft));
|
||||
EditorGUILayout.Space(15);
|
||||
guiContent.text = "Right";
|
||||
overlayTarget.srcRectRight = ClampRect(EditorGUILayout.RectField(overlayTarget.srcRectRight));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
else if (overlayTarget.textureRect == PXR_CompositionLayer.TextureRect.MonoScopic)
|
||||
{
|
||||
overlayTarget.srcRectLeft = new Rect(0, 0, 1, 1);
|
||||
overlayTarget.srcRectRight = new Rect(0, 0, 1, 1);
|
||||
}
|
||||
else if (overlayTarget.textureRect == PXR_CompositionLayer.TextureRect.StereoScopic)
|
||||
{
|
||||
overlayTarget.srcRectLeft = new Rect(0, 0, 0.5f, 1);
|
||||
overlayTarget.srcRectRight = new Rect(0.5f, 0, 0.5f, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.textureRect = PXR_CompositionLayer.TextureRect.MonoScopic;
|
||||
overlayTarget.srcRectLeft = new Rect(0, 0, 1, 1);
|
||||
overlayTarget.srcRectRight = new Rect(0, 0, 1, 1);
|
||||
}
|
||||
|
||||
guiContent.tooltip = "";
|
||||
GUI.enabled = true;
|
||||
if (overlayTarget.overlayShape == PXR_CompositionLayer.OverlayShape.Quad ||
|
||||
overlayTarget.overlayShape == PXR_CompositionLayer.OverlayShape.Equirect ||
|
||||
overlayTarget.overlayShape == PXR_CompositionLayer.OverlayShape.Fisheye)
|
||||
{
|
||||
guiContent.text = "Destination Rects";
|
||||
overlayTarget.destinationRect = (PXR_CompositionLayer.DestinationRect)EditorGUILayout.EnumPopup(guiContent, overlayTarget.destinationRect);
|
||||
|
||||
if (overlayTarget.destinationRect == PXR_CompositionLayer.DestinationRect.Custom)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Left Rect");
|
||||
EditorGUILayout.LabelField("Right Rect");
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
overlayTarget.dstRectLeft = ClampRect(EditorGUILayout.RectField(overlayTarget.dstRectLeft));
|
||||
EditorGUILayout.Space(15);
|
||||
guiContent.text = "Right";
|
||||
overlayTarget.dstRectRight = ClampRect(EditorGUILayout.RectField(overlayTarget.dstRectRight));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.enabled = false;
|
||||
overlayTarget.dstRectLeft = new Rect(0, 0, 1, 1);
|
||||
overlayTarget.dstRectRight = new Rect(0, 0, 1, 1);
|
||||
GUI.enabled = true;
|
||||
}
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
}
|
||||
guiContent.text = "Use Premultiplied Alpha";
|
||||
guiContent.tooltip = @"Enable premultiplied alpha for this content.
|
||||
|
||||
When enabled:
|
||||
• RGB color channels are multiplied by Alpha (R*A, G*A, B*A)
|
||||
• Improves performance for transparent elements (e.g., UI, particles)
|
||||
• Fixes edge artifacts in semitransparent objects
|
||||
• Matches OpenXR and GPU blending requirements
|
||||
|
||||
Recommended for:
|
||||
• UI panels with transparency
|
||||
• Particle effects
|
||||
• Materials using alpha blending
|
||||
• Any content requiring frequent transparency mixing
|
||||
|
||||
Note: Ensure textures are imported with 'Alpha Is Transparency'
|
||||
or manually pre-multiply colors if needed.";
|
||||
overlayTarget.usePremultipliedAlpha = EditorGUILayout.Toggle(guiContent, overlayTarget.usePremultipliedAlpha);
|
||||
|
||||
guiContent.text = "Use Texture Alpha for Blending";
|
||||
guiContent.tooltip = @"Use the texture's alpha channel for transparency blending.
|
||||
When enabled:
|
||||
• Semi-transparent elements (UI, particles) will blend correctly with the background.
|
||||
• Alpha values (0-1) control pixel transparency during composition.
|
||||
• Works with premultiplied alpha textures if properly configured.
|
||||
|
||||
Recommended for:
|
||||
• Any content requiring transparency (e.g., overlays, glass effects).
|
||||
• Disabling may cause artifacts or incorrect rendering.";
|
||||
overlayTarget.useTextureAlphaBlending = EditorGUILayout.Toggle(guiContent, overlayTarget.useTextureAlphaBlending);
|
||||
|
||||
guiContent.text = "Layer Blend";
|
||||
overlayTarget.useLayerBlend = EditorGUILayout.Toggle(guiContent, overlayTarget.useLayerBlend);
|
||||
if (overlayTarget.useLayerBlend)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
guiContent.text = "Src Color";
|
||||
overlayTarget.srcColor = (PxrBlendFactor)EditorGUILayout.EnumPopup(guiContent, overlayTarget.srcColor);
|
||||
guiContent.text = "Dst Color";
|
||||
overlayTarget.dstColor = (PxrBlendFactor)EditorGUILayout.EnumPopup(guiContent, overlayTarget.dstColor);
|
||||
guiContent.text = "Src Alpha";
|
||||
overlayTarget.srcAlpha = (PxrBlendFactor)EditorGUILayout.EnumPopup(guiContent, overlayTarget.srcAlpha);
|
||||
guiContent.text = "Dst Alpha";
|
||||
overlayTarget.dstAlpha = (PxrBlendFactor)EditorGUILayout.EnumPopup(guiContent, overlayTarget.dstAlpha);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
if (overlayTarget.overlayShape == PXR_CompositionLayer.OverlayShape.Eac)
|
||||
{
|
||||
guiContent.text = "Model Type";
|
||||
overlayTarget.eacModelType = (PXR_CompositionLayer.EACModelType)EditorGUILayout.EnumPopup(guiContent, overlayTarget.eacModelType);
|
||||
|
||||
if (PXR_CompositionLayer.EACModelType.Eac360ViewPort == overlayTarget.eacModelType ||
|
||||
PXR_CompositionLayer.EACModelType.Eac180ViewPort == overlayTarget.eacModelType)
|
||||
{
|
||||
|
||||
guiContent.text = "Offset Pos Left";
|
||||
Vector3 offsetPosLeft = EditorGUILayout.Vector3Field(guiContent, overlayTarget.offsetPosLeft);
|
||||
|
||||
|
||||
guiContent.text = "Offset Pos Right";
|
||||
Vector3 offsetPosRight = EditorGUILayout.Vector3Field(guiContent, overlayTarget.offsetPosRight);
|
||||
|
||||
|
||||
guiContent.text = "Offset Rot Left";
|
||||
Vector4 offsetRotLeft = EditorGUILayout.Vector4Field(guiContent, overlayTarget.offsetRotLeft);
|
||||
|
||||
|
||||
guiContent.text = "Offset Rot Right";
|
||||
Vector4 offsetRotRight = EditorGUILayout.Vector4Field(guiContent, overlayTarget.offsetRotRight);
|
||||
|
||||
overlayTarget.SetEACOffsetPosAndRot(offsetPosLeft, offsetPosRight, offsetRotLeft, offsetRotRight);
|
||||
}
|
||||
|
||||
guiContent.text = "Overlap Factor";
|
||||
overlayTarget.overlapFactor = EditorGUILayout.FloatField(guiContent, overlayTarget.overlapFactor);
|
||||
//overlayTarget.SetEACFactor(overlapFactor);
|
||||
}
|
||||
|
||||
guiContent.text = "Override Color Scale";
|
||||
overlayTarget.overrideColorScaleAndOffset = EditorGUILayout.Toggle(guiContent, overlayTarget.overrideColorScaleAndOffset);
|
||||
if (overlayTarget.overrideColorScaleAndOffset)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
|
||||
guiContent.text = "Scale";
|
||||
Vector4 colorScale = EditorGUILayout.Vector4Field(guiContent, overlayTarget.colorScale);
|
||||
|
||||
guiContent.text = "Offset";
|
||||
Vector4 colorOffset = EditorGUILayout.Vector4Field(guiContent, overlayTarget.colorOffset);
|
||||
overlayTarget.SetLayerColorScaleAndOffset(colorScale, colorOffset);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
//Super Resolution
|
||||
var superresolutionContent = new GUIContent();
|
||||
superresolutionContent.text = "Super Resolution";
|
||||
superresolutionContent.tooltip = "Single pass spatial aware upscaling technique.\n\nThis can't be used with Sharpening. \nAlso can't be used along with subsample feature due to unsupported texture format. \n\nThis effect won't work properly under low resolutions when Adaptive Resolution is also enabled.";
|
||||
overlayTarget.superResolution = EditorGUILayout.Toggle(superresolutionContent, overlayTarget.superResolution);
|
||||
|
||||
//Supersampling
|
||||
var supersamplingContent = new GUIContent();
|
||||
supersamplingContent.text = "Supersampling Mode";
|
||||
supersamplingContent.tooltip = "Normal: Normal Quality \n\nQuality: Higher Quality, higher GPU usage\n\nThis effect won't work properly under low resolutions when Adaptive Resolution or Sharpening is also enabled.\n\nThis can't be used with Super Resolution or Sharpening. It will be automatically disabled when you enable Super Resolution or Sharpening. \nAlso can't be used along with subsample feature due to unsupported texture format";
|
||||
|
||||
var supersamplingEnhanceContent = new GUIContent();
|
||||
supersamplingEnhanceContent.text = "Supersampling Enhance Mode";
|
||||
supersamplingEnhanceContent.tooltip = "None: Full screen will be super sampled\n\nFixed Foveated: Only the central fixation point will be sharpened\n\nSelf Adaptive: Only when contrast between the current pixel and the surrounding pixels exceeds a certain threshold will be sharpened.\n\nThis menu will be only enabled while Sharpening (either Normal or Quality) is enabled.";
|
||||
|
||||
if (overlayTarget.superResolution)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
overlayTarget.supersamplingMode = SuperSamplingMode.None;
|
||||
overlayTarget.supersamplingEnhance = SuperSamplingEnhance.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
overlayTarget.supersamplingMode = (SuperSamplingMode)EditorGUILayout.EnumPopup(supersamplingContent, overlayTarget.supersamplingMode);
|
||||
if (overlayTarget.supersamplingMode == SuperSamplingMode.None)
|
||||
{
|
||||
overlayTarget.supersamplingEnhance = SuperSamplingEnhance.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
overlayTarget.supersamplingEnhance = (SuperSamplingEnhance)EditorGUILayout.EnumPopup(supersamplingEnhanceContent, overlayTarget.supersamplingEnhance);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
if (overlayTarget.supersamplingMode != SuperSamplingMode.None)
|
||||
{
|
||||
if (overlayTarget.supersamplingMode == SuperSamplingMode.Normal)
|
||||
{
|
||||
overlayTarget.normalSupersampling = true;
|
||||
overlayTarget.qualitySupersampling = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.normalSupersampling = false;
|
||||
overlayTarget.qualitySupersampling = true;
|
||||
}
|
||||
|
||||
if (overlayTarget.supersamplingEnhance == SuperSamplingEnhance.FixedFoveated)
|
||||
{
|
||||
overlayTarget.fixedFoveatedSupersampling = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.fixedFoveatedSupersampling = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.normalSupersampling = false;
|
||||
overlayTarget.qualitySupersampling = false;
|
||||
overlayTarget.fixedFoveatedSupersampling = false;
|
||||
}
|
||||
|
||||
//Sharpening
|
||||
var sharpeningContent = new GUIContent();
|
||||
sharpeningContent.text = "Sharpening Mode";
|
||||
sharpeningContent.tooltip = "Normal: Normal Quality \n\nQuality: Higher Quality, higher GPU usage\n\nThis effect won't work properly under low resolutions when Adaptive Resolution is also enabled.\n\nThis can't be used with Super Resolution and Supersampling. It will be automatically disabled when you enable Super Resolution or Supersampling. \nAlso can't be used along with subsample feature due to unsupported texture format";
|
||||
var sharpeningEnhanceContent = new GUIContent();
|
||||
sharpeningEnhanceContent.text = "Sharpening Enhance Mode";
|
||||
sharpeningEnhanceContent.tooltip = "None: Full screen will be sharpened\n\nFixed Foveated: Only the central fixation point will be sharpened\n\nSelf Adaptive: Only when contrast between the current pixel and the surrounding pixels exceeds a certain threshold will be sharpened.\n\nThis menu will be only enabled while Sharpening (either Normal or Quality) is enabled.";
|
||||
|
||||
if (overlayTarget.superResolution || overlayTarget.normalSupersampling || overlayTarget.qualitySupersampling || overlayTarget.fixedFoveatedSupersampling)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
overlayTarget.sharpeningMode = SharpeningMode.None;
|
||||
overlayTarget.sharpeningEnhance = SharpeningEnhance.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
overlayTarget.sharpeningMode = (SharpeningMode)EditorGUILayout.EnumPopup(sharpeningContent, overlayTarget.sharpeningMode);
|
||||
if (overlayTarget.sharpeningMode == SharpeningMode.None)
|
||||
{
|
||||
overlayTarget.sharpeningEnhance = SharpeningEnhance.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
overlayTarget.sharpeningEnhance = (SharpeningEnhance)EditorGUILayout.EnumPopup(sharpeningEnhanceContent, overlayTarget.sharpeningEnhance);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
if (overlayTarget.sharpeningMode != SharpeningMode.None)
|
||||
{
|
||||
if (overlayTarget.sharpeningMode == SharpeningMode.Normal)
|
||||
{
|
||||
overlayTarget.normalSharpening = true;
|
||||
overlayTarget.qualitySharpening = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.normalSharpening = false;
|
||||
overlayTarget.qualitySharpening = true;
|
||||
}
|
||||
|
||||
if (overlayTarget.sharpeningEnhance == SharpeningEnhance.Both)
|
||||
{
|
||||
overlayTarget.fixedFoveatedSharpening = true;
|
||||
overlayTarget.selfAdaptiveSharpening = true;
|
||||
}
|
||||
else if (overlayTarget.sharpeningEnhance == SharpeningEnhance.FixedFoveated)
|
||||
{
|
||||
overlayTarget.fixedFoveatedSharpening = true;
|
||||
overlayTarget.selfAdaptiveSharpening = false;
|
||||
}
|
||||
else if (overlayTarget.sharpeningEnhance == SharpeningEnhance.SelfAdaptive)
|
||||
{
|
||||
overlayTarget.fixedFoveatedSharpening = false;
|
||||
overlayTarget.selfAdaptiveSharpening = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.fixedFoveatedSharpening = false;
|
||||
overlayTarget.selfAdaptiveSharpening = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.normalSharpening = false;
|
||||
overlayTarget.qualitySharpening = false;
|
||||
overlayTarget.fixedFoveatedSharpening = false;
|
||||
overlayTarget.selfAdaptiveSharpening = false;
|
||||
}
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
EditorUtility.SetDirty(overlayTarget);
|
||||
EditorUtility.SetDirty(overlayTarget);
|
||||
}
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEngine.SceneManagement.SceneManager.GetActiveScene());
|
||||
}
|
||||
}
|
||||
private Rect ClampRect(Rect rect)
|
||||
{
|
||||
rect.x = Mathf.Clamp01(rect.x);
|
||||
rect.y = Mathf.Clamp01(rect.y);
|
||||
rect.width = Mathf.Clamp01(rect.width);
|
||||
rect.height = Mathf.Clamp01(rect.height);
|
||||
return rect;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6903c7ff46f75648b231bb4f83b47a7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,174 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.XR.PXR.Editor
|
||||
{
|
||||
public class PXR_EditorStyles
|
||||
{
|
||||
public Color colorLine = new Color32(0xD9, 0xD9, 0xD9, 255);
|
||||
public Color colorSelected = new Color32(0x7B, 0x7B, 0x7B, 255);
|
||||
public Color colorDocumentationUrlNormal = new Color32(0x0F, 0x6F, 0xD5, 255);
|
||||
public Color colorDocumentationUrlHover = new Color32(0x0F, 0x6F, 0xD5, 205);
|
||||
|
||||
private GUIStyle _dialogIconStyle;
|
||||
private GUIStyle _headerText;
|
||||
private GUIStyle _versionText;
|
||||
private GUIStyle _contentArea;
|
||||
private GUIStyle _contentText;
|
||||
private GUIStyle _buttonStyle;
|
||||
private GUIStyle _buttonSelectedStyle;
|
||||
private GUIStyle _buttonToOpenStyle;
|
||||
private GUIStyle _backgroundColorStyle;
|
||||
private GUIStyle _bigWhiteTitleStyle;
|
||||
private GUIStyle _smallBlueLinkStyle;
|
||||
|
||||
|
||||
public GUIStyle HeaderText => _headerText ??= new GUIStyle(EditorStyles.largeLabel)
|
||||
{
|
||||
fontStyle = FontStyle.Normal,
|
||||
fontSize = 48,
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
fixedHeight = 69,
|
||||
fixedWidth = 600,
|
||||
normal = new GUIStyleState()
|
||||
{
|
||||
textColor = Color.white
|
||||
}
|
||||
};
|
||||
|
||||
public GUIStyle BigWhiteTitleStyle => _bigWhiteTitleStyle ??= new GUIStyle(EditorStyles.largeLabel)
|
||||
{
|
||||
fontStyle = FontStyle.Bold,
|
||||
fontSize = 20,
|
||||
fixedHeight = 25,
|
||||
alignment = TextAnchor.MiddleLeft,
|
||||
normal = new GUIStyleState()
|
||||
{
|
||||
textColor = Color.white
|
||||
}
|
||||
};
|
||||
|
||||
public GUIStyle VersionText => _versionText ??= new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
fontStyle = FontStyle.Normal,
|
||||
fontSize = 18,
|
||||
alignment = TextAnchor.LowerCenter,
|
||||
fixedHeight = 69,
|
||||
fixedWidth = 150,
|
||||
padding = new RectOffset(8, 0, 0, 8),
|
||||
normal = new GUIStyleState()
|
||||
{
|
||||
textColor = Color.white
|
||||
}
|
||||
};
|
||||
|
||||
public GUIStyle ContentText => _contentText ??= new GUIStyle(EditorStyles.wordWrappedLabel)
|
||||
{
|
||||
richText = true,
|
||||
stretchHeight = true,
|
||||
fontSize = 16,
|
||||
normal = new GUIStyleState()
|
||||
{
|
||||
textColor = Color.white
|
||||
}
|
||||
};
|
||||
|
||||
public GUIStyle SmallBlueLinkStyle => _smallBlueLinkStyle ??= new GUIStyle(EditorStyles.linkLabel)
|
||||
{
|
||||
fontStyle = FontStyle.Normal,
|
||||
fontSize = 16,
|
||||
fixedHeight = 25,
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
normal = new GUIStyleState()
|
||||
{
|
||||
textColor = colorDocumentationUrlNormal
|
||||
},
|
||||
hover = new GUIStyleState()
|
||||
{
|
||||
textColor = colorDocumentationUrlHover
|
||||
}
|
||||
};
|
||||
|
||||
public GUIStyle IconStyle => _dialogIconStyle ??= new GUIStyle()
|
||||
{
|
||||
fixedHeight = 80,
|
||||
fixedWidth = 250,
|
||||
padding = new RectOffset(0, 10, 0, 0),
|
||||
alignment = TextAnchor.UpperRight,
|
||||
};
|
||||
|
||||
public Texture2D MakeTexture(int width, int height, Color color)
|
||||
{
|
||||
Texture2D texture = new Texture2D(width, height);
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
texture.SetPixel(x, y, color);
|
||||
}
|
||||
}
|
||||
texture.Apply();
|
||||
return texture;
|
||||
}
|
||||
|
||||
public GUIStyle ContentArea => _contentArea ??= new GUIStyle(EditorStyles.textArea)
|
||||
{
|
||||
stretchHeight = true,
|
||||
padding = new RectOffset(4, 4, 4, 4),
|
||||
};
|
||||
|
||||
public GUIStyle Button => _buttonStyle ??= new GUIStyle(EditorStyles.miniButton)
|
||||
{
|
||||
stretchWidth = true,
|
||||
fixedWidth = 150,
|
||||
fixedHeight = 36,
|
||||
fontStyle = FontStyle.Bold,
|
||||
richText = true,
|
||||
padding = new RectOffset(4, 4, 4, 4),
|
||||
normal = new GUIStyleState() { background = MakeTexture(2, 2, colorLine) }
|
||||
};
|
||||
|
||||
public GUIStyle ButtonSelected => _buttonSelectedStyle ??= new GUIStyle(EditorStyles.miniButton)
|
||||
{
|
||||
stretchWidth = true,
|
||||
fixedWidth = 150,
|
||||
fixedHeight = 36,
|
||||
fontStyle = FontStyle.Bold,
|
||||
richText = true,
|
||||
padding = new RectOffset(4, 4, 4, 4),
|
||||
normal = new GUIStyleState() { background = MakeTexture(2, 2, colorSelected) }
|
||||
};
|
||||
|
||||
public GUIStyle ButtonToOpen => _buttonToOpenStyle ??= new GUIStyle(EditorStyles.miniButton)
|
||||
{
|
||||
stretchWidth = true,
|
||||
fixedWidth = 250,
|
||||
fixedHeight = 25,
|
||||
fontSize = 16,
|
||||
richText = true,
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
padding = new RectOffset(4, 4, 4, 4),
|
||||
normal = new GUIStyleState()
|
||||
{
|
||||
textColor = Color.white,
|
||||
background = MakeTexture(2, 2, colorSelected)
|
||||
}
|
||||
};
|
||||
|
||||
public GUIStyle BackgroundColor => _backgroundColorStyle ??= new GUIStyle(EditorStyles.wordWrappedLabel)
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f43138445b42d748b11284441ceed22
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,37 @@
|
||||
#if !PICO_OPENXR_SDK
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using Unity.XR.PXR;
|
||||
|
||||
[CustomEditor(typeof(PXR_Hand))]
|
||||
public class PXR_HandEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
DrawDefaultInspector();
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
PXR_Hand hand = (PXR_Hand)target;
|
||||
|
||||
EditorGUILayout.LabelField("Hand Joints", EditorStyles.boldLabel);
|
||||
|
||||
for (int i = 0; i < (int)HandJoint.JointMax; i++)
|
||||
{
|
||||
string jointName = ((HandJoint)i).ToString();
|
||||
hand.handJoints[i] = (Transform)EditorGUILayout.ObjectField(jointName, hand.handJoints[i], typeof(Transform), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53a39cdaaf582104da549e4a50988330
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,649 @@
|
||||
#if !PICO_OPENXR_SDK
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using UnityEditorInternal;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.XR.PXR.Editor
|
||||
{
|
||||
[CustomEditor(typeof(PXR_HandPoseGenerator))]
|
||||
public class PXR_HandPoseGeneratorEditor : UnityEditor.Editor
|
||||
{
|
||||
private static bool shapesRecognizer = true;
|
||||
private static bool bonesRecognizer = false;
|
||||
private static bool transRecognizer = false;
|
||||
private static bool thumb = true;
|
||||
private static bool index = true;
|
||||
private static bool middle = true;
|
||||
private static bool ring = true;
|
||||
private static bool pinky = true;
|
||||
|
||||
private PXR_HandPoseGenerator m_Target;
|
||||
private PXR_HandPoseConfig config;
|
||||
private PXR_HandPosePreview preview;
|
||||
private ReorderableList bonesArray;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_Target = (PXR_HandPoseGenerator)target;
|
||||
InitHandPosePreview();
|
||||
InitBonesGroup();
|
||||
}
|
||||
private void OnDisable()
|
||||
{
|
||||
DestroyHandPosePreview();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
GUILayout.Label("Hand Pose Config");
|
||||
m_Target.config = (PXR_HandPoseConfig)EditorGUILayout.ObjectField(m_Target.config, typeof(PXR_HandPoseConfig), false);
|
||||
|
||||
if (GUILayout.Button("New"))
|
||||
{
|
||||
m_Target.config = CreateInstance<PXR_HandPoseConfig>();
|
||||
AssetDatabase.CreateAsset(m_Target.config, string.Format("Assets/{0}.asset", typeof(PXR_HandPoseConfig).Name + "_" + DateTime.Now.ToString("MMddhhmmss")));
|
||||
}
|
||||
|
||||
//if (GUILayout.Button("Play"))
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (m_Target.config != null)
|
||||
{
|
||||
if (config != m_Target.config)
|
||||
{
|
||||
config = m_Target.config;
|
||||
ConfigRead();
|
||||
}
|
||||
|
||||
shapesRecognizer = EditorGUILayout.Foldout(shapesRecognizer, "Shapes");
|
||||
if (shapesRecognizer)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Space(10);
|
||||
using (new GUILayout.VerticalScope())
|
||||
{
|
||||
thumb = EditorGUILayout.Foldout(thumb, "Thumb");
|
||||
if (thumb)
|
||||
{
|
||||
FingerConfig(m_Target.thumb);
|
||||
}
|
||||
index = EditorGUILayout.Foldout(index, "Index");
|
||||
if (index)
|
||||
{
|
||||
FingerConfig(m_Target.index);
|
||||
}
|
||||
middle = EditorGUILayout.Foldout(middle, "Middle");
|
||||
if (middle)
|
||||
{
|
||||
FingerConfig(m_Target.middle);
|
||||
}
|
||||
ring = EditorGUILayout.Foldout(ring, "Ring");
|
||||
if (ring)
|
||||
{
|
||||
FingerConfig(m_Target.ring);
|
||||
}
|
||||
pinky = EditorGUILayout.Foldout(pinky, "Pinky");
|
||||
if (pinky)
|
||||
{
|
||||
FingerConfig(m_Target.pinky);
|
||||
}
|
||||
EditorGUILayout.Space(5);
|
||||
serializedObject.FindProperty("shapesholdDuration").floatValue = EditorGUILayout.FloatField("Hold Duration", Mathf.Max(0, serializedObject.FindProperty("shapesholdDuration").floatValue));
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
}
|
||||
|
||||
bonesRecognizer = EditorGUILayout.Foldout(bonesRecognizer, "Bones");
|
||||
if (bonesRecognizer)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Space(10);
|
||||
using (new GUILayout.VerticalScope())
|
||||
{
|
||||
BonesConfig(m_Target.Bones);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
transRecognizer = EditorGUILayout.Foldout(transRecognizer, "Transform");
|
||||
if (transRecognizer)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Space(10);
|
||||
using (new GUILayout.VerticalScope())
|
||||
{
|
||||
TransConfig();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
ConfigSave();
|
||||
UpdatePosePreview();
|
||||
EditorUtility.SetDirty(m_Target.config);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigSave()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_Target.config.shapesRecognizer.holdDuration = m_Target.shapesholdDuration;
|
||||
m_Target.config.shapesRecognizer.thumb = m_Target.thumb;
|
||||
m_Target.config.shapesRecognizer.index = m_Target.index;
|
||||
m_Target.config.shapesRecognizer.middle = m_Target.middle;
|
||||
m_Target.config.shapesRecognizer.ring = m_Target.ring;
|
||||
m_Target.config.shapesRecognizer.pinky = m_Target.pinky;
|
||||
|
||||
m_Target.config.bonesRecognizer.holdDuration = m_Target.bonesHoldDuration;
|
||||
m_Target.config.bonesRecognizer.Bones = m_Target.Bones;
|
||||
|
||||
m_Target.config.transRecognizer.holdDuration = m_Target.transHoldDuration;
|
||||
m_Target.config.transRecognizer.trackAxis = m_Target.trackAxis;
|
||||
m_Target.config.transRecognizer.spaceType = m_Target.spaceType;
|
||||
m_Target.config.transRecognizer.trackTarget = m_Target.trackTarget;
|
||||
m_Target.config.transRecognizer.angleThreshold = m_Target.angleThreshold;
|
||||
m_Target.config.transRecognizer.thresholdWidth = m_Target.thresholdWidth;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("Save Error " + e.ToString());
|
||||
}
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
private void UpdatePosePreview()
|
||||
{
|
||||
if (shapesRecognizer)
|
||||
{
|
||||
preview.UpdateShapeState(m_Target.config.shapesRecognizer);
|
||||
}
|
||||
else
|
||||
{
|
||||
preview.ResetShapeState();
|
||||
}
|
||||
if (transRecognizer)
|
||||
{
|
||||
preview.UpdateTransformState(m_Target.config.transRecognizer);
|
||||
}
|
||||
else
|
||||
{
|
||||
preview.ResetTransformState();
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigRead()
|
||||
{
|
||||
m_Target.shapesholdDuration = m_Target.config.shapesRecognizer.holdDuration;
|
||||
m_Target.thumb = m_Target.config.shapesRecognizer.thumb;
|
||||
m_Target.index = m_Target.config.shapesRecognizer.index;
|
||||
m_Target.middle = m_Target.config.shapesRecognizer.middle;
|
||||
m_Target.ring = m_Target.config.shapesRecognizer.ring;
|
||||
m_Target.pinky = m_Target.config.shapesRecognizer.pinky;
|
||||
|
||||
m_Target.bonesHoldDuration = m_Target.config.bonesRecognizer.holdDuration;
|
||||
m_Target.Bones = m_Target.config.bonesRecognizer.Bones;
|
||||
|
||||
m_Target.transHoldDuration = m_Target.config.transRecognizer.holdDuration;
|
||||
m_Target.trackAxis = m_Target.config.transRecognizer.trackAxis;
|
||||
m_Target.spaceType = m_Target.config.transRecognizer.spaceType;
|
||||
m_Target.trackTarget = m_Target.config.transRecognizer.trackTarget;
|
||||
m_Target.angleThreshold = m_Target.config.transRecognizer.angleThreshold;
|
||||
m_Target.thresholdWidth = m_Target.config.transRecognizer.thresholdWidth;
|
||||
}
|
||||
|
||||
private void TransConfig()
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal("box");
|
||||
EditorGUILayout.Space(5);
|
||||
using (new GUILayout.VerticalScope())
|
||||
{
|
||||
EditorGUILayout.Space(5);
|
||||
m_Target.trackAxis = (TransRecognizer.TrackAxis)EditorGUILayout.EnumPopup("Track Axis", m_Target.trackAxis);
|
||||
m_Target.trackTarget = (TransRecognizer.TrackTarget)EditorGUILayout.EnumPopup("Track Target", m_Target.trackTarget);
|
||||
m_Target.angleThreshold = EditorGUILayout.FloatField("Angle Threshold", m_Target.angleThreshold);
|
||||
m_Target.thresholdWidth = EditorGUILayout.FloatField("Margin", m_Target.thresholdWidth);
|
||||
EditorGUILayout.Space(5);
|
||||
}
|
||||
EditorGUILayout.Space(5);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.Space(5);
|
||||
m_Target.transHoldDuration = EditorGUILayout.FloatField("Hold Duration", m_Target.transHoldDuration);
|
||||
}
|
||||
|
||||
private void BonesConfig(List<BonesRecognizer.BonesGroup> listBones)
|
||||
{
|
||||
using (new GUILayout.VerticalScope())
|
||||
{
|
||||
bonesArray.DoLayoutList();
|
||||
}
|
||||
serializedObject.FindProperty("bonesHoldDuration").floatValue = EditorGUILayout.FloatField("Hold Duration", Mathf.Max(0, serializedObject.FindProperty("bonesHoldDuration").floatValue));
|
||||
}
|
||||
|
||||
private void InitBonesGroup()
|
||||
{
|
||||
bonesArray = new ReorderableList(serializedObject, serializedObject.FindProperty("Bones"), true, true, true, true);
|
||||
|
||||
bonesArray.drawHeaderCallback = (Rect rect) =>
|
||||
{
|
||||
GUI.Label(rect, "Bones Groups");
|
||||
};
|
||||
|
||||
bonesArray.elementHeightCallback = (index) =>
|
||||
{
|
||||
var element = bonesArray.serializedProperty.GetArrayElementAtIndex(index);
|
||||
var h = EditorGUIUtility.singleLineHeight;
|
||||
if (element.isExpanded)
|
||||
h += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.singleLineHeight;
|
||||
return h;
|
||||
};
|
||||
|
||||
bonesArray.drawElementCallback = (Rect rect, int index, bool selected, bool focused) =>
|
||||
{
|
||||
SerializedProperty item = bonesArray.serializedProperty.GetArrayElementAtIndex(index);
|
||||
|
||||
var posRect_label = new Rect(rect)
|
||||
{
|
||||
x = rect.x + 14,
|
||||
width = rect.width - 18,
|
||||
height = EditorGUIUtility.singleLineHeight
|
||||
};
|
||||
item.isExpanded = EditorGUI.BeginFoldoutHeaderGroup(posRect_label, item.isExpanded, item.isExpanded ? "" : $"{index}");
|
||||
if (item.isExpanded)
|
||||
{
|
||||
rect.height -= 8 + EditorGUIUtility.singleLineHeight;
|
||||
rect.y += 18;
|
||||
|
||||
GUIStyle style = new GUIStyle(EditorStyles.label);
|
||||
style.fontSize = 20;
|
||||
style.fontStyle = FontStyle.Bold;
|
||||
EditorGUI.LabelField(rect, " " + index.ToString(), style);
|
||||
EditorGUI.DrawRect(rect, new Color(0, 0, 0, 0.2f));
|
||||
|
||||
rect.y += 6;
|
||||
EditorGUI.PropertyField(rect, item, new GUIContent());
|
||||
}
|
||||
EditorGUI.EndFoldoutHeaderGroup();
|
||||
|
||||
};
|
||||
|
||||
bonesArray.onAddCallback = (ReorderableList list) =>
|
||||
{
|
||||
ReorderableList.defaultBehaviours.DoAddButton(list);
|
||||
list.serializedProperty.GetArrayElementAtIndex(list.count - 1).FindPropertyRelative("distance").floatValue = 0.03f;
|
||||
list.serializedProperty.GetArrayElementAtIndex(list.count - 1).FindPropertyRelative("thresholdWidth").floatValue = 0.01f;
|
||||
};
|
||||
|
||||
bonesArray.onRemoveCallback = (ReorderableList list) =>
|
||||
{
|
||||
{
|
||||
ReorderableList.defaultBehaviours.DoRemoveButton(list);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void FingerConfig(ShapesRecognizer.Finger finger)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal("box");
|
||||
EditorGUILayout.Space(5);
|
||||
using (new GUILayout.VerticalScope())
|
||||
{
|
||||
EditorGUILayout.Space(5);
|
||||
FlexionConfig(finger, finger.fingerConfigs.flexionConfigs);
|
||||
CurlConfig(finger, finger.fingerConfigs.curlConfigs);
|
||||
AbductionConfig(finger, finger.fingerConfigs.abductionConfigs);
|
||||
EditorGUILayout.Space(5);
|
||||
}
|
||||
EditorGUILayout.Space(5);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.Space(5);
|
||||
}
|
||||
|
||||
private void FlexionConfig(ShapesRecognizer.Finger finger, ShapesRecognizer.RangeConfigs flexionConfigs)
|
||||
{
|
||||
finger.flexion = (ShapesRecognizer.Flexion)EditorGUILayout.EnumPopup("Flexion", finger.flexion);
|
||||
Vector2 defaultVal = new Vector2();
|
||||
switch (finger.flexion)
|
||||
{
|
||||
case ShapesRecognizer.Flexion.Any:
|
||||
return;
|
||||
case ShapesRecognizer.Flexion.Open:
|
||||
defaultVal = GetDefaultShapeVal(finger.handFinger, ShapesRecognizer.ShapeType.flexion, true);
|
||||
flexionConfigs.min = defaultVal.x;
|
||||
flexionConfigs.max = defaultVal.y;
|
||||
break;
|
||||
case ShapesRecognizer.Flexion.Close:
|
||||
defaultVal = GetDefaultShapeVal(finger.handFinger, ShapesRecognizer.ShapeType.flexion, false);
|
||||
flexionConfigs.min = defaultVal.x;
|
||||
flexionConfigs.max = defaultVal.y;
|
||||
break;
|
||||
//case ShapesRecognizer.Flexion.Custom:
|
||||
// EditorGUILayout.MinMaxSlider("Custom Range",
|
||||
// ref flexionConfigs.min,
|
||||
// ref flexionConfigs.max,
|
||||
// ShapesRecognizer.flexionMin,
|
||||
// ShapesRecognizer.flexionMax);
|
||||
// break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
flexionConfigs.width = EditorGUILayout.Slider("Margin", flexionConfigs.width, 0,
|
||||
ShapesRecognizer.flexionMax - ShapesRecognizer.flexionMin);
|
||||
EditorGUILayout.LabelField(new GUIContent("Flexion Range"),
|
||||
new GUIContent($"[{flexionConfigs.min + " - " + flexionConfigs.width}, {flexionConfigs.max + " + " + flexionConfigs.width}]"));
|
||||
}
|
||||
|
||||
private void CurlConfig(ShapesRecognizer.Finger finger, ShapesRecognizer.RangeConfigs curlConfigs)
|
||||
{
|
||||
finger.curl = (ShapesRecognizer.Curl)EditorGUILayout.EnumPopup("Curl", finger.curl);
|
||||
Vector2 defaultVal;
|
||||
switch (finger.curl)
|
||||
{
|
||||
case ShapesRecognizer.Curl.Any:
|
||||
return;
|
||||
case ShapesRecognizer.Curl.Open:
|
||||
defaultVal = GetDefaultShapeVal(finger.handFinger, ShapesRecognizer.ShapeType.curl, true);
|
||||
curlConfigs.min = defaultVal.x;
|
||||
curlConfigs.max = defaultVal.y;
|
||||
break;
|
||||
case ShapesRecognizer.Curl.Close:
|
||||
defaultVal = GetDefaultShapeVal(finger.handFinger, ShapesRecognizer.ShapeType.curl, false);
|
||||
curlConfigs.min = defaultVal.x;
|
||||
curlConfigs.max = defaultVal.y;
|
||||
break;
|
||||
//case ShapesRecognizer.Curl.Custom:
|
||||
// EditorGUILayout.MinMaxSlider("Custom Range",
|
||||
// ref curlConfigs.min,
|
||||
// ref curlConfigs.max,
|
||||
// finger.handFinger == HandFinger.Thumb ? ShapesRecognizer.curlThumbMin : ShapesRecognizer.curlMin,
|
||||
// finger.handFinger == HandFinger.Thumb ? ShapesRecognizer.curlThumbMax : ShapesRecognizer.curlMax);
|
||||
// break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
curlConfigs.width = EditorGUILayout.Slider("Margin", curlConfigs.width, 0,
|
||||
ShapesRecognizer.curlMax - ShapesRecognizer.curlMin);
|
||||
EditorGUILayout.LabelField(new GUIContent("Curl Range"),
|
||||
new GUIContent($"[{curlConfigs.min + " - " + curlConfigs.width}, {curlConfigs.max + " + " + curlConfigs.width}]"));
|
||||
}
|
||||
|
||||
private void AbductionConfig(ShapesRecognizer.Finger finger, ShapesRecognizer.RangeConfigsAbduction abductionConfigs)
|
||||
{
|
||||
if (finger.handFinger == HandFinger.Pinky) return;
|
||||
|
||||
finger.abduction = (ShapesRecognizer.Abduction)EditorGUILayout.EnumPopup("Abduction", finger.abduction);
|
||||
Vector2 defaultVal = GetDefaultShapeVal(finger.handFinger, ShapesRecognizer.ShapeType.abduction);
|
||||
abductionConfigs.mid = defaultVal.x;
|
||||
switch (finger.abduction)
|
||||
{
|
||||
case ShapesRecognizer.Abduction.Any:
|
||||
return;
|
||||
case ShapesRecognizer.Abduction.Open:
|
||||
break;
|
||||
case ShapesRecognizer.Abduction.Close:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
abductionConfigs.width = EditorGUILayout.Slider("Margin", abductionConfigs.width, 0,
|
||||
ShapesRecognizer.abductionMax - ShapesRecognizer.abductionMin);
|
||||
EditorGUILayout.LabelField(new GUIContent("Abduction Range"),
|
||||
new GUIContent($"[{abductionConfigs.mid + " ± " + abductionConfigs.width + "/2"}]"));
|
||||
}
|
||||
|
||||
private Vector2 GetDefaultShapeVal(HandFinger finger, ShapesRecognizer.ShapeType shapeType, bool isOpen = true)
|
||||
{
|
||||
Vector2 val = new Vector2();
|
||||
switch (shapeType)
|
||||
{
|
||||
case ShapesRecognizer.ShapeType.flexion:
|
||||
val.x = finger == HandFinger.Thumb ? (isOpen ? ShapesRecognizer.flexionThumbOpenMin : ShapesRecognizer.flexionThumbCloseMin) :
|
||||
(isOpen ? ShapesRecognizer.flexionOpenMin : ShapesRecognizer.flexionCloseMin);
|
||||
val.y = finger == HandFinger.Thumb ? (isOpen ? ShapesRecognizer.flexionThumbOpenMax : ShapesRecognizer.flexionThumbCloseMax) :
|
||||
(isOpen ? ShapesRecognizer.flexionOpenMax : ShapesRecognizer.flexionCloseMax);
|
||||
break;
|
||||
case ShapesRecognizer.ShapeType.curl:
|
||||
val.x = finger == HandFinger.Thumb ? (isOpen ? ShapesRecognizer.curlThumbOpenMin : ShapesRecognizer.curlThumbCloseMin) :
|
||||
(isOpen ? ShapesRecognizer.curlOpenMin : ShapesRecognizer.curlCloseMin);
|
||||
val.y = finger == HandFinger.Thumb ? (isOpen ? ShapesRecognizer.curlThumbOpenMax : ShapesRecognizer.curlThumbCloseMax) :
|
||||
(isOpen ? ShapesRecognizer.curlOpenMax : ShapesRecognizer.curlCloseMax);
|
||||
break;
|
||||
case ShapesRecognizer.ShapeType.abduction:
|
||||
val.x = finger == HandFinger.Thumb ? ShapesRecognizer.abductionThumbMid : ShapesRecognizer.abductionMid;
|
||||
val.y = finger == HandFinger.Thumb ? ShapesRecognizer.abductionThumbWidth : ShapesRecognizer.abductionWidth;
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public override bool HasPreviewGUI()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private void DestroyHandPosePreview()
|
||||
{
|
||||
if (previewInstance)
|
||||
{
|
||||
DestroyImmediate(previewInstance);
|
||||
}
|
||||
previewInstance = null;
|
||||
|
||||
if (previewRenderUtility != null)
|
||||
{
|
||||
previewRenderUtility.Cleanup();
|
||||
previewRenderUtility = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override GUIContent GetPreviewTitle()
|
||||
{
|
||||
return new GUIContent("Hand Pose");
|
||||
}
|
||||
|
||||
public override void OnPreviewSettings()
|
||||
{
|
||||
if (GUILayout.Button("Reset", "preButton"))
|
||||
{
|
||||
dragPos = Vector2.zero;
|
||||
}
|
||||
}
|
||||
|
||||
private PreviewRenderUtility previewRenderUtility;
|
||||
private GameObject previewInstance;
|
||||
private Vector2 dragPos;
|
||||
|
||||
private void InitHandPosePreview()
|
||||
{
|
||||
if (previewRenderUtility == null)
|
||||
{
|
||||
previewRenderUtility = new PreviewRenderUtility(true);
|
||||
previewRenderUtility.cameraFieldOfView = 60f;
|
||||
|
||||
previewInstance = Instantiate(m_Target.preview.gameObject);
|
||||
previewInstance.SetActive(true);
|
||||
preview = previewInstance.GetComponent<PXR_HandPosePreview>();
|
||||
previewRenderUtility.AddSingleGO(previewInstance);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Vector2 Drag2D(Vector2 scrollPosition, Rect position)
|
||||
{
|
||||
int controlID = GUIUtility.GetControlID("Slider".GetHashCode(), FocusType.Passive);
|
||||
Event current = Event.current;
|
||||
|
||||
switch (current.GetTypeForControl(controlID))
|
||||
{
|
||||
case EventType.MouseDown:
|
||||
{
|
||||
bool flag = position.Contains(current.mousePosition) && position.width > 50f;
|
||||
if (flag)
|
||||
{
|
||||
GUIUtility.hotControl = controlID;
|
||||
current.Use();
|
||||
EditorGUIUtility.SetWantsMouseJumping(1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case EventType.MouseUp:
|
||||
{
|
||||
bool flag2 = GUIUtility.hotControl == controlID;
|
||||
if (flag2)
|
||||
{
|
||||
GUIUtility.hotControl = 0;
|
||||
}
|
||||
|
||||
EditorGUIUtility.SetWantsMouseJumping(0);
|
||||
break;
|
||||
}
|
||||
case EventType.MouseDrag:
|
||||
{
|
||||
bool flag3 = GUIUtility.hotControl == controlID;
|
||||
if (flag3)
|
||||
{
|
||||
scrollPosition -= current.delta / Mathf.Min(position.width, position.height) * 140f;
|
||||
current.Use();
|
||||
GUI.changed = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return scrollPosition;
|
||||
}
|
||||
|
||||
public override void OnPreviewGUI(Rect rect, GUIStyle background)
|
||||
{
|
||||
dragPos = Drag2D(dragPos, rect);
|
||||
|
||||
if (Event.current.type != EventType.Repaint)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (previewRenderUtility != null)
|
||||
{
|
||||
previewRenderUtility.BeginPreview(rect, background);
|
||||
|
||||
Camera camera = previewRenderUtility.camera;
|
||||
camera.clearFlags = CameraClearFlags.Depth;
|
||||
camera.nearClipPlane = 0.01f;
|
||||
camera.farClipPlane = 100f;
|
||||
camera.transform.position = camera.transform.forward * -2f;
|
||||
|
||||
preview.posePreviewX.localEulerAngles = new Vector3(0, dragPos.x, 0);
|
||||
preview.posePreviewY.localEulerAngles = new Vector3(Mathf.Clamp(dragPos.y, -60f, 0f), 0f, 0f);
|
||||
|
||||
camera.Render();
|
||||
previewRenderUtility.EndAndDrawPreview(rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CustomPropertyDrawer(typeof(DisplayOnly))]
|
||||
public class DisplayOnlyDrawer : PropertyDrawer
|
||||
{
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
return EditorGUI.GetPropertyHeight(property, label, true);
|
||||
}
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
EditorGUI.PropertyField(position, property, label, true);
|
||||
GUI.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
[CustomPropertyDrawer(typeof(LabelAttribute))]
|
||||
public class LabelAttributeDrawer : PropertyDrawer
|
||||
{
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
LabelAttribute labelAttribute = this.attribute as LabelAttribute;
|
||||
EditorGUI.PropertyField(position, property, new GUIContent(labelAttribute.name));
|
||||
}
|
||||
}
|
||||
|
||||
[CustomPropertyDrawer(typeof(BonesRecognizer.BonesGroup))]
|
||||
public class PXR_BonesGroupPropertyDrawer : PropertyDrawer
|
||||
{
|
||||
private float propertyHeight = EditorGUIUtility.singleLineHeight;
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
EditorGUI.BeginProperty(position, label, property);
|
||||
|
||||
var Space_Height = 2;
|
||||
|
||||
var rect = position;
|
||||
rect.height = EditorGUIUtility.singleLineHeight;
|
||||
rect.width = position.width - position.width / 6;
|
||||
rect.y += Space_Height;
|
||||
|
||||
var boneRect = rect;
|
||||
|
||||
boneRect.position = new Vector2(rect.position.x + rect.width / 15 * 2, rect.position.y);
|
||||
var handAProperty = property.FindPropertyRelative("bone1");
|
||||
EditorGUI.PropertyField(boneRect, handAProperty);
|
||||
|
||||
|
||||
rect.y += EditorGUIUtility.singleLineHeight + Space_Height;
|
||||
|
||||
boneRect.position = new Vector2(rect.position.x + rect.width / 15 * 2, rect.position.y);
|
||||
var handBProperty = property.FindPropertyRelative("bone2");
|
||||
EditorGUI.PropertyField(boneRect, handBProperty);
|
||||
|
||||
|
||||
rect.y += EditorGUIUtility.singleLineHeight + Space_Height;
|
||||
|
||||
boneRect.position = new Vector2(rect.position.x + rect.width / 15 * 2, rect.position.y);
|
||||
var disProperty = property.FindPropertyRelative("distance");
|
||||
EditorGUI.PropertyField(boneRect, disProperty);
|
||||
|
||||
rect.y += EditorGUIUtility.singleLineHeight + Space_Height;
|
||||
|
||||
boneRect.position = new Vector2(rect.position.x + rect.width / 15 * 2, rect.position.y);
|
||||
var thresProperty = property.FindPropertyRelative("thresholdWidth");
|
||||
EditorGUI.PropertyField(boneRect, thresProperty);
|
||||
|
||||
propertyHeight = rect.y - position.y + EditorGUIUtility.singleLineHeight;
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
|
||||
}
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
return propertyHeight;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aae883d2d057e1e45939843a36892dd7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,445 @@
|
||||
#if !PICO_OPENXR_SDK
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using Unity.XR.CoreUtils;
|
||||
using Unity.XR.PXR;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace Unity.XR.PXR.Editor
|
||||
{
|
||||
[CustomEditor(typeof(PXR_Manager))]
|
||||
public class PXR_ManagerEditor : UnityEditor.Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
GUI.changed = false;
|
||||
DrawDefaultInspector();
|
||||
|
||||
PXR_Manager manager = (PXR_Manager)target;
|
||||
PXR_ProjectSetting projectConfig = PXR_ProjectSetting.GetProjectConfig();
|
||||
|
||||
//Screen Fade
|
||||
manager.screenFade = EditorGUILayout.Toggle("Open Screen Fade", manager.screenFade);
|
||||
if (Camera.main != null)
|
||||
{
|
||||
var head = Camera.main.transform;
|
||||
if (head)
|
||||
{
|
||||
var fade = head.GetComponent<PXR_ScreenFade>();
|
||||
if (manager.screenFade)
|
||||
{
|
||||
if (!fade)
|
||||
{
|
||||
head.gameObject.AddComponent<PXR_ScreenFade>();
|
||||
Selection.activeObject = head;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fade) DestroyImmediate(fade);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//ffr
|
||||
manager.foveatedRenderingMode = (FoveatedRenderingMode)EditorGUILayout.EnumPopup("Foveated Rendering Mode", manager.foveatedRenderingMode);
|
||||
if (FoveatedRenderingMode.FixedFoveatedRendering == manager.foveatedRenderingMode)
|
||||
{
|
||||
projectConfig.enableETFR = false;
|
||||
projectConfig.recommendSubsamping = false;
|
||||
projectConfig.validationFFREnabled = false;
|
||||
projectConfig.validationETFREnabled = false;
|
||||
projectConfig.foveationLevel= manager.foveationLevel = (FoveationLevel)EditorGUILayout.EnumPopup("Foveated Rendering Level", manager.foveationLevel);
|
||||
manager.eyeFoveationLevel = FoveationLevel.None;
|
||||
if (FoveationLevel.None != manager.foveationLevel)
|
||||
{
|
||||
projectConfig.validationFFREnabled = true;
|
||||
if (GraphicsDeviceType.OpenGLES3 == PlayerSettings.GetGraphicsAPIs(EditorUserBuildSettings.activeBuildTarget)[0] && PlayerSettings.colorSpace == ColorSpace.Gamma)
|
||||
{
|
||||
projectConfig.enableSubsampled = false;
|
||||
projectConfig.recommendSubsamping = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
projectConfig.enableSubsampled = EditorGUILayout.Toggle(" Subsampling", projectConfig.enableSubsampled);
|
||||
projectConfig.recommendSubsamping = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (FoveatedRenderingMode.EyeTrackedFoveatedRendering == manager.foveatedRenderingMode) //etfr
|
||||
{
|
||||
projectConfig.enableETFR = true;
|
||||
projectConfig.recommendSubsamping = false;
|
||||
projectConfig.validationFFREnabled = false;
|
||||
projectConfig.validationETFREnabled = false;
|
||||
projectConfig.foveationLevel=manager.eyeFoveationLevel = (FoveationLevel)EditorGUILayout.EnumPopup("Foveated Rendering Level", manager.eyeFoveationLevel);
|
||||
manager.foveationLevel = FoveationLevel.None;
|
||||
if (FoveationLevel.None != manager.eyeFoveationLevel)
|
||||
{
|
||||
projectConfig.validationETFREnabled = true;
|
||||
if (GraphicsDeviceType.OpenGLES3 == PlayerSettings.GetGraphicsAPIs(EditorUserBuildSettings.activeBuildTarget)[0] && PlayerSettings.colorSpace == ColorSpace.Gamma)
|
||||
{
|
||||
projectConfig.enableSubsampled = false;
|
||||
projectConfig.recommendSubsamping = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
projectConfig.enableSubsampled = EditorGUILayout.Toggle(" Subsampling", projectConfig.enableSubsampled);
|
||||
projectConfig.recommendSubsamping = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//eye tracking
|
||||
GUIStyle firstLevelStyle = new GUIStyle(GUI.skin.label);
|
||||
firstLevelStyle.alignment = TextAnchor.UpperLeft;
|
||||
firstLevelStyle.fontStyle = FontStyle.Bold;
|
||||
firstLevelStyle.fontSize = 12;
|
||||
firstLevelStyle.wordWrap = true;
|
||||
var guiContent = new GUIContent();
|
||||
guiContent.text = "Eye Tracking";
|
||||
guiContent.tooltip = "Before calling EyeTracking API, enable this option first, only for Neo3 Pro Eye , PICO 4 Pro device.";
|
||||
projectConfig.eyeTracking = EditorGUILayout.Toggle(guiContent, projectConfig.eyeTracking);
|
||||
manager.eyeTracking = projectConfig.eyeTracking;
|
||||
if (manager.eyeTracking || FoveatedRenderingMode.EyeTrackedFoveatedRendering == manager.foveatedRenderingMode)
|
||||
{
|
||||
projectConfig.eyetrackingCalibration = EditorGUILayout.Toggle(new GUIContent("Eye Tracking Calibration"), projectConfig.eyetrackingCalibration);
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
EditorGUILayout.LabelField("Note:", firstLevelStyle);
|
||||
EditorGUILayout.LabelField("Eye Tracking is supported only on Neo 3 Pro Eye , PICO 4 Pro");
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
//face tracking
|
||||
var FaceContent = new GUIContent();
|
||||
FaceContent.text = "Face Tracking Mode";
|
||||
manager.trackingMode = (FaceTrackingMode)EditorGUILayout.EnumPopup(FaceContent, manager.trackingMode);
|
||||
if (manager.trackingMode == FaceTrackingMode.PXR_FTM_NONE)
|
||||
{
|
||||
projectConfig.faceTracking = false;
|
||||
projectConfig.lipsyncTracking = false;
|
||||
}
|
||||
else if (manager.trackingMode == FaceTrackingMode.PXR_FTM_FACE_LIPS_VIS || manager.trackingMode == FaceTrackingMode.PXR_FTM_FACE_LIPS_BS)
|
||||
{
|
||||
projectConfig.faceTracking = true;
|
||||
projectConfig.lipsyncTracking = true;
|
||||
}
|
||||
else if (manager.trackingMode == FaceTrackingMode.PXR_FTM_FACE)
|
||||
{
|
||||
projectConfig.faceTracking = true;
|
||||
projectConfig.lipsyncTracking = false;
|
||||
}
|
||||
else if (manager.trackingMode == FaceTrackingMode.PXR_FTM_LIPS)
|
||||
{
|
||||
projectConfig.faceTracking = false;
|
||||
projectConfig.lipsyncTracking = true;
|
||||
}
|
||||
manager.faceTracking = projectConfig.faceTracking;
|
||||
manager.lipsyncTracking = projectConfig.lipsyncTracking;
|
||||
|
||||
//hand tracking
|
||||
var handContent = new GUIContent();
|
||||
handContent.text = "Hand Tracking";
|
||||
projectConfig.handTracking = EditorGUILayout.Toggle(handContent, projectConfig.handTracking);
|
||||
if (projectConfig.handTracking)
|
||||
{
|
||||
//hand tracking Support
|
||||
var handSupport = new GUIContent();
|
||||
handSupport.text = "Hand Tracking Support";
|
||||
projectConfig.handTrackingSupportType =(HandTrackingSupport)EditorGUILayout.EnumPopup(handSupport, projectConfig.handTrackingSupportType);
|
||||
}
|
||||
|
||||
//Adaptive Hand Model
|
||||
var adaptiveContent = new GUIContent();
|
||||
adaptiveContent.text = "Adaptive Hand Model(PICO)";
|
||||
adaptiveContent.tooltip = "If this function is selected, the hand model will change according to the actual size of the user's palm. Note that the hand model only works on PICO.";
|
||||
projectConfig.adaptiveHand = EditorGUILayout.Toggle(adaptiveContent, projectConfig.adaptiveHand);
|
||||
//high frequency tracking
|
||||
var highfrequencytracking = new GUIContent();
|
||||
highfrequencytracking.text = "High Frequency Tracking(60Hz)";
|
||||
highfrequencytracking.tooltip = "If turned on, hand tracking will run at a higher tracking frequency, which will improve the smoothness of hand tracking, but the power consumption will increase.";
|
||||
projectConfig.highFrequencyHand = EditorGUILayout.Toggle(highfrequencytracking, projectConfig.highFrequencyHand);
|
||||
//body tracking
|
||||
var bodyContent = new GUIContent();
|
||||
bodyContent.text = "Body Tracking";
|
||||
projectConfig.bodyTracking = EditorGUILayout.Toggle(bodyContent, projectConfig.bodyTracking);
|
||||
manager.bodyTracking = projectConfig.bodyTracking;
|
||||
|
||||
// content protect
|
||||
projectConfig.useContentProtect = EditorGUILayout.Toggle("Use Content Protect", projectConfig.useContentProtect);
|
||||
|
||||
//MRC
|
||||
var mrcContent = new GUIContent();
|
||||
mrcContent.text = "MRC";
|
||||
projectConfig.openMRC = EditorGUILayout.Toggle(mrcContent, projectConfig.openMRC);
|
||||
manager.openMRC = projectConfig.openMRC;
|
||||
if (manager.openMRC == true)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
string[] layerNames = new string[32];
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
layerNames[i] = LayerMask.LayerToName(i);
|
||||
if (layerNames[i].Length == 0)
|
||||
{
|
||||
layerNames[i] = "LayerName " + i.ToString();
|
||||
}
|
||||
}
|
||||
manager.foregroundLayerMask = EditorGUILayout.MaskField("Foreground Layer Masks", manager.foregroundLayerMask, layerNames);
|
||||
manager.backgroundLayerMask = EditorGUILayout.MaskField("Background Layer Masks", manager.backgroundLayerMask, layerNames);
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
//Late Latching
|
||||
projectConfig.latelatching = EditorGUILayout.Toggle("Use Late Latching", projectConfig.latelatching);
|
||||
manager.lateLatching = projectConfig.latelatching;
|
||||
if (manager.lateLatching)
|
||||
{
|
||||
projectConfig.latelatchingDebug = EditorGUILayout.Toggle(" Late Latching Debug", projectConfig.latelatchingDebug);
|
||||
manager.latelatchingDebug = projectConfig.latelatchingDebug;
|
||||
}
|
||||
|
||||
if (Camera.main != null)
|
||||
{
|
||||
var head = Camera.main.transform;
|
||||
if (head)
|
||||
{
|
||||
var fade = head.GetComponent<PXR_LateLatching>();
|
||||
if (manager.lateLatching)
|
||||
{
|
||||
if (!fade)
|
||||
{
|
||||
head.gameObject.AddComponent<PXR_LateLatching>();
|
||||
Selection.activeObject = head;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fade) DestroyImmediate(fade);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// msaa
|
||||
if (QualitySettings.renderPipeline != null)
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
projectConfig.enableRecommendMSAA = EditorGUILayout.Toggle("Use Recommended MSAA", projectConfig.enableRecommendMSAA);
|
||||
manager.useRecommendedAntiAliasingLevel = projectConfig.enableRecommendMSAA;
|
||||
EditorGUI.EndDisabledGroup();
|
||||
EditorGUILayout.HelpBox("A Scriptable Render Pipeline is in use,the 'Use Recommended MSAA' will not be used. ", MessageType.Info, true);
|
||||
projectConfig.recommendMSAA = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
projectConfig.enableRecommendMSAA = EditorGUILayout.Toggle("Use Recommended MSAA", projectConfig.enableRecommendMSAA);
|
||||
manager.useRecommendedAntiAliasingLevel = projectConfig.enableRecommendMSAA;
|
||||
if (!projectConfig.enableRecommendMSAA)
|
||||
{
|
||||
projectConfig.recommendMSAA = true;
|
||||
}
|
||||
}
|
||||
|
||||
//Adaptive Resolution
|
||||
guiContent = new GUIContent();
|
||||
guiContent.text = "Adaptive Resolution";
|
||||
guiContent.tooltip = "Adaptively change resolution based on GPU performance using renderViewportScale. Render buffer will be allocated to max adaptive resolution scale size. Currently, FFR should be disabled with this feature.";
|
||||
projectConfig.adaptiveResolution = EditorGUILayout.Toggle(guiContent, projectConfig.adaptiveResolution);
|
||||
manager.adaptiveResolution = projectConfig.adaptiveResolution;
|
||||
if (manager.adaptiveResolution)
|
||||
{
|
||||
EditorGUILayout.LabelField("Min Adaptive Resolution Scale:");
|
||||
manager.minEyeTextureScale = EditorGUILayout.Slider(manager.minEyeTextureScale, 0.7f, 1.3f);
|
||||
EditorGUILayout.LabelField("Max Adaptive Resolution Scale:");
|
||||
manager.maxEyeTextureScale = EditorGUILayout.Slider(manager.maxEyeTextureScale, 0.7f, 1.3f);
|
||||
manager.adaptiveResolutionPowerSetting = (AdaptiveResolutionPowerSetting)EditorGUILayout.EnumPopup(" Power Setting", manager.adaptiveResolutionPowerSetting);
|
||||
|
||||
}
|
||||
|
||||
#if UNITY_2021_3_OR_NEWER
|
||||
XROrigin xrOrigin = FindAnyObjectByType<XROrigin>();
|
||||
#else
|
||||
XROrigin xrOrigin = FindObjectOfType<XROrigin>();
|
||||
#endif
|
||||
if (xrOrigin.RequestedTrackingOriginMode != XROrigin.TrackingOriginMode.Floor)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
projectConfig.stageMode = EditorGUILayout.Toggle("Stage Mode", false);
|
||||
GUI.enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
projectConfig.stageMode = EditorGUILayout.Toggle("Stage Mode", projectConfig.stageMode);
|
||||
}
|
||||
|
||||
//mr
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
projectConfig.videoSeeThrough = EditorGUILayout.Toggle("Video Seethrough", projectConfig.videoSeeThrough);
|
||||
projectConfig.spatialAnchor = EditorGUILayout.Toggle("Spatial Anchor", projectConfig.spatialAnchor);
|
||||
projectConfig.sceneCapture = EditorGUILayout.Toggle("Scene Capture", projectConfig.sceneCapture);
|
||||
projectConfig.sharedAnchor = EditorGUILayout.Toggle("Shared Spatial Anchor", projectConfig.sharedAnchor);
|
||||
projectConfig.spatialMesh = EditorGUILayout.Toggle("Spatial Mesh", projectConfig.spatialMesh);
|
||||
if (projectConfig.spatialMesh)
|
||||
{
|
||||
projectConfig.meshLod = (PxrMeshLod)EditorGUILayout.EnumPopup(" LOD", projectConfig.meshLod);
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
//mr safeguard
|
||||
|
||||
var mrSafeguardContent = new GUIContent();
|
||||
mrSafeguardContent.text = "MR Safeguard";
|
||||
mrSafeguardContent.tooltip =
|
||||
"MR safety, if you choose this option, your application will adopt MR safety policies during runtime. If not selected, it will continue to use VR safety policies by default.";
|
||||
projectConfig.mrSafeguard = EditorGUILayout.Toggle(mrSafeguardContent, projectConfig.mrSafeguard);
|
||||
|
||||
var secureMRContent = new GUIContent();
|
||||
secureMRContent.text = "SecureMR";
|
||||
projectConfig.secureMR = EditorGUILayout.Toggle(secureMRContent, projectConfig.secureMR);
|
||||
|
||||
//Super Resolution
|
||||
var superresolutionContent = new GUIContent();
|
||||
superresolutionContent.text = "Super Resolution";
|
||||
superresolutionContent.tooltip = "Single pass spatial aware upscaling technique.\n\nThis can't be used with Sharpening. \nAlso can't be used along with subsample feature due to unsupported texture format. \n\nThis effect won't work properly under low resolutions when Adaptive Resolution is also enabled.";
|
||||
projectConfig.superResolution = EditorGUILayout.Toggle(superresolutionContent, projectConfig.superResolution);
|
||||
manager.enableSuperResolution = projectConfig.superResolution;
|
||||
|
||||
//Sharpening
|
||||
|
||||
var sharpeningContent = new GUIContent();
|
||||
sharpeningContent.text = "Sharpening Mode";
|
||||
sharpeningContent.tooltip = "Normal: Normal Quality \n\nQuality: Higher Quality, higher GPU usage\n\nThis effect won't work properly under low resolutions when Adaptive Resolution is also enabled.\n\nThis can't be used with Super Resolution. It will be automatically disabled when you enable Super Resolution. \nAlso can't be used along with subsample feature due to unsupported texture format";
|
||||
var sharpeningEnhanceContent = new GUIContent();
|
||||
sharpeningEnhanceContent.text = "Sharpening Enhance Mode";
|
||||
sharpeningEnhanceContent.tooltip = "None: Full screen will be sharpened\n\nFixed Foveated: Only the central fixation point will be sharpened\n\nSelf Adaptive: Only when contrast between the current pixel and the surrounding pixels exceeds a certain threshold will be sharpened.\n\nThis menu will be only enabled while Sharpening (either Normal or Quality) is enabled.";
|
||||
|
||||
if (projectConfig.superResolution)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
manager.sharpeningMode = SharpeningMode.None;
|
||||
manager.sharpeningEnhance = SharpeningEnhance.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
manager.sharpeningMode = (SharpeningMode)EditorGUILayout.EnumPopup(sharpeningContent, manager.sharpeningMode);
|
||||
if (manager.sharpeningMode == SharpeningMode.None)
|
||||
{
|
||||
manager.sharpeningEnhance = SharpeningEnhance.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
manager.sharpeningEnhance = (SharpeningEnhance)EditorGUILayout.EnumPopup(sharpeningEnhanceContent, manager.sharpeningEnhance);
|
||||
}
|
||||
|
||||
if (manager.sharpeningMode != SharpeningMode.None)
|
||||
{
|
||||
if (manager.sharpeningMode == SharpeningMode.Normal)
|
||||
{
|
||||
projectConfig.normalSharpening = true;
|
||||
projectConfig.qualitySharpening = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
projectConfig.normalSharpening = false;
|
||||
projectConfig.qualitySharpening = true;
|
||||
}
|
||||
|
||||
if (manager.sharpeningEnhance == SharpeningEnhance.Both)
|
||||
{
|
||||
projectConfig.fixedFoveatedSharpening = true;
|
||||
projectConfig.selfAdaptiveSharpening = true;
|
||||
}
|
||||
else if (manager.sharpeningEnhance == SharpeningEnhance.FixedFoveated)
|
||||
{
|
||||
projectConfig.fixedFoveatedSharpening = true;
|
||||
projectConfig.selfAdaptiveSharpening = false;
|
||||
}
|
||||
else if (manager.sharpeningEnhance == SharpeningEnhance.SelfAdaptive)
|
||||
{
|
||||
projectConfig.fixedFoveatedSharpening = false;
|
||||
projectConfig.selfAdaptiveSharpening = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
projectConfig.fixedFoveatedSharpening = false;
|
||||
projectConfig.selfAdaptiveSharpening = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
projectConfig.normalSharpening = false;
|
||||
projectConfig.qualitySharpening = false;
|
||||
projectConfig.fixedFoveatedSharpening = false;
|
||||
projectConfig.selfAdaptiveSharpening = false;
|
||||
}
|
||||
|
||||
var usePremultipliedAlphaContent = new GUIContent();
|
||||
usePremultipliedAlphaContent.text = "Use Premultiplied Alpha";
|
||||
usePremultipliedAlphaContent.tooltip = @"Enable premultiplied alpha for this content.
|
||||
|
||||
When enabled:
|
||||
• RGB color channels are multiplied by Alpha (R*A, G*A, B*A)
|
||||
• Improves performance for transparent elements (e.g., UI, particles)
|
||||
• Fixes edge artifacts in semitransparent objects
|
||||
• Matches OpenXR and GPU blending requirements
|
||||
|
||||
Recommended for:
|
||||
• UI panels with transparency
|
||||
• Particle effects
|
||||
• Materials using alpha blending
|
||||
• Any content requiring frequent transparency mixing
|
||||
|
||||
Note: Ensure textures are imported with 'Alpha Is Transparency'
|
||||
or manually pre-multiply colors if needed.";
|
||||
manager.usePremultipliedAlpha = EditorGUILayout.Toggle(usePremultipliedAlphaContent, manager.usePremultipliedAlpha);
|
||||
|
||||
guiContent.text = "Layer Blend";
|
||||
manager.useLayerBlend = EditorGUILayout.Toggle(guiContent, manager.useLayerBlend);
|
||||
if (manager.useLayerBlend)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
guiContent.text = "Src Color";
|
||||
manager.srcColor = (PxrBlendFactor)EditorGUILayout.EnumPopup(guiContent, manager.srcColor);
|
||||
guiContent.text = "Dst Color";
|
||||
manager.dstColor = (PxrBlendFactor)EditorGUILayout.EnumPopup(guiContent, manager.dstColor);
|
||||
guiContent.text = "Src Alpha";
|
||||
manager.srcAlpha = (PxrBlendFactor)EditorGUILayout.EnumPopup(guiContent, manager.srcAlpha);
|
||||
guiContent.text = "Dst Alpha";
|
||||
manager.dstAlpha = (PxrBlendFactor)EditorGUILayout.EnumPopup(guiContent, manager.dstAlpha);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
if (GUI.changed)
|
||||
{
|
||||
EditorUtility.SetDirty(projectConfig);
|
||||
EditorUtility.SetDirty(manager);
|
||||
}
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
EditorUtility.SetDirty(PXR_ProjectSetting.GetProjectConfig());
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79735b12af5b1844aba3a1342ec41bb1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,63 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
#if XR_MGMT_GTE_320
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.XR.Management.Metadata;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.XR.PXR.Editor
|
||||
{
|
||||
internal class PXR_Metadata : IXRPackage
|
||||
{
|
||||
private class PXR_PackageMetadata : IXRPackageMetadata
|
||||
{
|
||||
public string packageName => "PICO Plugin";
|
||||
public string packageId => "com.unity.xr.picoxr";
|
||||
public string settingsType => "Unity.XR.PXR.PXR_Settings";
|
||||
public List<IXRLoaderMetadata> loaderMetadata => lLoaderMetadata;
|
||||
|
||||
private static readonly List<IXRLoaderMetadata> lLoaderMetadata = new List<IXRLoaderMetadata>() { new PXR_LoaderMetadata() };
|
||||
}
|
||||
|
||||
private class PXR_LoaderMetadata : IXRLoaderMetadata
|
||||
{
|
||||
public string loaderName => "PICO";
|
||||
public string loaderType => "Unity.XR.PXR.PXR_Loader";
|
||||
public List<BuildTargetGroup> supportedBuildTargets => SupportedBuildTargets;
|
||||
|
||||
private static readonly List<BuildTargetGroup> SupportedBuildTargets = new List<BuildTargetGroup>()
|
||||
{
|
||||
BuildTargetGroup.Android
|
||||
};
|
||||
}
|
||||
|
||||
private static IXRPackageMetadata Metadata = new PXR_PackageMetadata();
|
||||
public IXRPackageMetadata metadata => Metadata;
|
||||
|
||||
public bool PopulateNewSettingsInstance(ScriptableObject obj)
|
||||
{
|
||||
var settings = obj as PXR_Settings;
|
||||
if (settings != null)
|
||||
{
|
||||
settings.stereoRenderingModeAndroid = PXR_Settings.StereoRenderingModeAndroid.MultiPass;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ef29a1525ea68f479c41ed3c17dced9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,115 @@
|
||||
#if PICO_OPENXR_SDK
|
||||
using Unity.XR.PXR;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
[CustomEditor(typeof(PICOFeature))]
|
||||
internal class PXR_OpenXRFeatureEditor : Editor
|
||||
{
|
||||
private PXR_OpenXRProjectSetting projectConfig;
|
||||
void OnEnable()
|
||||
{
|
||||
projectConfig = PXR_OpenXRProjectSetting.GetProjectConfig();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
|
||||
// Update anything from the serializable object
|
||||
EditorGUIUtility.labelWidth = 215.0f;
|
||||
|
||||
//eye tracking
|
||||
GUIStyle firstLevelStyle = new GUIStyle(GUI.skin.label);
|
||||
firstLevelStyle.alignment = TextAnchor.UpperLeft;
|
||||
firstLevelStyle.fontStyle = FontStyle.Bold;
|
||||
firstLevelStyle.fontSize = 12;
|
||||
firstLevelStyle.wordWrap = true;
|
||||
var guiContent = new GUIContent();
|
||||
guiContent.text = "Eye Tracking";
|
||||
guiContent.tooltip = "Before calling EyeTracking API, enable this option first, only for Neo3 Pro Eye , PICO 4 Pro device.";
|
||||
projectConfig.isEyeTracking = EditorGUILayout.Toggle(guiContent, projectConfig.isEyeTracking);
|
||||
if (projectConfig.isEyeTracking)
|
||||
{
|
||||
projectConfig.isEyeTrackingCalibration = EditorGUILayout.Toggle(new GUIContent("Eye Tracking Calibration"), projectConfig.isEyeTrackingCalibration);
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
EditorGUILayout.LabelField("Note: Eye Tracking is supported only on Neo 3 Pro Eye , PICO 4 Pro", firstLevelStyle);
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
projectConfig.isHandTracking = EditorGUILayout.Toggle("Hand Tracking", projectConfig.isHandTracking);
|
||||
if (projectConfig.isHandTracking)
|
||||
{
|
||||
//hand tracking Support
|
||||
var handSupport = new GUIContent();
|
||||
handSupport.text = "Hand Tracking Support";
|
||||
projectConfig.handTrackingSupportType =(HandTrackingSupport)EditorGUILayout.EnumPopup(handSupport, projectConfig.handTrackingSupportType);
|
||||
//high frequency tracking
|
||||
var highfrequencytracking = new GUIContent();
|
||||
highfrequencytracking.text = "High Frequency Tracking(60Hz)";
|
||||
highfrequencytracking.tooltip = "If turned on, hand tracking will run at a higher tracking frequency, which will improve the smoothness of hand tracking, but the power consumption will increase.";
|
||||
projectConfig.highFrequencyHand = EditorGUILayout.Toggle(highfrequencytracking, projectConfig.highFrequencyHand);
|
||||
}
|
||||
|
||||
var displayFrequencyContent = new GUIContent();
|
||||
displayFrequencyContent.text = "Display Refresh Rates";
|
||||
projectConfig.displayFrequency = (SystemDisplayFrequency)EditorGUILayout.EnumPopup(displayFrequencyContent, projectConfig.displayFrequency);
|
||||
|
||||
// content protect
|
||||
projectConfig.useContentProtect = EditorGUILayout.Toggle("Use Content Protect", projectConfig.useContentProtect);
|
||||
if (projectConfig.useContentProtect)
|
||||
{
|
||||
projectConfig.contentProtectFlags = (SecureContentFlag)EditorGUILayout.EnumPopup("Content Protect", projectConfig.contentProtectFlags);
|
||||
}
|
||||
|
||||
//FFR
|
||||
var foveationEnableContent = new GUIContent();
|
||||
foveationEnableContent.text = "Foveated Rendering";
|
||||
projectConfig.foveationEnable = EditorGUILayout.Toggle(foveationEnableContent, projectConfig.foveationEnable);
|
||||
if (projectConfig.foveationEnable)
|
||||
{
|
||||
var foveationContent = new GUIContent();
|
||||
foveationContent.text = "Foveated Rendering Mode";
|
||||
projectConfig.foveatedRenderingMode = (FoveationFeature.FoveatedRenderingMode)EditorGUILayout.EnumPopup(foveationContent, projectConfig.foveatedRenderingMode);
|
||||
|
||||
var foveationLevel = new GUIContent();
|
||||
foveationLevel.text = "Foveated Rendering Level";
|
||||
projectConfig.foveatedRenderingLevel = (FoveationFeature.FoveatedRenderingLevel)EditorGUILayout.EnumPopup(foveationLevel, projectConfig.foveatedRenderingLevel);
|
||||
|
||||
if (projectConfig.foveatedRenderingLevel !=FoveationFeature.FoveatedRenderingLevel.Off)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
var subsampledEnabledContent = new GUIContent();
|
||||
subsampledEnabledContent.text = "Subsampling";
|
||||
projectConfig.isSubsampledEnabled = EditorGUILayout.Toggle(subsampledEnabledContent, projectConfig.isSubsampledEnabled);
|
||||
GUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
EditorGUILayout.LabelField("This function has been replaced by the official interface in versions above 1.9.1.", firstLevelStyle);
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
GUILayout.BeginHorizontal();
|
||||
guiContent.text = "System Splash Screen";
|
||||
EditorGUILayout.LabelField(guiContent, GUILayout.Width(185));
|
||||
projectConfig.systemSplashScreen = (Texture2D)EditorGUILayout.ObjectField(projectConfig.systemSplashScreen, typeof(Texture2D), true);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
EditorGUILayout.LabelField("Note: Set the system splash screen picture in PNG format.", firstLevelStyle);
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
var MRSafeguard = new GUIContent();
|
||||
MRSafeguard.text = "MR Safeguard";
|
||||
MRSafeguard.tooltip = "MR safety, if you choose this option, your application will adopt MR safety policies during runtime. If not selected, it will continue to use VR safety policies by default.";
|
||||
projectConfig.MRSafeguard = EditorGUILayout.Toggle(MRSafeguard, projectConfig.MRSafeguard);
|
||||
|
||||
serializedObject.Update();
|
||||
if (GUI.changed)
|
||||
{
|
||||
EditorUtility.SetDirty(projectConfig);
|
||||
}
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e67ae0563df474ab807e604306a144b
|
||||
timeCreated: 1738740836
|
||||
@@ -0,0 +1,60 @@
|
||||
#if PICO_OPENXR_SDK
|
||||
using UnityEditor;
|
||||
using UnityEditor.XR.OpenXR.Features;
|
||||
using UnityEngine.XR.OpenXR.Features.Interactions;
|
||||
|
||||
namespace Unity.XR.OpenXR.Features.PICOSupport
|
||||
{
|
||||
[OpenXRFeatureSet(
|
||||
FeatureIds = new string[] {
|
||||
LayerSecureContentFeature.featureId,
|
||||
DisplayRefreshRateFeature.featureId,
|
||||
PassthroughFeature.featureId,
|
||||
FoveationFeature.featureId,
|
||||
BodyTrackingFeature.featureId,
|
||||
PICOSceneCapture.featureId,
|
||||
PICOSpatialMesh.featureId,
|
||||
PICOSpatialAnchor.featureId,
|
||||
PICOFeature.featureId,
|
||||
OpenXRExtensions.featureId,
|
||||
PICO4ControllerProfile.featureId,
|
||||
PICO4UltraControllerProfile.featureId,
|
||||
PICONeo3ControllerProfile.featureId,
|
||||
PICOG3ControllerProfile.featureId,
|
||||
},
|
||||
DefaultFeatureIds = new string[] {
|
||||
LayerSecureContentFeature.featureId,
|
||||
DisplayRefreshRateFeature.featureId,
|
||||
PassthroughFeature.featureId,
|
||||
FoveationFeature.featureId,
|
||||
BodyTrackingFeature.featureId,
|
||||
PICOSceneCapture.featureId,
|
||||
PICOSpatialMesh.featureId,
|
||||
PICOSpatialAnchor.featureId,
|
||||
PICOFeature.featureId,
|
||||
OpenXRExtensions.featureId,
|
||||
PICO4ControllerProfile.featureId,
|
||||
PICO4UltraControllerProfile.featureId,
|
||||
PICONeo3ControllerProfile.featureId,
|
||||
PICOG3ControllerProfile.featureId,
|
||||
},
|
||||
UiName = "PICO XR",
|
||||
Description = "Feature set for using PICO XR Features",
|
||||
FeatureSetId = featureSetId,
|
||||
SupportedBuildTargets = new BuildTargetGroup[] { BuildTargetGroup.Android},
|
||||
RequiredFeatureIds = new string[]
|
||||
{
|
||||
PICOFeature.featureId,
|
||||
OpenXRExtensions.featureId,
|
||||
PICO4ControllerProfile.featureId,
|
||||
PICO4UltraControllerProfile.featureId,
|
||||
PICONeo3ControllerProfile.featureId,
|
||||
PICOG3ControllerProfile.featureId,
|
||||
}
|
||||
)]
|
||||
public class PXR_OpenXRFeatureSet
|
||||
{
|
||||
public const string featureSetId = "com.picoxr.openxr.features";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 091580be507bbc846bf44f8b65d67293
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,475 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Unity.XR.PXR.Editor
|
||||
{
|
||||
[Obsolete("PXR_OverLayEditor is obsolete and will be removed in the next version. Please use PXR_CompositionLayerEditor instead.", false)]
|
||||
[CanEditMultipleObjects]
|
||||
[CustomEditor(typeof(PXR_OverLay))]
|
||||
public class PXR_OverLayEditor : UnityEditor.Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
var guiContent = new GUIContent();
|
||||
foreach (PXR_OverLay overlayTarget in targets)
|
||||
{
|
||||
EditorGUILayout.LabelField("Overlay Settings", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
guiContent.text = "Type";
|
||||
overlayTarget.overlayType = (PXR_OverLay.OverlayType)EditorGUILayout.EnumPopup(guiContent, overlayTarget.overlayType);
|
||||
guiContent.text = "Shape";
|
||||
overlayTarget.overlayShape = (PXR_OverLay.OverlayShape)EditorGUILayout.EnumPopup(guiContent, overlayTarget.overlayShape);
|
||||
guiContent.text = "Depth";
|
||||
overlayTarget.layerDepth = EditorGUILayout.IntField(guiContent, overlayTarget.layerDepth);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
guiContent.text = "Clones";
|
||||
overlayTarget.isClones = EditorGUILayout.Toggle(guiContent, overlayTarget.isClones);
|
||||
if (overlayTarget.isClones)
|
||||
{
|
||||
overlayTarget.originalOverLay = EditorGUILayout.ObjectField("Original OverLay", overlayTarget.originalOverLay, typeof(PXR_OverLay), true) as PXR_OverLay;
|
||||
|
||||
GUIStyle firstLevelStyle = new GUIStyle(GUI.skin.label);
|
||||
firstLevelStyle.alignment = TextAnchor.UpperLeft;
|
||||
firstLevelStyle.fontStyle = FontStyle.Bold;
|
||||
firstLevelStyle.fontSize = 12;
|
||||
firstLevelStyle.wordWrap = true;
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
EditorGUILayout.LabelField("Note:", firstLevelStyle);
|
||||
EditorGUILayout.LabelField("Original OverLay cannot be empty or itself!");
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUILayout.LabelField("Overlay Textures", EditorStyles.boldLabel);
|
||||
guiContent.text = "Texture Type";
|
||||
overlayTarget.textureType = (PXR_OverLay.TextureType)EditorGUILayout.EnumPopup(guiContent, overlayTarget.textureType);
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
if (overlayTarget.overlayShape == PXR_OverLay.OverlayShape.BlurredQuad)
|
||||
{
|
||||
overlayTarget.textureType = PXR_OverLay.TextureType.ExternalSurface;
|
||||
}
|
||||
|
||||
if (overlayTarget.textureType == PXR_OverLay.TextureType.ExternalSurface)
|
||||
{
|
||||
overlayTarget.isExternalAndroidSurface = true;
|
||||
overlayTarget.isDynamic = false;
|
||||
}
|
||||
else if (overlayTarget.textureType == PXR_OverLay.TextureType.DynamicTexture)
|
||||
{
|
||||
overlayTarget.isExternalAndroidSurface = false;
|
||||
overlayTarget.isDynamic = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.isExternalAndroidSurface = false;
|
||||
overlayTarget.isDynamic = false;
|
||||
}
|
||||
|
||||
if (overlayTarget.isExternalAndroidSurface)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
guiContent.text = "DRM";
|
||||
overlayTarget.isExternalAndroidSurfaceDRM = EditorGUILayout.Toggle(guiContent, overlayTarget.isExternalAndroidSurfaceDRM);
|
||||
|
||||
guiContent.text = "3D Surface Type";
|
||||
guiContent.tooltip = "The functions of '3D Surface Type' and 'Source Rects' are similar, and only one of them can be used. ";
|
||||
overlayTarget.externalAndroidSurface3DType = (PXR_OverLay.Surface3DType)EditorGUILayout.EnumPopup(guiContent, overlayTarget.externalAndroidSurface3DType);
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
if (overlayTarget.overlayShape == PXR_OverLay.OverlayShape.BlurredQuad)
|
||||
{
|
||||
EditorGUILayout.LabelField("Blurred Quad");
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
guiContent.text = "Mode";
|
||||
overlayTarget.blurredQuadMode = (PXR_OverLay.BlurredQuadMode)EditorGUILayout.EnumPopup(guiContent, overlayTarget.blurredQuadMode);
|
||||
|
||||
guiContent.text = "Scale";
|
||||
overlayTarget.blurredQuadScale = EditorGUILayout.FloatField(guiContent, Mathf.Abs(overlayTarget.blurredQuadScale));
|
||||
|
||||
guiContent.text = "Shift";
|
||||
overlayTarget.blurredQuadShift = EditorGUILayout.Slider(guiContent, overlayTarget.blurredQuadShift, -1, 1);
|
||||
|
||||
guiContent.text = "FOV";
|
||||
overlayTarget.blurredQuadFOV = EditorGUILayout.Slider(guiContent, overlayTarget.blurredQuadFOV, 0, 180f);
|
||||
|
||||
guiContent.text = "IPD";
|
||||
overlayTarget.blurredQuadIPD = EditorGUILayout.Slider(guiContent, overlayTarget.blurredQuadIPD, 0.01f, 1.0f);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
guiContent.tooltip = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.LabelField("Texture");
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
|
||||
var labelControlRect = EditorGUILayout.GetControlRect();
|
||||
EditorGUI.LabelField(new Rect(labelControlRect.x, labelControlRect.y, labelControlRect.width / 2, labelControlRect.height), new GUIContent("Left", "Texture used for the left eye"));
|
||||
EditorGUI.LabelField(new Rect(labelControlRect.x + labelControlRect.width / 2, labelControlRect.y, labelControlRect.width / 2, labelControlRect.height), new GUIContent("Right", "Texture used for the right eye"));
|
||||
|
||||
var textureControlRect = EditorGUILayout.GetControlRect(GUILayout.Height(64));
|
||||
overlayTarget.layerTextures[0] = (Texture)EditorGUI.ObjectField(new Rect(textureControlRect.x, textureControlRect.y, 64, textureControlRect.height), overlayTarget.layerTextures[0], typeof(Texture), false);
|
||||
overlayTarget.layerTextures[1] = (Texture)EditorGUI.ObjectField(new Rect(textureControlRect.x + textureControlRect.width / 2, textureControlRect.y, 64, textureControlRect.height), overlayTarget.layerTextures[1] != null ? overlayTarget.layerTextures[1] : overlayTarget.layerTextures[0], typeof(Texture), false);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
if (overlayTarget.overlayShape == PXR_OverLay.OverlayShape.Equirect ||
|
||||
overlayTarget.overlayShape == PXR_OverLay.OverlayShape.Fisheye)
|
||||
{
|
||||
guiContent.text = "Radius";
|
||||
overlayTarget.radius = EditorGUILayout.FloatField(guiContent, Mathf.Abs(overlayTarget.radius));
|
||||
}
|
||||
}
|
||||
|
||||
if (overlayTarget.overlayShape == PXR_OverLay.OverlayShape.Quad ||
|
||||
overlayTarget.overlayShape == PXR_OverLay.OverlayShape.Cylinder ||
|
||||
overlayTarget.overlayShape == PXR_OverLay.OverlayShape.Equirect ||
|
||||
overlayTarget.overlayShape == PXR_OverLay.OverlayShape.Eac ||
|
||||
overlayTarget.overlayShape == PXR_OverLay.OverlayShape.Fisheye)
|
||||
{
|
||||
guiContent.text = "Texture Rects";
|
||||
overlayTarget.useImageRect = EditorGUILayout.Toggle(guiContent, overlayTarget.useImageRect);
|
||||
if (overlayTarget.useImageRect)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
if (PXR_OverLay.Surface3DType.Single != overlayTarget.externalAndroidSurface3DType)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
}
|
||||
guiContent.text = "Source Rects";
|
||||
guiContent.tooltip = "The functions of '3D Surface Type' and 'Source Rects' are similar, and only one of them can be used. ";
|
||||
overlayTarget.textureRect = (PXR_OverLay.TextureRect)EditorGUILayout.EnumPopup(guiContent, overlayTarget.textureRect);
|
||||
|
||||
if (PXR_OverLay.Surface3DType.Single == overlayTarget.externalAndroidSurface3DType)
|
||||
{
|
||||
if (overlayTarget.textureRect == PXR_OverLay.TextureRect.Custom)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Left Rect");
|
||||
EditorGUILayout.LabelField("Right Rect");
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
overlayTarget.srcRectLeft = ClampRect(EditorGUILayout.RectField(overlayTarget.srcRectLeft));
|
||||
EditorGUILayout.Space(15);
|
||||
guiContent.text = "Right";
|
||||
overlayTarget.srcRectRight = ClampRect(EditorGUILayout.RectField(overlayTarget.srcRectRight));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
else if (overlayTarget.textureRect == PXR_OverLay.TextureRect.MonoScopic)
|
||||
{
|
||||
overlayTarget.srcRectLeft = new Rect(0, 0, 1, 1);
|
||||
overlayTarget.srcRectRight = new Rect(0, 0, 1, 1);
|
||||
}
|
||||
else if (overlayTarget.textureRect == PXR_OverLay.TextureRect.StereoScopic)
|
||||
{
|
||||
overlayTarget.srcRectLeft = new Rect(0, 0, 0.5f, 1);
|
||||
overlayTarget.srcRectRight = new Rect(0.5f, 0, 0.5f, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.textureRect = PXR_OverLay.TextureRect.MonoScopic;
|
||||
overlayTarget.srcRectLeft = new Rect(0, 0, 1, 1);
|
||||
overlayTarget.srcRectRight = new Rect(0, 0, 1, 1);
|
||||
}
|
||||
|
||||
guiContent.tooltip = "";
|
||||
GUI.enabled = true;
|
||||
if (overlayTarget.overlayShape == PXR_OverLay.OverlayShape.Quad ||
|
||||
overlayTarget.overlayShape == PXR_OverLay.OverlayShape.Equirect ||
|
||||
overlayTarget.overlayShape == PXR_OverLay.OverlayShape.Fisheye)
|
||||
{
|
||||
guiContent.text = "Destination Rects";
|
||||
overlayTarget.destinationRect = (PXR_OverLay.DestinationRect)EditorGUILayout.EnumPopup(guiContent, overlayTarget.destinationRect);
|
||||
|
||||
if (overlayTarget.destinationRect == PXR_OverLay.DestinationRect.Custom)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Left Rect");
|
||||
EditorGUILayout.LabelField("Right Rect");
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
overlayTarget.dstRectLeft = ClampRect(EditorGUILayout.RectField(overlayTarget.dstRectLeft));
|
||||
EditorGUILayout.Space(15);
|
||||
guiContent.text = "Right";
|
||||
overlayTarget.dstRectRight = ClampRect(EditorGUILayout.RectField(overlayTarget.dstRectRight));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.enabled = false;
|
||||
overlayTarget.dstRectLeft = new Rect(0, 0, 1, 1);
|
||||
overlayTarget.dstRectRight = new Rect(0, 0, 1, 1);
|
||||
GUI.enabled = true;
|
||||
}
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
guiContent.text = "Layer Blend";
|
||||
overlayTarget.useLayerBlend = EditorGUILayout.Toggle(guiContent, overlayTarget.useLayerBlend);
|
||||
if (overlayTarget.useLayerBlend)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
guiContent.text = "Src Color";
|
||||
overlayTarget.srcColor = (PxrBlendFactor)EditorGUILayout.EnumPopup(guiContent, overlayTarget.srcColor);
|
||||
guiContent.text = "Dst Color";
|
||||
overlayTarget.dstColor = (PxrBlendFactor)EditorGUILayout.EnumPopup(guiContent, overlayTarget.dstColor);
|
||||
guiContent.text = "Src Alpha";
|
||||
overlayTarget.srcAlpha = (PxrBlendFactor)EditorGUILayout.EnumPopup(guiContent, overlayTarget.srcAlpha);
|
||||
guiContent.text = "Dst Alpha";
|
||||
overlayTarget.dstAlpha = (PxrBlendFactor)EditorGUILayout.EnumPopup(guiContent, overlayTarget.dstAlpha);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
if (overlayTarget.overlayShape == PXR_OverLay.OverlayShape.Eac)
|
||||
{
|
||||
guiContent.text = "Model Type";
|
||||
overlayTarget.eacModelType = (PXR_OverLay.EACModelType)EditorGUILayout.EnumPopup(guiContent, overlayTarget.eacModelType);
|
||||
|
||||
if (PXR_OverLay.EACModelType.Eac360ViewPort == overlayTarget.eacModelType ||
|
||||
PXR_OverLay.EACModelType.Eac180ViewPort == overlayTarget.eacModelType)
|
||||
{
|
||||
|
||||
guiContent.text = "Offset Pos Left";
|
||||
Vector3 offsetPosLeft = EditorGUILayout.Vector3Field(guiContent, overlayTarget.offsetPosLeft);
|
||||
|
||||
|
||||
guiContent.text = "Offset Pos Right";
|
||||
Vector3 offsetPosRight = EditorGUILayout.Vector3Field(guiContent, overlayTarget.offsetPosRight);
|
||||
|
||||
|
||||
guiContent.text = "Offset Rot Left";
|
||||
Vector4 offsetRotLeft = EditorGUILayout.Vector4Field(guiContent, overlayTarget.offsetRotLeft);
|
||||
|
||||
|
||||
guiContent.text = "Offset Rot Right";
|
||||
Vector4 offsetRotRight = EditorGUILayout.Vector4Field(guiContent, overlayTarget.offsetRotRight);
|
||||
|
||||
overlayTarget.SetEACOffsetPosAndRot(offsetPosLeft, offsetPosRight, offsetRotLeft, offsetRotRight);
|
||||
}
|
||||
|
||||
guiContent.text = "Overlap Factor";
|
||||
overlayTarget.overlapFactor = EditorGUILayout.FloatField(guiContent, overlayTarget.overlapFactor);
|
||||
//overlayTarget.SetEACFactor(overlapFactor);
|
||||
}
|
||||
|
||||
guiContent.text = "Override Color Scale";
|
||||
overlayTarget.overrideColorScaleAndOffset = EditorGUILayout.Toggle(guiContent, overlayTarget.overrideColorScaleAndOffset);
|
||||
if (overlayTarget.overrideColorScaleAndOffset)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
|
||||
guiContent.text = "Scale";
|
||||
Vector4 colorScale = EditorGUILayout.Vector4Field(guiContent, overlayTarget.colorScale);
|
||||
|
||||
guiContent.text = "Offset";
|
||||
Vector4 colorOffset = EditorGUILayout.Vector4Field(guiContent, overlayTarget.colorOffset);
|
||||
overlayTarget.SetLayerColorScaleAndOffset(colorScale, colorOffset);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
guiContent.text = "isAlphaPremultiplied";
|
||||
overlayTarget.isPremultipliedAlpha = EditorGUILayout.Toggle(guiContent, overlayTarget.isPremultipliedAlpha);
|
||||
|
||||
//Super Resolution
|
||||
var superresolutionContent = new GUIContent();
|
||||
superresolutionContent.text = "Super Resolution";
|
||||
superresolutionContent.tooltip = "Single pass spatial aware upscaling technique.\n\nThis can't be used with Sharpening. \nAlso can't be used along with subsample feature due to unsupported texture format. \n\nThis effect won't work properly under low resolutions when Adaptive Resolution is also enabled.";
|
||||
overlayTarget.superResolution = EditorGUILayout.Toggle(superresolutionContent, overlayTarget.superResolution);
|
||||
|
||||
//Supersampling
|
||||
var supersamplingContent = new GUIContent();
|
||||
supersamplingContent.text = "Supersampling Mode";
|
||||
supersamplingContent.tooltip = "Normal: Normal Quality \n\nQuality: Higher Quality, higher GPU usage\n\nThis effect won't work properly under low resolutions when Adaptive Resolution or Sharpening is also enabled.\n\nThis can't be used with Super Resolution or Sharpening. It will be automatically disabled when you enable Super Resolution or Sharpening. \nAlso can't be used along with subsample feature due to unsupported texture format";
|
||||
|
||||
var supersamplingEnhanceContent = new GUIContent();
|
||||
supersamplingEnhanceContent.text = "Supersampling Enhance Mode";
|
||||
supersamplingEnhanceContent.tooltip = "None: Full screen will be super sampled\n\nFixed Foveated: Only the central fixation point will be sharpened\n\nSelf Adaptive: Only when contrast between the current pixel and the surrounding pixels exceeds a certain threshold will be sharpened.\n\nThis menu will be only enabled while Sharpening (either Normal or Quality) is enabled.";
|
||||
|
||||
if (overlayTarget.superResolution)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
overlayTarget.supersamplingMode = SuperSamplingMode.None;
|
||||
overlayTarget.supersamplingEnhance = SuperSamplingEnhance.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
overlayTarget.supersamplingMode = (SuperSamplingMode)EditorGUILayout.EnumPopup(supersamplingContent, overlayTarget.supersamplingMode);
|
||||
if (overlayTarget.supersamplingMode == SuperSamplingMode.None)
|
||||
{
|
||||
overlayTarget.supersamplingEnhance = SuperSamplingEnhance.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
overlayTarget.supersamplingEnhance = (SuperSamplingEnhance)EditorGUILayout.EnumPopup(supersamplingEnhanceContent, overlayTarget.supersamplingEnhance);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
if (overlayTarget.supersamplingMode != SuperSamplingMode.None)
|
||||
{
|
||||
if (overlayTarget.supersamplingMode == SuperSamplingMode.Normal)
|
||||
{
|
||||
overlayTarget.normalSupersampling = true;
|
||||
overlayTarget.qualitySupersampling = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.normalSupersampling = false;
|
||||
overlayTarget.qualitySupersampling = true;
|
||||
}
|
||||
|
||||
if (overlayTarget.supersamplingEnhance == SuperSamplingEnhance.FixedFoveated)
|
||||
{
|
||||
overlayTarget.fixedFoveatedSupersampling = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.fixedFoveatedSupersampling = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.normalSupersampling = false;
|
||||
overlayTarget.qualitySupersampling = false;
|
||||
overlayTarget.fixedFoveatedSupersampling = false;
|
||||
}
|
||||
|
||||
//Sharpening
|
||||
var sharpeningContent = new GUIContent();
|
||||
sharpeningContent.text = "Sharpening Mode";
|
||||
sharpeningContent.tooltip = "Normal: Normal Quality \n\nQuality: Higher Quality, higher GPU usage\n\nThis effect won't work properly under low resolutions when Adaptive Resolution is also enabled.\n\nThis can't be used with Super Resolution and Supersampling. It will be automatically disabled when you enable Super Resolution or Supersampling. \nAlso can't be used along with subsample feature due to unsupported texture format";
|
||||
var sharpeningEnhanceContent = new GUIContent();
|
||||
sharpeningEnhanceContent.text = "Sharpening Enhance Mode";
|
||||
sharpeningEnhanceContent.tooltip = "None: Full screen will be sharpened\n\nFixed Foveated: Only the central fixation point will be sharpened\n\nSelf Adaptive: Only when contrast between the current pixel and the surrounding pixels exceeds a certain threshold will be sharpened.\n\nThis menu will be only enabled while Sharpening (either Normal or Quality) is enabled.";
|
||||
|
||||
if (overlayTarget.superResolution || overlayTarget.normalSupersampling || overlayTarget.qualitySupersampling || overlayTarget.fixedFoveatedSupersampling)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
overlayTarget.sharpeningMode = SharpeningMode.None;
|
||||
overlayTarget.sharpeningEnhance = SharpeningEnhance.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
overlayTarget.sharpeningMode = (SharpeningMode)EditorGUILayout.EnumPopup(sharpeningContent, overlayTarget.sharpeningMode);
|
||||
if (overlayTarget.sharpeningMode == SharpeningMode.None)
|
||||
{
|
||||
overlayTarget.sharpeningEnhance = SharpeningEnhance.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
overlayTarget.sharpeningEnhance = (SharpeningEnhance)EditorGUILayout.EnumPopup(sharpeningEnhanceContent, overlayTarget.sharpeningEnhance);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
if (overlayTarget.sharpeningMode != SharpeningMode.None)
|
||||
{
|
||||
if (overlayTarget.sharpeningMode == SharpeningMode.Normal)
|
||||
{
|
||||
overlayTarget.normalSharpening = true;
|
||||
overlayTarget.qualitySharpening = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.normalSharpening = false;
|
||||
overlayTarget.qualitySharpening = true;
|
||||
}
|
||||
|
||||
if (overlayTarget.sharpeningEnhance == SharpeningEnhance.Both)
|
||||
{
|
||||
overlayTarget.fixedFoveatedSharpening = true;
|
||||
overlayTarget.selfAdaptiveSharpening = true;
|
||||
}
|
||||
else if (overlayTarget.sharpeningEnhance == SharpeningEnhance.FixedFoveated)
|
||||
{
|
||||
overlayTarget.fixedFoveatedSharpening = true;
|
||||
overlayTarget.selfAdaptiveSharpening = false;
|
||||
}
|
||||
else if (overlayTarget.sharpeningEnhance == SharpeningEnhance.SelfAdaptive)
|
||||
{
|
||||
overlayTarget.fixedFoveatedSharpening = false;
|
||||
overlayTarget.selfAdaptiveSharpening = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.fixedFoveatedSharpening = false;
|
||||
overlayTarget.selfAdaptiveSharpening = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayTarget.normalSharpening = false;
|
||||
overlayTarget.qualitySharpening = false;
|
||||
overlayTarget.fixedFoveatedSharpening = false;
|
||||
overlayTarget.selfAdaptiveSharpening = false;
|
||||
}
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
EditorUtility.SetDirty(overlayTarget);
|
||||
EditorUtility.SetDirty(overlayTarget);
|
||||
}
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEngine.SceneManagement.SceneManager.GetActiveScene());
|
||||
}
|
||||
}
|
||||
private Rect ClampRect(Rect rect)
|
||||
{
|
||||
rect.x = Mathf.Clamp01(rect.x);
|
||||
rect.y = Mathf.Clamp01(rect.y);
|
||||
rect.width = Mathf.Clamp01(rect.width);
|
||||
rect.height = Mathf.Clamp01(rect.height);
|
||||
return rect;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f8f0bf8ebd71f76449ace919f41e1a38
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,71 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
namespace Unity.XR.PXR.Editor
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public static class PXR_SDKBuildCheck
|
||||
{
|
||||
private static bool doNotShowAgain = false;
|
||||
|
||||
static PXR_SDKBuildCheck()
|
||||
{
|
||||
ObjectFactory.componentWasAdded += ComponentWasAdded;
|
||||
BuildPlayerWindow.RegisterBuildPlayerHandler(OnBuild);
|
||||
doNotShowAgain = GetDoNotShowBuildWarning();
|
||||
Debug.Log("PXRLog [Build Check]RegisterBuildPlayerHandler,Already Do not show: " + doNotShowAgain);
|
||||
}
|
||||
static void ComponentWasAdded(Component com)
|
||||
{
|
||||
if (com.name == "XR Rig")
|
||||
{
|
||||
if (!com.GetComponent<PXR_Manager>() && com.GetType() != typeof(Transform))
|
||||
{
|
||||
com.gameObject.AddComponent<PXR_Manager>();
|
||||
}
|
||||
}
|
||||
}
|
||||
static bool GetDoNotShowBuildWarning()
|
||||
{
|
||||
string path = PXR_SDKSettingEditor.assetPath + typeof(PXR_SDKSettingAsset).ToString() + ".asset";
|
||||
if (File.Exists(path))
|
||||
{
|
||||
PXR_SDKSettingAsset asset = AssetDatabase.LoadAssetAtPath<PXR_SDKSettingAsset>(path);
|
||||
if (asset != null)
|
||||
{
|
||||
return asset.doNotShowBuildWarning;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void OnBuild(BuildPlayerOptions options)
|
||||
{
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
NamedBuildTarget recommendedBuildTarget = NamedBuildTarget.Android;
|
||||
#else
|
||||
BuildTargetGroup recommendedBuildTarget = BuildTargetGroup.Android;
|
||||
#endif
|
||||
PlayerSettings.SetScriptingBackend(recommendedBuildTarget, ScriptingImplementation.IL2CPP);
|
||||
PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARM64;
|
||||
BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf7c5670489d91e439f9b568da17cfc3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
public class PXR_SDKSettingAsset : ScriptableObject
|
||||
{
|
||||
public bool ignoreSDKSetting = false;
|
||||
public bool doNotShowBuildWarning = false;
|
||||
public bool appIDChecked = false;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e08befb1867d8945b4f1ddac43e65c5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,896 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using UnityEditor.XR.Management;
|
||||
using UnityEngine.XR.Management;
|
||||
using UnityEditor.XR.Management.Metadata;
|
||||
using UnityEditor.Build;
|
||||
|
||||
namespace Unity.XR.PXR.Editor
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public class PXR_SDKSettingEditor : EditorWindow
|
||||
{
|
||||
public static string assetPath = "Assets/Resources/";
|
||||
private const string titleName = "PICO Integration SDK";
|
||||
private const string windowName = titleName + "Window";
|
||||
private static PXR_SDKSettingEditor instance;
|
||||
private static PXR_EditorStyles _styles;
|
||||
public event Action<Response> WhenResponded = delegate { };
|
||||
private const string PICO_ICON_NAME = "PICO developer.png";
|
||||
private Vector2 scrollPosition = Vector2.zero;
|
||||
private const BuildTarget recommendedBuildTarget = BuildTarget.Android;
|
||||
|
||||
public enum Response
|
||||
{
|
||||
Configs,
|
||||
Tools,
|
||||
Samples,
|
||||
About,
|
||||
}
|
||||
|
||||
private Dictionary<Response, bool> buttonClickedStates = new Dictionary<Response, bool>()
|
||||
{
|
||||
{ Response.Configs, false },
|
||||
{ Response.Tools, false },
|
||||
{ Response.Samples, false },
|
||||
{ Response.About, false }
|
||||
};
|
||||
|
||||
Action openProjectValidationAction = () =>
|
||||
{
|
||||
SettingsService.OpenProjectSettings("Project/XR Plug-in Management/Project Validation");
|
||||
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Tools_ProjectValidation_Open);
|
||||
};
|
||||
|
||||
Action applyARM64Action = () => {
|
||||
PlayerSettings.SetScriptingBackend(NamedBuildTarget.Android, ScriptingImplementation.IL2CPP);
|
||||
PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARM64;
|
||||
};
|
||||
|
||||
Action applyMinAndroidAPIAction = () =>
|
||||
{
|
||||
PlayerSettings.Android.minSdkVersion = PXR_Utils.minSdkVersionInEditor;
|
||||
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Configs_RequiredAndroidSdkVersionsApplied);
|
||||
};
|
||||
|
||||
Action applyPICOXRPluginAction = () =>
|
||||
{
|
||||
SettingsService.OpenProjectSettings("Project/XR Plug-in Management");
|
||||
|
||||
var buildTargetSettings = AssetDatabase.FindAssets("t:XRGeneralSettingsPerBuildTarget")
|
||||
.Select(guid => AssetDatabase.LoadAssetAtPath<XRGeneralSettingsPerBuildTarget>(AssetDatabase.GUIDToAssetPath(guid)))
|
||||
.FirstOrDefault();
|
||||
|
||||
if (buildTargetSettings == null)
|
||||
{
|
||||
buildTargetSettings = ScriptableObject.CreateInstance<XRGeneralSettingsPerBuildTarget>();
|
||||
AssetDatabase.CreateAsset(buildTargetSettings, "Assets/XRGeneralSettingsPerBuildTarget.asset");
|
||||
Debug.Log($"PXR_Loader XRGeneralSettingsPerBuildTarget");
|
||||
}
|
||||
|
||||
var generalSettings = buildTargetSettings.SettingsForBuildTarget(BuildTargetGroup.Android);
|
||||
if (generalSettings == null)
|
||||
{
|
||||
generalSettings = ScriptableObject.CreateInstance<XRGeneralSettings>();
|
||||
AssetDatabase.AddObjectToAsset(generalSettings, buildTargetSettings);
|
||||
buildTargetSettings.SetSettingsForBuildTarget(BuildTargetGroup.Android, generalSettings);
|
||||
|
||||
var managerSettings = ScriptableObject.CreateInstance<XRManagerSettings>();
|
||||
AssetDatabase.AddObjectToAsset(managerSettings, buildTargetSettings);
|
||||
generalSettings.Manager = managerSettings;
|
||||
|
||||
EditorUtility.SetDirty(buildTargetSettings);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
if (generalSettings.Manager)
|
||||
{
|
||||
while (generalSettings.Manager.activeLoaders.Count > 0)
|
||||
{
|
||||
var loaderName = generalSettings.Manager.activeLoaders[0].GetType().FullName;
|
||||
XRPackageMetadataStore.RemoveLoader(generalSettings.Manager, loaderName, BuildTargetGroup.Android);
|
||||
}
|
||||
|
||||
bool success = XRPackageMetadataStore.AssignLoader(generalSettings.Manager, "PXR_Loader", BuildTargetGroup.Android);
|
||||
}
|
||||
|
||||
PXR_Utils.UpdateSDKSymbols();
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Configs_RequiredPICOXRPluginApplied);
|
||||
};
|
||||
Action applyBuildTargetAction = () =>
|
||||
{
|
||||
EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Android, recommendedBuildTarget);
|
||||
EditorUserBuildSettings.selectedBuildTargetGroup = BuildTargetGroup.Android;
|
||||
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Configs_RequiredBuildTargetAndroidApplied);
|
||||
};
|
||||
|
||||
|
||||
[MenuItem("PICO/Portal", false, 0)]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = GetWindow<PXR_SDKSettingEditor>();
|
||||
instance.Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
instance.Focus();
|
||||
}
|
||||
string version = "_UnityXR_" + PXR_Plugin.System.UPxr_GetSDKVersion() + "_" + Application.unityVersion;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Enter + version);
|
||||
}
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
private static void InitializeOnLoad()
|
||||
{
|
||||
if (!PXR_ProjectSetting.GetProjectConfig().portalInited)
|
||||
{
|
||||
EditorApplication.delayCall += () =>
|
||||
{
|
||||
EditorApplication.update += UpdateOnce;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateOnce()
|
||||
{
|
||||
EditorApplication.update -= UpdateOnce;
|
||||
ShowWindow();
|
||||
PXR_ProjectSetting.GetProjectConfig().portalInited = true;
|
||||
PXR_ProjectSetting.SaveAssets();
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_styles ??= new PXR_EditorStyles();
|
||||
titleContent = new GUIContent(titleName);
|
||||
minSize = new Vector2(1080, 640);
|
||||
maxSize = minSize + new Vector2(2, 2);
|
||||
EditorApplication.delayCall += () => maxSize = new Vector2(4000, 4000);
|
||||
|
||||
buttonClickedStates[Response.Configs] = true;
|
||||
}
|
||||
private void OnEnable()
|
||||
{
|
||||
_styles ??= new PXR_EditorStyles();
|
||||
buttonClickedStates[(Response)PXR_ProjectSetting.GetProjectConfig().portalFirstSelected] = true;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
instance = null;
|
||||
}
|
||||
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
if (EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
using (new EditorGUILayout.VerticalScope())
|
||||
{
|
||||
EditorGUILayout.Space(20);
|
||||
DrawTitle(titleName);
|
||||
EditorGUILayout.Space(10);
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
DrawHorizontalLine(_styles.colorLine, 2);
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
GUILayout.Space(30);
|
||||
DrawLeftButton();
|
||||
GUILayout.Space(30);
|
||||
DrawVerticalLine(_styles.colorLine, 2);
|
||||
GUILayout.Space(30);
|
||||
|
||||
Rect windowRect = position;
|
||||
float xOffset = 30 + 200 + 30;
|
||||
float width = windowRect.width - xOffset;
|
||||
float topSpaceUsed = 30 + _styles.HeaderText.fixedHeight + 30;
|
||||
float height = windowRect.height - topSpaceUsed - 30 - 2;
|
||||
|
||||
_styles.BackgroundColor.fixedWidth = width;
|
||||
_styles.BackgroundColor.fixedHeight = height;
|
||||
using (new GUILayout.VerticalScope(_styles.BackgroundColor))
|
||||
{
|
||||
if (buttonClickedStates[Response.Configs])
|
||||
{
|
||||
scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, true);
|
||||
GUILayout.Space(30);
|
||||
using (new EditorGUILayout.VerticalScope())
|
||||
{
|
||||
string title = "Information";
|
||||
GUILayout.Label(title, _styles.BigWhiteTitleStyle, GUILayout.ExpandWidth(true));
|
||||
string bodyContent = "Supported Unity Version: Unity 2020.3.21 and above.";
|
||||
EditorGUILayout.LabelField(bodyContent, _styles.ContentText);
|
||||
|
||||
GUILayout.Space(30);
|
||||
title = "Configuration";
|
||||
GUILayout.Label(title, _styles.BigWhiteTitleStyle, GUILayout.ExpandWidth(true));
|
||||
|
||||
|
||||
string strinfo = $"Required: Build Target = {recommendedBuildTarget}";
|
||||
bool appliedBuildTarget = EditorUserBuildSettings.activeBuildTarget == recommendedBuildTarget;
|
||||
EditorConfigurations(strinfo, appliedBuildTarget, applyBuildTargetAction);
|
||||
|
||||
strinfo = $"Required: AndroidSdkVersions = {PXR_Utils.minSdkVersionInEditor}";
|
||||
bool appliedAdroidSdkVersions = PlayerSettings.Android.minSdkVersion == PXR_Utils.minSdkVersionInEditor;
|
||||
EditorConfigurations(strinfo, appliedAdroidSdkVersions, applyMinAndroidAPIAction);
|
||||
|
||||
strinfo = $"Required: ARM64 and IL2CPP scripting must be enabled";
|
||||
bool appliedARM64 = PlayerSettings.Android.targetArchitectures == AndroidArchitecture.ARM64 &&
|
||||
PlayerSettings.GetScriptingBackend(BuildTargetGroup.Android) == ScriptingImplementation.IL2CPP;
|
||||
EditorConfigurations(strinfo, appliedARM64, applyARM64Action);
|
||||
|
||||
strinfo = "Required: PICO XR plugin must be enabled";
|
||||
EditorConfigurations(strinfo, PXR_Utils.IsPXRPluginEnabled(), applyPICOXRPluginAction);
|
||||
|
||||
bool applied = appliedBuildTarget && appliedAdroidSdkVersions && appliedARM64 && PXR_Utils.IsPXRPluginEnabled();
|
||||
if (!applied)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
bodyContent = "For one-click configuration, you can click 'Apply' one by one or use 'Apply All'.";
|
||||
EditorGUILayout.LabelField(bodyContent, _styles.ContentText, GUILayout.Width(673), GUILayout.ExpandHeight(true));
|
||||
|
||||
if (GUILayout.Button("Apply All", GUILayout.ExpandWidth(false), GUILayout.Width(80), GUILayout.Height(30)))
|
||||
{
|
||||
applyBuildTargetAction.Invoke();
|
||||
applyMinAndroidAPIAction.Invoke();
|
||||
applyARM64Action.Invoke();
|
||||
applyPICOXRPluginAction.Invoke();
|
||||
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Configs_ToApplyAllApplied);
|
||||
}
|
||||
|
||||
var buttonRectToApplyAll = GUILayoutUtility.GetLastRect();
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
EditorGUIUtility.AddCursorRect(buttonRectToApplyAll, MouseCursor.Link);
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUILayout.Space(20);
|
||||
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
bodyContent = "For more configuration items, open Project Validation.";
|
||||
EditorGUILayout.LabelField(bodyContent, _styles.ContentText, GUILayout.Width(673), GUILayout.ExpandHeight(true));
|
||||
if (GUILayout.Button("Open", GUILayout.Width(80), GUILayout.Height(30)))
|
||||
{
|
||||
SettingsService.OpenProjectSettings("Project/XR Plug-in Management/Project Validation");
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Configs_ProjectValidation);
|
||||
}
|
||||
var buttonRectProjectValidation = GUILayoutUtility.GetLastRect();
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
EditorGUIUtility.AddCursorRect(buttonRectProjectValidation, MouseCursor.Link);
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
|
||||
GUILayout.Space(30);
|
||||
title = "PICO XR Project Setting";
|
||||
GUILayout.Label(title, _styles.BigWhiteTitleStyle, GUILayout.ExpandWidth(true));
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
bodyContent = $"SDK Settings for turning on and off features. You can locate it at this filepath: {assetPath}PXR_ProjectSetting.asset.";
|
||||
EditorGUILayout.LabelField(bodyContent, _styles.ContentText, GUILayout.Width(673), GUILayout.ExpandHeight(true));
|
||||
|
||||
if (GUILayout.Button("Open", GUILayout.ExpandWidth(false), GUILayout.Width(80), GUILayout.Height(30)))
|
||||
{
|
||||
PXR_ProjectSetting asset;
|
||||
string path = assetPath + "PXR_ProjectSetting.asset";
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
asset = new PXR_ProjectSetting();
|
||||
ScriptableObjectUtility.CreateAsset<PXR_ProjectSetting>(asset, assetPath);
|
||||
}
|
||||
|
||||
asset = AssetDatabase.LoadAssetAtPath<PXR_ProjectSetting>(path);
|
||||
if (asset != null)
|
||||
{
|
||||
AssetDatabase.OpenAsset(asset);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Asset not found at path: " + assetPath);
|
||||
}
|
||||
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Configs_OpenPICOXRProjectSetting);
|
||||
}
|
||||
var buttonRectProjectSetting = GUILayoutUtility.GetLastRect();
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
EditorGUIUtility.AddCursorRect(buttonRectProjectSetting, MouseCursor.Link);
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
}
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
else if (buttonClickedStates[Response.Tools])
|
||||
{
|
||||
scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, true);
|
||||
GUILayout.Space(30);
|
||||
using (new EditorGUILayout.VerticalScope())
|
||||
{
|
||||
string title = "Unity Editor Tools and Developer Tools";
|
||||
GUILayout.Label(title, _styles.BigWhiteTitleStyle, GUILayout.ExpandWidth(true));
|
||||
|
||||
title = "Project Validation";
|
||||
string links = "https://developer.picoxr.com/document/unity/project-validation/";
|
||||
GUIContent bodyContent = new GUIContent("Project Validation can display the validation rules requiredby the installed XR package. For any validation rules that are not properly set up, you can use thhis feature to automatically fix them with a single click.");
|
||||
DrawTwoRowLayout(title, bodyContent, links, openProjectValidationAction);
|
||||
|
||||
title = "PICO Building Blocks";
|
||||
links = "https://developer.picoxr.com/document/unity/pico-building-blocks/";
|
||||
bodyContent = new GUIContent("The PICO Building Block system allows you to set up features, including those in the SDK and Unity Engine, with a single click.");
|
||||
DrawTwoRowLayout(title, bodyContent, links);
|
||||
|
||||
title = "PICO XR Toolkit-MR";
|
||||
links = "https://developer.picoxr.com/document/unity/sense-pack-overview/";
|
||||
bodyContent = new GUIContent("The PICO XR Toolkit-MR part is a set of tools included in the SensePack on top of the Mixed Reality API. It is used to perform common operations when building spatial perception applications.");
|
||||
DrawTwoRowLayout(title, bodyContent, links);
|
||||
|
||||
title = "XR Profiling Toolkit";
|
||||
links = "https://github.com/Pico-Developer/XR-Profiling-Toolkit";
|
||||
bodyContent = new GUIContent("An automated and customizable graphics profiling tool for evaluating the performance of XR applications on cross-vendor headsets.");
|
||||
DrawTwoRowLayout(title, bodyContent, links);
|
||||
|
||||
title = "PICO Developer Center";
|
||||
links = "https://developer.picoxr.com/resources/#pdc";
|
||||
bodyContent = new GUIContent("PICO Developer Center (referred to as PDC tools below) is a developer service platform that integrates essential tools like the ADB command debugging tool and real-time preview tool. You can efficiently manage, develop, and debug your apps using the PDC tool.");
|
||||
DrawTwoRowLayout(title, bodyContent, links);
|
||||
|
||||
title = "Emulator";
|
||||
links = "https://developer.picoxr.com/resources/#emulator";
|
||||
bodyContent = new GUIContent("You can install your app on PICO Emulator and run it, so as to preview how your app performs.");
|
||||
DrawTwoRowLayout(title, bodyContent, links);
|
||||
|
||||
title = "More Developer Tools";
|
||||
links = "https://developer.picoxr.com/document/unity/developer-tools-overview/";
|
||||
bodyContent = new GUIContent("PICO provides a range of developer tools covering app debugging, performance monitoring, haptic editing, and more.See the Developer Tools Documentationpage to learn more details.");
|
||||
DrawTwoRowLayout(title, bodyContent, links);
|
||||
}
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
else if (buttonClickedStates[Response.Samples])
|
||||
{
|
||||
scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, true);
|
||||
GUILayout.Space(30);
|
||||
using (new EditorGUILayout.VerticalScope())
|
||||
{
|
||||
string title = "PICO Unity Integration SDK Samples";
|
||||
GUILayout.Label(title, _styles.BigWhiteTitleStyle, GUILayout.ExpandWidth(true));
|
||||
|
||||
GUILayout.Space(30);
|
||||
string bodyContent = "Besides the Samples you can import through the Unity Paackage Manager interface, PICO provides comprehensive sample projects that coverthe core features of the Unity Integration SDK on GitHub.";
|
||||
EditorGUILayout.LabelField(bodyContent, _styles.ContentText);
|
||||
|
||||
title = "Mixed Reality Sample";
|
||||
string gitHubLink = "https://github.com/Pico-Developer/MRSample-Unity";
|
||||
string documentationLink = "https://developer.picoxr.com/document/unity/mixed-reality-sample/";
|
||||
DrawSDKSampleLayout(title, documentationLink, gitHubLink);
|
||||
|
||||
title = "Interaction Sample";
|
||||
gitHubLink = "https://github.com/Pico-Developer/InteractionSample-Unity";
|
||||
documentationLink = "https://developer.picoxr.com/document/unity/y3lpmdhw/";
|
||||
DrawSDKSampleLayout(title, documentationLink, gitHubLink);
|
||||
|
||||
title = "Motion Tracker Sample";
|
||||
gitHubLink = "https://github.com/Pico-Developer/PICOMotionTrackerSample-Unity";
|
||||
documentationLink = "https://developer.picoxr.com/document/unity/6bona7fv/";
|
||||
DrawSDKSampleLayout(title, documentationLink, gitHubLink);
|
||||
|
||||
title = "Platform Services Sample";
|
||||
gitHubLink = "https://github.com/Pico-Developer/PlatformSample-Unity";
|
||||
documentationLink = "https://developer.picoxr.com/document/unity/simple-demo/";
|
||||
DrawSDKSampleLayout(title, documentationLink, gitHubLink);
|
||||
|
||||
title = "Spatial Audio Sample";
|
||||
gitHubLink = "https://github.com/Pico-Developer/SpatialAudioSample-Unity";
|
||||
documentationLink = "https://developer.picoxr.com/document/unity/spatial-audio-sample/";
|
||||
DrawSDKSampleLayout(title, documentationLink, gitHubLink);
|
||||
|
||||
title = "AR Foundation Sample";
|
||||
gitHubLink = "https://github.com/Pico-Developer/PICOARFoundationSamples-Unity";
|
||||
documentationLink = "https://developer.picoxr.com/document/unity/ar-foundation-for-pico-unity-integration-sdk/";
|
||||
DrawSDKSampleLayout(title, documentationLink, gitHubLink);
|
||||
|
||||
title = "Adaptive Resolution Sample";
|
||||
gitHubLink = "https://github.com/Pico-Developer/AdaptiveResolutionSample-Unity";
|
||||
documentationLink = "https://developer.picoxr.com/document/unity/adaptive-resolution-demo/";
|
||||
DrawSDKSampleLayout(title, documentationLink, gitHubLink);
|
||||
|
||||
title = "Toon World";
|
||||
gitHubLink = "https://github.com/Pico-Developer/ToonSample-Unity";
|
||||
documentationLink = "https://developer.picoxr.com/document/unity/toon-world/";
|
||||
DrawSDKSampleLayout(title, documentationLink, gitHubLink);
|
||||
|
||||
title = "MicroWar";
|
||||
gitHubLink = "https://github.com/picoxr/MicroWar";
|
||||
documentationLink = "https://developer.picoxr.com/document/unity/micro-war/";
|
||||
DrawSDKSampleLayout(title, documentationLink, gitHubLink);
|
||||
|
||||
title = "PICO Avatar Sample";
|
||||
gitHubLink = "https://github.com/Pico-Developer/PICO-Avatar-SDK-Unity";
|
||||
DrawSDKSampleLayout(title, null, gitHubLink);
|
||||
|
||||
title = "URP Fork";
|
||||
gitHubLink = "https://github.com/Pico-Developer/PICO-URP-Fork";
|
||||
DrawSDKSampleLayout(title, null, gitHubLink);
|
||||
}
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
else if (buttonClickedStates[Response.About])
|
||||
{
|
||||
string title = "About the SDK";
|
||||
GUIContent bodyContent = new GUIContent("PICO's official Unity package for developing applications for PICO XR devices.");
|
||||
DrawTwoRowLayout(title, bodyContent);
|
||||
|
||||
title = "Features";
|
||||
bodyContent = new GUIContent("The SDK provides features covering rendering, input and interaction, mixed reality, spatial audio, motion tracker, platform services, and enterprise features, etc.");
|
||||
DrawTwoRowLayout(title, bodyContent);
|
||||
|
||||
title = "Documentation";
|
||||
bodyContent = new GUIContent("Please visit the following page on PICO Developer Website for the latest documentation and samples:");
|
||||
DrawTwoRowLayout(title, bodyContent);
|
||||
string link = "https://developer.picoxr.com/document/unity";
|
||||
if (GUILayout.Button(link, _styles.SmallBlueLinkStyle, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
Application.OpenURL(link);
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_About_Documentation);
|
||||
}
|
||||
var buttonRectDocumentation = GUILayoutUtility.GetLastRect();
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
EditorGUIUtility.AddCursorRect(buttonRectDocumentation, MouseCursor.Link);
|
||||
}
|
||||
|
||||
title = "Installation";
|
||||
bodyContent = new GUIContent("We recommend using 'add package from git URL' to add the SDK from the PICO Developer GitHub:");
|
||||
DrawTwoRowLayout(title, bodyContent);
|
||||
|
||||
link = "https://github.com/Pico-Developer/PICO-Unity-Integration-SDK";
|
||||
if (GUILayout.Button(link, _styles.SmallBlueLinkStyle, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
Application.OpenURL(link);
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_About_Installation);
|
||||
}
|
||||
|
||||
var buttonRectInstallation = GUILayoutUtility.GetLastRect();
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
EditorGUIUtility.AddCursorRect(buttonRectInstallation, MouseCursor.Link);
|
||||
}
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawTitle(string title)
|
||||
{
|
||||
using (new GUILayout.HorizontalScope())
|
||||
{
|
||||
EditorGUILayout.LabelField(title, _styles.HeaderText, GUILayout.ExpandWidth(true));
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.LabelField("Version " + PXR_Plugin.System.UPxr_GetSDKVersion(), _styles.VersionText, GUILayout.ExpandWidth(true));
|
||||
|
||||
string iconPath = Path.Combine(PXR_Utils.sdkPackageName, assetPath, PICO_ICON_NAME);
|
||||
var content = EditorGUIUtility.TrIconContent(iconPath, "PICO Logo");
|
||||
EditorGUILayout.LabelField(content, _styles.IconStyle,
|
||||
GUILayout.Width(_styles.IconStyle.fixedWidth),
|
||||
GUILayout.Height(_styles.IconStyle.fixedHeight), GUILayout.ExpandWidth(true));
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawTwoRowLayout(string title, GUIContent bodyContent, string link = null, System.Action buttonAction = null, string button = null)
|
||||
{
|
||||
GUILayout.Space(30);
|
||||
using (new EditorGUILayout.VerticalScope())
|
||||
{
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
GUILayout.Label(title, _styles.BigWhiteTitleStyle, GUILayout.ExpandWidth(true));
|
||||
if (link != null)
|
||||
{
|
||||
if (GUILayout.Button("Documentation", _styles.SmallBlueLinkStyle, GUILayout.Width(200)))
|
||||
{
|
||||
Application.OpenURL(link);
|
||||
|
||||
if (title == "Project Validation")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Tools_ProjectValidation_Documentation);
|
||||
}
|
||||
else if (title == "PICO Building Blocks")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Tools_BuildingBlocks);
|
||||
}
|
||||
else if (title == "PICO XR Toolkit-MR")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Tools_PICOXRToolkitMR);
|
||||
}
|
||||
else if (title == "XR Profiling Toolkit")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Tools_XRProfilingToolkit);
|
||||
}
|
||||
else if (title == "PICO Developer Center")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Tools_PICODeveloperCenter);
|
||||
}
|
||||
else if (title == "Emulator")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Tools_Emulator);
|
||||
}
|
||||
else if (title == "More Developer Tools")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Tools_MoreDeveloperTools);
|
||||
}
|
||||
}
|
||||
|
||||
var buttonRect = GUILayoutUtility.GetLastRect();
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
EditorGUIUtility.AddCursorRect(buttonRect, MouseCursor.Link);
|
||||
}
|
||||
}
|
||||
if (buttonAction != null)
|
||||
{
|
||||
string buttonText = button != null ? button : "Open " + title;
|
||||
if (GUILayout.Button(buttonText, _styles.ButtonToOpen, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
buttonAction?.Invoke();
|
||||
}
|
||||
|
||||
var buttonRect = GUILayoutUtility.GetLastRect();
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
EditorGUIUtility.AddCursorRect(buttonRect, MouseCursor.Link);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIStyle Box = new GUIStyle()
|
||||
{
|
||||
fixedWidth = 250,
|
||||
};
|
||||
GUILayout.Box("", Box, GUILayout.ExpandWidth(false));
|
||||
}
|
||||
|
||||
GUILayout.Space(30);
|
||||
}
|
||||
EditorGUILayout.Space(10);
|
||||
if (bodyContent != null)
|
||||
{
|
||||
EditorGUILayout.LabelField(bodyContent, _styles.ContentText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawHorizontalLine(Color color, int thickness)
|
||||
{
|
||||
Rect rect = EditorGUILayout.GetControlRect(false, thickness);
|
||||
EditorGUI.DrawRect(rect, color);
|
||||
}
|
||||
private void DrawVerticalLine(Color color, int thickness)
|
||||
{
|
||||
Rect rect = new Rect(220, 122, thickness, Screen.height);
|
||||
EditorGUI.DrawRect(rect, color);
|
||||
}
|
||||
|
||||
private void DrawLeftButton()
|
||||
{
|
||||
using (new EditorGUILayout.VerticalScope())
|
||||
{
|
||||
EditorGUILayout.Space(30);
|
||||
|
||||
var buttons = new[] {
|
||||
("<size=18>Configs</size>", Response.Configs),
|
||||
("<size=18>Tools</size>", Response.Tools),
|
||||
("<size=18>Samples</size>", Response.Samples),
|
||||
("<size=18>About</size>", Response.About)
|
||||
};
|
||||
|
||||
foreach (var (btnText, response) in buttons)
|
||||
{
|
||||
bool isClicked = GUILayout.Button(btnText,
|
||||
buttonClickedStates[response] ? _styles.ButtonSelected : _styles.Button,
|
||||
GUILayout.ExpandHeight(false));
|
||||
|
||||
var rect = GUILayoutUtility.GetLastRect();
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
EditorGUIUtility.AddCursorRect(rect, MouseCursor.Link);
|
||||
}
|
||||
|
||||
if (isClicked)
|
||||
{
|
||||
ClickedButton(response);
|
||||
}
|
||||
EditorGUILayout.Space(30);
|
||||
}
|
||||
}
|
||||
|
||||
float windowHeight = position.height;
|
||||
float toggleY = windowHeight - EditorGUIUtility.singleLineHeight - 20;
|
||||
float toggleX = 20;
|
||||
float toggleWidth = position.width - 30;
|
||||
|
||||
Rect toggleRect = new Rect(toggleX, toggleY, toggleWidth, EditorGUIUtility.singleLineHeight);
|
||||
|
||||
var guiContent = new GUIContent();
|
||||
guiContent.text = "Allow usage data collection";
|
||||
guiContent.tooltip = "To improve service quality, we will collect non-identifiable behavioral data (such as engine or sdk version, the status of sdk and engine capabilities being enabled, etc.). You can disable this at any time.";
|
||||
PXR_ProjectSetting.GetProjectConfig().isDataCollectionDisabled = !EditorGUI.ToggleLeft(toggleRect, guiContent, !PXR_ProjectSetting.GetProjectConfig().isDataCollectionDisabled);
|
||||
|
||||
if (toggleRect.Contains(Event.current.mousePosition))
|
||||
{
|
||||
EditorGUIUtility.AddCursorRect(toggleRect, MouseCursor.Link);
|
||||
}
|
||||
}
|
||||
|
||||
private void ClickedButton(Response responseT)
|
||||
{
|
||||
var keys = buttonClickedStates.Keys.ToArray();
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
var response = keys[i];
|
||||
buttonClickedStates[response] = responseT == response;
|
||||
}
|
||||
WhenResponded.Invoke(responseT);
|
||||
switch (responseT)
|
||||
{
|
||||
case Response.Configs:
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Configs_Open);
|
||||
break;
|
||||
case Response.Tools:
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Tools_Open);
|
||||
break;
|
||||
case Response.Samples:
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Sample_Open);
|
||||
break;
|
||||
case Response.About:
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_About_Open);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSDKSampleLayout(string title, string documentationLink, string gitHubLink)
|
||||
{
|
||||
GUILayout.Space(20);
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
|
||||
_styles.BigWhiteTitleStyle.fontStyle = FontStyle.Bold;
|
||||
GUILayout.Label(title, _styles.BigWhiteTitleStyle, GUILayout.ExpandWidth(false));
|
||||
|
||||
if (documentationLink != null)
|
||||
{
|
||||
GUILayout.Label(" | ", _styles.BigWhiteTitleStyle, GUILayout.Width(20));
|
||||
if (GUILayout.Button("Documentation", _styles.SmallBlueLinkStyle, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
Application.OpenURL(documentationLink);
|
||||
|
||||
if (title == "Mixed Reality Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_MixedRealitySample_Documentation);
|
||||
}
|
||||
else if (title == "Interaction Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_InteractionSample_Documentation);
|
||||
}
|
||||
else if (title == "Motion Tracker Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_MotionTrackerSample_Documentation);
|
||||
}
|
||||
else if (title == "Platform Services Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_PlatformServicesSample_Documentation);
|
||||
}
|
||||
else if (title == "Spatial Audio Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_SpatialAudioSample_Documentation);
|
||||
}
|
||||
else if (title == "AR Foundation Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_ARFoundationSample_Documentation);
|
||||
}
|
||||
else if (title == "Adaptive Resolution Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_AdaptiveResolutionSample_Documentation);
|
||||
}
|
||||
else if (title == "Toon World")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_ToonWorldSample_Documentation);
|
||||
}
|
||||
else if (title == "MicroWar")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_MicroWarSample_Documentation);
|
||||
}
|
||||
else if (title == "PICO Avatar Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_PICOAvatarSample_Documentation);
|
||||
}
|
||||
else if (title == "URP Fork")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_URPFork_Documentation);
|
||||
}
|
||||
}
|
||||
|
||||
var buttonRectDoc = GUILayoutUtility.GetLastRect();
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
EditorGUIUtility.AddCursorRect(buttonRectDoc, MouseCursor.Link);
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.Label(" | ", _styles.BigWhiteTitleStyle, GUILayout.Width(20));
|
||||
if (GUILayout.Button("GitHub", _styles.SmallBlueLinkStyle, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
Application.OpenURL(gitHubLink);
|
||||
|
||||
if (title == "Mixed Reality Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_MixedRealitySample_GitHub);
|
||||
}
|
||||
else if (title == "Interaction Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_InteractionSample_GitHub);
|
||||
}
|
||||
else if (title == "Motion Tracker Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_MotionTrackerSample_GitHub);
|
||||
}
|
||||
else if (title == "Platform Services Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_PlatformServicesSample_GitHub);
|
||||
}
|
||||
else if (title == "Spatial Audio Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_SpatialAudioSample_GitHub);
|
||||
}
|
||||
else if (title == "AR Foundation Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_ARFoundationSample_GitHub);
|
||||
}
|
||||
else if (title == "Adaptive Resolution Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_AdaptiveResolutionSample_GitHub);
|
||||
}
|
||||
else if (title == "Toon World")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_ToonWorldSample_GitHub);
|
||||
}
|
||||
else if (title == "MicroWar")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_MicroWarSample_GitHub);
|
||||
}
|
||||
else if (title == "PICO Avatar Sample")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_PICOAvatarSample_GitHub);
|
||||
}
|
||||
else if (title == "URP Fork")
|
||||
{
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strPortal, PXR_AppLog.strPortal_Samples_URPFork_GitHub);
|
||||
}
|
||||
}
|
||||
|
||||
var buttonRectGitHub = GUILayoutUtility.GetLastRect();
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
EditorGUIUtility.AddCursorRect(buttonRectGitHub, MouseCursor.Link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EditorConfigurations(string strConfiguration, bool enable, Action buttonAction)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
var iconStyle = new GUIStyle
|
||||
{
|
||||
fixedWidth = 30,
|
||||
stretchHeight = true,
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
};
|
||||
if (enable)
|
||||
{
|
||||
GUI.color = Color.green;
|
||||
EditorGUILayout.LabelField(EditorGUIUtility.IconContent("FilterSelectedOnly"), iconStyle, GUILayout.Width(30), GUILayout.ExpandHeight(true));
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.color = Color.yellow;
|
||||
EditorGUILayout.LabelField(EditorGUIUtility.IconContent("console.warnicon"), iconStyle, GUILayout.Width(30), GUILayout.ExpandHeight(true));
|
||||
}
|
||||
GUI.color = Color.white;
|
||||
EditorGUILayout.LabelField(strConfiguration, _styles.ContentText, GUILayout.Width(640), GUILayout.ExpandHeight(true));
|
||||
_styles.ContentText.normal.textColor = Color.white;
|
||||
|
||||
GUIStyle styleApplied = new GUIStyle();
|
||||
styleApplied.fontSize = 14;
|
||||
styleApplied.fixedWidth = 80;
|
||||
styleApplied.fixedHeight = 30;
|
||||
styleApplied.padding = new RectOffset(4, 4, 4, 4);
|
||||
styleApplied.alignment = TextAnchor.MiddleCenter;
|
||||
if (enable)
|
||||
{
|
||||
styleApplied.normal.textColor = Color.green;
|
||||
GUILayout.Label("Applied", styleApplied);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GUILayout.Button("Apply", GUILayout.ExpandWidth(false), GUILayout.Width(80), GUILayout.Height(30)))
|
||||
{
|
||||
buttonAction?.Invoke();
|
||||
}
|
||||
|
||||
var buttonRectToApply = GUILayoutUtility.GetLastRect();
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
EditorGUIUtility.AddCursorRect(buttonRectToApply, MouseCursor.Link);
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private void CloseWindow()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ScriptableObjectUtility
|
||||
{
|
||||
public static void CreateAsset<T>(T classdata, string path) where T : ScriptableObject
|
||||
{
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath(path + typeof(T).ToString() + ".asset");
|
||||
|
||||
AssetDatabase.CreateAsset(classdata, assetPathAndName);
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bda4ef25984fa08429a6ed3e06f78303
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,192 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Linq;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.Rendering;
|
||||
#if AR_FOUNDATION_5 || AR_FOUNDATION_6
|
||||
using UnityEngine.XR.ARFoundation;
|
||||
#endif
|
||||
|
||||
namespace Unity.XR.PXR.Editor
|
||||
{
|
||||
[CustomEditor(typeof(PXR_Settings))]
|
||||
public class PXR_SettingsEditor : UnityEditor.Editor
|
||||
{
|
||||
private const string StereoRenderingModeAndroid = "stereoRenderingModeAndroid";
|
||||
private const string SystemDisplayFrequency = "systemDisplayFrequency";
|
||||
private const string OptimizeBufferDiscards = "optimizeBufferDiscards";
|
||||
private const string SystemSplashScreen = "systemSplashScreen";
|
||||
|
||||
static GUIContent guiStereoRenderingMode = EditorGUIUtility.TrTextContent("Stereo Rendering Mode");
|
||||
static GUIContent guiDisplayFrequency = EditorGUIUtility.TrTextContent("Display Refresh Rates");
|
||||
private static GUIContent guiOptimizeBuffer = EditorGUIUtility.TrTextContent("Optimize Buffer Discards(Vulkan)");
|
||||
static GUIContent guiSystemSplashScreen = EditorGUIUtility.TrTextContent("System Splash Screen");
|
||||
|
||||
private SerializedProperty stereoRenderingModeAndroid;
|
||||
private SerializedProperty systemDisplayFrequency;
|
||||
private SerializedProperty optimizeBufferDiscards;
|
||||
private SerializedProperty appLog;
|
||||
private SerializedProperty systemSplashScreen;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if (stereoRenderingModeAndroid == null)
|
||||
stereoRenderingModeAndroid = serializedObject.FindProperty(StereoRenderingModeAndroid);
|
||||
if (systemDisplayFrequency == null)
|
||||
systemDisplayFrequency = serializedObject.FindProperty(SystemDisplayFrequency);
|
||||
if (optimizeBufferDiscards == null)
|
||||
optimizeBufferDiscards = serializedObject.FindProperty(OptimizeBufferDiscards);
|
||||
if (systemSplashScreen == null)
|
||||
systemSplashScreen = serializedObject.FindProperty(SystemSplashScreen);
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (serializedObject == null || serializedObject.targetObject == null)
|
||||
return;
|
||||
|
||||
serializedObject.Update();
|
||||
EditorGUIUtility.labelWidth = 200.0f;
|
||||
BuildTargetGroup selectedBuildTargetGroup = EditorGUILayout.BeginBuildTargetSelectionGrouping();
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.BeginVertical(GUILayout.ExpandWidth(true));
|
||||
if (EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
EditorGUILayout.HelpBox("PICO settings cannot be changed when the editor is in play mode.", MessageType.Info);
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
|
||||
if (selectedBuildTargetGroup == BuildTargetGroup.Android)
|
||||
{
|
||||
EditorGUILayout.PropertyField(stereoRenderingModeAndroid, guiStereoRenderingMode);
|
||||
EditorGUILayout.PropertyField(systemDisplayFrequency, guiDisplayFrequency);
|
||||
EditorGUILayout.PropertyField(optimizeBufferDiscards, guiOptimizeBuffer);
|
||||
|
||||
bool aswDisabled = false;
|
||||
#if !UNITY_2021_1_OR_NEWER
|
||||
aswDisabled = true;
|
||||
#endif
|
||||
if (GraphicsDeviceType.OpenGLES3 == PlayerSettings.GetGraphicsAPIs(EditorUserBuildSettings.activeBuildTarget)[0])
|
||||
{
|
||||
GUI.enabled = false;
|
||||
serializedObject.FindProperty("enableAppSpaceWarp").boolValue = false;
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("enableAppSpaceWarp"), new GUIContent("Application SpaceWarp", "Set Graphics API to Vulkan."));
|
||||
}
|
||||
else if (aswDisabled)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
serializedObject.FindProperty("enableAppSpaceWarp").boolValue = false;
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("enableAppSpaceWarp"), new GUIContent("Application SpaceWarp", "Unity Editor: 2021 LTS or later."));
|
||||
}
|
||||
else if (serializedObject.FindProperty("stereoRenderingModeAndroid").intValue == 0)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
serializedObject.FindProperty("enableAppSpaceWarp").boolValue = false;
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("enableAppSpaceWarp"), new GUIContent("Application SpaceWarp", "Set Stereo Rendering Mode to Multiview."));
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("enableAppSpaceWarp"), new GUIContent("Application SpaceWarp"));
|
||||
}
|
||||
GUI.enabled = true;
|
||||
|
||||
EditorGUILayout.PropertyField(systemSplashScreen, guiSystemSplashScreen);
|
||||
|
||||
#if AR_FOUNDATION_5 || AR_FOUNDATION_6
|
||||
PXR_ProjectSetting projectConfig = PXR_ProjectSetting.GetProjectConfig();
|
||||
var guiContent = new GUIContent();
|
||||
guiContent.text = "AR Foundation";
|
||||
projectConfig.arFoundation = EditorGUILayout.Toggle(guiContent, projectConfig.arFoundation);
|
||||
if (projectConfig.arFoundation)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
// body tracking
|
||||
guiContent.text = "Body Tracking";
|
||||
projectConfig.bodyTracking = EditorGUILayout.Toggle(guiContent, projectConfig.bodyTracking);
|
||||
|
||||
// face tracking
|
||||
guiContent.text = "Face Tracking";
|
||||
projectConfig.faceTracking = EditorGUILayout.Toggle(guiContent, projectConfig.faceTracking);
|
||||
|
||||
// anchor
|
||||
guiContent.text = "Anchor";
|
||||
projectConfig.spatialAnchor = EditorGUILayout.Toggle(guiContent, projectConfig.spatialAnchor);
|
||||
|
||||
// anchor
|
||||
guiContent.text = "Meshing";
|
||||
projectConfig.spatialMesh = EditorGUILayout.Toggle(guiContent, projectConfig.spatialMesh);
|
||||
|
||||
List<ARCameraManager> components = FindComponentsInScene<ARCameraManager>().Where(component => (component.enabled && component.gameObject.CompareTag("MainCamera"))).ToList();
|
||||
bool cameraEffect = false;
|
||||
for (int i = 0; i < components.Count; i++)
|
||||
{
|
||||
ARCameraManager aRCamera = components[i];
|
||||
if (aRCamera.gameObject.GetComponent<PXR_ARCameraEffectManager>())
|
||||
{
|
||||
cameraEffect = true;
|
||||
}
|
||||
Camera camera = aRCamera.gameObject.GetComponent<Camera>();
|
||||
if (camera)
|
||||
{
|
||||
camera.clearFlags = CameraClearFlags.SolidColor;
|
||||
camera.backgroundColor = new Color(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!cameraEffect && components.Count > 0)
|
||||
{
|
||||
ARCameraManager aRCamera = components[0];
|
||||
if (!aRCamera.gameObject.GetComponent<PXR_ARCameraEffectManager>())
|
||||
{
|
||||
aRCamera.gameObject.AddComponent<PXR_ARCameraEffectManager>();
|
||||
}
|
||||
cameraEffect = true;
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
EditorUtility.SetDirty(projectConfig);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.EndBuildTargetSelectionGrouping();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
EditorGUIUtility.labelWidth = 0f;
|
||||
}
|
||||
|
||||
public static List<T> FindComponentsInScene<T>() where T : Component
|
||||
{
|
||||
var activeScene = SceneManager.GetActiveScene();
|
||||
var foundComponents = new List<T>();
|
||||
|
||||
var rootObjects = activeScene.GetRootGameObjects();
|
||||
foreach (var rootObject in rootObjects)
|
||||
{
|
||||
var components = rootObject.GetComponentsInChildren<T>(true);
|
||||
foundComponents.AddRange(components);
|
||||
}
|
||||
|
||||
return foundComponents;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61ac45442d9eb5f40a131d621c5f1ff7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,51 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.XR.PXR.Editor
|
||||
{
|
||||
[CustomEditor(typeof(PXR_SpatialMeshManager))]
|
||||
public class PXR_SpatialMeshManagerEditor : UnityEditor.Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
DrawDefaultInspector();
|
||||
|
||||
PXR_SpatialMeshColorSetting colorSetting = PXR_SpatialMeshColorSetting.GetSpatialMeshColorSetting();
|
||||
|
||||
EditorGUILayout.BeginVertical("framebox");
|
||||
GUILayout.Label("Custom Mesh Color", EditorStyles.boldLabel);
|
||||
GUILayout.Space(5);
|
||||
|
||||
if (colorSetting.colorLists != null)
|
||||
{
|
||||
var labels = Enum.GetNames(typeof(PxrSemanticLabel));
|
||||
for (int i = 0; i < colorSetting.colorLists.Count; i++)
|
||||
{
|
||||
colorSetting.colorLists[i] = EditorGUILayout.ColorField(labels[i], colorSetting.colorLists[i]);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
if (GUI.changed)
|
||||
{
|
||||
PXR_SpatialMeshColorSetting.SaveAssets();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0577c31c891b4e40b6076926195776d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,777 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Unity.XR.CoreUtils;
|
||||
using Unity.XR.CoreUtils.Editor;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
using UnityEditor.PackageManager;
|
||||
using UnityEditor.PackageManager.Requests;
|
||||
using UnityEditor.PackageManager.UI;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEditor.XR.Management;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using static Unity.XR.CoreUtils.XROrigin;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEditor.Build;
|
||||
using Unity.XR.CoreUtils.Capabilities.Editor;
|
||||
using UnityEngine.XR.Management;
|
||||
using Unity.XR.CoreUtils.Capabilities;
|
||||
|
||||
#if UNITY_OPENXR
|
||||
using UnityEngine.XR.OpenXR;
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
|
||||
#if XR_HAND
|
||||
using UnityEngine.XR.Hands.OpenXR;
|
||||
#endif
|
||||
|
||||
#if PICO_OPENXR_SDK
|
||||
using Unity.XR.OpenXR.Features.PICOSupport;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if URP
|
||||
using UnityEngine.Rendering.Universal;
|
||||
#endif
|
||||
|
||||
namespace Unity.XR.PXR
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
internal static class PXR_Utils
|
||||
{
|
||||
public static string BuildingBlock = "[Building Block]";
|
||||
public const string BuildingBlockPathO = "GameObject/PICO Building Blocks/";
|
||||
public const string BuildingBlockPathP = "PICO/PICO Building Blocks/";
|
||||
public static string sdkPackageName = "Packages/com.unity.xr.picoxr/";
|
||||
|
||||
|
||||
public static AndroidSdkVersions minSdkVersionInEditor = AndroidSdkVersions.AndroidApiLevel29;
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
public static NamedBuildTarget recommendedBuildTarget = NamedBuildTarget.Android;
|
||||
#else
|
||||
public static BuildTargetGroup recommendedBuildTarget = BuildTargetGroup.Android;
|
||||
#endif
|
||||
|
||||
#region xr.interaction.toolkit
|
||||
public static string xriPackageName = "com.unity.xr.interaction.toolkit";
|
||||
public static string xriVersion = "2.5.4";
|
||||
public static PackageVersion xriPackageVersion250 = new PackageVersion("2.5.0");
|
||||
public static PackageVersion xriPackageVersion300 = new PackageVersion("3.0.0");
|
||||
public static string xriCategory = "XR Interaction Toolkit";
|
||||
public static string xriSamplesPath = "Assets/Samples/XR Interaction Toolkit";
|
||||
public static string xriStarterAssetsSampleName = "Starter Assets";
|
||||
public static string xriHandsInteractionDemoSampleName = "Hands Interaction Demo";
|
||||
public static string xri2HandsSetupPefabName = "XR Interaction Hands Setup";
|
||||
public static string xri3HandsSetupPefabName = "XR Origin Hands (XR Rig)";
|
||||
public static PackageVersion XRICurPackageVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return new PackageVersion(xriVersion);
|
||||
}
|
||||
}
|
||||
public static string XRIDefaultInputActions
|
||||
{
|
||||
get
|
||||
{
|
||||
return $"{xriSamplesPath}/{xriVersion}/Starter Assets/XRI Default Input Actions.inputactions";
|
||||
}
|
||||
}
|
||||
|
||||
public static string XRIDefaultLeftControllerPreset
|
||||
{
|
||||
get
|
||||
{
|
||||
if (XRICurPackageVersion >= xriPackageVersion250)
|
||||
{
|
||||
return $"{xriSamplesPath}/{xriVersion}/Starter Assets/Presets/XRI Default Left Controller.preset";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"{xriSamplesPath}/{xriVersion}/Starter Assets/XRI Default Left Controller.preset";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string XRIDefaultRightControllerPreset
|
||||
{
|
||||
get
|
||||
{
|
||||
if (XRICurPackageVersion >= xriPackageVersion250)
|
||||
{
|
||||
return $"{xriSamplesPath}/{xriVersion}/Starter Assets/Presets/XRI Default Right Controller.preset";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"{xriSamplesPath}/{xriVersion}/Starter Assets/XRI Default Right Controller.preset";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string XRInteractionHandsSetupPath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (XRICurPackageVersion >= xriPackageVersion300)
|
||||
{
|
||||
return $"{xriSamplesPath}/{xriVersion}/{xriHandsInteractionDemoSampleName}/Prefabs/{xri3HandsSetupPefabName}.prefab";
|
||||
}
|
||||
else if (XRICurPackageVersion >= xriPackageVersion250 && XRICurPackageVersion < xriPackageVersion300)
|
||||
{
|
||||
return $"{xriSamplesPath}/{xriVersion}/{xriHandsInteractionDemoSampleName}/Prefabs/{xri2HandsSetupPefabName}.prefab";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"{xriSamplesPath}/{xriVersion}/{xriHandsInteractionDemoSampleName}/Runtime/Prefabs/{xri2HandsSetupPefabName}.prefab";
|
||||
}
|
||||
}
|
||||
}
|
||||
public static string XRInteractionPokeButtonPath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (XRICurPackageVersion >= xriPackageVersion250)
|
||||
{
|
||||
return $"{xriSamplesPath}/{xriVersion}/{xriHandsInteractionDemoSampleName}/HandsDemoSceneAssets/Prefabs/PokeButton.prefab";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"{xriSamplesPath}/{xriVersion}/{xriHandsInteractionDemoSampleName}/Runtime/Prefabs/PokeButton.prefab";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string XRInteractionXRI300OriginPath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (XRICurPackageVersion >= xriPackageVersion250)
|
||||
{
|
||||
return $"{xriSamplesPath}/{xriVersion}/{xriStarterAssetsSampleName}/Prefabs/XR Origin (XR Rig).prefab";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"{xriSamplesPath}/{xriVersion}/{xriStarterAssetsSampleName}/Runtime/Prefabs/XR Origin (XR Rig).prefab";
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region xr.hands
|
||||
public static string xrHandPackageName = "com.unity.xr.hands";
|
||||
public static string xrHandVersion = "1.4.1";
|
||||
public static PackageVersion xrHandRecommendedPackageVersion = new PackageVersion("1.3.0");
|
||||
public static string xrHandSamplesPath = "Assets/Samples/XR Hands";
|
||||
public static string xrHandGesturesSampleName = "Gestures";
|
||||
public static string xrHandVisualizerSampleName = "HandVisualizer";
|
||||
|
||||
public static string XRHandLeftHandPrefabPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return $"{xrHandSamplesPath}/{xrHandVersion}/HandVisualizer/Prefabs/Left Hand Tracking.prefab";
|
||||
}
|
||||
}
|
||||
|
||||
public static string XRHandRightHandPrefabPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return $"{xrHandSamplesPath}/{xrHandVersion}/HandVisualizer/Prefabs/Right Hand Tracking.prefab";
|
||||
}
|
||||
}
|
||||
|
||||
static AddRequest xrHandsPackageAddRequest;
|
||||
public static void InstallOrUpdateHands()
|
||||
{
|
||||
var currentT = DateTime.Now;
|
||||
var endT = currentT + TimeSpan.FromSeconds(3);
|
||||
|
||||
var request = Client.Search(xrHandPackageName);
|
||||
if (request.Status == StatusCode.InProgress)
|
||||
{
|
||||
Debug.Log($"Searching for ({xrHandPackageName}) in Unity Package Registry.");
|
||||
while (request.Status == StatusCode.InProgress && currentT < endT)
|
||||
{
|
||||
currentT = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
var addRequest = xrHandPackageName;
|
||||
if (request.Status == StatusCode.Success && request.Result.Length > 0)
|
||||
{
|
||||
var versions = request.Result[0].versions;
|
||||
#if UNITY_2022_2_OR_NEWER
|
||||
var recommendedVersion = new PackageVersion(versions.recommended);
|
||||
#else
|
||||
var recommendedVersion = new PackageVersion(versions.verified);
|
||||
#endif
|
||||
var latestCompatible = new PackageVersion(versions.latestCompatible);
|
||||
if (recommendedVersion < xrHandRecommendedPackageVersion && xrHandRecommendedPackageVersion <= latestCompatible)
|
||||
addRequest = $"{xrHandPackageName}@{xrHandRecommendedPackageVersion}";
|
||||
}
|
||||
|
||||
xrHandsPackageAddRequest = Client.Add(addRequest);
|
||||
if (xrHandsPackageAddRequest.Error != null)
|
||||
{
|
||||
Debug.LogError($"Package installation error: {xrHandsPackageAddRequest.Error}: {xrHandsPackageAddRequest.Error.message}");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region xr.openxr
|
||||
public static string openXRPackageName = "com.unity.xr.openxr";
|
||||
public static PackageVersion openXRPackageVersion182 = new PackageVersion("1.8.2");
|
||||
public static string openXRVersion = "1.7.1";
|
||||
|
||||
public static PackageVersion openXRCurPackageVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return new PackageVersion(openXRVersion);
|
||||
}
|
||||
}
|
||||
public static string GetPackageVersionSync(string packageName)
|
||||
{
|
||||
var request = Client.List();
|
||||
while (!request.IsCompleted) { }
|
||||
return request.Result.FirstOrDefault(p => p.name == packageName)?.version;
|
||||
}
|
||||
|
||||
public static void EnableHandTrackingFeature()
|
||||
{
|
||||
#if XR_HAND && PICO_OPENXR_SDK
|
||||
EnableOpenXRFeature<HandTracking>();
|
||||
EnableOpenXRFeature<UnityEngine.XR.OpenXR.Features.Interactions.HandInteractionProfile>();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PICO_OPENXR_SDK
|
||||
public static void EnableOpenXRFeature<T>() where T : OpenXRFeature
|
||||
{
|
||||
var settings = OpenXRSettings.GetSettingsForBuildTargetGroup(BuildTargetGroup.Android);
|
||||
foreach (var feature in settings.GetFeatures<OpenXRFeature>())
|
||||
{
|
||||
if (feature is T targetFeature && !targetFeature.enabled)
|
||||
{
|
||||
targetFeature.enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
public static List<T> FindComponentsInScene<T>() where T : Component
|
||||
{
|
||||
var activeScene = SceneManager.GetActiveScene();
|
||||
var foundComponents = new List<T>();
|
||||
|
||||
var rootObjects = activeScene.GetRootGameObjects();
|
||||
foreach (var rootObject in rootObjects)
|
||||
{
|
||||
var components = rootObject.GetComponentsInChildren<T>(true);
|
||||
foundComponents.AddRange(components);
|
||||
}
|
||||
|
||||
return foundComponents;
|
||||
}
|
||||
public static List<T> FindGameObjectsInScene<T>() where T : Component
|
||||
{
|
||||
var activeScene = SceneManager.GetActiveScene();
|
||||
var foundComponents = new List<T>();
|
||||
|
||||
var rootObjects = activeScene.GetRootGameObjects();
|
||||
foreach (var rootObject in rootObjects)
|
||||
{
|
||||
var components = rootObject.GetComponentsInChildren<T>(true);
|
||||
foundComponents.AddRange(components);
|
||||
}
|
||||
|
||||
return foundComponents;
|
||||
}
|
||||
|
||||
public static void AddNewTag(string newTag)
|
||||
{
|
||||
SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
|
||||
SerializedProperty tags = tagManager.FindProperty("tags");
|
||||
|
||||
bool tagExists = false;
|
||||
for (int i = 0; i < tags.arraySize; i++)
|
||||
{
|
||||
if (tags.GetArrayElementAtIndex(i).stringValue == newTag)
|
||||
{
|
||||
tagExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tagExists)
|
||||
{
|
||||
tags.InsertArrayElementAtIndex(tags.arraySize);
|
||||
tags.GetArrayElementAtIndex(tags.arraySize - 1).stringValue = newTag;
|
||||
tagManager.ApplyModifiedProperties();
|
||||
Debug.Log($"Tag '{newTag}' has been added.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Tag '{newTag}' already exists.");
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryFindSample(string packageName, string packageVersion, string sampleDisplayName, out Sample sample)
|
||||
{
|
||||
sample = default;
|
||||
|
||||
IEnumerable<Sample> packageSamples;
|
||||
try
|
||||
{
|
||||
packageSamples = Sample.FindByPackage(packageName, packageVersion);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Couldn't find samples of the {ToString(packageName, packageVersion)} package. Exception: {e}");
|
||||
return false;
|
||||
}
|
||||
if (packageSamples == null)
|
||||
{
|
||||
Debug.LogWarning($"Couldn't find samples of the {ToString(packageName, packageVersion)} package.");
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var packageSample in packageSamples)
|
||||
{
|
||||
if (packageSample.displayName == sampleDisplayName)
|
||||
{
|
||||
Debug.Log($" TryFindSample packageSample.displayName={packageSample.displayName}, sampleDisplayName={sampleDisplayName}");
|
||||
sample = packageSample;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.LogWarning($"Couldn't find {sampleDisplayName} sample in the { packageName}:{ packageVersion}.");
|
||||
return false;
|
||||
}
|
||||
private static string ToString(string packageName, string packageVersion)
|
||||
{
|
||||
return string.IsNullOrEmpty(packageVersion) ? packageName : $"{packageName}@{packageVersion}";
|
||||
}
|
||||
|
||||
public static void SetTrackingOriginMode(TrackingOriginMode trackingOriginMode = TrackingOriginMode.Device)
|
||||
{
|
||||
List<XROrigin> components = FindComponentsInScene<XROrigin>().Where(component => component.isActiveAndEnabled).ToList();
|
||||
|
||||
foreach (XROrigin origin in components)
|
||||
{
|
||||
if (TrackingOriginMode.NotSpecified == origin.RequestedTrackingOriginMode)
|
||||
{
|
||||
Debug.Log($"SetTrackingOriginMode {trackingOriginMode}");
|
||||
origin.RequestedTrackingOriginMode = trackingOriginMode;
|
||||
EditorUtility.SetDirty(origin);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
}
|
||||
}
|
||||
#if XRI_TOOLKIT_3
|
||||
public static GameObject CheckAndCreateXROriginXRI300()
|
||||
{
|
||||
GameObject cameraOrigin;
|
||||
string k_BuildingBlocksXRI300OriginName = BuildingBlock + " XR Origin (XR Rig) XRI300";
|
||||
|
||||
List<Transform> transforms = FindComponentsInScene<Transform>().Where(component => component.name == k_BuildingBlocksXRI300OriginName).ToList();
|
||||
if (transforms.Count == 0)
|
||||
{
|
||||
GameObject buildingBlockGO = new GameObject();
|
||||
Selection.activeGameObject = buildingBlockGO;
|
||||
|
||||
List<XROrigin> components = FindComponentsInScene<XROrigin>().Where(component => component.isActiveAndEnabled).ToList();
|
||||
if (components.Count != 0)
|
||||
{
|
||||
foreach (var c in components)
|
||||
{
|
||||
c.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
GameObject ob = PrefabUtility.LoadPrefabContents(XRInteractionXRI300OriginPath);
|
||||
Undo.RegisterCreatedObjectUndo(ob, "Create XRInteractionXRI300OriginPath.");
|
||||
var activeScene = SceneManager.GetActiveScene();
|
||||
var rootObjects = activeScene.GetRootGameObjects();
|
||||
Undo.SetTransformParent(ob.transform, buildingBlockGO.transform, true, "Parent to buildingBlockGO.");
|
||||
ob.transform.localPosition = Vector3.zero;
|
||||
ob.transform.localRotation = Quaternion.identity;
|
||||
ob.transform.localScale = Vector3.one;
|
||||
ob.SetActive(true);
|
||||
cameraOrigin = ob;
|
||||
|
||||
if (!cameraOrigin.GetComponent<PXR_Manager>())
|
||||
{
|
||||
cameraOrigin.AddComponent<PXR_Manager>();
|
||||
}
|
||||
|
||||
var characterController = cameraOrigin.GetComponent<CharacterController>();
|
||||
if (characterController)
|
||||
{
|
||||
characterController.enabled = false;
|
||||
}
|
||||
|
||||
if (cameraOrigin.transform.Find("Locomotion/Move"))
|
||||
{
|
||||
cameraOrigin.transform.Find("Locomotion/Move").gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
buildingBlockGO.name = k_BuildingBlocksXRI300OriginName;
|
||||
Undo.RegisterCreatedObjectUndo(buildingBlockGO, "Create buildingBlockGO.");
|
||||
|
||||
EditorSceneManager.MarkSceneDirty(buildingBlockGO.scene);
|
||||
EditorSceneManager.SaveScene(buildingBlockGO.scene);
|
||||
|
||||
SetTrackingOriginMode();
|
||||
PXR_ProjectSetting.SaveAssets();
|
||||
}
|
||||
else
|
||||
{
|
||||
cameraOrigin = transforms[0].GetChild(0).gameObject;
|
||||
}
|
||||
|
||||
return cameraOrigin;
|
||||
}
|
||||
#endif
|
||||
public static GameObject CheckAndCreateXROrigin()
|
||||
{
|
||||
GameObject cameraOrigin;
|
||||
List<XROrigin> components = FindComponentsInScene<XROrigin>().Where(component => component.isActiveAndEnabled).ToList();
|
||||
if (components.Count == 0)
|
||||
{
|
||||
if (!EditorApplication.ExecuteMenuItem("GameObject/XR/XR Origin (VR)"))
|
||||
{
|
||||
EditorApplication.ExecuteMenuItem("GameObject/XR/XR Origin (Action-based)");
|
||||
}
|
||||
cameraOrigin = FindComponentsInScene<XROrigin>().Where(component => component.isActiveAndEnabled).ToList()[0].gameObject;
|
||||
cameraOrigin.name = PXR_Utils.BuildingBlock + " XR Origin (XR Rig)";
|
||||
Undo.RegisterCreatedObjectUndo(cameraOrigin, "Create XR Origin");
|
||||
cameraOrigin.transform.localPosition = Vector3.zero;
|
||||
cameraOrigin.transform.localRotation = Quaternion.identity;
|
||||
cameraOrigin.transform.localScale = Vector3.one;
|
||||
cameraOrigin.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
cameraOrigin = components[0].gameObject;
|
||||
}
|
||||
|
||||
if (!cameraOrigin.GetComponent<PXR_Manager>())
|
||||
{
|
||||
cameraOrigin.AddComponent<PXR_Manager>();
|
||||
}
|
||||
|
||||
return cameraOrigin;
|
||||
}
|
||||
|
||||
public static GameObject GetMainCameraGOForXROrigin()
|
||||
{
|
||||
GameObject cameraGameObject = Camera.main.gameObject;
|
||||
List<Camera> components = FindComponentsInScene<Camera>().Where(component => (component.enabled && component.gameObject.CompareTag("MainCamera"))).ToList();
|
||||
for (int i = 0; i < components.Count; i++)
|
||||
{
|
||||
GameObject gameObject = components[i].transform.gameObject;
|
||||
if (gameObject.GetComponentsInParent<XROrigin>().Length == 1)
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
cameraGameObject = gameObject;
|
||||
}
|
||||
}
|
||||
|
||||
return cameraGameObject;
|
||||
}
|
||||
|
||||
public static Camera GetMainCameraForXROrigin()
|
||||
{
|
||||
Camera mainCamera = Camera.main;
|
||||
|
||||
List<Camera> components = FindComponentsInScene<Camera>().Where(component => (component.enabled && component.gameObject.CompareTag("MainCamera"))).ToList();
|
||||
for (int i = 0; i < components.Count; i++)
|
||||
{
|
||||
Camera camera = components[i];
|
||||
if (camera.GetComponentsInParent<XROrigin>().Length == 1)
|
||||
{
|
||||
camera.gameObject.SetActive(true);
|
||||
mainCamera = camera;
|
||||
}
|
||||
}
|
||||
|
||||
return mainCamera;
|
||||
}
|
||||
|
||||
public static void SetOneMainCameraInScene()
|
||||
{
|
||||
bool hasOneMainCamera = false;
|
||||
List<Camera> components = FindComponentsInScene<Camera>().Where(component => (component.enabled && component.gameObject.activeSelf)).ToList();
|
||||
if (components.Count == 0)
|
||||
{
|
||||
if (!EditorApplication.ExecuteMenuItem("GameObject/XR/XR Origin (VR)"))
|
||||
{
|
||||
EditorApplication.ExecuteMenuItem("GameObject/XR/XR Origin (Action-based)");
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < components.Count; i++)
|
||||
{
|
||||
GameObject gameObject = components[i].transform.gameObject;
|
||||
if (gameObject.GetComponentsInParent<XROrigin>().Length >= 1 && !hasOneMainCamera)
|
||||
{
|
||||
if (!gameObject.CompareTag("MainCamera"))
|
||||
{
|
||||
gameObject.tag = "MainCamera";
|
||||
}
|
||||
gameObject.SetActive(true);
|
||||
hasOneMainCamera = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
string newTag = $"Camera{i}";
|
||||
AddNewTag(newTag);
|
||||
gameObject.tag = newTag;
|
||||
gameObject.SetActive(false);
|
||||
components[i].enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool UpdateSamples(string packageName, string sampleDisplayName)
|
||||
{
|
||||
Debug.LogError($"Need to import {sampleDisplayName} first! Once completed, click this Block again.");
|
||||
bool result = EditorUtility.DisplayDialog($"{sampleDisplayName}", $"It's detected that {sampleDisplayName} has not been imported in the current project. You can choose OK to auto-import it, or Cancel and install it manually. ", "OK", "Cancel");
|
||||
if (result)
|
||||
{
|
||||
if (TryFindSample(packageName, string.Empty, sampleDisplayName, out var sample))
|
||||
{
|
||||
sample.Import(Sample.ImportOptions.OverridePreviousImports);
|
||||
AssetDatabase.Refresh();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static string minUnityVersion = "2020.3.21f1";
|
||||
public static int CompareUnityVersions(string versionA, string versionB)
|
||||
{
|
||||
string[] partsA = versionA.Split(new char[] { '.', 'f' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] partsB = versionB.Split(new char[] { '.', 'f' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
int maxLength = Math.Max(partsA.Length, partsB.Length);
|
||||
|
||||
for (int i = 0; i < maxLength; i++)
|
||||
{
|
||||
int partA = i < partsA.Length ? int.Parse(partsA[i]) : 0;
|
||||
int partB = i < partsB.Length ? int.Parse(partsB[i]) : 0;
|
||||
|
||||
if (partA > partB)
|
||||
return 1;
|
||||
if (partA < partB)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static bool updateBasedOnCapabilityProfileSelection = false;
|
||||
static PXR_Utils()
|
||||
{
|
||||
CapabilityProfileSelection.SelectionSaved += OnSelectionSaved;
|
||||
}
|
||||
|
||||
private static void OnSelectionSaved()
|
||||
{
|
||||
updateBasedOnCapabilityProfileSelection = true;
|
||||
}
|
||||
|
||||
public static bool IsPXRValidationEnabled()
|
||||
{
|
||||
if (updateBasedOnCapabilityProfileSelection)
|
||||
{
|
||||
return CapabilityProfileSelection.Selected.Any(c => c is PXR_SDKCapability);
|
||||
}
|
||||
return IsPXRPluginEnabled();
|
||||
}
|
||||
|
||||
public static bool IsOpenXRValidationEnabled()
|
||||
{
|
||||
if (updateBasedOnCapabilityProfileSelection)
|
||||
{
|
||||
return CapabilityProfileSelection.Selected.Any(c => c is PXR_OpenXR_SDKCapability);
|
||||
}
|
||||
return IsOpenXRPluginEnabled();
|
||||
}
|
||||
|
||||
public static void ReSetCapabilityProfileSelection()
|
||||
{
|
||||
CapabilityProfileSelection.Clear();
|
||||
CapabilityProfileSelection.Save();
|
||||
updateBasedOnCapabilityProfileSelection = false;
|
||||
}
|
||||
|
||||
public static bool IsPXRPluginEnabled()
|
||||
{
|
||||
var generalSettings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(
|
||||
BuildTargetGroup.Android);
|
||||
if (generalSettings == null)
|
||||
return false;
|
||||
|
||||
var managerSettings = generalSettings.AssignedSettings;
|
||||
|
||||
return managerSettings != null && managerSettings.activeLoaders.Any(loader => loader is PXR_Loader);
|
||||
}
|
||||
|
||||
|
||||
public static bool IsOpenXRPluginEnabled()
|
||||
{
|
||||
#if PICO_OPENXR_SDK
|
||||
var generalSettings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(
|
||||
BuildTargetGroup.Android);
|
||||
if (generalSettings == null)
|
||||
return false;
|
||||
|
||||
var managerSettings = generalSettings.AssignedSettings;
|
||||
|
||||
return managerSettings != null && managerSettings.activeLoaders.Any(loader => loader is OpenXRLoader);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#region Symbols
|
||||
public static string _openxr_xdk = "PICO_OPENXR_SDK";
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
public static void IsPicoSpatializerAvailable()
|
||||
{
|
||||
string name = "PICO_SPATIALIZER";
|
||||
#if UNITY_EDITOR
|
||||
string spatializerPath = sdkPackageName + "SpatialAudio/ByteDance.PICO.XR.Spatializer.asmdef";
|
||||
var asmDef = AssetDatabase.LoadAssetAtPath<AssemblyDefinitionAsset>(spatializerPath);
|
||||
if (asmDef == null)
|
||||
{
|
||||
RemoveDefineSymbol(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDefineSymbols(name);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool SetDefineSymbols(string name)
|
||||
{
|
||||
var buildTarget = NamedBuildTarget.FromBuildTargetGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
|
||||
string currentDefines = PlayerSettings.GetScriptingDefineSymbols(buildTarget);
|
||||
|
||||
var defineSymbols = new HashSet<string>(currentDefines.Split(';', StringSplitOptions.RemoveEmptyEntries));
|
||||
|
||||
if (!defineSymbols.Contains(name))
|
||||
{
|
||||
defineSymbols.Add(name);
|
||||
string newDefines = string.Join(";", defineSymbols);
|
||||
PlayerSettings.SetScriptingDefineSymbols(buildTarget, newDefines);
|
||||
Debug.Log($"SetDefineSymbols Final define symbols: {newDefines}");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void RemoveDefineSymbol(string name)
|
||||
{
|
||||
var buildTarget = NamedBuildTarget.FromBuildTargetGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
|
||||
string currentDefines = PlayerSettings.GetScriptingDefineSymbols(buildTarget);
|
||||
|
||||
var defineSymbols = new HashSet<string>(currentDefines.Split(';', StringSplitOptions.RemoveEmptyEntries));
|
||||
|
||||
if (defineSymbols.Remove(name))
|
||||
{
|
||||
string newDefines = string.Join(";", defineSymbols);
|
||||
PlayerSettings.SetScriptingDefineSymbols(buildTarget, newDefines);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool UpdateSDKSymbols()
|
||||
{
|
||||
XRGeneralSettings generalSettings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(BuildTargetGroup.Android);
|
||||
if (generalSettings == null) return false;
|
||||
var assignedSettings = generalSettings.AssignedSettings;
|
||||
if (assignedSettings == null) return false;
|
||||
|
||||
string[] defineSymbols = PlayerSettings.GetScriptingDefineSymbols(NamedBuildTarget.Android).Split(';');
|
||||
List<string> defineSymbolsList = new List<string>(defineSymbols);
|
||||
|
||||
bool modified = false;
|
||||
foreach (XRLoader loader in assignedSettings.activeLoaders)
|
||||
{
|
||||
#if UNITY_OPENXR
|
||||
if (loader is OpenXRLoader)
|
||||
{
|
||||
if (!defineSymbolsList.Contains(_openxr_xdk))
|
||||
{
|
||||
defineSymbolsList.Add(_openxr_xdk);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (loader is PXR_Loader)
|
||||
{
|
||||
modified |= defineSymbolsList.Remove(PXR_Utils._openxr_xdk);
|
||||
}
|
||||
}
|
||||
|
||||
if (modified)
|
||||
{
|
||||
PXR_Utils.ReSetCapabilityProfileSelection();
|
||||
string finalSymbols = string.Join(";", defineSymbolsList);
|
||||
PlayerSettings.SetScriptingDefineSymbols(NamedBuildTarget.Android, finalSymbols);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#if URP
|
||||
public static UniversalRenderPipelineAsset GetCurrentURPAsset()
|
||||
{
|
||||
UniversalRenderPipelineAsset universalRenderPipelineAsset = null;
|
||||
if (QualitySettings.renderPipeline != null)
|
||||
{
|
||||
universalRenderPipelineAsset = (UniversalRenderPipelineAsset)QualitySettings.renderPipeline;
|
||||
|
||||
}
|
||||
else if (GraphicsSettings.currentRenderPipeline != null)
|
||||
{
|
||||
universalRenderPipelineAsset = (UniversalRenderPipelineAsset)GraphicsSettings.defaultRenderPipeline;
|
||||
}
|
||||
return universalRenderPipelineAsset;
|
||||
}
|
||||
#endif
|
||||
|
||||
public static void DisableHDR()
|
||||
{
|
||||
#if URP
|
||||
if (QualitySettings.renderPipeline != null)
|
||||
{
|
||||
UniversalRenderPipelineAsset universalRenderPipelineAsset = (UniversalRenderPipelineAsset)QualitySettings.renderPipeline;
|
||||
universalRenderPipelineAsset.supportsHDR = false;
|
||||
|
||||
}
|
||||
else if (GraphicsSettings.currentRenderPipeline != null)
|
||||
{
|
||||
UniversalRenderPipelineAsset universalRenderPipelineAsset = (UniversalRenderPipelineAsset)GraphicsSettings.defaultRenderPipeline;
|
||||
universalRenderPipelineAsset.supportsHDR = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dba8b5e166a8df943b94a4a307890a8d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,63 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Unity.XR.PXR;
|
||||
using UnityEditor;
|
||||
using UnityEditor.XR.Management;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Management;
|
||||
#if UNITY_OPENXR
|
||||
using UnityEngine.XR.OpenXR;
|
||||
#endif
|
||||
|
||||
|
||||
[XRCustomLoaderUI("Unity.XR.PXR.PXR_Loader", BuildTargetGroup.Standalone)]
|
||||
[XRCustomLoaderUI("Unity.XR.PXR.PXR_Loader", BuildTargetGroup.Android)]
|
||||
internal class PXR_XRLoaderUI : IXRCustomLoaderUI
|
||||
{
|
||||
public static readonly GUIContent k_LoaderName = new GUIContent("PICO");
|
||||
protected float renderLineHeight = 0;
|
||||
/// <inheritdoc/>
|
||||
public float RequiredRenderHeight { get; protected set; }
|
||||
public virtual void SetRenderedLineHeight(float height)
|
||||
{
|
||||
renderLineHeight = height;
|
||||
RequiredRenderHeight = height;
|
||||
}
|
||||
protected Rect CalculateRectForContent(float xMin, float yMin, GUIStyle style, GUIContent content)
|
||||
{
|
||||
var size = style.CalcSize(content);
|
||||
var rect = new Rect();
|
||||
rect.xMin = xMin;
|
||||
rect.yMin = yMin;
|
||||
rect.width = size.x;
|
||||
rect.height = renderLineHeight;
|
||||
return rect;
|
||||
}
|
||||
|
||||
public void OnGUI(Rect rect)
|
||||
{
|
||||
|
||||
float xMin = rect.xMin;
|
||||
float yMin = rect.yMin;
|
||||
|
||||
var labelRect = CalculateRectForContent(xMin, yMin, EditorStyles.toggle, k_LoaderName);
|
||||
var newToggled = EditorGUI.ToggleLeft(labelRect, k_LoaderName, IsLoaderEnabled);
|
||||
if (newToggled != IsLoaderEnabled)
|
||||
{
|
||||
IsLoaderEnabled = newToggled;
|
||||
}
|
||||
|
||||
PXR_Utils.UpdateSDKSymbols();
|
||||
}
|
||||
|
||||
public bool IsLoaderEnabled { get; set; }
|
||||
public string[] IncompatibleLoaders => new string[]
|
||||
{
|
||||
"UnityEngine.XR.OpenXR.OpenXRLoader",
|
||||
"UnityEngine.XR.WindowsMR.WindowsMRLoader",
|
||||
"Unity.XR.Oculus.OculusLoader",
|
||||
};
|
||||
|
||||
public BuildTargetGroup ActiveBuildTargetGroup { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea44ec7d2f0948146bf4054ce6b398bf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d63b7efba6a1a4468976ca8dbc3572f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,122 @@
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Unity.XR.CoreUtils.Editor;
|
||||
using Unity.XR.PXR;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Rendering;
|
||||
using UnityEditor.XR.Management;
|
||||
using UnityEngine;
|
||||
|
||||
#if PICO_OPENXR_SDK
|
||||
using Unity.XR.OpenXR.Features.PICOSupport;
|
||||
#endif
|
||||
|
||||
static class PXR_ProjectValidationOptional
|
||||
{
|
||||
const string k_Catergory = "PICO Optional";
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
static void AddOptionalRules()
|
||||
{
|
||||
var androidGlobalRules = new[]
|
||||
{
|
||||
#region Cross-Platform Validation (PXR & OpenXR)
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Disable Realtime GI.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return !Lightmapping.realtimeGI;
|
||||
},
|
||||
FixItMessage = "Open Window > Rendering > Lighting > Realtime Lighting > Realtime Global lllumination: disabled.",
|
||||
FixIt = () =>
|
||||
{
|
||||
Lightmapping.realtimeGI = false;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_DisableRealtimeGI);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Enable GPU Skinning.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return PlayerSettings.gpuSkinning;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings > Player> Other Settings > GPU Skinning :enabled",
|
||||
FixIt = () =>
|
||||
{
|
||||
PlayerSettings.gpuSkinning = true;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_GPUSkinning);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
#endregion
|
||||
|
||||
#region PXR Platform Validation
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "When enabling ET or ETFR, option 'Eye Tracking Calibration' can be used.",
|
||||
IsRuleEnabled = PXR_Utils.IsPXRValidationEnabled,
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
if (PXR_ProjectSetting.GetProjectConfig().eyeTracking || PXR_ProjectSetting.GetProjectConfig().enableETFR)
|
||||
{
|
||||
return PXR_ProjectSetting.GetProjectConfig().eyetrackingCalibration;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
FixItMessage = "PXR_Manager > 'Eye Tracking Calibration' set to enable.",
|
||||
FixIt = () =>
|
||||
{
|
||||
PXR_ProjectSetting.GetProjectConfig().eyetrackingCalibration = true;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_EyeTrackingCalibration);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
#endregion
|
||||
|
||||
#region PICO OpenXR Validation
|
||||
#if PICO_OPENXR_SDK
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "When enabling ET or ETFR, option 'Eye Tracking Calibration' can be used.",
|
||||
IsRuleEnabled = PXR_Utils.IsOpenXRValidationEnabled,
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
if (PXR_OpenXRProjectSetting.GetProjectConfig().isEyeTracking ||
|
||||
(PXR_OpenXRProjectSetting.GetProjectConfig().foveatedRenderingMode == FoveationFeature.FoveatedRenderingMode.EyeTrackedFoveatedRendering &&
|
||||
PXR_OpenXRProjectSetting.GetProjectConfig().foveatedRenderingLevel != FoveationFeature.FoveatedRenderingLevel.Off))
|
||||
{
|
||||
return PXR_OpenXRProjectSetting.GetProjectConfig().isEyeTrackingCalibration;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
FixItMessage = "PXR_Manager > 'Eye Tracking Calibration' set to enable.",
|
||||
FixIt = () =>
|
||||
{
|
||||
PXR_OpenXRProjectSetting.GetProjectConfig().isEyeTrackingCalibration = true;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_EyeTrackingCalibration);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
#endif
|
||||
#endregion
|
||||
};
|
||||
BuildValidator.AddRules(BuildTargetGroup.Android, androidGlobalRules);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 722e801b1e226c44ebcb4c18060d4b11
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,726 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Unity.XR.CoreUtils;
|
||||
using Unity.XR.CoreUtils.Editor;
|
||||
using Unity.XR.PXR;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Rendering;
|
||||
using UnityEditor.XR.Management;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.XR;
|
||||
using static Unity.XR.CoreUtils.XROrigin;
|
||||
#if URP
|
||||
using UnityEngine.Rendering.Universal;
|
||||
#endif
|
||||
|
||||
#if PICO_OPENXR_SDK
|
||||
using Unity.XR.OpenXR.Features.PICOSupport;
|
||||
#endif
|
||||
|
||||
static class PXR_ProjectValidationRecommend
|
||||
{
|
||||
const string k_Catergory = "PICO Recommend";
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
static void AddRecommendRules()
|
||||
{
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
NamedBuildTarget recommendedBuildTarget = NamedBuildTarget.Android;
|
||||
#else
|
||||
const BuildTargetGroup recommendedBuildTarget = BuildTargetGroup.Android;
|
||||
#endif
|
||||
var androidGlobalRules = new[]
|
||||
{
|
||||
#region Cross-Platform Validation (PXR & OpenXR)
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Set 'Target API Level' to automatic.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return PlayerSettings.Android.targetSdkVersion == AndroidSdkVersions.AndroidApiLevelAuto;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings > Player> Other Settings > 'Target API Level' to set automatic.",
|
||||
FixIt = () =>
|
||||
{
|
||||
PlayerSettings.Android.targetSdkVersion = AndroidSdkVersions.AndroidApiLevelAuto;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_TargetAPILevelAuto);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Set 'Install Location' to automatic.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return PlayerSettings.Android.preferredInstallLocation == AndroidPreferredInstallLocation.Auto;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings > Player> Other Settings > 'Install Location' to set automatic.",
|
||||
FixIt = () =>
|
||||
{
|
||||
PlayerSettings.Android.preferredInstallLocation = AndroidPreferredInstallLocation.Auto;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_InstallLocationAuto);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "'Graphics Jobs' using disable.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return !PlayerSettings.graphicsJobs;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings > Player> Other Settings > 'Graphics Jobs' set to disable.",
|
||||
FixIt = () =>
|
||||
{
|
||||
PlayerSettings.graphicsJobs = false;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_DisableGraphicsJobs);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using tracking origin mode : Device or Floor.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
List<XROrigin> components = FindComponentsInScene<XROrigin>().Where(component => component.isActiveAndEnabled).ToList();
|
||||
|
||||
foreach(XROrigin origin in components)
|
||||
{
|
||||
if (TrackingOriginMode.NotSpecified == origin.RequestedTrackingOriginMode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
FixItMessage = "XROrigin > TrackingOriginMode.Device.",
|
||||
FixIt = () =>
|
||||
{
|
||||
List<XROrigin> components = FindComponentsInScene<XROrigin>().Where(component => component.isActiveAndEnabled).ToList();
|
||||
foreach(XROrigin origin in components)
|
||||
{
|
||||
origin.RequestedTrackingOriginMode = TrackingOriginMode.Device;
|
||||
}
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_TrackingOriginModeDevice);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using recommended 'Texture compression': ETC2 or ASTC.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return EditorUserBuildSettings.androidBuildSubtarget == MobileTextureSubtarget.ASTC ||
|
||||
EditorUserBuildSettings.androidBuildSubtarget == MobileTextureSubtarget.ETC2;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > 'Texture compression'.",
|
||||
FixIt = () =>
|
||||
{
|
||||
EditorUserBuildSettings.androidBuildSubtarget = MobileTextureSubtarget.ETC2;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_ETC2);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using '32-bit Display Buffer*'.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return PlayerSettings.use32BitDisplayBuffer;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings > Player> Resolution and Presentation > 'Use 32-bit Display Buffer*' set enable.",
|
||||
FixIt = () =>
|
||||
{
|
||||
PlayerSettings.use32BitDisplayBuffer = true;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_DisplayBufferFormat);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using Multithreaded Rendering.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return PlayerSettings.GetMobileMTRendering(recommendedBuildTarget);
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings > Player> Other Settings > 'Multithreaded Rendering' set to enable.",
|
||||
FixIt = () =>
|
||||
{
|
||||
PlayerSettings.SetMobileMTRendering(recommendedBuildTarget, true);
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_Multithreaded);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using recommended 'Pixel Light Count'.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
if(EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
|
||||
{
|
||||
return QualitySettings.pixelLightCount <= 1;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings> Quality> 'Pixel Light Count' set to 1.",
|
||||
FixIt = () =>
|
||||
{
|
||||
QualitySettings.pixelLightCount = 1;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_MaximumPixelLights);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
|
||||
#if UNITY_2022_2_OR_NEWER
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using recommended Texture Quality.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return QualitySettings.globalTextureMipmapLimit == 0;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings> Quality> 'Global Mipmap Limit' set to '0: Full Resolution'.",
|
||||
FixIt = () =>
|
||||
{
|
||||
QualitySettings.globalTextureMipmapLimit = 0;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_TextureQualitytoFullRes);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
#else
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using recommended Texture Quality.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return QualitySettings.masterTextureLimit == 0;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings> Quality> 'Texture Quality' set to 'Full Res'.",
|
||||
FixIt = () =>
|
||||
{
|
||||
QualitySettings.masterTextureLimit = 0;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_TextureQualitytoFullRes);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
#endif
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using recommended 'Anisotropic Texture'.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return QualitySettings.anisotropicFiltering == AnisotropicFiltering.Enable;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings> Quality> 'Anisotropic Texture' set to 'Per Texture'.",
|
||||
FixIt = () =>
|
||||
{
|
||||
QualitySettings.anisotropicFiltering = AnisotropicFiltering.Enable;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_AnisotropicFiltering);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using rendering path: forward.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return EditorGraphicsSettings.GetTierSettings(BuildTargetGroup.Android, Graphics.activeTier).renderingPath == RenderingPath.Forward;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings> Graphics > RenderingPath.Forward.",
|
||||
FixIt = () =>
|
||||
{
|
||||
var renderingTier = EditorGraphicsSettings.GetTierSettings(BuildTargetGroup.Android, Graphics.activeTier);
|
||||
renderingTier.renderingPath = RenderingPath.Forward;
|
||||
EditorGraphicsSettings.SetTierSettings(BuildTargetGroup.Android, Graphics.activeTier, renderingTier);
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_RenderingPathToForward);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using stereo rendering mode: multiview.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return GetSettings().stereoRenderingModeAndroid == PXR_Settings.StereoRenderingModeAndroid.Multiview;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings> PICO > Stereo Rendering Mode: Multiview.",
|
||||
FixIt = () =>
|
||||
{
|
||||
GetSettings().stereoRenderingModeAndroid = PXR_Settings.StereoRenderingModeAndroid.Multiview;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_Multiview);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using Default Contact Offset: 0.01f.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return Physics.defaultContactOffset >= 0.01f;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings> Physics > Default Contact Offset: 0.01f.",
|
||||
FixIt = () =>
|
||||
{
|
||||
Physics.defaultContactOffset = 0.01f;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_ContactOffset001);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using Sleep Threshold: 0.005f.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return Physics.sleepThreshold >= 0.005f;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings> Physics > Sleep Threshold: 0.005f.",
|
||||
FixIt = () =>
|
||||
{
|
||||
Physics.sleepThreshold = 0.005f;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_SleepThreshold0005);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using Default Solver Iterations: 8.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return Physics.defaultSolverIterations <= 8;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings> Physics > Default Solver Iterations: 8.",
|
||||
FixIt = () =>
|
||||
{
|
||||
Physics.defaultSolverIterations = 8;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_SolverIteration8);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = $"A single scene recommended up to 4 compositor layers.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return FindComponentsInScene<PXR_CompositionLayer>().Where(component => component.isActiveAndEnabled).ToList().Count <= 4;
|
||||
},
|
||||
FixItMessage = "You can click 'Fix' to navigate to the designated developer documentation page and follow the instructions to set it. ",
|
||||
FixIt = () =>
|
||||
{
|
||||
string url = "https://developer.picoxr.com/en/document/unity/vr-compositor-layers/";
|
||||
Application.OpenURL(url);
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_Overlay4);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
#if URP
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "When using URP, set IntermediateTextureMode.Auto.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
UniversalRenderPipelineAsset universalRenderPipelineAsset = PXR_Utils.GetCurrentURPAsset();
|
||||
if(universalRenderPipelineAsset != null)
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(universalRenderPipelineAsset);
|
||||
var dependency = AssetDatabase.GetDependencies(path);
|
||||
for (int i = 0; i < dependency.Length; i++)
|
||||
{
|
||||
if (AssetDatabase.GetMainAssetTypeAtPath(dependency[i]) != typeof(UniversalRendererData))
|
||||
continue;
|
||||
|
||||
UniversalRendererData renderData = (UniversalRendererData)AssetDatabase.LoadAssetAtPath(dependency[i], typeof(UniversalRendererData));
|
||||
return renderData.intermediateTextureMode == IntermediateTextureMode.Auto;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
FixItMessage = "Open Universal Render Pipeline Asset_Renderer > set IntermediateTextureMode.Auto.",
|
||||
FixIt = () =>
|
||||
{
|
||||
UniversalRenderPipelineAsset universalRenderPipelineAsset = PXR_Utils.GetCurrentURPAsset();
|
||||
if(universalRenderPipelineAsset != null)
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(universalRenderPipelineAsset);
|
||||
var dependency = AssetDatabase.GetDependencies(path);
|
||||
for (int i = 0; i < dependency.Length; i++)
|
||||
{
|
||||
if (AssetDatabase.GetMainAssetTypeAtPath(dependency[i]) != typeof(UniversalRendererData))
|
||||
continue;
|
||||
|
||||
UniversalRendererData renderData = (UniversalRendererData)AssetDatabase.LoadAssetAtPath(dependency[i], typeof(UniversalRendererData));
|
||||
renderData.intermediateTextureMode = IntermediateTextureMode.Auto;
|
||||
}
|
||||
}
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_URPIntermediatetexturetoAuto);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "When using URP, set disable SSAO.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
UniversalRenderPipelineAsset universalRenderPipelineAsset = PXR_Utils.GetCurrentURPAsset();
|
||||
if(universalRenderPipelineAsset != null)
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(universalRenderPipelineAsset);
|
||||
var dependency = AssetDatabase.GetDependencies(path);
|
||||
for (int i = 0; i < dependency.Length; i++)
|
||||
{
|
||||
if (AssetDatabase.GetMainAssetTypeAtPath(dependency[i]) != typeof(UniversalRendererData))
|
||||
continue;
|
||||
|
||||
UniversalRendererData renderData = (UniversalRendererData)AssetDatabase.LoadAssetAtPath(dependency[i], typeof(UniversalRendererData));
|
||||
|
||||
return renderData.rendererFeatures.Count == 0 || !renderData.rendererFeatures.Any(feature => feature != null && (feature.isActive && feature.GetType().Name == "ScreenSpaceAmbientOcclusion"));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
FixItMessage = "Open Universal Render Pipeline Asset_Renderer > disable ScreenSpaceAmbientOcclusion.",
|
||||
FixIt = () =>
|
||||
{
|
||||
UniversalRenderPipelineAsset universalRenderPipelineAsset = PXR_Utils.GetCurrentURPAsset();
|
||||
if(universalRenderPipelineAsset != null)
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(universalRenderPipelineAsset);
|
||||
var dependency = AssetDatabase.GetDependencies(path);
|
||||
for (int i = 0; i < dependency.Length; i++)
|
||||
{
|
||||
if (AssetDatabase.GetMainAssetTypeAtPath(dependency[i]) != typeof(UniversalRendererData))
|
||||
continue;
|
||||
|
||||
UniversalRendererData renderData = (UniversalRendererData)AssetDatabase.LoadAssetAtPath(dependency[i], typeof(UniversalRendererData));
|
||||
foreach( var feature in renderData.rendererFeatures)
|
||||
{
|
||||
if (feature != null && feature.GetType().Name == "ScreenSpaceAmbientOcclusion")
|
||||
feature.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_URPDisableSSAO);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "When the URP package is installed but not set up and used, it is recommended to use or delete it.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
if (QualitySettings.renderPipeline == null && GraphicsSettings.currentRenderPipeline == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
FixItMessage = "If you are not clear about how to set it, you can click 'Fix' to navigate to the designated developer documentation page and follow the instructions to set it.",
|
||||
FixIt = () =>
|
||||
{
|
||||
string url = "https://developer-cn.picoxr.com/document/unity/universal-render-pipeline/";
|
||||
Application.OpenURL(url);
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_URPNoUseToDelete);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
#endif
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using recommended 'Run Without Focus'.",
|
||||
IsRuleEnabled = ()=>
|
||||
{
|
||||
return PXR_Utils.IsPXRValidationEnabled() || PXR_Utils.IsOpenXRValidationEnabled();
|
||||
},
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
bool isRunInBackgroundEnabled = PlayerSettings.runInBackground;
|
||||
|
||||
return isRunInBackgroundEnabled;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings > Player > Resolution and Presentation > Resolution > 'Run Without Focus' set to enable.",
|
||||
FixIt = () =>
|
||||
{
|
||||
PlayerSettings.runInBackground = true;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_Unity6RunInBackground);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
#endif
|
||||
#endregion
|
||||
|
||||
#region PXR Platform Validation
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using MRC.",
|
||||
IsRuleEnabled = PXR_Utils.IsPXRValidationEnabled,
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return PXR_ProjectSetting.GetProjectConfig().openMRC;
|
||||
},
|
||||
FixItMessage = "PXR_Manager > 'MRC' set to enable.",
|
||||
FixIt = () =>
|
||||
{
|
||||
PXR_ProjectSetting.GetProjectConfig().openMRC = true;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_MRC);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Recommended to set system refresh rate to default. After setting, executed based on device rates.",
|
||||
IsRuleEnabled = PXR_Utils.IsPXRValidationEnabled,
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return GetSettings().systemDisplayFrequency == PXR_Settings.SystemDisplayFrequency.Default;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings> PICO > Display Refresh Rates: Default.",
|
||||
FixIt = () =>
|
||||
{
|
||||
GetSettings().systemDisplayFrequency = PXR_Settings.SystemDisplayFrequency.Default;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_DisplayRefreshRatesDefault);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "When using Vulkan, it is recommended to check the 'Optimize Buffer Discards' option.",
|
||||
IsRuleEnabled = PXR_Utils.IsPXRValidationEnabled,
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
if (GraphicsDeviceType.OpenGLES3 == PlayerSettings.GetGraphicsAPIs(EditorUserBuildSettings.activeBuildTarget)[0])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return GetSettings().optimizeBufferDiscards;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings> PICO > 'Optimize Buffer Discards' set to enable.",
|
||||
FixIt = () =>
|
||||
{
|
||||
GetSettings().optimizeBufferDiscards = true;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_VKOptimizeBufferDiscards);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "'Color Space' using Linear.",
|
||||
IsRuleEnabled = PXR_Utils.IsPXRValidationEnabled,
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return PlayerSettings.colorSpace == ColorSpace.Linear;
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings > Player> Other Settings > 'Color Space' set to 'Linear'.",
|
||||
FixIt = () =>
|
||||
{
|
||||
PlayerSettings.colorSpace = ColorSpace.Linear;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_ColorSpaceLinear);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "When using ETFR/FFR, it is recommended to enable subsampling to improve performance.",
|
||||
IsRuleEnabled = PXR_Utils.IsPXRValidationEnabled,
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
if (PXR_ProjectSetting.GetProjectConfig().recommendSubsamping)
|
||||
{
|
||||
return PXR_ProjectSetting.GetProjectConfig().enableSubsampled;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
FixItMessage = "PXR_Manager > Subsamping set to enable.",
|
||||
FixIt = () =>
|
||||
{
|
||||
PXR_ProjectSetting.GetProjectConfig().enableSubsampled = true;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_FFRSubsampling);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Using recommended MSAA.",
|
||||
IsRuleEnabled = PXR_Utils.IsPXRValidationEnabled,
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
if (PXR_ProjectSetting.GetProjectConfig().recommendMSAA)
|
||||
{
|
||||
return PXR_ProjectSetting.GetProjectConfig().enableRecommendMSAA;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
FixItMessage = "PXR_Manager > 'Use Recommended MSAA' set to enable.",
|
||||
FixIt = () =>
|
||||
{
|
||||
PXR_ProjectSetting.GetProjectConfig().enableRecommendMSAA = true;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_MSAA);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
new BuildValidationRule
|
||||
{
|
||||
Category = k_Catergory,
|
||||
Message = "Not recommended to use both 'Application SpaceWarp' and 'Content Protect' simultaneously.",
|
||||
IsRuleEnabled = PXR_Utils.IsPXRValidationEnabled,
|
||||
CheckPredicate = () =>
|
||||
{
|
||||
return !(PXR_ProjectSetting.GetProjectConfig().useContentProtect && GetSettings().enableAppSpaceWarp);
|
||||
},
|
||||
FixItMessage = "Open Project Settings > Player Settings> PICO > Application SpaceWarp: disabled.",
|
||||
FixIt = () =>
|
||||
{
|
||||
GetSettings().enableAppSpaceWarp = false;
|
||||
PXR_AppLog.PXR_OnEvent(PXR_AppLog.strProjectValidation, PXR_AppLog.strProjectValidation_APPSWNoContentProtect);
|
||||
},
|
||||
Error = false
|
||||
},
|
||||
#endregion
|
||||
|
||||
#region PICO OpenXR Validation
|
||||
|
||||
#endregion
|
||||
|
||||
};
|
||||
BuildValidator.AddRules(BuildTargetGroup.Android, androidGlobalRules);
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
public static List<T> FindComponentsInScene<T>() where T : Component
|
||||
{
|
||||
var activeScene = SceneManager.GetActiveScene();
|
||||
var foundComponents = new List<T>();
|
||||
|
||||
var rootObjects = activeScene.GetRootGameObjects();
|
||||
foreach (var rootObject in rootObjects)
|
||||
{
|
||||
var components = rootObject.GetComponentsInChildren<T>(true);
|
||||
foundComponents.AddRange(components);
|
||||
}
|
||||
|
||||
return foundComponents;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0de36cde8e3d3df4684f21ecfea95d77
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ee7b364f4dea3945a08be5340c61410
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"name": "Unity.XR.PICO.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"Unity.XR.PICO",
|
||||
"Unity.XR.Management",
|
||||
"Unity.XR.Management.Editor",
|
||||
"Unity.XR.ARFoundation",
|
||||
"Unity.XR.CoreUtils",
|
||||
"Unity.XR.CoreUtils.Editor",
|
||||
"Unity.RenderPipelines.Universal.Runtime",
|
||||
"Unity.XR.Interaction.Toolkit",
|
||||
"Unity.InputSystem",
|
||||
"Unity.XR.Hands.Samples.VisualizerSample",
|
||||
"Unity.XR.Hands",
|
||||
"Unity.XR.OpenXR",
|
||||
"Unity.XR.OpenXR.Editor",
|
||||
"Pico.Spatializer"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.unity.xr.management",
|
||||
"expression": "3.2.0",
|
||||
"define": "XR_MGMT_GTE_320"
|
||||
},
|
||||
{
|
||||
"name": "com.unity.xr.hands",
|
||||
"expression": "1.3.0",
|
||||
"define": "XR_HAND"
|
||||
},
|
||||
{
|
||||
"name": "com.unity.render-pipelines.universal",
|
||||
"expression": "12.1.12",
|
||||
"define": "URP"
|
||||
},
|
||||
{
|
||||
"name": "com.unity.xr.openxr",
|
||||
"expression": "",
|
||||
"define": "UNITY_OPENXR"
|
||||
},
|
||||
{
|
||||
"name": "com.unity.xr.arfoundation",
|
||||
"expression": "[5.1.2,6.0.0]",
|
||||
"define": "AR_FOUNDATION_5"
|
||||
},
|
||||
{
|
||||
"name": "com.unity.xr.arfoundation",
|
||||
"expression": "6.0.0",
|
||||
"define": "AR_FOUNDATION_6"
|
||||
},
|
||||
{
|
||||
"name": "com.unity.xr.interaction.toolkit",
|
||||
"expression": "3.0.0",
|
||||
"define": "XRI_TOOLKIT_3"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc14c791d414ba84589e05cbda4403fd
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user