Skip to content

Fix issue when switching back to custom sensor type in physical camera #417

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions com.unity.render-pipelines.high-definition/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Fix conflicts with Handles manipulation when performing a Reset in DecalComponent (case 1238833)
- Fixed depth prepass and postpass being disabled after changing the shader in the material UI.
- Fixed issue with sceneview camera settings not being saved after Editor restart.
- Fixed issue when switching back to custom sensor type in physical camera settings (case 1244350).

### Changed
- Improve MIP selection for decals on Transparents
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.Rendering;
Expand Down Expand Up @@ -62,6 +63,8 @@ enum ShutterSpeedUnit
"Custom"
};

static readonly int k_CustomPresetIndex = k_ApertureFormatNames.Length - 1;

static readonly Vector2[] k_ApertureFormatValues =
{
new Vector2(4.8f, 3.5f),
Expand All @@ -76,6 +79,10 @@ enum ShutterSpeedUnit
new Vector2(70.41f, 52.63f)
};

// Saves the value of the sensor size when the user switches from "custom" size to a preset per camera.
// We use a ConditionalWeakTable instead of a Dictionary to avoid keeping alive (with strong references) deleted cameras
static ConditionalWeakTable<Camera, object> s_PerCameraSensorSizeHistory = new ConditionalWeakTable<Camera, object>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Does it need to be an object and not a vector2 though? I guess it is for checking if the value is there or not? If that's the case TryGetValue returns false if the object is not found.

Copy link
Contributor

@FrancescoC-unity FrancescoC-unity May 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also -def not needed, but for future reference- to slightly decrease the cost of the hashing and memory consumption of this table, you could use the instance id of the object (Camera) as a Key which is unique per unity object. (Can query from the game object with GetInstanceID() )

This would also solve the issue with not being able to use the dictionary to not keep Cameras alive, though the Weak table is nice in that it auto deletes stuff when is not used anywhere else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately ConditionalWeakTable work only with reference types, so I could not use Vector2 directly, it does not even compile. There is some overhead with the boxing operation, but this is paid only when the user switches from a preset to custom in the UI. Scripts that add/delete cameras will never hit that.

Using a traditional dictionary + instanceID is certainly an alternative, not sure if it is better or worse.


static bool s_FovChanged;
static float s_FovLastValue;

Expand Down Expand Up @@ -298,14 +305,51 @@ static void Drawer_PhysicalCamera(SerializedHDCamera p, Editor owner)
using (new EditorGUI.IndentLevelScope())
{
EditorGUI.BeginChangeCheck();
int filmGateIndex = Array.IndexOf(k_ApertureFormatValues, new Vector2((float)Math.Round(cam.sensorSize.vector2Value.x, 3), (float)Math.Round(cam.sensorSize.vector2Value.y, 3)));
if (filmGateIndex == -1)
filmGateIndex = EditorGUILayout.Popup(cameraTypeContent, k_ApertureFormatNames.Length - 1, k_ApertureFormatNames);
else
filmGateIndex = EditorGUILayout.Popup(cameraTypeContent, filmGateIndex, k_ApertureFormatNames);

if (EditorGUI.EndChangeCheck() && filmGateIndex < k_ApertureFormatValues.Length)
cam.sensorSize.vector2Value = k_ApertureFormatValues[filmGateIndex];
int oldFilmGateIndex = Array.IndexOf(k_ApertureFormatValues, new Vector2((float)Math.Round(cam.sensorSize.vector2Value.x, 3), (float)Math.Round(cam.sensorSize.vector2Value.y, 3)));

// If it is not one of the preset sizes, set it to custom
oldFilmGateIndex = (oldFilmGateIndex == -1) ? k_CustomPresetIndex: oldFilmGateIndex;

// Get the new user selection
int newFilmGateIndex = EditorGUILayout.Popup(cameraTypeContent, oldFilmGateIndex, k_ApertureFormatNames);

if (EditorGUI.EndChangeCheck())
{
// Retrieve the previous custom size value, if one exists for this camera
object previousCustomValue;
s_PerCameraSensorSizeHistory.TryGetValue((Camera)p.serializedObject.targetObject, out previousCustomValue);

// When switching from custom to a preset, update the last custom value (to display again, in case the user switches back to custom)
if (oldFilmGateIndex == k_CustomPresetIndex)
{
if (previousCustomValue == null)
{
s_PerCameraSensorSizeHistory.Add((Camera)p.serializedObject.targetObject, cam.sensorSize.vector2Value);
}
else
{
previousCustomValue = cam.sensorSize.vector2Value;
}
}

if (newFilmGateIndex < k_CustomPresetIndex)
{
cam.sensorSize.vector2Value = k_ApertureFormatValues[newFilmGateIndex];
}
else
{
// The user switched back to custom, so display by deafulr the previous custom value
if (previousCustomValue != null)
{
cam.sensorSize.vector2Value = (Vector2)previousCustomValue;
}
else
{
cam.sensorSize.vector2Value = new Vector2(36.0f, 24.0f); // this is the value new cameras are created with
}
}
}

EditorGUILayout.PropertyField(cam.sensorSize, sensorSizeContent);
EditorGUILayout.PropertyField(p.iso, isoContent);
Expand Down