浏览代码

Getting PerceptionCamera editor working

/labeler_mock
Jon Hogins 5 年前
当前提交
60555526
共有 5 个文件被更改,包括 297 次插入9 次删除
  1. 30
      TestProjects/PerceptionURP/Assets/Scenes/SampleScene.unity
  2. 242
      com.unity.perception/Editor/GroundTruth/PerceptionCameraEditor.cs
  3. 3
      com.unity.perception/Runtime/GroundTruth/PerceptionCamera.cs
  4. 23
      TestProjects/PerceptionURP/Assets/SemanticSegmentationLabelingConfiguration.asset
  5. 8
      TestProjects/PerceptionURP/Assets/SemanticSegmentationLabelingConfiguration.asset.meta

30
TestProjects/PerceptionURP/Assets/Scenes/SampleScene.unity


boundingBoxOrigin: 0
LabelingConfiguration: {fileID: 11400000, guid: e74234fe725079e4aa7ecd74797ceb79,
type: 2}
labelers:
- id: 0
- id: 1
- id: 2
references:
version: 1
00000000:
type: {class: RenderedObjectInfoLabeler, ns: UnityEngine.Perception.GroundTruth,
asm: Unity.Perception.Runtime}
data:
enabled: 1
foldout: 0
annotationId: F9F22E05-443F-4602-A422-EBE4EA9B55CB
labelingConfiguration: {fileID: 0}
00000001:
type: {class: BoundingBoxLabeler, ns: UnityEngine.Perception.GroundTruth, asm: Unity.Perception.Runtime}
data:
enabled: 1
foldout: 0
annotationId: F9F22E05-443F-4602-A422-EBE4EA9B55CB
labelingConfiguration: {fileID: 11400000, guid: e74234fe725079e4aa7ecd74797ceb79,
type: 2}
00000002:
type: {class: SemanticSegmentationLabeler, ns: UnityEngine.Perception.GroundTruth,
asm: Unity.Perception.Runtime}
data:
enabled: 1
foldout: 0
annotationId: 12F94D8D-5425-4DEB-9B21-5E53AD957D66
labelConfig: {fileID: 0}
--- !u!114 &963194231
MonoBehaviour:
m_ObjectHideFlags: 0

242
com.unity.perception/Editor/GroundTruth/PerceptionCameraEditor.cs


using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine.Rendering;
namespace UnityEditor.Perception.GroundTruth
{

public void OnEnable()
{
m_LabelersList = new ReorderableList(this.serializedObject, this.serializedObject.FindProperty(nameof(PerceptionCamera.labelers)), true, false, true, true);
m_LabelersList.drawHeaderCallback = (rect) => {
EditorGUI.LabelField(rect, "Camera Labelers", EditorStyles.largeLabel);
};
m_LabelersList.elementHeightCallback = GetElementHeight;
m_LabelersList.drawElementCallback = DrawElement;
m_LabelersList.onAddCallback += OnAdd;

{
var serializedProperty = this.serializedObject.FindProperty(nameof(PerceptionCamera.labelers));
var element = serializedProperty.GetArrayElementAtIndex(index);
var editor = Editor.CreateEditor(element.managedReferenceValue);
return 10;
var editor = GetCameraLabelerDrawer(element, index);
return editor.GetElementHeight(element);
PerceptionCamera PerceptionCamera => ((PerceptionCamera)this.target);
var editor = Editor.CreateEditor(element.managedReferenceValue);
editor.OnInspectorGUI();
var editor = GetCameraLabelerDrawer(element, index);
editor.OnGUI(rect, element);
throw new System.NotImplementedException();
var labelers = serializedObject.FindProperty(nameof(PerceptionCamera.labelers));
labelers.DeleteArrayElementAtIndex(list.index);
serializedObject.ApplyModifiedProperties();
Undo.RegisterCompleteObjectUndo(target, "Remove camera labeler");
labelers.InsertArrayElementAtIndex(0);
var element = labelers.GetArrayElementAtIndex(0);
element.managedReferenceValue = new BoundingBoxLabeler();
var dropdownOptions = TypeCache.GetTypesDerivedFrom<CameraLabeler>();
var menu = new GenericMenu();
foreach (var option in dropdownOptions)
{
var localOption = option;
menu.AddItem(new GUIContent(option.Name),
false,
() => AddLabeler(labelers, localOption));
}
menu.ShowAsContext();
}
void AddLabeler(SerializedProperty labelers, Type labelerType)
{
var insertIndex = labelers.arraySize;
labelers.InsertArrayElementAtIndex(insertIndex);
var element = labelers.GetArrayElementAtIndex(insertIndex);
var labeler = (CameraLabeler) Activator.CreateInstance(labelerType);
labeler.enabled = true;
element.managedReferenceValue = labeler;
serializedObject.ApplyModifiedProperties();
}

//EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(PerceptionCamera.labelers)));
m_LabelersList.DoLayoutList();
}
Dictionary<SerializedProperty, CameraLabelerDrawer> cameraLabelerDrawers = new Dictionary<SerializedProperty, CameraLabelerDrawer>();
CameraLabelerDrawer GetCameraLabelerDrawer(SerializedProperty element, int listIndex)
{
CameraLabelerDrawer drawer;
if (cameraLabelerDrawers.TryGetValue(element, out drawer))
return drawer;
var labeler = PerceptionCamera.labelers[listIndex];
foreach (var drawerType in TypeCache.GetTypesWithAttribute(typeof(CameraLabelerDrawerAttribute)))
{
var attr = drawerType.GetCustomAttributes(typeof(CameraLabelerDrawerAttribute), true)[0] as CameraLabelerDrawerAttribute;
if (attr.targetLabelerType == labeler.GetType())
{
drawer = Activator.CreateInstance(drawerType) as CameraLabelerDrawer;
drawer.CameraLabeler = labeler;
break;
}
if (attr.targetLabelerType.IsAssignableFrom(labeler.GetType()))
{
drawer = Activator.CreateInstance(drawerType) as CameraLabelerDrawer;
drawer.CameraLabeler = labeler;
}
}
cameraLabelerDrawers[element] = drawer;
return drawer;
}
}
[AttributeUsage(AttributeTargets.Class)]
class CameraLabelerDrawerAttribute : Attribute
{
public CameraLabelerDrawerAttribute(Type targetLabelerType)
{
this.targetLabelerType = targetLabelerType;
}
public Type targetLabelerType;
}
[CameraLabelerDrawer(typeof(CameraLabeler))]
public class CameraLabelerDrawer
{
public CameraLabeler CameraLabeler { get; internal set; }
class Styles
{
public static float defaultLineSpace = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
public static float reorderableListHandleIndentWidth = 12;
public static GUIContent enabled = new GUIContent("Enabled", "Enable or Disable the custom pass");
}
bool firstTime = true;
// Serialized Properties
SerializedProperty m_Enabled;
SerializedProperty m_LabelerFoldout;
List<SerializedProperty> m_CustomPassUserProperties = new List<SerializedProperty>();
void FetchProperties(SerializedProperty property)
{
m_Enabled = property.FindPropertyRelative(nameof(CameraLabeler.enabled));
m_LabelerFoldout = property.FindPropertyRelative(nameof(CameraLabeler.foldout));
}
void LoadUserProperties(SerializedProperty customPass)
{
foreach (var field in CameraLabeler.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
var serializeField = field.GetCustomAttribute<SerializeField>();
var hideInInspector = field.GetCustomAttribute<HideInInspector>();
var nonSerialized = field.GetCustomAttribute<NonSerializedAttribute>();
if (nonSerialized != null || hideInInspector != null)
continue;
if (!field.IsPublic && serializeField == null)
continue;
if (field.Name == nameof(CameraLabeler.enabled) || field.Name == nameof(CameraLabeler.foldout))
continue;
var prop = customPass.FindPropertyRelative(field.Name);
if (prop != null)
m_CustomPassUserProperties.Add(prop);
}
}
void InitInternal(SerializedProperty customPass)
{
FetchProperties(customPass);
Initialize(customPass);
LoadUserProperties(customPass);
firstTime = false;
}
/// <summary>
/// Use this function to initialize the local SerializedProperty you will use in your pass.
/// </summary>
/// <param name="customPass">Your custom pass instance represented as a SerializedProperty</param>
protected virtual void Initialize(SerializedProperty customPass) {}
internal void OnGUI(Rect rect, SerializedProperty property)
{
rect.height = EditorGUIUtility.singleLineHeight;
EditorGUI.BeginChangeCheck();
if (firstTime)
InitInternal(property);
DoHeaderGUI(ref rect);
if (m_LabelerFoldout.boolValue)
{
EditorGUI.EndChangeCheck();
return;
}
EditorGUI.BeginDisabledGroup(!m_Enabled.boolValue);
{
DoPassGUI(property, rect);
}
EditorGUI.EndDisabledGroup();
if (EditorGUI.EndChangeCheck())
property.serializedObject.ApplyModifiedProperties();
}
/// <summary>
/// Implement this function to draw your custom GUI.
/// </summary>
/// <param name="customPass">Your custom pass instance represented as a SerializedProperty</param>
/// <param name="rect">space available for you to draw the UI</param>
protected virtual void DoPassGUI(SerializedProperty customPass, Rect rect)
{
foreach (var prop in m_CustomPassUserProperties)
{
EditorGUI.PropertyField(rect, prop);
rect.y += Styles.defaultLineSpace;
}
}
void DoHeaderGUI(ref Rect rect)
{
var enabledSize = EditorStyles.boldLabel.CalcSize(Styles.enabled) + new Vector2(Styles.reorderableListHandleIndentWidth, 0);
var headerRect = new Rect(rect.x + Styles.reorderableListHandleIndentWidth,
rect.y + EditorGUIUtility.standardVerticalSpacing,
rect.width - Styles.reorderableListHandleIndentWidth - enabledSize.x,
EditorGUIUtility.singleLineHeight);
rect.y += Styles.defaultLineSpace;
var enabledRect = headerRect;
enabledRect.x = rect.xMax - enabledSize.x;
enabledRect.width = enabledSize.x;
m_LabelerFoldout.boolValue = EditorGUI.Foldout(headerRect, m_LabelerFoldout.boolValue, $"{CameraLabeler.GetType().Name}", true, EditorStyles.boldLabel);
EditorGUIUtility.labelWidth = enabledRect.width - 14;
m_Enabled.boolValue = EditorGUI.Toggle(enabledRect, Styles.enabled, m_Enabled.boolValue);
EditorGUIUtility.labelWidth = 0;
}
/// <summary>
/// Implement this functions if you implement DoPassGUI. The result of this function must match the number of lines displayed in your custom GUI.
/// Note that this height can be dynamic.
/// </summary>
/// <param name="customPass">Your custom pass instance represented as a SerializedProperty</param>
/// <returns>The height in pixels of tour custom pass GUI</returns>
protected virtual float GetHeight(SerializedProperty customPass)
{
float height = 0;
foreach (var prop in m_CustomPassUserProperties)
{
height += EditorGUI.GetPropertyHeight(prop);
height += EditorGUIUtility.standardVerticalSpacing;
}
return height;
}
internal float GetElementHeight(SerializedProperty property)
{
float height = Styles.defaultLineSpace;
if (firstTime)
InitInternal(property);
if (m_LabelerFoldout.boolValue)
return height;
return height + GetHeight(property);
}
}
}

3
com.unity.perception/Runtime/GroundTruth/PerceptionCamera.cs


[Serializable]
public abstract class CameraLabeler
{
public bool enabled;
public bool foldout;
}
}

23
TestProjects/PerceptionURP/Assets/SemanticSegmentationLabelingConfiguration.asset


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 0}
m_Name: SemanticSegmentationLabelingConfiguration
m_EditorClassIdentifier: Unity.Perception.Runtime:UnityEngine.Perception.GroundTruth:SemanticSegmentationLabelConfig
LabelEntries:
- label: box
pixelValue: 10000
- label: cube
pixelValue: 20000
- label: crate
pixelValue: 30000
AutoAssignIds: 1
StartingLabelId: 1

8
TestProjects/PerceptionURP/Assets/SemanticSegmentationLabelingConfiguration.asset.meta


fileFormatVersion: 2
guid: c140c5aa05dd09e4fadaa26de31b1f39
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存