Initial Commit
This commit is contained in:
@@ -0,0 +1,324 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using ColorMapEditorType = OVRPassthroughLayer.ColorMapEditorType;
|
||||
|
||||
[CustomPropertyDrawer(typeof(OVRPassthroughLayer.SerializedSurfaceGeometry))]
|
||||
class SerializedSurfaceGeometryPropertyDrawer : PropertyDrawer
|
||||
{
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
// Find the SerializedProperties by name
|
||||
var meshFilterProperty =
|
||||
property.FindPropertyRelative(nameof(OVRPassthroughLayer.SerializedSurfaceGeometry.meshFilter));
|
||||
var updateTransformProperty =
|
||||
property.FindPropertyRelative(nameof(OVRPassthroughLayer.SerializedSurfaceGeometry.updateTransform));
|
||||
var propertyHeight = position.height / 2;
|
||||
|
||||
using (new EditorGUI.PropertyScope(position, label, property))
|
||||
{
|
||||
var surfaceGeometryPropertyPosition = new Rect(position.x, position.y, position.width, propertyHeight);
|
||||
EditorGUI.PropertyField(surfaceGeometryPropertyPosition, meshFilterProperty,
|
||||
new GUIContent("Surface Geometry", "The GameObject from which to generate surface geometry."));
|
||||
|
||||
var heightOffset = EditorGUI.GetPropertyHeight(updateTransformProperty) +
|
||||
EditorGUIUtility.standardVerticalSpacing;
|
||||
var updateTransformPosition =
|
||||
new Rect(position.x, position.y + heightOffset, position.width, propertyHeight);
|
||||
EditorGUI.PropertyField(updateTransformPosition, updateTransformProperty, new GUIContent("Update Transform",
|
||||
"When enabled, updates the mesh's transform every frame. Use this if the GameObject is dynamic."));
|
||||
}
|
||||
}
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
return base.GetPropertyHeight(property, label) * 2.2f;
|
||||
}
|
||||
}
|
||||
|
||||
[CustomEditor(typeof(OVRPassthroughLayer))]
|
||||
public class OVRPassthroughLayerEditor : Editor
|
||||
{
|
||||
private readonly static string[] _colorMapNames =
|
||||
{
|
||||
"None",
|
||||
"Color Adjustment",
|
||||
"Grayscale",
|
||||
"Grayscale to Color",
|
||||
"Color LUT",
|
||||
"Blended Color LUTs",
|
||||
"Custom"
|
||||
};
|
||||
|
||||
private readonly static string[] _selectableColorMapNames =
|
||||
{
|
||||
_colorMapNames[0],
|
||||
_colorMapNames[1],
|
||||
_colorMapNames[2],
|
||||
_colorMapNames[3],
|
||||
_colorMapNames[4],
|
||||
_colorMapNames[5]
|
||||
};
|
||||
|
||||
private ColorMapEditorType[] _colorMapTypes =
|
||||
{
|
||||
ColorMapEditorType.None,
|
||||
ColorMapEditorType.ColorAdjustment,
|
||||
ColorMapEditorType.Grayscale,
|
||||
ColorMapEditorType.GrayscaleToColor,
|
||||
ColorMapEditorType.ColorLut,
|
||||
ColorMapEditorType.InterpolatedColorLut,
|
||||
ColorMapEditorType.Custom
|
||||
};
|
||||
|
||||
private SerializedProperty _projectionSurfaces;
|
||||
|
||||
private SerializedProperty _propProjectionSurfaceType;
|
||||
private SerializedProperty _propOverlayType;
|
||||
private SerializedProperty _propCompositionDepth;
|
||||
|
||||
private SerializedProperty _propTextureOpacity;
|
||||
private SerializedProperty _propEdgeRenderingEnabled;
|
||||
private SerializedProperty _propEdgeColor;
|
||||
private SerializedProperty _propColorMapEditorContrast;
|
||||
private SerializedProperty _propColorMapEditorBrightness;
|
||||
private SerializedProperty _propColorMapEditorPosterize;
|
||||
private SerializedProperty _propColorMapEditorGradient;
|
||||
private SerializedProperty _propColorMapEditorSaturation;
|
||||
|
||||
private SerializedProperty _propColorLutSourceTexture;
|
||||
private SerializedProperty _propColorLutTargetTexture;
|
||||
private SerializedProperty _propLutWeight;
|
||||
private SerializedProperty _propFlipLutY;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
_projectionSurfaces = serializedObject.FindProperty(nameof(OVRPassthroughLayer.serializedSurfaceGeometry));
|
||||
|
||||
_propProjectionSurfaceType = serializedObject.FindProperty(nameof(OVRPassthroughLayer.projectionSurfaceType));
|
||||
_propOverlayType = serializedObject.FindProperty(nameof(OVRPassthroughLayer.overlayType));
|
||||
_propCompositionDepth = serializedObject.FindProperty(nameof(OVRPassthroughLayer.compositionDepth));
|
||||
_propTextureOpacity = serializedObject.FindProperty(nameof(OVRPassthroughLayer.textureOpacity_));
|
||||
_propEdgeRenderingEnabled = serializedObject.FindProperty(nameof(OVRPassthroughLayer.edgeRenderingEnabled_));
|
||||
_propEdgeColor = serializedObject.FindProperty(nameof(OVRPassthroughLayer.edgeColor_));
|
||||
_propColorMapEditorContrast = serializedObject.FindProperty(nameof(OVRPassthroughLayer.colorMapEditorContrast));
|
||||
_propColorMapEditorBrightness =
|
||||
serializedObject.FindProperty(nameof(OVRPassthroughLayer.colorMapEditorBrightness));
|
||||
_propColorMapEditorPosterize =
|
||||
serializedObject.FindProperty(nameof(OVRPassthroughLayer.colorMapEditorPosterize));
|
||||
_propColorMapEditorSaturation =
|
||||
serializedObject.FindProperty(nameof(OVRPassthroughLayer.colorMapEditorSaturation));
|
||||
_propColorMapEditorGradient = serializedObject.FindProperty(nameof(OVRPassthroughLayer.colorMapEditorGradient));
|
||||
|
||||
_propColorLutSourceTexture = serializedObject.FindProperty(nameof(OVRPassthroughLayer._colorLutSourceTexture));
|
||||
_propColorLutTargetTexture = serializedObject.FindProperty(nameof(OVRPassthroughLayer._colorLutTargetTexture));
|
||||
_propLutWeight = serializedObject.FindProperty(nameof(OVRPassthroughLayer._lutWeight));
|
||||
_propFlipLutY = serializedObject.FindProperty(nameof(OVRPassthroughLayer._flipLutY));
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
OVRPassthroughLayer layer = (OVRPassthroughLayer)target;
|
||||
|
||||
serializedObject.Update();
|
||||
EditorGUILayout.PropertyField(_propProjectionSurfaceType,
|
||||
new GUIContent("Projection Surface", "The type of projection surface for this Passthrough layer"));
|
||||
|
||||
if (layer.projectionSurfaceType == OVRPassthroughLayer.ProjectionSurfaceType.UserDefined)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_projectionSurfaces, new GUIContent("Projection Surfaces"));
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Compositing", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUILayout.PropertyField(_propOverlayType,
|
||||
new GUIContent("Placement", "Whether this overlay should layer behind the scene or in front of it"));
|
||||
EditorGUILayout.PropertyField(_propCompositionDepth,
|
||||
new GUIContent("Composition Depth",
|
||||
"Depth value used to sort layers in the scene, smaller value appears in front"));
|
||||
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Style", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUILayout.Slider(_propTextureOpacity, 0, 1f, new GUIContent("Opacity"));
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.PropertyField(_propEdgeRenderingEnabled,
|
||||
new GUIContent("Edge Rendering", "Highlight salient edges in the camera images in a specific color"));
|
||||
EditorGUILayout.PropertyField(_propEdgeColor, new GUIContent("Edge Color"));
|
||||
|
||||
if (serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
layer.SetStyleDirty();
|
||||
}
|
||||
|
||||
layer.textureOpacity = _propTextureOpacity.floatValue;
|
||||
layer.edgeRenderingEnabled = _propEdgeRenderingEnabled.boolValue;
|
||||
layer.edgeColor = _propEdgeColor.colorValue;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// Custom popup for color map type to control order, names, and visibility of types
|
||||
int colorMapTypeIndex = Array.IndexOf(_colorMapTypes, layer.colorMapEditorType);
|
||||
if (colorMapTypeIndex == -1)
|
||||
{
|
||||
Debug.LogWarning("Invalid color map type encountered");
|
||||
colorMapTypeIndex = 0;
|
||||
}
|
||||
|
||||
// Dropdown list contains "Custom" only if it is currently selected.
|
||||
string[] colorMapNames = layer.colorMapEditorType == ColorMapEditorType.Custom
|
||||
? _colorMapNames
|
||||
: _selectableColorMapNames;
|
||||
GUIContent[] colorMapLabels = new GUIContent[colorMapNames.Length];
|
||||
for (int i = 0; i < colorMapNames.Length; i++)
|
||||
colorMapLabels[i] = new GUIContent(colorMapNames[i]);
|
||||
bool modified = false;
|
||||
OVREditorUtil.SetupPopupField(target,
|
||||
new GUIContent("Color Control", "The type of color controls applied to this layer"), ref colorMapTypeIndex,
|
||||
colorMapLabels,
|
||||
ref modified);
|
||||
layer.colorMapEditorType = _colorMapTypes[colorMapTypeIndex];
|
||||
|
||||
if (layer.colorMapEditorType == ColorMapEditorType.Grayscale
|
||||
|| layer.colorMapEditorType == ColorMapEditorType.GrayscaleToColor
|
||||
|| layer.colorMapEditorType == ColorMapEditorType.ColorAdjustment)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propColorMapEditorContrast, new GUIContent("Contrast"));
|
||||
EditorGUILayout.PropertyField(_propColorMapEditorBrightness, new GUIContent("Brightness"));
|
||||
}
|
||||
|
||||
if (layer.colorMapEditorType == ColorMapEditorType.Grayscale
|
||||
|| layer.colorMapEditorType == ColorMapEditorType.GrayscaleToColor)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propColorMapEditorPosterize, new GUIContent("Posterize"));
|
||||
}
|
||||
|
||||
if (layer.colorMapEditorType == ColorMapEditorType.ColorAdjustment)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propColorMapEditorSaturation, new GUIContent("Saturation"));
|
||||
}
|
||||
|
||||
if (layer.colorMapEditorType == ColorMapEditorType.GrayscaleToColor)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propColorMapEditorGradient, new GUIContent("Colorize"));
|
||||
}
|
||||
|
||||
if (layer.colorMapEditorType == ColorMapEditorType.ColorLut
|
||||
|| layer.colorMapEditorType == ColorMapEditorType.InterpolatedColorLut)
|
||||
{
|
||||
var sourceLutLabel = layer.colorMapEditorType == ColorMapEditorType.ColorLut
|
||||
? "LUT"
|
||||
: "Source LUT";
|
||||
|
||||
EditorGUILayout.PropertyField(_propColorLutSourceTexture, new GUIContent(sourceLutLabel));
|
||||
PerformLutTextureCheck((Texture2D)_propColorLutSourceTexture.objectReferenceValue);
|
||||
|
||||
if (layer.colorMapEditorType == ColorMapEditorType.InterpolatedColorLut)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propColorLutTargetTexture, new GUIContent("Target LUT"));
|
||||
PerformLutTextureCheck((Texture2D)_propColorLutTargetTexture.objectReferenceValue);
|
||||
}
|
||||
|
||||
var flipLutYTooltip = "Flip LUT textures along the vertical axis on load. This is needed for LUT " +
|
||||
"images which have color (0, 0, 0) in the top-left corner. Some color grading systems, " +
|
||||
"e.g. Unity post-processing, have color (0, 0, 0) in the bottom-left corner, " +
|
||||
"in which case flipping is not needed.";
|
||||
EditorGUILayout.PropertyField(_propFlipLutY, new GUIContent("Flip Vertically", flipLutYTooltip));
|
||||
|
||||
var weightTooltip = layer.colorMapEditorType == ColorMapEditorType.ColorLut
|
||||
? "Blend between the original colors and the specified LUT. A value of 0 leaves the colors unchanged, a value of 1 fully applies the LUT."
|
||||
: "Blend between the source and the target LUT. A value of 0 fully applies the source LUT and a value of 1 fully applies the target LUT.";
|
||||
EditorGUILayout.PropertyField(_propLutWeight, new GUIContent("Blend", weightTooltip));
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void PerformLutTextureCheck(Texture2D texture)
|
||||
{
|
||||
if (texture != null)
|
||||
{
|
||||
if (!OVRPassthroughColorLut.IsTextureSupported(texture, out var message))
|
||||
{
|
||||
EditorGUILayout.HelpBox(message, MessageType.Error);
|
||||
}
|
||||
|
||||
CheckLutImportSettings(texture);
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckLutImportSettings(Texture lut)
|
||||
{
|
||||
if (lut != null)
|
||||
{
|
||||
var importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(lut)) as TextureImporter;
|
||||
|
||||
// Fails when using an internal texture as you can't change import settings on
|
||||
// builtin resources, thus the check for null
|
||||
if (importer != null)
|
||||
{
|
||||
bool isReadable = importer.isReadable == true;
|
||||
bool isUncompressed = importer.textureCompression == TextureImporterCompression.Uncompressed;
|
||||
bool valid = isReadable && isUncompressed;
|
||||
|
||||
if (!valid)
|
||||
{
|
||||
string warningMessage = ""
|
||||
+ (isReadable ? "" : "Texture is not readable. ")
|
||||
+ (isUncompressed ? "" : "Texture is compressed.");
|
||||
DrawFixMeBox(warningMessage, () => SetLutImportSettings(importer));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetLutImportSettings(TextureImporter importer)
|
||||
{
|
||||
importer.isReadable = true;
|
||||
importer.textureCompression = TextureImporterCompression.Uncompressed;
|
||||
importer.SaveAndReimport();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
private void DrawFixMeBox(string text, Action action)
|
||||
{
|
||||
EditorGUILayout.HelpBox(text, MessageType.Warning);
|
||||
|
||||
GUILayout.Space(-32);
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button("Fix", GUILayout.Width(60)))
|
||||
action();
|
||||
|
||||
GUILayout.Space(8);
|
||||
}
|
||||
|
||||
GUILayout.Space(11);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user