172 lines
7.3 KiB
C#
172 lines
7.3 KiB
C#
|
using System.Linq;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace UnityEditor.Rendering
|
||
|
{
|
||
|
/// <summary> Camera UI Shared Properties among SRP</summary>
|
||
|
public static partial class CameraUI
|
||
|
{
|
||
|
/// <summary>Camera Projection type</summary>
|
||
|
public enum ProjectionType
|
||
|
{
|
||
|
/// <summary> Perspective</summary>
|
||
|
Perspective,
|
||
|
/// <summary> Orthographic</summary>
|
||
|
Orthographic
|
||
|
}
|
||
|
|
||
|
/// <summary>Camera Projection matrix mode</summary>
|
||
|
public enum ProjectionMatrixMode
|
||
|
{
|
||
|
/// <summary> Explicit</summary>
|
||
|
Explicit,
|
||
|
/// <summary> Implicit</summary>
|
||
|
Implicit,
|
||
|
/// <summary> PhysicalPropertiesBased</summary>
|
||
|
PhysicalPropertiesBased,
|
||
|
}
|
||
|
|
||
|
static bool s_FovChanged;
|
||
|
static float s_FovLastValue;
|
||
|
|
||
|
static ProjectionType DrawerProjectionType(ISerializedCamera p, Editor owner)
|
||
|
{
|
||
|
var cam = p.baseCameraSettings;
|
||
|
|
||
|
ProjectionType projectionType;
|
||
|
|
||
|
Rect perspectiveRect = EditorGUILayout.GetControlRect();
|
||
|
EditorGUI.BeginProperty(perspectiveRect, Styles.projectionContent, cam.orthographic);
|
||
|
{
|
||
|
projectionType = cam.orthographic.boolValue ? ProjectionType.Orthographic : ProjectionType.Perspective;
|
||
|
|
||
|
EditorGUI.BeginChangeCheck();
|
||
|
projectionType = (ProjectionType)EditorGUI.EnumPopup(perspectiveRect, Styles.projectionContent, projectionType);
|
||
|
if (EditorGUI.EndChangeCheck())
|
||
|
cam.orthographic.boolValue = (projectionType == ProjectionType.Orthographic);
|
||
|
}
|
||
|
EditorGUI.EndProperty();
|
||
|
|
||
|
return projectionType;
|
||
|
}
|
||
|
|
||
|
static void DrawerOrthographicType(ISerializedCamera p, Editor owner)
|
||
|
{
|
||
|
EditorGUILayout.PropertyField(p.baseCameraSettings.orthographicSize, Styles.sizeContent);
|
||
|
Drawer_FieldClippingPlanes(p, owner);
|
||
|
}
|
||
|
|
||
|
static void DrawerPerspectiveType(ISerializedCamera p, Editor owner)
|
||
|
{
|
||
|
var cam = p.baseCameraSettings;
|
||
|
|
||
|
var targets = p.serializedObject.targetObjects;
|
||
|
var camera0 = targets[0] as Camera;
|
||
|
|
||
|
float fovCurrentValue;
|
||
|
bool multipleDifferentFovValues = false;
|
||
|
bool isPhysicalCamera = p.projectionMatrixMode.intValue == (int)ProjectionMatrixMode.PhysicalPropertiesBased;
|
||
|
|
||
|
var rect = EditorGUILayout.GetControlRect();
|
||
|
|
||
|
var guiContent = EditorGUI.BeginProperty(rect, Styles.FOVAxisModeContent, cam.fovAxisMode);
|
||
|
EditorGUI.showMixedValue = cam.fovAxisMode.hasMultipleDifferentValues;
|
||
|
|
||
|
CoreEditorUtils.DrawEnumPopup<Camera.FieldOfViewAxis>(rect, guiContent, cam.fovAxisMode);
|
||
|
|
||
|
bool fovAxisVertical = cam.fovAxisMode.intValue == 0;
|
||
|
|
||
|
if (!fovAxisVertical && !cam.fovAxisMode.hasMultipleDifferentValues)
|
||
|
{
|
||
|
float aspectRatio = isPhysicalCamera ? cam.sensorSize.vector2Value.x / cam.sensorSize.vector2Value.y : camera0.aspect;
|
||
|
// camera.aspect is not serialized so we have to check all targets.
|
||
|
fovCurrentValue = Camera.VerticalToHorizontalFieldOfView(camera0.fieldOfView, aspectRatio);
|
||
|
if (targets.Cast<Camera>().Any(camera => camera.fieldOfView != fovCurrentValue))
|
||
|
multipleDifferentFovValues = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fovCurrentValue = cam.verticalFOV.floatValue;
|
||
|
multipleDifferentFovValues = cam.fovAxisMode.hasMultipleDifferentValues;
|
||
|
}
|
||
|
|
||
|
EditorGUI.showMixedValue = multipleDifferentFovValues;
|
||
|
var content = EditorGUI.BeginProperty(EditorGUILayout.BeginHorizontal(), Styles.fieldOfViewContent, cam.verticalFOV);
|
||
|
EditorGUI.BeginDisabledGroup(p.projectionMatrixMode.hasMultipleDifferentValues || isPhysicalCamera && (cam.sensorSize.hasMultipleDifferentValues || cam.fovAxisMode.hasMultipleDifferentValues));
|
||
|
EditorGUI.BeginChangeCheck();
|
||
|
s_FovLastValue = EditorGUILayout.Slider(content, fovCurrentValue, 0.00001f, 179f);
|
||
|
s_FovChanged = EditorGUI.EndChangeCheck();
|
||
|
EditorGUI.EndDisabledGroup();
|
||
|
EditorGUILayout.EndHorizontal();
|
||
|
EditorGUI.EndProperty();
|
||
|
EditorGUI.showMixedValue = false;
|
||
|
|
||
|
Drawer_FieldClippingPlanes(p, owner);
|
||
|
|
||
|
content = EditorGUI.BeginProperty(EditorGUILayout.BeginHorizontal(), Styles.physicalCameraContent, p.projectionMatrixMode);
|
||
|
EditorGUI.showMixedValue = p.projectionMatrixMode.hasMultipleDifferentValues;
|
||
|
|
||
|
EditorGUI.BeginChangeCheck();
|
||
|
isPhysicalCamera = EditorGUILayout.Toggle(content, isPhysicalCamera);
|
||
|
if (EditorGUI.EndChangeCheck())
|
||
|
{
|
||
|
p.projectionMatrixMode.intValue = isPhysicalCamera ? (int)ProjectionMatrixMode.PhysicalPropertiesBased : (int)ProjectionMatrixMode.Implicit;
|
||
|
s_FovChanged = true;
|
||
|
}
|
||
|
EditorGUILayout.EndHorizontal();
|
||
|
EditorGUI.EndProperty();
|
||
|
|
||
|
EditorGUI.showMixedValue = false;
|
||
|
if (s_FovChanged)
|
||
|
{
|
||
|
if (!isPhysicalCamera || p.projectionMatrixMode.hasMultipleDifferentValues)
|
||
|
{
|
||
|
cam.verticalFOV.floatValue = fovAxisVertical
|
||
|
? s_FovLastValue
|
||
|
: Camera.HorizontalToVerticalFieldOfView(s_FovLastValue, camera0.aspect);
|
||
|
}
|
||
|
else if (!p.projectionMatrixMode.hasMultipleDifferentValues)
|
||
|
{
|
||
|
cam.verticalFOV.floatValue = fovAxisVertical
|
||
|
? s_FovLastValue
|
||
|
: Camera.HorizontalToVerticalFieldOfView(s_FovLastValue, camera0.aspect);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>Draws projection related fields on the inspector</summary>
|
||
|
/// <param name="p"><see cref="ISerializedCamera"/> The serialized camera</param>
|
||
|
/// <param name="owner"><see cref="Editor"/> The editor owner calling this drawer</param>
|
||
|
public static void Drawer_Projection(ISerializedCamera p, Editor owner)
|
||
|
{
|
||
|
// Most of this is replicated from CameraEditor.DrawProjection as we don't want to draw
|
||
|
// it the same way it's done in non-SRP cameras. Unfortunately, because a lot of the
|
||
|
// code is internal, we have to copy/paste some stuff from the editor code :(
|
||
|
var projectionType = DrawerProjectionType(p, owner);
|
||
|
|
||
|
if (p.baseCameraSettings.orthographic.hasMultipleDifferentValues)
|
||
|
return;
|
||
|
|
||
|
using (new EditorGUI.IndentLevelScope())
|
||
|
{
|
||
|
if (projectionType == ProjectionType.Orthographic)
|
||
|
{
|
||
|
DrawerOrthographicType(p, owner);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DrawerPerspectiveType(p, owner);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void Drawer_FieldClippingPlanes(ISerializedCamera p, Editor owner)
|
||
|
{
|
||
|
CoreEditorUtils.DrawMultipleFields(
|
||
|
Styles.clippingPlaneMultiFieldTitle,
|
||
|
new[] { p.baseCameraSettings.nearClippingPlane, p.baseCameraSettings.farClippingPlane },
|
||
|
new[] { Styles.nearPlaneContent, Styles.farPlaneContent });
|
||
|
}
|
||
|
}
|
||
|
}
|