version 2.0.0

This commit is contained in:
srl87
2023-09-14 18:17:47 +08:00
parent 13e9d00b37
commit ca21423a06
953 changed files with 125887 additions and 21229 deletions

View File

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

View File

@@ -0,0 +1,539 @@
// "VIVE SDK
// © 2020 HTC Corporation. All Rights Reserved.
//
// Unless otherwise required by copyright law and practice,
// upon the execution of HTC SDK license agreement,
// HTC grants you access to and use of the VIVE SDK(s).
// You shall fully comply with all of HTCs SDK license agreement terms and
// conditions signed by you and all SDK and API requirements,
// specifications, and documentation provided by HTC to You."
using UnityEngine;
#if UNITY_EDITOR
namespace VIVE.OpenXR.CompositionLayer.Editor
{
#region Composition Layer Editor
using UnityEditor;
using UnityEditor.SceneManagement;
using VIVE.OpenXR.CompositionLayer;
using UnityEditor.XR.OpenXR.Features;
[CustomEditor(typeof(CompositionLayer))]
public class CompositionLayerEditor : Editor
{
static string PropertyName_LayerType = "layerType";
static GUIContent Label_LayerType = new GUIContent("Type", "Specify the type of the composition layer.");
SerializedProperty Property_LayerType;
static string PropertyName_CompositionDepth = "compositionDepth";
static GUIContent Label_CompositionDepth = new GUIContent("Composition Depth", "Specify the composition depth of the layer.");
SerializedProperty Property_CompositionDepth;
static string PropertyName_LayerShape = "layerShape";
static GUIContent Label_LayerShape = new GUIContent("Shape", "Specify the shape of the layer.");
SerializedProperty Property_LayerShape;
static string PropertyName_LayerVisibility = "layerVisibility";
static GUIContent Label_LayerVisibility = new GUIContent("Visibility", "Specify the visibility of the layer.");
SerializedProperty Property_LayerVisibility;
static string PropertyName_LockMode = "lockMode";
static GUIContent Label_LockMode = new GUIContent("Locked Parameter", "Cylinder Layer parameter to be locked when changing the radius.");
SerializedProperty Property_LockMode;
static string PropertyName_QuadWidth = "m_QuadWidth";
static GUIContent Label_QuadWidth = new GUIContent("Width", "Width of a Quad Layer");
SerializedProperty Property_QuadWidth;
static string PropertyName_QuadHeight = "m_QuadHeight";
static GUIContent Label_QuadHeight = new GUIContent("Height", "Height of a Quad Layer");
SerializedProperty Property_QuadHeight;
static string PropertyName_CylinderHeight = "m_CylinderHeight";
static GUIContent Label_CylinderHeight = new GUIContent("Height", "Height of Cylinder Layer");
SerializedProperty Property_CylinderHeight;
static string PropertyName_CylinderArcLength = "m_CylinderArcLength";
static GUIContent Label_CylinderArcLength = new GUIContent("Arc Length", "Arc Length of Cylinder Layer");
SerializedProperty Property_CylinderArcLength;
static string PropertyName_CylinderRadius = "m_CylinderRadius";
static GUIContent Label_CylinderRadius = new GUIContent("Radius", "Radius of Cylinder Layer");
SerializedProperty Property_CylinderRadius;
static string PropertyName_AngleOfArc = "m_CylinderAngleOfArc";
static GUIContent Label_AngleOfArc = new GUIContent("Arc Angle", "Central angle of arc of Cylinder Layer");
SerializedProperty Property_AngleOfArc;
static string PropertyName_IsDynamicLayer = "isDynamicLayer";
static GUIContent Label_IsDynamicLayer = new GUIContent("Dynamic Layer", "Specify whether Layer needs to be updated each frame or not.");
SerializedProperty Property_IsDynamicLayer;
static string PropertyName_ApplyColorScaleBias = "applyColorScaleBias";
static GUIContent Label_ApplyColorScaleBias = new GUIContent("Apply Color Scale Bias", "Color scale and bias are applied to a layer color during composition, after its conversion to premultiplied alpha representation. LayerColor = LayerColor * colorScale + colorBias");
SerializedProperty Property_ApplyColorScaleBias;
static string PropertyName_ColorScale = "colorScale";
static GUIContent Label_ColorScale = new GUIContent("Color Scale", "Will be used for modulatting the color sourced from the images.");
SerializedProperty Property_ColorScale;
static string PropertyName_ColorBias = "colorBias";
static GUIContent Label_ColorBias = new GUIContent("Color Bias", "Will be used for offseting the color sourced from the images.");
SerializedProperty Property_ColorBias;
static string PropertyName_IsProtectedSurface = "isProtectedSurface";
static GUIContent Label_IsProtectedSurface = new GUIContent("Protected Surface");
SerializedProperty Property_IsProtectedSurface;
static string PropertyName_RenderPriority = "renderPriority";
static GUIContent Label_RenderPriority = new GUIContent("Render Priority", "When Auto Fallback is enabled, layers with a higher render priority will be rendered as normal layers first.");
SerializedProperty Property_RenderPriority;
static string PropertyName_TrackingOrigin = "trackingOrigin";
static GUIContent Label_TrackingOrigin = new GUIContent("Tracking Origin", "Assign the tracking origin here to offset the pose of the Composition Layer.");
SerializedProperty Property_TrackingOrigin;
private bool showLayerParams = true, showColorScaleBiasParams = true;
#pragma warning disable
private bool showExternalSurfaceParams = false;
#pragma warning restore
public override void OnInspectorGUI()
{
if (Property_LayerType == null) Property_LayerType = serializedObject.FindProperty(PropertyName_LayerType);
if (Property_CompositionDepth == null) Property_CompositionDepth = serializedObject.FindProperty(PropertyName_CompositionDepth);
if (Property_LayerShape == null) Property_LayerShape = serializedObject.FindProperty(PropertyName_LayerShape);
if (Property_LayerVisibility == null) Property_LayerVisibility = serializedObject.FindProperty(PropertyName_LayerVisibility);
if (Property_LockMode == null) Property_LockMode = serializedObject.FindProperty(PropertyName_LockMode);
if (Property_QuadWidth == null) Property_QuadWidth = serializedObject.FindProperty(PropertyName_QuadWidth);
if (Property_QuadHeight == null) Property_QuadHeight = serializedObject.FindProperty(PropertyName_QuadHeight);
if (Property_CylinderHeight == null) Property_CylinderHeight = serializedObject.FindProperty(PropertyName_CylinderHeight);
if (Property_CylinderArcLength == null) Property_CylinderArcLength = serializedObject.FindProperty(PropertyName_CylinderArcLength);
if (Property_CylinderRadius == null) Property_CylinderRadius = serializedObject.FindProperty(PropertyName_CylinderRadius);
if (Property_AngleOfArc == null) Property_AngleOfArc = serializedObject.FindProperty(PropertyName_AngleOfArc);
if (Property_IsDynamicLayer == null) Property_IsDynamicLayer = serializedObject.FindProperty(PropertyName_IsDynamicLayer);
if (Property_ApplyColorScaleBias == null) Property_ApplyColorScaleBias = serializedObject.FindProperty(PropertyName_ApplyColorScaleBias);
if (Property_ColorScale == null) Property_ColorScale = serializedObject.FindProperty(PropertyName_ColorScale);
if (Property_ColorBias == null) Property_ColorBias = serializedObject.FindProperty(PropertyName_ColorBias);
if (Property_IsProtectedSurface == null) Property_IsProtectedSurface = serializedObject.FindProperty(PropertyName_IsProtectedSurface);
if (Property_RenderPriority == null) Property_RenderPriority = serializedObject.FindProperty(PropertyName_RenderPriority);
if (Property_TrackingOrigin == null) Property_TrackingOrigin = serializedObject.FindProperty(PropertyName_TrackingOrigin);
CompositionLayer targetCompositionLayer = target as CompositionLayer;
if (!FeatureHelpers.GetFeatureWithIdForBuildTarget(BuildTargetGroup.Android, ViveCompositionLayer.featureId).enabled)
{
EditorGUILayout.HelpBox("The Composition Layer feature is not enabled in OpenXR Settings.\nEnable it to use the Composition Layer.", MessageType.Warning);
}
EditorGUILayout.PropertyField(Property_LayerType, new GUIContent(Label_LayerType));
serializedObject.ApplyModifiedProperties();
EditorGUILayout.PropertyField(Property_CompositionDepth, new GUIContent(Label_CompositionDepth));
serializedObject.ApplyModifiedProperties();
EditorGUILayout.PropertyField(Property_LayerShape, new GUIContent(Label_LayerShape));
serializedObject.ApplyModifiedProperties();
if (Property_LayerShape.intValue == (int)CompositionLayer.LayerShape.Cylinder)
{
if (!FeatureHelpers.GetFeatureWithIdForBuildTarget(BuildTargetGroup.Android, ViveCompositionLayerCylinder.featureId).enabled)
{
EditorGUILayout.HelpBox("The Composition Layer Cylinder feature is not enabled in OpenXR Settings.\nEnable it to use Cylinder layers.", MessageType.Warning);
}
if (targetCompositionLayer.isPreviewingQuad)
{
targetCompositionLayer.isPreviewingQuad = false;
if (targetCompositionLayer.generatedPreview != null)
{
DestroyImmediate(targetCompositionLayer.generatedPreview);
}
}
Transform generatedQuadTransform = targetCompositionLayer.transform.Find(CompositionLayer.QuadUnderlayMeshName);
if (generatedQuadTransform != null)
{
DestroyImmediate(generatedQuadTransform.gameObject);
}
EditorGUI.indentLevel++;
showLayerParams = EditorGUILayout.Foldout(showLayerParams, "Cylinder Parameters");
if (showLayerParams)
{
float radiusLowerBound = Mathf.Max(0.001f, CompositionLayer.CylinderParameterHelper.ArcLengthAndDegAngleOfArcToRadius(targetCompositionLayer.cylinderArcLength, targetCompositionLayer.angleOfArcUpperLimit));
float radiusUpperBound = CompositionLayer.CylinderParameterHelper.ArcLengthAndDegAngleOfArcToRadius(targetCompositionLayer.cylinderArcLength, targetCompositionLayer.angleOfArcLowerLimit);
EditorGUILayout.HelpBox("Changing the Arc Length will affect the upper and lower bounds of the radius.\nUpper Bound of Radius: " + radiusUpperBound + "\nLower Bound of Radius: " + radiusLowerBound, MessageType.Info);
EditorGUILayout.PropertyField(Property_CylinderRadius, new GUIContent(Label_CylinderRadius));
EditorGUILayout.PropertyField(Property_LockMode, new GUIContent(Label_LockMode));
serializedObject.ApplyModifiedProperties();
EditorGUILayout.HelpBox("Arc Length and Arc Angle are correlated, adjusting one of them changes the other as well. The Radius will not be changed when adjusting these two values.", MessageType.Info);
if (targetCompositionLayer.lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcLength)
{
GUI.enabled = false;
EditorGUILayout.PropertyField(Property_CylinderArcLength, new GUIContent(Label_CylinderArcLength));
GUI.enabled = true;
EditorGUILayout.Slider(Property_AngleOfArc, targetCompositionLayer.angleOfArcLowerLimit, targetCompositionLayer.angleOfArcUpperLimit, new GUIContent(Label_AngleOfArc));
}
else if (targetCompositionLayer.lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcAngle)
{
EditorGUILayout.PropertyField(Property_CylinderArcLength, new GUIContent(Label_CylinderArcLength));
GUI.enabled = false;
EditorGUILayout.Slider(Property_AngleOfArc, targetCompositionLayer.angleOfArcLowerLimit, targetCompositionLayer.angleOfArcUpperLimit, new GUIContent(Label_AngleOfArc));
GUI.enabled = true;
}
EditorGUILayout.PropertyField(Property_CylinderHeight, new GUIContent(Label_CylinderHeight));
}
EditorGUI.indentLevel--;
serializedObject.ApplyModifiedProperties();
CompositionLayer.CylinderLayerParamAdjustmentMode currentAdjustmentMode = targetCompositionLayer.CurrentAdjustmentMode();
switch (currentAdjustmentMode)
{
case CompositionLayer.CylinderLayerParamAdjustmentMode.ArcLength:
{
targetCompositionLayer.CylinderAngleOfArc = CompositionLayer.CylinderParameterHelper.RadiusAndArcLengthToDegAngleOfArc(targetCompositionLayer.CylinderArcLength, targetCompositionLayer.CylinderRadius);
float cylinderArcLengthRef = targetCompositionLayer.CylinderArcLength;
if (!ArcLengthValidityCheck(ref cylinderArcLengthRef, targetCompositionLayer.CylinderRadius, targetCompositionLayer.angleOfArcLowerLimit, targetCompositionLayer.angleOfArcUpperLimit))
{
targetCompositionLayer.CylinderArcLength = cylinderArcLengthRef;
targetCompositionLayer.CylinderAngleOfArc = CompositionLayer.CylinderParameterHelper.RadiusAndArcLengthToDegAngleOfArc(targetCompositionLayer.CylinderArcLength, targetCompositionLayer.CylinderRadius);
}
serializedObject.ApplyModifiedProperties();
break;
}
case CompositionLayer.CylinderLayerParamAdjustmentMode.ArcAngle:
{
targetCompositionLayer.CylinderArcLength = CompositionLayer.CylinderParameterHelper.RadiusAndDegAngleOfArcToArcLength(targetCompositionLayer.CylinderAngleOfArc, targetCompositionLayer.CylinderRadius);
serializedObject.ApplyModifiedProperties();
break;
}
case CompositionLayer.CylinderLayerParamAdjustmentMode.Radius:
default:
{
float cylinderRadiusRef = targetCompositionLayer.CylinderRadius;
RadiusValidityCheck(targetCompositionLayer.CylinderArcLength, ref cylinderRadiusRef, targetCompositionLayer.angleOfArcLowerLimit, targetCompositionLayer.angleOfArcUpperLimit, targetCompositionLayer.lockMode);
targetCompositionLayer.CylinderRadius = cylinderRadiusRef;
if (targetCompositionLayer.lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcLength)
{
targetCompositionLayer.CylinderAngleOfArc = CompositionLayer.CylinderParameterHelper.RadiusAndArcLengthToDegAngleOfArc(targetCompositionLayer.CylinderArcLength, targetCompositionLayer.CylinderRadius);
float cylinderArcLengthRef = targetCompositionLayer.CylinderArcLength;
if (!ArcLengthValidityCheck(ref cylinderArcLengthRef, targetCompositionLayer.CylinderRadius, targetCompositionLayer.angleOfArcLowerLimit, targetCompositionLayer.angleOfArcUpperLimit))
{
targetCompositionLayer.CylinderArcLength = cylinderArcLengthRef;
targetCompositionLayer.CylinderAngleOfArc = CompositionLayer.CylinderParameterHelper.RadiusAndArcLengthToDegAngleOfArc(targetCompositionLayer.CylinderArcLength, targetCompositionLayer.CylinderRadius);
}
}
else if (targetCompositionLayer.lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcAngle)
{
targetCompositionLayer.CylinderArcLength = CompositionLayer.CylinderParameterHelper.RadiusAndDegAngleOfArcToArcLength(targetCompositionLayer.CylinderAngleOfArc, targetCompositionLayer.CylinderRadius);
}
serializedObject.ApplyModifiedProperties();
break;
}
}
EditorGUILayout.HelpBox("Current Layer Aspect Ratio (Arc Length : Height) = " + targetCompositionLayer.CylinderArcLength + " : " + targetCompositionLayer.CylinderHeight, MessageType.Info);
Vector3 CompositionLayerScale = targetCompositionLayer.gameObject.transform.localScale;
bool CylinderParamsChanged = targetCompositionLayer.LayerDimensionsChanged();
if (targetCompositionLayer.isPreviewingCylinder)
{
Transform generatedPreviewTransform = targetCompositionLayer.transform.Find(CompositionLayer.CylinderPreviewName);
if (generatedPreviewTransform != null)
{
targetCompositionLayer.generatedPreview = generatedPreviewTransform.gameObject;
if (CylinderParamsChanged)
{
//Generate vertices
Vector3[] cylinderVertices = CompositionLayer.MeshGenerationHelper.GenerateCylinderVertex(targetCompositionLayer.CylinderAngleOfArc, targetCompositionLayer.CylinderRadius, targetCompositionLayer.CylinderHeight);;
MeshFilter cylinderMeshFilter = targetCompositionLayer.generatedPreview.GetComponent<MeshFilter>();
//Generate Mesh
cylinderMeshFilter.mesh = CompositionLayer.MeshGenerationHelper.GenerateCylinderMesh(targetCompositionLayer.CylinderAngleOfArc, cylinderVertices);
targetCompositionLayer.generatedPreview.transform.localPosition = Vector3.zero;
targetCompositionLayer.generatedPreview.transform.localRotation = Quaternion.identity;
targetCompositionLayer.generatedPreview.transform.localScale = targetCompositionLayer.GetNormalizedLocalScale(targetCompositionLayer.transform, Vector3.one);
}
if (targetCompositionLayer.generatedPreview.GetComponent<MeshRenderer>().sharedMaterial.mainTexture != targetCompositionLayer.texture)
{
targetCompositionLayer.generatedPreview.GetComponent<MeshRenderer>().sharedMaterial.mainTexture = targetCompositionLayer.texture;
}
if (GUILayout.Button("Hide Cylinder Preview"))
{
targetCompositionLayer.isPreviewingCylinder = false;
if (targetCompositionLayer.generatedPreview != null)
{
DestroyImmediate(targetCompositionLayer.generatedPreview);
}
}
}
else
{
targetCompositionLayer.isPreviewingCylinder = false;
}
}
else
{
if (GUILayout.Button("Show Cylinder Preview"))
{
targetCompositionLayer.isPreviewingCylinder = true;
Vector3[] cylinderVertices = CompositionLayer.MeshGenerationHelper.GenerateCylinderVertex(targetCompositionLayer.CylinderAngleOfArc, targetCompositionLayer.CylinderRadius, targetCompositionLayer.CylinderHeight);
//Add components to Game Object
targetCompositionLayer.generatedPreview = new GameObject();
targetCompositionLayer.generatedPreview.hideFlags = HideFlags.HideAndDontSave;
targetCompositionLayer.generatedPreview.name = CompositionLayer.CylinderPreviewName;
targetCompositionLayer.generatedPreview.transform.SetParent(targetCompositionLayer.gameObject.transform);
targetCompositionLayer.generatedPreview.transform.localPosition = Vector3.zero;
targetCompositionLayer.generatedPreview.transform.localRotation = Quaternion.identity;
targetCompositionLayer.generatedPreview.transform.localScale = targetCompositionLayer.GetNormalizedLocalScale(targetCompositionLayer.transform, Vector3.one);
MeshRenderer cylinderMeshRenderer = targetCompositionLayer.generatedPreview.AddComponent<MeshRenderer>();
MeshFilter cylinderMeshFilter = targetCompositionLayer.generatedPreview.AddComponent<MeshFilter>();
cylinderMeshRenderer.sharedMaterial = new Material(Shader.Find("Unlit/Transparent"));
if (targetCompositionLayer.texture != null)
{
cylinderMeshRenderer.sharedMaterial.mainTexture = targetCompositionLayer.texture;
}
//Generate Mesh
cylinderMeshFilter.mesh = CompositionLayer.MeshGenerationHelper.GenerateCylinderMesh(targetCompositionLayer.CylinderAngleOfArc, cylinderVertices);
}
}
EditorGUILayout.Space(10);
serializedObject.ApplyModifiedProperties();
}
else if (Property_LayerShape.intValue == (int)CompositionLayer.LayerShape.Quad)
{
if (targetCompositionLayer.isPreviewingCylinder)
{
targetCompositionLayer.isPreviewingCylinder = false;
if (targetCompositionLayer.generatedPreview != null)
{
DestroyImmediate(targetCompositionLayer.generatedPreview);
}
}
EditorGUI.indentLevel++;
showLayerParams = EditorGUILayout.Foldout(showLayerParams, "Quad Parameters");
if (showLayerParams)
{
EditorGUILayout.PropertyField(Property_QuadWidth, new GUIContent(Label_QuadWidth));
EditorGUILayout.PropertyField(Property_QuadHeight, new GUIContent(Label_QuadHeight));
}
EditorGUI.indentLevel--;
EditorGUILayout.HelpBox("Current Layer Aspect Ratio (Width : Height) = " + targetCompositionLayer.quadWidth + " : " + targetCompositionLayer.quadHeight, MessageType.Info);
Vector3 CompositionLayerScale = targetCompositionLayer.gameObject.transform.localScale;
bool QuadParamsChanged = targetCompositionLayer.LayerDimensionsChanged();
if (targetCompositionLayer.isPreviewingQuad)
{
Transform generatedPreviewTransform = targetCompositionLayer.transform.Find(CompositionLayer.QuadPreviewName);
if (generatedPreviewTransform != null)
{
targetCompositionLayer.generatedPreview = generatedPreviewTransform.gameObject;
if (QuadParamsChanged)
{
//Generate vertices
Vector3[] quadVertices = CompositionLayer.MeshGenerationHelper.GenerateQuadVertex(targetCompositionLayer.quadWidth, targetCompositionLayer.quadHeight);
MeshFilter quadMeshFilter = targetCompositionLayer.generatedPreview.GetComponent<MeshFilter>();
//Generate Mesh
quadMeshFilter.mesh = CompositionLayer.MeshGenerationHelper.GenerateQuadMesh(quadVertices);
targetCompositionLayer.generatedPreview.transform.localPosition = Vector3.zero;
targetCompositionLayer.generatedPreview.transform.localRotation = Quaternion.identity;
targetCompositionLayer.generatedPreview.transform.localScale = targetCompositionLayer.GetNormalizedLocalScale(targetCompositionLayer.transform, Vector3.one);
}
if (targetCompositionLayer.generatedPreview.GetComponent<MeshRenderer>().sharedMaterial.mainTexture != targetCompositionLayer.texture)
{
targetCompositionLayer.generatedPreview.GetComponent<MeshRenderer>().sharedMaterial.mainTexture = targetCompositionLayer.texture;
}
if (GUILayout.Button("Hide Quad Preview"))
{
targetCompositionLayer.isPreviewingQuad = false;
if (targetCompositionLayer.generatedPreview != null)
{
DestroyImmediate(targetCompositionLayer.generatedPreview);
}
}
}
else
{
targetCompositionLayer.isPreviewingQuad = false;
}
}
else
{
if (GUILayout.Button("Show Quad Preview"))
{
targetCompositionLayer.isPreviewingQuad = true;
//Generate vertices
Vector3[] quadVertices = CompositionLayer.MeshGenerationHelper.GenerateQuadVertex(targetCompositionLayer.quadWidth, targetCompositionLayer.quadHeight);
//Add components to Game Object
targetCompositionLayer.generatedPreview = new GameObject();
targetCompositionLayer.generatedPreview.hideFlags = HideFlags.HideAndDontSave;
targetCompositionLayer.generatedPreview.name = CompositionLayer.QuadPreviewName;
targetCompositionLayer.generatedPreview.transform.SetParent(targetCompositionLayer.gameObject.transform);
targetCompositionLayer.generatedPreview.transform.localPosition = Vector3.zero;
targetCompositionLayer.generatedPreview.transform.localRotation = Quaternion.identity;
targetCompositionLayer.generatedPreview.transform.localScale = targetCompositionLayer.GetNormalizedLocalScale(targetCompositionLayer.transform, Vector3.one);
MeshRenderer quadMeshRenderer = targetCompositionLayer.generatedPreview.AddComponent<MeshRenderer>();
MeshFilter quadMeshFilter = targetCompositionLayer.generatedPreview.AddComponent<MeshFilter>();
quadMeshRenderer.sharedMaterial = new Material(Shader.Find("Unlit/Transparent"));
if (targetCompositionLayer.texture != null)
{
quadMeshRenderer.sharedMaterial.mainTexture = targetCompositionLayer.texture;
}
//Generate Mesh
quadMeshFilter.mesh = CompositionLayer.MeshGenerationHelper.GenerateQuadMesh(quadVertices);
}
}
}
//Rect UI For textures
Rect labelRect = EditorGUILayout.GetControlRect();
EditorGUI.LabelField(new Rect(labelRect.x, labelRect.y, labelRect.width / 2, labelRect.height), new GUIContent("Texture", "Texture to be rendered on the layer"));
Rect textureRect = EditorGUILayout.GetControlRect(GUILayout.Height(64));
targetCompositionLayer.texture = (Texture)EditorGUI.ObjectField(new Rect(textureRect.x, textureRect.y, 64, textureRect.height), targetCompositionLayer.texture, typeof(Texture), true);
EditorGUILayout.PropertyField(Property_LayerVisibility, new GUIContent(Label_LayerVisibility));
serializedObject.ApplyModifiedProperties();
EditorGUILayout.PropertyField(Property_IsDynamicLayer, Label_IsDynamicLayer);
serializedObject.ApplyModifiedProperties();
EditorGUILayout.PropertyField(Property_ApplyColorScaleBias, Label_ApplyColorScaleBias);
serializedObject.ApplyModifiedProperties();
if (targetCompositionLayer.applyColorScaleBias)
{
if(!FeatureHelpers.GetFeatureWithIdForBuildTarget(BuildTargetGroup.Android, ViveCompositionLayerColorScaleBias.featureId).enabled)
{
EditorGUILayout.HelpBox("The Color Scale Bias feature is not enabled in OpenXR Settings.", MessageType.Warning);
}
EditorGUI.indentLevel++;
showColorScaleBiasParams = EditorGUILayout.Foldout(showColorScaleBiasParams, "Color Scale Bias Parameters");
if (showColorScaleBiasParams)
{
EditorGUILayout.PropertyField(Property_ColorScale, Label_ColorScale);
EditorGUILayout.PropertyField(Property_ColorBias, Label_ColorBias);
serializedObject.ApplyModifiedProperties();
}
EditorGUI.indentLevel--;
}
ViveCompositionLayer compositionLayerFeature = (ViveCompositionLayer)FeatureHelpers.GetFeatureWithIdForBuildTarget(BuildTargetGroup.Android, ViveCompositionLayer.featureId);
if (compositionLayerFeature != null && compositionLayerFeature.enableAutoFallback)
{
EditorGUILayout.PropertyField(Property_RenderPriority, new GUIContent(Label_RenderPriority));
serializedObject.ApplyModifiedProperties();
}
EditorGUILayout.PropertyField(Property_TrackingOrigin, Label_TrackingOrigin);
serializedObject.ApplyModifiedProperties();
}
public static bool RadiusValidityCheck(float inArcLength, ref float inRadius, float thetaLowerLimit, float thetaUpperLimit, CompositionLayer.CylinderLayerParamLockMode lockMode)
{
bool isValid = true;
if (inRadius <= 0)
{
inRadius = CompositionLayer.CylinderParameterHelper.ArcLengthAndDegAngleOfArcToRadius(inArcLength, thetaUpperLimit);
isValid = false;
return isValid;
}
float degThetaResult = CompositionLayer.CylinderParameterHelper.RadiusAndArcLengthToDegAngleOfArc(inArcLength, inRadius);
if (degThetaResult < thetaLowerLimit)
{
if (lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcAngle) //Angle locked, increase arc length
{
ArcLengthValidityCheck(ref inArcLength, inRadius, thetaLowerLimit, thetaUpperLimit);
inRadius = CompositionLayer.CylinderParameterHelper.ArcLengthAndDegAngleOfArcToRadius(inArcLength, thetaLowerLimit);
}
else if (lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcLength) //ArcLength Locked, keep angle at min
{
inRadius = CompositionLayer.CylinderParameterHelper.ArcLengthAndDegAngleOfArcToRadius(inArcLength, thetaLowerLimit);
}
isValid = false;
}
else if (degThetaResult > thetaUpperLimit)
{
if (lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcAngle) //Angle locked, decrease arc length
{
ArcLengthValidityCheck(ref inArcLength, inRadius, thetaLowerLimit, thetaUpperLimit);
inRadius = CompositionLayer.CylinderParameterHelper.ArcLengthAndDegAngleOfArcToRadius(inArcLength, thetaUpperLimit);
}
else if (lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcLength) //ArcLength Locked, keep angle at max
{
inRadius = CompositionLayer.CylinderParameterHelper.ArcLengthAndDegAngleOfArcToRadius(inArcLength, thetaUpperLimit);
}
isValid = false;
}
return isValid;
}
public static bool ArcLengthValidityCheck(ref float inArcLength, float inRadius, float thetaLowerLimit, float thetaUpperLimit)
{
bool isValid = true;
if (inArcLength <= 0)
{
inArcLength = CompositionLayer.CylinderParameterHelper.RadiusAndDegAngleOfArcToArcLength(thetaLowerLimit, inRadius);
isValid = false;
return isValid;
}
float degThetaResult = CompositionLayer.CylinderParameterHelper.RadiusAndArcLengthToDegAngleOfArc(inArcLength, inRadius);
if (degThetaResult < thetaLowerLimit)
{
inArcLength = CompositionLayer.CylinderParameterHelper.RadiusAndDegAngleOfArcToArcLength(thetaLowerLimit, inRadius);
isValid = false;
}
else if (degThetaResult > thetaUpperLimit)
{
inArcLength = CompositionLayer.CylinderParameterHelper.RadiusAndDegAngleOfArcToArcLength(thetaUpperLimit, inRadius);
isValid = false;
}
return isValid;
}
}
#endregion
}
#endif

View File

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

View File

@@ -0,0 +1,308 @@
// "VIVE SDK
// © 2020 HTC Corporation. All Rights Reserved.
//
// Unless otherwise required by copyright law and practice,
// upon the execution of HTC SDK license agreement,
// HTC grants you access to and use of the VIVE SDK(s).
// You shall fully comply with all of HTCs SDK license agreement terms and
// conditions signed by you and all SDK and API requirements,
// specifications, and documentation provided by HTC to You."
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace VIVE.OpenXR.CompositionLayer.Editor
{
using UnityEditor;
using UnityEngine.UI;
[CustomEditor(typeof(CompositionLayerUICanvas))]
public class CompositionLayerUICanvasEditor : Editor
{
static string PropertyName_MaxRenderTextureSize = "maxRenderTextureSize";
static GUIContent Label_MaxRenderTextureSize = new GUIContent("Max Render Texture Size", "Maximum render texture dimension. e.g. If maxRenderTextureSize is 1024, the render texture dimensions of a canvas with an Aspect Ratio of 2:1 will be 1024 x 512.");
SerializedProperty Property_MaxRenderTextureSize;
static string PropertyName_LayerType = "layerType";
static GUIContent Label_LayerType = new GUIContent("Layer Type", "Overlays render on top of all in-game objects.\nUnderlays can be occluded by in-game objects but may introduce alpha blending issues with transparent objects.");
SerializedProperty Property_LayerType;
static string PropertyName_LayerVisibility = "layerVisibility";
static GUIContent Label_LayerVisibility = new GUIContent("Visibility", "Specify the visibility of the layer.");
SerializedProperty Property_LayerVisibility;
static string PropertyName_CameraBGColor = "cameraBGColor";
static GUIContent Label_CameraBGColor = new GUIContent("Camera Background Color", "Background color of the camera for rendering the Canvas to the render texture target.\nChanging this option will affect the tint of the final image of the Canvas if no background gameobject is assigned.");
SerializedProperty Property_CameraBGColor;
static string PropertyName_BackgroundGO = "backgroundGO";
static GUIContent Label_BackgroundGO = new GUIContent("Background GameObject", "GameObject that contains a UI Component and will be used as the background of the Canvas.\nWhen succesfully assigned, the area which the background UI component covers will no longer be affected by the background color of the camera.");
SerializedProperty Property_BackgroundGO;
static string PropertyName_EnableAlphaBlendingCorrection = "enableAlphaBlendingCorrection";
static GUIContent Label_EnableAlphaBlendingCorrection = new GUIContent("Enable Alpha Blending Correction", "Enable this option if transparent UI elements are rendering darker than expected in an overall sense.\nNote that enabling this option will consume more resources.");
SerializedProperty Property_EnableAlphaBlendingCorrection;
static string PropertyName_CompositionDepth = "compositionDepth";
static GUIContent Label_CompositionDepth = new GUIContent("Composition Depth", "Specify Layer Composition Depth.");
SerializedProperty Property_CompositionDepth;
static string PropertyName_RenderPriority = "renderPriority";
static GUIContent Label_RenderPriority = new GUIContent("Render Priority", "When Auto Fallback is enabled, layers with a higher render priority will be rendered as normal layers first.");
SerializedProperty Property_RenderPriority;
static string PropertyName_TrackingOrigin = "trackingOrigin";
static GUIContent Label_TrackingOrigin = new GUIContent("Tracking Origin", "Assign the tracking origin here to offset the pose of the Composition Layer.");
SerializedProperty Property_TrackingOrigin;
bool isCurrentBackgroundGOValid = true, isMaterialReplaced = true, backgroundUINotFoundError = false, backgroundObjectNotChildError = false;
List<GameObject> validbackgroundGO;
private const string layerNameString = "CompositionLayerUICanvas";
public override void OnInspectorGUI()
{
//Check if current selected layer is rendered by main camera
if (Property_MaxRenderTextureSize == null) Property_MaxRenderTextureSize = serializedObject.FindProperty(PropertyName_MaxRenderTextureSize);
if (Property_LayerType == null) Property_LayerType = serializedObject.FindProperty(PropertyName_LayerType);
if (Property_LayerVisibility == null) Property_LayerVisibility = serializedObject.FindProperty(PropertyName_LayerVisibility);
if (Property_CameraBGColor == null) Property_CameraBGColor = serializedObject.FindProperty(PropertyName_CameraBGColor);
if (Property_BackgroundGO == null) Property_BackgroundGO = serializedObject.FindProperty(PropertyName_BackgroundGO);
if (Property_EnableAlphaBlendingCorrection == null) Property_EnableAlphaBlendingCorrection = serializedObject.FindProperty(PropertyName_EnableAlphaBlendingCorrection);
if (Property_CompositionDepth == null) Property_CompositionDepth = serializedObject.FindProperty(PropertyName_CompositionDepth);
if (Property_RenderPriority == null) Property_RenderPriority = serializedObject.FindProperty(PropertyName_RenderPriority);
if (Property_TrackingOrigin == null) Property_TrackingOrigin = serializedObject.FindProperty(PropertyName_TrackingOrigin);
CompositionLayerUICanvas targetLayerCanvasUI = target as CompositionLayerUICanvas;
Graphic[] graphicComponents = targetLayerCanvasUI.GetComponentsInChildren<Graphic>();
EditorGUILayout.HelpBox("CompositionLayerUICanvas will automatically generate the components necessary for rendering UI Canvas(es) with CompositionLayer(s).", MessageType.Info);
EditorGUILayout.PropertyField(Property_MaxRenderTextureSize, Label_MaxRenderTextureSize);
serializedObject.ApplyModifiedProperties();
EditorGUILayout.PropertyField(Property_LayerType, Label_LayerType);
serializedObject.ApplyModifiedProperties();
if (targetLayerCanvasUI.layerType == CompositionLayer.LayerType.Underlay)
{
EditorGUILayout.HelpBox("When using Underlay, overlapping non-opaque canvas elements (i.e. elements with alpha value < 1) might look different during runtime due to inherent alpha blending limitations.\n", MessageType.Warning);
EditorGUILayout.PropertyField(Property_EnableAlphaBlendingCorrection, Label_EnableAlphaBlendingCorrection);
serializedObject.ApplyModifiedProperties();
}
else
{
targetLayerCanvasUI.enableAlphaBlendingCorrection = false;
}
EditorGUILayout.PropertyField(Property_LayerVisibility, new GUIContent(Label_LayerVisibility));
serializedObject.ApplyModifiedProperties();
if (isCurrentBackgroundGOValid) //Cache valid result
{
validbackgroundGO = new List<GameObject>();
foreach (GameObject backgroundGO in targetLayerCanvasUI.backgroundGO)
{
validbackgroundGO.Add(backgroundGO);
}
}
List<GameObject> prevBackgroundGO = new List<GameObject>();
foreach (GameObject backgroundGO in targetLayerCanvasUI.backgroundGO)
{
prevBackgroundGO.Add(backgroundGO);
}
EditorGUILayout.PropertyField(Property_BackgroundGO, Label_BackgroundGO);
serializedObject.ApplyModifiedProperties();
bool needMaterialReplacement = false;
if (targetLayerCanvasUI.backgroundGO != null)
{
List<Graphic> backgroundGraphics = new List<Graphic>();
foreach (GameObject backgroundGO in targetLayerCanvasUI.backgroundGO)
{
if (backgroundGO == null) continue;
backgroundGraphics.Add(backgroundGO.GetComponent<Graphic>());
}
bool backgroundGraphicIsInChild = false;
if (backgroundGraphics.Count > 0)
{
foreach (Graphic backgroundGraphic in backgroundGraphics) //Loop through graphic components of selected background objects
{
if (backgroundGraphic != null)
{
backgroundUINotFoundError = false;
foreach (Graphic graphicComponent in graphicComponents) //Loop through graphic components under current canvas
{
if (graphicComponent == backgroundGraphic)
{
backgroundGraphicIsInChild = true;
backgroundObjectNotChildError = false;
break;
}
backgroundGraphicIsInChild = false;
}
if (!backgroundGraphicIsInChild) //Triggers when one of the selected objects is invalid
{
backgroundObjectNotChildError = true;
break;
}
}
else
{
backgroundUINotFoundError = true;
break;
}
}
if (!backgroundUINotFoundError && !backgroundObjectNotChildError)
{
isCurrentBackgroundGOValid = true;
foreach (GameObject backgroundGOCurr in targetLayerCanvasUI.backgroundGO)
{
if (backgroundGOCurr == null) continue;
if (!prevBackgroundGO.Contains(backgroundGOCurr)) //Needs material replacement
{
needMaterialReplacement = true;
isMaterialReplaced = false;
break;
}
}
EditorGUILayout.HelpBox("The blending mode of the background UI shader will be changed in order to ignore the background color of the camera.", MessageType.Info);
}
else
{
isCurrentBackgroundGOValid = false;
if (backgroundUINotFoundError)
{
EditorGUILayout.HelpBox("The background object you are trying to assign does not contain a UI Component.", MessageType.Error);
}
if (backgroundObjectNotChildError)
{
EditorGUILayout.HelpBox("The background object you are trying to assign is not under the current Canvas.", MessageType.Error);
}
if (GUILayout.Button("Revert Background GameObjects"))
{
targetLayerCanvasUI.backgroundGO = validbackgroundGO;
}
}
}
}
EditorGUILayout.PropertyField(Property_CameraBGColor, Label_CameraBGColor);
serializedObject.ApplyModifiedProperties();
//Check the material config of the UI elements
foreach (Graphic graphicComponent in graphicComponents)
{
if (graphicComponent.material == null || graphicComponent.material == graphicComponent.defaultMaterial)
{
needMaterialReplacement = true;
isMaterialReplaced = false;
break;
}
}
if (needMaterialReplacement || !isMaterialReplaced)
{
EditorGUILayout.HelpBox("The current material configurations of the UI elements will lead to incorrect alpha blending.\n" +
"Replace the materials to yield better visual results.", MessageType.Error);
if (GUILayout.Button("Replace UI Materials"))
{
targetLayerCanvasUI.ReplaceUIMaterials();
isMaterialReplaced = true;
}
}
//Check if current selected layer is rendered by main camera
if (Camera.main != null)
{
if ((Camera.main.cullingMask & (1 << targetLayerCanvasUI.gameObject.layer)) != 0)
{
EditorGUILayout.HelpBox("Currently selected layer: " + LayerMask.LayerToName(targetLayerCanvasUI.gameObject.layer) + "\nThis layer is not culled by the Main Camera.\nSelect a layer that will not be rendered by the Main Camera and apply it to all child objects.", MessageType.Error);
//TODO: Add Auto Layer button
if (GUILayout.Button("Auto Select Layer"))
{
// Open tag manager
SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
// Layers Property
SerializedProperty layersProp = tagManager.FindProperty("layers");
//Check if the layer CompositionLayerUICanvas exists
bool layerExists = false, firstEmptyLayerFound = false;
int emptyLayerIndex = 0;
for (int i = 0; i < layersProp.arraySize; i++)
{
if (layersProp.GetArrayElementAtIndex(i).stringValue == layerNameString)
{
layerExists = true;
ApplyLayerToGameObjectRecursive(targetLayerCanvasUI.gameObject, i);
break;
}
else if (layersProp.GetArrayElementAtIndex(i).stringValue == "")
{
if (!firstEmptyLayerFound) //Remember the index of the first empty layer
{
firstEmptyLayerFound = true;
emptyLayerIndex = i;
}
}
}
if (!layerExists) //Create layer and apply it
{
layersProp.GetArrayElementAtIndex(emptyLayerIndex).stringValue = layerNameString;
ApplyLayerToGameObjectRecursive(targetLayerCanvasUI.gameObject, emptyLayerIndex);
tagManager.ApplyModifiedProperties();
}
}
}
}
else
{
EditorGUILayout.HelpBox("Main Camera not found, and hence cannot confirm the status of its Culling Mask.\nMake sure that the Main Camera does not draw the " + LayerMask.LayerToName(targetLayerCanvasUI.gameObject.layer) + " layer." , MessageType.Warning);
}
EditorGUILayout.PropertyField(Property_CompositionDepth, Label_CompositionDepth);
serializedObject.ApplyModifiedProperties();
EditorGUILayout.PropertyField(Property_RenderPriority, Label_RenderPriority);
serializedObject.ApplyModifiedProperties();
EditorGUILayout.PropertyField(Property_TrackingOrigin, Label_TrackingOrigin);
serializedObject.ApplyModifiedProperties();
}
private void ApplyLayerToGameObjectRecursive(GameObject targetGO, int layerID)
{
if (targetGO.transform.childCount > 0)
{
for (int i=0; i<targetGO.transform.childCount; i++)
{
ApplyLayerToGameObjectRecursive(targetGO.transform.GetChild(i).gameObject, layerID);
}
}
targetGO.layer = layerID;
}
}
}

View File

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