From 4deadb500a27ca1c5740e48913f83a9bcb7967aa Mon Sep 17 00:00:00 2001 From: Vova Vernygora Date: Thu, 14 Apr 2022 14:23:24 -0400 Subject: [PATCH] RC 0.11.1-preview.1 --- com.unity.perception/CHANGELOG.md | 24 ++ .../Documentation~/DatasetCapture.md | 110 ++++-- .../Uxml/Randomizer/AddRandomizerMenu.uxml | 2 +- .../Randomizer/RandomizerList.cs | 10 + .../Editor/Visualizer/VisualizerInstaller.cs | 58 ++-- .../Consumers/IFileSystemEndpoint.cs | 5 - .../Consumers/PerceptionEndpoint.cs | 52 +-- .../Consumers/PerceptionJsonFactory.cs | 7 +- .../Runtime/GroundTruth/DataModel/Metadata.cs | 210 +++++++++++- .../Runtime/GroundTruth/DatasetCapture.cs | 25 ++ .../GroundTruth/Labeling/RenderingUtil.cs | 43 +++ .../Labeling/RenderingUtil.cs.meta | 3 + .../Runtime/GroundTruth/PerceptionCamera.cs | 20 +- .../BackgroundObjectPlacementRandomizer.cs | 2 +- .../ForegroundObjectPlacementRandomizer.cs | 2 +- .../Utilities/GameObjectOneWayCache.cs | 16 +- .../Randomization/Scenarios/ScenarioBase.cs | 126 ++++++- .../Runtime/Settings/PerceptionSettings.cs | 150 ++++++++- .../Editor/PerceptionCameraEditorTests.cs | 61 ++-- .../GroundTruthTests/DatasetCaptureTests.cs | 116 +++++-- .../GroundTruthTests/GroundTruthTestBase.cs | 15 + .../KeypointGroundTruthTests.cs | 4 +- .../Runtime/GroundTruthTests/MetadataTests.cs | 53 +++ .../GroundTruthTests/PerceptionFormatTest.cs | 1 + .../PerceptionSettingsTests.cs | 112 ++++++ .../PerceptionSettingsTests.cs.meta | 11 + .../GroundTruthTests/RgbOutputTests.cs | 97 +++++- .../Runtime/GroundTruthTests/TestHelper.cs | 14 + .../TestAssets/CubeSceneSettings.lighting | 2 +- .../Runtime/TestAssets/UnlitMaterialHDRP.mat | 284 ++++++++++++++++ .../TestAssets/UnlitMaterialHDRP.mat.meta | 8 + .../Runtime/TestAssets/UnlitMaterialURP.mat | 308 +++++++++++++++++ .../TestAssets/UnlitMaterialURP.mat.meta | 8 + .../Runtime/TestAssets/UnlitObject.unity | 318 ++++++++++++++++++ .../Runtime/TestAssets/UnlitObject.unity.meta | 7 + .../Unity.Perception.Runtime.Tests.asmdef | 6 +- com.unity.perception/package.json | 2 +- 37 files changed, 2091 insertions(+), 201 deletions(-) create mode 100644 com.unity.perception/Runtime/GroundTruth/Labeling/RenderingUtil.cs create mode 100644 com.unity.perception/Runtime/GroundTruth/Labeling/RenderingUtil.cs.meta create mode 100644 com.unity.perception/Tests/Runtime/GroundTruthTests/PerceptionSettingsTests.cs create mode 100644 com.unity.perception/Tests/Runtime/GroundTruthTests/PerceptionSettingsTests.cs.meta create mode 100644 com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialHDRP.mat create mode 100644 com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialHDRP.mat.meta create mode 100644 com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialURP.mat create mode 100644 com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialURP.mat.meta create mode 100644 com.unity.perception/Tests/Runtime/TestAssets/UnlitObject.unity create mode 100644 com.unity.perception/Tests/Runtime/TestAssets/UnlitObject.unity.meta diff --git a/com.unity.perception/CHANGELOG.md b/com.unity.perception/CHANGELOG.md index ffcb7a1be..4892bc0e8 100644 --- a/com.unity.perception/CHANGELOG.md +++ b/com.unity.perception/CHANGELOG.md @@ -21,6 +21,30 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed +## [0.11.1-preview.1] - 2022-04-13 + +### Added + +Added the ability to define the output of a standalone player with an '--output-path' command line argument + +### Changed + +Exceptions thrown in randomizers will now end the run + +Duplicates in categorical parameters are checked and reported + +User output paths are now written out in user's settings + +### Fixed + +Fixed captured RGB images being upside down or dark in various cases + +Fixed UI when there are many randomizers in the project + +Fixed Scenario UI when the last randomizer is removed + +Fixed the Visualizer installation bug, Visualizer can be installed and opened properly now. + ## [0.10.0-preview.1] - 2022-03-09 ### Upgrade Notes diff --git a/com.unity.perception/Documentation~/DatasetCapture.md b/com.unity.perception/Documentation~/DatasetCapture.md index c55952cd0..497ccbd70 100644 --- a/com.unity.perception/Documentation~/DatasetCapture.md +++ b/com.unity.perception/Documentation~/DatasetCapture.md @@ -14,55 +14,90 @@ You can register custom sensors using `DatasetCapture.RegisterSensor()`. The `si `Time.captureDeltaTime` is set at every frame in order to precisely fall on the next sensor that requires simulation, and this includes multi-sensor simulations. For instance, if one sensor has a `simulationDeltaTime` of 2 and another 3, the first five values for `Time.captureDeltaTime` will be 2, 1, 1, 2, and 3, meaning simulation will happen on the timestamps 0, 2, 3, 4, 6, and 9. ## Custom annotations and metrics -In addition to the common annotations and metrics produced by [PerceptionCamera](PerceptionCamera.md), scripts can produce their own via `DatasetCapture`. You must first register annotation and metric definitions using `DatasetCapture.RegisterAnnotationDefinition()` or `DatasetCapture.RegisterMetricDefinition()`. These return `AnnotationDefinition` and `MetricDefinition` instances which you can then use to report values during runtime. +In addition to the common annotations and metrics produced by [PerceptionCamera](PerceptionCamera.md), scripts can produce their own via `DatasetCapture`. You must first create and register annotation and metric definitions using `DatasetCapture.RegisterAnnotationDefinition()` or `DatasetCapture.RegisterMetric()`. These are used~~~~ to report values during runtime. Annotations and metrics are always associated with the frame they are reported in. They may also be associated with a specific sensor by using the `Report*` methods on `SensorHandle`. ### Example - ```csharp using System; using UnityEngine; using UnityEngine.Perception.GroundTruth; +using UnityEngine.Perception.GroundTruth.DataModel; +using UnityEngine.Rendering; -[RequireComponent(typeof(PerceptionCamera))] -public class CustomAnnotationAndMetricReporter : MonoBehaviour +public class CustomLabeler : CameraLabeler { + public override string description => "Demo labeler"; + public override string labelerId => "Demo labeler"; + protected override bool supportsVisualization => false; + public GameObject targetLight; public GameObject target; MetricDefinition lightMetricDefinition; - AnnotationDefinition boundingBoxAnnotationDefinition; - SensorHandle cameraSensorHandle; + AnnotationDefinition targetPositionDef; - public void Start() + class TargetPositionDef : AnnotationDefinition { - //Metrics and annotations are registered up-front - lightMetricDefinition = DatasetCapture.RegisterMetricDefinition( - "Light position", - "The world-space position of the light", - Guid.Parse("1F6BFF46-F884-4CC5-A878-DB987278FE35")); - boundingBoxAnnotationDefinition = DatasetCapture.RegisterAnnotationDefinition( - "Target bounding box", - "The position of the target in the camera's local space", - id: Guid.Parse("C0B4A22C-0420-4D9F-BAFC-954B8F7B35A7")); + public TargetPositionDef(string id) + : base(id) { } + + public override string modelType => "targetPosDef"; + public override string description => "The position of the target in the camera's local space"; } - public void Update() + [Serializable] + class TargetPosition : Annotation + { + public TargetPosition(AnnotationDefinition definition, string sensorId, Vector3 pos) + : base(definition, sensorId) + { + position = pos; + } + + public Vector3 position; + + public override void ToMessage(IMessageBuilder builder) + { + base.ToMessage(builder); + builder.AddFloatArray("position", MessageBuilderUtils.ToFloatVector(position)); + } + + public override bool IsValid() => true; + + } + + protected override void Setup() + { + lightMetricDefinition = + new MetricDefinition( + "LightMetric", + "lightMetric1", + "The world-space position of the light"); + DatasetCapture.RegisterMetric(lightMetricDefinition); + + targetPositionDef = new TargetPositionDef("target1"); + DatasetCapture.RegisterAnnotationDefinition(targetPositionDef); + } + + protected override void OnBeginRendering(ScriptableRenderContext scriptableRenderContext) { //Report the light's position by manually creating the json array string. var lightPos = targetLight.transform.position; - DatasetCapture.ReportMetric(lightMetricDefinition, - $@"[{{ ""x"": {lightPos.x}, ""y"": {lightPos.y}, ""z"": {lightPos.z} }}]"); + var metric = new GenericMetric(new[] { lightPos.x, lightPos.y, lightPos.z }, lightMetricDefinition); + DatasetCapture.ReportMetric(lightMetricDefinition, metric); + //compute the location of the object in the camera's local space - Vector3 targetPos = transform.worldToLocalMatrix * target.transform.position; + Vector3 targetPos = perceptionCamera.transform.worldToLocalMatrix * target.transform.position; + //Report using the PerceptionCamera's SensorHandle if scheduled this frame - var sensorHandle = GetComponent().SensorHandle; + var sensorHandle = perceptionCamera.SensorHandle; + if (sensorHandle.ShouldCaptureThisFrame) { - sensorHandle.ReportAnnotationValues( - boundingBoxAnnotationDefinition, - new[] { targetPos }); + var annotation = new TargetPosition(targetPositionDef, sensorHandle.Id, targetPos); + sensorHandle.ReportAnnotation(targetPositionDef, annotation); } } } @@ -73,21 +108,26 @@ public class CustomAnnotationAndMetricReporter : MonoBehaviour // "annotation_id": null, // "sequence_id": "9768671e-acea-4c9e-a670-0f2dba5afe12", // "step": 1, -// "metric_definition": "1f6bff46-f884-4cc5-a878-db987278fe35", -// "values": [{ "x": 96.1856, "y": 192.676, "z": -193.8386 }] +// "metric_definition": "lightMetric1", +// "values": [ +// 96.1856, +// 192.675964, +// -193.838638 +// ] // }, // Example annotation that is added to each capture in the dataset: // { -// "id": "33f5a3aa-3e5e-48f1-8339-6cbd64ed4562", -// "annotation_definition": "c0b4a22c-0420-4d9f-bafc-954b8f7b35a7", -// "values": [ -// [ -// -1.03097284, -// 0.07265166, -// -6.318692 +// "annotation_id": "target1", +// "model_type": "targetPosDef", +// "description": "The position of the target in the camera's local space", +// "sensor_id": "camera", +// "id": "target1", +// "position": [ +// 1.85350215, +// -0.253945172, +// -5.015307 // ] -// ] // } -``` \ No newline at end of file +``` diff --git a/com.unity.perception/Editor/Randomization/Uxml/Randomizer/AddRandomizerMenu.uxml b/com.unity.perception/Editor/Randomization/Uxml/Randomizer/AddRandomizerMenu.uxml index 7d14bbfbc..953237aca 100644 --- a/com.unity.perception/Editor/Randomization/Uxml/Randomizer/AddRandomizerMenu.uxml +++ b/com.unity.perception/Editor/Randomization/Uxml/Randomizer/AddRandomizerMenu.uxml @@ -7,7 +7,7 @@ - + diff --git a/com.unity.perception/Editor/Randomization/VisualElements/Randomizer/RandomizerList.cs b/com.unity.perception/Editor/Randomization/VisualElements/Randomizer/RandomizerList.cs index 7d0abedb4..cb0fd6968 100644 --- a/com.unity.perception/Editor/Randomization/VisualElements/Randomizer/RandomizerList.cs +++ b/com.unity.perception/Editor/Randomization/VisualElements/Randomizer/RandomizerList.cs @@ -66,6 +66,16 @@ void RefreshList() return; } + if (m_Property.arraySize == 0) + { + var textElement = new TextElement() + { + text = "No randomizers added. Add any to resume" + }; + textElement.AddToClassList("scenario__error-box"); + m_Container.Add(textElement); + } + for (var i = 0; i < m_Property.arraySize; i++) m_Container.Add(new RandomizerElement(m_Property.GetArrayElementAtIndex(i), this)); } diff --git a/com.unity.perception/Editor/Visualizer/VisualizerInstaller.cs b/com.unity.perception/Editor/Visualizer/VisualizerInstaller.cs index 5fe4ab284..30f93055f 100644 --- a/com.unity.perception/Editor/Visualizer/VisualizerInstaller.cs +++ b/com.unity.perception/Editor/Visualizer/VisualizerInstaller.cs @@ -41,34 +41,48 @@ const string k_NameOfVisualizerProcess #elif UNITY_EDITOR_WIN = "datasetvisualizer"; #endif - - internal static Task InstallationCommand(ref int exitCode, string packagesPath) + + internal static Task InstallationCommand(ref int exitCode, string packagesPath, bool forcePublic) + { + var exitCodeCopy = exitCode; + var pythonPath = Path.Combine(Directory.GetParent(packagesPath)?.ToString() ?? string.Empty, "python.exe"); + + var indexURL = forcePublic ? string.Empty : GetIndexURL(); + +#if UNITY_EDITOR_WIN + var task = Task.Run(() => ExecuteCmd($"{pythonPath} -m pip install --upgrade --no-warn-script-location unity-cv-datasetvisualizer {indexURL}", ref exitCodeCopy)); +#elif UNITY_EDITOR_OSX + var task = Task.Run(() => ExecuteCmd($"cd {packagesPath}; ./python3.7 -m pip install --upgrade unity-cv-datasetvisualizer {indexURL}", ref exitCodeCopy)); +#endif + exitCode = exitCodeCopy; + return task; + } + + internal static Task UninstallCommand(ref int exitCode, string packagesPath) { var exitCodeCopy = exitCode; - var pythonPath = packagesPath + "\\..\\python.exe"; - var index_url = get_index_url(); + var pythonPath = Path.Combine(Directory.GetParent(packagesPath)?.ToString() ?? string.Empty, "Scripts"); #if UNITY_EDITOR_WIN - var task = Task.Run(() => ExecuteCmd($"\"{pythonPath}\" -m pip install --upgrade --no-warn-script-location unity-cv-datasetvisualizer\"{index_url}\"", ref exitCodeCopy)); + var task = Task.Run(() => ExecuteCmd($"cd {pythonPath} && pip uninstall -y unity-cv-datasetvisualizer", ref exitCodeCopy)); #elif UNITY_EDITOR_OSX - var task = Task.Run(() => ExecuteCmd($"cd \'{packagesPath}\'; ./python3.7 -m pip install --upgrade unity-cv-datasetvisualizer \'{index_url}'", ref exitCodeCopy)); + var task = Task.Run(() => ExecuteCmd($"cd {packagesPath}; ./python3.7 pip uninstall unity-cv-datasetvisualizer", ref exitCodeCopy)); #endif exitCode = exitCodeCopy; return task; } // return the internal artifactory index url if using the internal perception package - static String get_index_url() + static string GetIndexURL() { - var pckName = "com.unity.perception.internal"; - if ( !File.Exists("Packages/manifest.json") ) - return ""; - string jsonText = File.ReadAllText("Packages/manifest.json"); - var hasPerceptionInternal = jsonText.Contains( pckName ); - if (hasPerceptionInternal) + const string pckName = "com.unity.perception.internal"; + if (!File.Exists("Packages/manifest.json")) { - return " --index-url=https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/unity-pypi-local/simple/"; + return string.Empty; } - return ""; + + var jsonText = File.ReadAllText("Packages/manifest.json"); + var hasPerceptionInternal = jsonText.Contains( pckName ); + return hasPerceptionInternal ? "--index-url=https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/unity-pypi-local/simple/" : string.Empty; } // ReSharper disable Unity.PerformanceAnalysis @@ -117,8 +131,12 @@ static async Task SetupVisualizer() EditorUtility.DisplayProgressBar("Setting up the Visualizer", "Installing Visualizer (This may take a few minutes)", 2f / steps); - await InstallationCommand(ref exitCode, packagesPath); - + await InstallationCommand(ref exitCode, packagesPath, false); + if (exitCode != 0) + { + Debug.LogWarning("Installing Public Visualizer"); + await InstallationCommand(ref exitCode, packagesPath, true); + } if (exitCode != 0) { EditorUtility.ClearProgressBar(); @@ -231,7 +249,7 @@ public static async Task RunVisualizer(string project) { await SetupVisualizer(); } - + var lastDataPath = GetLastDataPath(); var (pythonPid, port, visualizerPid) = ReadEntry(lastDataPath); @@ -349,7 +367,7 @@ static void ExecuteVisualizer(string project) #elif UNITY_EDITOR_OSX var packagesPath = project.Replace("/Assets","/Library/PythonInstall/bin"); #endif - + var pathToData = GetLastDataPath(); #if UNITY_EDITOR_WIN packagesPath = packagesPath.Replace("/", "\\"); @@ -369,7 +387,7 @@ static void ExecuteVisualizer(string project) Debug.LogError("Failed launching the visualizer - Exit Code: " + exitCode); } } - + static string GetLastDataPath() { var lastEndpointType = PlayerPrefs.GetString(SimulationState.lastEndpointTypeKey, string.Empty); diff --git a/com.unity.perception/Runtime/GroundTruth/Consumers/IFileSystemEndpoint.cs b/com.unity.perception/Runtime/GroundTruth/Consumers/IFileSystemEndpoint.cs index eca0eb866..db00f509e 100644 --- a/com.unity.perception/Runtime/GroundTruth/Consumers/IFileSystemEndpoint.cs +++ b/com.unity.perception/Runtime/GroundTruth/Consumers/IFileSystemEndpoint.cs @@ -16,11 +16,6 @@ public interface IFileSystemEndpoint /// string defaultPathToken { get; } - /// - /// The default path to user if a user does not set a custom storage directory - /// - string defaultPath { get; } - /// /// The runtime directory that the dataset will be written to. /// This directory may be different from the in cases where the diff --git a/com.unity.perception/Runtime/GroundTruth/Consumers/PerceptionEndpoint.cs b/com.unity.perception/Runtime/GroundTruth/Consumers/PerceptionEndpoint.cs index 733c32a94..fa91f03a9 100644 --- a/com.unity.perception/Runtime/GroundTruth/Consumers/PerceptionEndpoint.cs +++ b/com.unity.perception/Runtime/GroundTruth/Consumers/PerceptionEndpoint.cs @@ -7,6 +7,7 @@ using Unity.Mathematics; using UnityEngine; using UnityEngine.Perception.GroundTruth.DataModel; +using UnityEngine.Perception.Settings; namespace UnityEngine.Perception.GroundTruth.Consumers { @@ -17,7 +18,6 @@ namespace UnityEngine.Perception.GroundTruth.Consumers public class PerceptionEndpoint : IConsumerEndpoint, IFileSystemEndpoint { const string k_DefaultPathToken = "_DEFAULT_PATH_"; - const string k_PrefsPathKey = "perceptionPathKey"; string m_DatasetPath; Dictionary m_SensorMap = new Dictionary(); @@ -36,9 +36,10 @@ public class PerceptionEndpoint : IConsumerEndpoint, IFileSystemEndpoint }; /// - /// The runtime resolved directory path where the dataset will be written to. + /// The runtime resolved directory path where the dataset will be written to. This value + /// should not be accessed directly. Please use /// - protected string m_CurrentPath; + protected string m_CurrentPathDoNotUseDirectly; /// /// The number of captures to write to a single captures file. @@ -61,33 +62,13 @@ public class PerceptionEndpoint : IConsumerEndpoint, IFileSystemEndpoint /// public string defaultPathToken => k_DefaultPathToken; - /// - public virtual string defaultPath - { - get - { - var persistentDataPath = Application.persistentDataPath; -#if UNITY_SIMULATION_CORE_PRESENT - if (Unity.Simulation.Configuration.Instance.IsSimulationRunningInCloud()) - persistentDataPath = Unity.Simulation.Configuration.Instance.GetStoragePath(); -#endif - return persistentDataPath; - } - } + string defaultPath => PerceptionSettings.instance.defaultOutputPath; /// public virtual string basePath { - get - { -#if UNITY_SIMULATION_CORE_PRESENT - if (Unity.Simulation.Configuration.Instance.IsSimulationRunningInCloud()) - return defaultPath; -#endif - var p = PlayerPrefs.GetString(k_PrefsPathKey, k_DefaultPathToken); - return p == k_DefaultPathToken ? defaultPath : p; - } - set => PlayerPrefs.SetString(k_PrefsPathKey, value); + get => PerceptionSettings.instance.GetOutputBasePath(); + set => PerceptionSettings.instance.SetOutputBasePath(value); } /// @@ -98,27 +79,28 @@ public virtual string currentPath { get { - if (string.IsNullOrEmpty(m_CurrentPath)) + if (string.IsNullOrEmpty(m_CurrentPathDoNotUseDirectly)) { #if UNITY_SIMULATION_CORE_PRESENT if (Unity.Simulation.Configuration.Instance.IsSimulationRunningInCloud()) { - m_CurrentPath = defaultPath; + m_CurrentPathDoNotUseDirectly = defaultPath; return defaultPath; } #endif - var baseDirectory = PlayerPrefs.GetString(k_PrefsPathKey, k_DefaultPathToken); - - if (baseDirectory == k_DefaultPathToken) + var p = basePath; + if (!Directory.Exists(p)) { - m_CurrentPath = PathUtils.CombineUniversal(Application.persistentDataPath, Guid.NewGuid().ToString()); + m_CurrentPathDoNotUseDirectly = PathUtils.CombineUniversal(defaultPath, Guid.NewGuid().ToString()); + Debug.LogError($"Tried to write perception output to an inaccessible path {p}. Using default path: {m_CurrentPathDoNotUseDirectly}"); } else { - m_CurrentPath = PathUtils.CombineUniversal(baseDirectory, Guid.NewGuid().ToString()); + m_CurrentPathDoNotUseDirectly = PathUtils.CombineUniversal(basePath, Guid.NewGuid().ToString()); } } - return m_CurrentPath; + + return m_CurrentPathDoNotUseDirectly; } } @@ -317,7 +299,7 @@ public void FrameGenerated(Frame frame) captureIdMap[(frame.step, rgb.id)] = id; var capture = new PerceptionCapture { - id = id, + id = id, sequence_id = seqId, step = frame.step, timestamp = frame.timestamp, diff --git a/com.unity.perception/Runtime/GroundTruth/Consumers/PerceptionJsonFactory.cs b/com.unity.perception/Runtime/GroundTruth/Consumers/PerceptionJsonFactory.cs index 2a78dce8d..b0800342a 100644 --- a/com.unity.perception/Runtime/GroundTruth/Consumers/PerceptionJsonFactory.cs +++ b/com.unity.perception/Runtime/GroundTruth/Consumers/PerceptionJsonFactory.cs @@ -94,9 +94,12 @@ public static JToken Convert(PerceptionEndpoint consumer, Frame frame, string la { return JToken.FromObject(PerceptionKeyPointValue.Convert(consumer, kp), consumer.Serializer); } + default: + { + var tmp = JToken.FromObject(annotation, consumer.Serializer); + return tmp; + } } - - return null; } } diff --git a/com.unity.perception/Runtime/GroundTruth/DataModel/Metadata.cs b/com.unity.perception/Runtime/GroundTruth/DataModel/Metadata.cs index a07e18528..3780cd0ca 100644 --- a/com.unity.perception/Runtime/GroundTruth/DataModel/Metadata.cs +++ b/com.unity.perception/Runtime/GroundTruth/DataModel/Metadata.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Unity.Collections; namespace UnityEngine.Perception.GroundTruth.DataModel { @@ -15,6 +17,11 @@ public Metadata() m_Metadata = new Dictionary(); } + Metadata(Dictionary metadata) + { + m_Metadata = metadata; + } + Dictionary m_Metadata; /// @@ -209,6 +216,11 @@ public void Add(string key, IEnumerable value) }; } + void Add(string key, MetadataEntry value) + { + m_Metadata[key] = value; + } + /// /// Gets a value out of the metadata. If the value does not exist, or if a request is made for the improper /// data type, an exception will be thrown. @@ -594,7 +606,7 @@ public Metadata[] GetSubMetadataArray(string key) if (!m_Metadata.TryGetValue(key, out var value)) throw new ArgumentException($"{key} does not exist in metadata"); - if (value.valueType != ValueType.BoolArray) + if (value.valueType != ValueType.SubMetadataArray) throw new InvalidOperationException($"{key} is not associated to a sub-metadata array"); return (Metadata[])value.value; @@ -614,7 +626,7 @@ public bool TryGetValue(string key, out Metadata[] value) return true; } - enum ValueType + internal enum ValueType { Int, UInt, @@ -629,10 +641,200 @@ enum ValueType SubMetadataArray } - struct MetadataEntry + internal struct MetadataEntry { public ValueType valueType; public object value; } + + class MetadataEntryConverter : JsonConverter + { + static void WriteMetadata(JsonWriter writer, Metadata value, JsonSerializer serializer) + { + writer.WriteStartObject(); + + foreach (var i in value.m_Metadata.Keys) + { + writer.WritePropertyName(i); + serializer.Serialize(writer, value.m_Metadata[i]); + } + + writer.WriteEndObject(); + } + + static void WriteMetadataEntry(JsonWriter writer, Metadata value, JsonSerializer serializer) + { + + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + switch (value) + { + case Metadata metadata: + WriteMetadata(writer, metadata, serializer); + return; + case MetadataEntry metadataEntry: + { + var entry = metadataEntry; + JObject jObject = null; + switch (entry.valueType) + { + case ValueType.Int: + jObject = new JObject { ["type"] = entry.valueType.ToString(), ["value"] = (int)entry.value }; + jObject.WriteTo(writer); + break; + case ValueType.UInt: + jObject = new JObject { ["type"] = entry.valueType.ToString(), ["value"] = (uint)entry.value }; + jObject.WriteTo(writer); + break; + case ValueType.Float: + jObject = new JObject { ["type"] = entry.valueType.ToString(), ["value"] = (float)entry.value }; + jObject.WriteTo(writer); + break; + case ValueType.String: + jObject = new JObject { ["type"] = entry.valueType.ToString(), ["value"] = (string)entry.value }; + jObject.WriteTo(writer); + break; + case ValueType.Bool: + jObject = new JObject { ["type"] = entry.valueType.ToString(), ["value"] = (bool)entry.value }; + jObject.WriteTo(writer); + break; + case ValueType.SubMetadata: + writer.WriteStartObject(); + writer.WritePropertyName("type"); + writer.WriteValue(entry.valueType.ToString()); + writer.WritePropertyName("value"); + serializer.Serialize(writer, entry.value); + writer.WriteEndObject(); + break; + case ValueType.IntArray: + jObject = new JObject { ["type"] = entry.valueType.ToString(), ["value"] = new JArray(entry.value) }; + jObject.WriteTo(writer); + break; + case ValueType.FloatArray: + jObject = new JObject { ["type"] = entry.valueType.ToString(), ["value"] = new JArray(entry.value) }; + jObject.WriteTo(writer); + break; + case ValueType.StringArray: + jObject = new JObject { ["type"] = entry.valueType.ToString(), ["value"] = new JArray(entry.value) }; + jObject.WriteTo(writer); + break; + case ValueType.BoolArray: + jObject = new JObject { ["type"] = entry.valueType.ToString(), ["value"] = new JArray(entry.value) }; + jObject.WriteTo(writer); + break; + case ValueType.SubMetadataArray: + writer.WriteStartObject(); + writer.WritePropertyName("type"); + writer.WriteValue(entry.valueType.ToString()); + writer.WritePropertyName("value"); + serializer.Serialize(writer, entry.value); + writer.WriteEndObject(); + break; + default: + throw new ArgumentOutOfRangeException(); + } + + break; + } + } + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + var jsonObject = JObject.Load(reader); + var properties = jsonObject.Properties().ToList(); + + var valueType = (ValueType)Enum.Parse(typeof(ValueType), (string)properties[0].Value); + + object value = null; + + switch (valueType) + { + case ValueType.Int: + value = (int)properties[1].Value; + break; + case ValueType.UInt: + value = (uint)properties[1].Value; + break; + case ValueType.Float: + value = (float)properties[1].Value; + break; + case ValueType.String: + value = (string)properties[1].Value; + break; + case ValueType.Bool: + value = (bool)properties[1].Value; + break; + case ValueType.SubMetadata: + { + var sub = new Metadata(); + var readIn = properties[1].Value.ToObject>(serializer); + foreach (var r in readIn.Keys) + { + sub.Add(r, readIn[r]); + } + + value = sub; + + break; + } + case ValueType.IntArray: + value = properties[1].Values().ToList().ConvertAll(a => (int)a).ToArray(); + break; + case ValueType.FloatArray: + value = properties[1].Values().ToList().ConvertAll(a => (float)a).ToArray(); + break; + case ValueType.StringArray: + value = properties[1].Values().ToList().ConvertAll(a => (string)a).ToArray(); + break; + case ValueType.BoolArray: + value = properties[1].Values().ToList().ConvertAll(a => (bool)a).ToArray(); + break; + case ValueType.SubMetadataArray: + { + var subList = new List(); + var readIn = properties[1].Values().ToList().ConvertAll(a => a.ToObject>(serializer)); + foreach (var r in readIn) + { + var sub = new Metadata(); + foreach (var k in r.Keys) + { + sub.Add(k, r[k]); + } + subList.Add(sub); + } + + value = subList.ToArray(); + break; + } + default: + throw new ArgumentOutOfRangeException(); + } + + return new MetadataEntry + { + valueType = valueType, + value = value + }; + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(MetadataEntry) || objectType == typeof(Metadata); + } + } + + public static Metadata FromJson(string json) + { + var map = JsonConvert.DeserializeObject>(json, new MetadataEntryConverter()); + return new Metadata(map); + } + + public string ToJson() + { + return JsonConvert.SerializeObject(m_Metadata, Formatting.Indented, new MetadataEntryConverter()); + } } } diff --git a/com.unity.perception/Runtime/GroundTruth/DatasetCapture.cs b/com.unity.perception/Runtime/GroundTruth/DatasetCapture.cs index 86522f846..7627db2fe 100644 --- a/com.unity.perception/Runtime/GroundTruth/DatasetCapture.cs +++ b/com.unity.perception/Runtime/GroundTruth/DatasetCapture.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; +using UnityEngine.Perception.GroundTruth.Consumers; using UnityEngine.Perception.GroundTruth.DataModel; using UnityEngine.Perception.Settings; @@ -82,6 +83,13 @@ public static (int sequence, int step) GetSequenceAndStepFromFrame(int frame) return currentSimulation.GetSequenceAndStepFromFrame(frame); } + /// + /// Reports a metric for the activate frame that is not associated with a sensor or an annotation. To + /// report a metric associated with an annotation use , to + /// report a metric associated with a sensor user . + /// + /// The metric definition to use + /// The metric to report public static void ReportMetric(MetricDefinition definition, Metric metric) { currentSimulation.ReportMetric(definition, metric, null, null); @@ -191,6 +199,23 @@ public static void ReportMetadata(string key, bool[] value) static IConsumerEndpoint m_OverrideEndpoint; + /// + /// Retrieve a handle to the active endpoint. + /// + public static IConsumerEndpoint activateEndpoint => m_ActiveSimulation.consumerEndpoint; + + /// + /// Sets the current output path for endpoints. This will set the path for the next simulation, it will + /// not affect a simulation that is currently executing. In order for this to take effect the caller should call + /// + /// + /// If the current endpoint is not an the value will be unused + /// The path to set + public static void SetOutputPath(string outputPath) + { + PerceptionSettings.instance.SetOutputBasePath(outputPath); + } + internal static void OverrideEndpoint(IConsumerEndpoint endpoint) { m_OverrideEndpoint = endpoint; diff --git a/com.unity.perception/Runtime/GroundTruth/Labeling/RenderingUtil.cs b/com.unity.perception/Runtime/GroundTruth/Labeling/RenderingUtil.cs new file mode 100644 index 000000000..1de961b08 --- /dev/null +++ b/com.unity.perception/Runtime/GroundTruth/Labeling/RenderingUtil.cs @@ -0,0 +1,43 @@ +using UnityEngine.Rendering; + +namespace UnityEngine.Perception.GroundTruth +{ + /// + /// Helper functions for rendering. + /// + internal class RenderingUtil + { + /// + /// Check if for the given rendering pipeline there is a need to flip Y during readback. + /// + /// Camera from which the readback is being performed. + /// When we are using a passed in rtid, then we don't need to flip. + /// A boolean indicating if the flip is required. + public static bool ShouldFlipColorY(Camera camera, bool usePassedInRenderTargetId) + { + bool shouldFlipY = false; + +#if URP_ENABLED + // Issue SIMPE-356: URP color channel is inverted with FXAA disabled, and PostProcessing enabled. + // Issue SIMPE-400: URP disabled PP, and FXAA, but with MSAA.. + var additionalCameraData = camera.GetComponent(); + var ppaa = additionalCameraData.antialiasing != AntialiasingMode.FastApproximateAntialiasing && additionalCameraData.renderPostProcessing != false; + shouldFlipY = SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal ? ppaa || SystemInfo.graphicsUVStartsAtTop : ppaa && SystemInfo.graphicsUVStartsAtTop; +#else + shouldFlipY = !usePassedInRenderTargetId && camera.targetTexture == null && SystemInfo.graphicsUVStartsAtTop; +#endif + return shouldFlipY; + } + + internal static void LogGraphicsAndFlipY(Camera camera) + { + var rt = camera.targetTexture == null ? "null" : camera.targetTexture.ToString(); + var uv = SystemInfo.graphicsUVStartsAtTop.ToString(); + var pipe = RenderPipelineManager.currentPipeline?.GetType()?.ToString(); + var gfx = SystemInfo.graphicsDeviceType.ToString(); + + Debug.Log($"ShouldFlipY: {ShouldFlipColorY(camera, false)} <= " + + $"camera({camera}) rt({rt}) uv({uv}) pipe({pipe}) gfx({gfx})"); + } + } +} diff --git a/com.unity.perception/Runtime/GroundTruth/Labeling/RenderingUtil.cs.meta b/com.unity.perception/Runtime/GroundTruth/Labeling/RenderingUtil.cs.meta new file mode 100644 index 000000000..31391dcb5 --- /dev/null +++ b/com.unity.perception/Runtime/GroundTruth/Labeling/RenderingUtil.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5237baced4374575b24659e1c6490ca5 +timeCreated: 1648822671 \ No newline at end of file diff --git a/com.unity.perception/Runtime/GroundTruth/PerceptionCamera.cs b/com.unity.perception/Runtime/GroundTruth/PerceptionCamera.cs index 87e4c8100..88457d5a6 100644 --- a/com.unity.perception/Runtime/GroundTruth/PerceptionCamera.cs +++ b/com.unity.perception/Runtime/GroundTruth/PerceptionCamera.cs @@ -530,15 +530,27 @@ void CaptureRGB(ScriptableRenderContext ctx) Profiler.BeginSample("CaptureDataFromLastFrame"); var cmd = CommandBufferPool.Get($"{ID}_PerceptionRGBCapture"); var tempRT1 = RenderTexture.GetTemporary( - attachedCamera.pixelWidth, attachedCamera.pixelHeight, 0, GraphicsFormat.R8G8B8A8_UNorm); + attachedCamera.pixelWidth, attachedCamera.pixelHeight, 0, GraphicsFormat.R8G8B8A8_SRGB); var tempRT2 = RenderTexture.GetTemporary( - attachedCamera.pixelWidth, attachedCamera.pixelHeight, 0, GraphicsFormat.R8G8B8A8_UNorm); + attachedCamera.pixelWidth, attachedCamera.pixelHeight, 0, GraphicsFormat.R8G8B8A8_SRGB); // Blit the back buffer to a temporary RenderTexture to obtain the RGB output image cmd.Blit(null, tempRT1); - // Invert the image (the image comes back upside down from the first blit) - cmd.Blit(tempRT1, tempRT2, new Vector2(1, -1), Vector2.up); + Vector2 scaleForFlip; + Vector2 offset; + if (RenderingUtil.ShouldFlipColorY(attachedCamera, false)) + { + scaleForFlip = new Vector2(1, -1); + offset = Vector2.up; + } + else + { + scaleForFlip = new Vector2(1, 1); + offset = Vector2.zero; + } + + cmd.Blit(tempRT1, tempRT2, scaleForFlip, offset); // Execute the CommandBuffer ctx.ExecuteCommandBuffer(cmd); diff --git a/com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Randomizers/BackgroundObjectPlacementRandomizer.cs b/com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Randomizers/BackgroundObjectPlacementRandomizer.cs index b98ade7ac..0f79ddcbf 100644 --- a/com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Randomizers/BackgroundObjectPlacementRandomizer.cs +++ b/com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Randomizers/BackgroundObjectPlacementRandomizer.cs @@ -52,7 +52,7 @@ protected override void OnAwake() m_Container = new GameObject("BackgroundContainer"); m_Container.transform.parent = scenario.transform; m_GameObjectOneWayCache = new GameObjectOneWayCache( - m_Container.transform, prefabs.categories.Select((element) => element.Item1).ToArray()); + m_Container.transform, prefabs.categories.Select((element) => element.Item1).ToArray(), this); } /// diff --git a/com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Randomizers/ForegroundObjectPlacementRandomizer.cs b/com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Randomizers/ForegroundObjectPlacementRandomizer.cs index 7b207600e..d208f0b0c 100644 --- a/com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Randomizers/ForegroundObjectPlacementRandomizer.cs +++ b/com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Randomizers/ForegroundObjectPlacementRandomizer.cs @@ -46,7 +46,7 @@ protected override void OnAwake() m_Container = new GameObject("Foreground Objects"); m_Container.transform.parent = scenario.transform; m_GameObjectOneWayCache = new GameObjectOneWayCache( - m_Container.transform, prefabs.categories.Select(element => element.Item1).ToArray()); + m_Container.transform, prefabs.categories.Select(element => element.Item1).ToArray(), this); } /// diff --git a/com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Utilities/GameObjectOneWayCache.cs b/com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Utilities/GameObjectOneWayCache.cs index 49438bf44..7bb2e42d4 100644 --- a/com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Utilities/GameObjectOneWayCache.cs +++ b/com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Utilities/GameObjectOneWayCache.cs @@ -32,7 +32,7 @@ public class GameObjectOneWayCache /// /// The parent object all cached instances will be parented under /// The gameObjects to cache - public GameObjectOneWayCache(Transform parent, GameObject[] gameObjects) + public GameObjectOneWayCache(Transform parent, GameObject[] gameObjects, Randomizer randomizer) { if (gameObjects.Length == 0) throw new ArgumentException( @@ -53,6 +53,13 @@ public GameObjectOneWayCache(Transform parent, GameObject[] gameObjects) obj.SetActive(false); } var instanceId = obj.GetInstanceID(); + if (m_InstanceIdToIndex.ContainsKey(instanceId)) + { + Debug.LogException(new Exception("Duplicated objects were added in the categories, the duplicated object will be ignored\n" + + "Randomizer: " + randomizer.GetType().Name + + "\nDuplicate objects: " + obj.name + "\n")); + continue; + } m_InstanceIdToIndex.Add(instanceId, index); m_InstantiatedObjects[index] = new List(); m_NumObjectsActive[index] = 0; @@ -124,9 +131,12 @@ public void ResetAllObjects() for (var i = 0; i < m_InstantiatedObjects.Length; ++i) { m_NumObjectsActive[i] = 0; - foreach (var cachedObjectData in m_InstantiatedObjects[i]) + if (m_InstantiatedObjects[i] != null) { - ResetObjectState(cachedObjectData); + foreach (var cachedObjectData in m_InstantiatedObjects[i]) + { + ResetObjectState(cachedObjectData); + } } } } diff --git a/com.unity.perception/Runtime/Randomization/Scenarios/ScenarioBase.cs b/com.unity.perception/Runtime/Randomization/Scenarios/ScenarioBase.cs index a1f6b0824..6c2a8ac9e 100644 --- a/com.unity.perception/Runtime/Randomization/Scenarios/ScenarioBase.cs +++ b/com.unity.perception/Runtime/Randomization/Scenarios/ScenarioBase.cs @@ -357,28 +357,95 @@ void Update() } #endregion + static void QuitApplication(Exception e) + { + Debug.LogException(e); + // save any game data here +#if UNITY_EDITOR + // Application.Quit() does not work in the editor so + // UnityEditor.EditorApplication.isPlaying need to be set to false to end the game + EditorApplication.isPlaying = false; +#else + Application.Quit(-1); +#endif + } + void IterationLoop() { // Increment iteration and cleanup last iteration if (isIterationComplete) { - IncrementIteration(); + try + { + IncrementIteration(); + } + catch (Exception e) + { + Debug.LogError($"[IncrementIteration] scenario {GetType()} thrown an exception {e.Message}"); + QuitApplication(e); + } + currentIterationFrame = 0; foreach (var randomizer in activeRandomizers) - randomizer.IterationEnd(); - OnIterationEnd(); + { + try + { + randomizer.IterationEnd(); + } + catch (Exception e) + { + Debug.LogError($"[IterationEnd] randomizer {randomizer.GetType()} thrown an exception {e.Message}"); + QuitApplication(e); + } + } + + try + { + OnIterationEnd(); + } + catch (Exception e) + { + Debug.LogError($"[OnIterationEnd] scenario {GetType()} thrown an exception {e.Message}"); + QuitApplication(e); + } } // Quit if scenario is complete if (isScenarioComplete) { foreach (var randomizer in activeRandomizers) - randomizer.ScenarioComplete(); + { + try + { + randomizer.ScenarioComplete(); + } + catch (Exception e) + { + Debug.LogError($"[ScenarioComplete] randomizer {randomizer.GetType()} thrown an exception {e.Message}"); + QuitApplication(e); + } + } - OnComplete(); + try + { + OnComplete(); + } + catch (Exception e) + { + Debug.LogError($"[OnComplete] scenario {GetType()} thrown an exception {e.Message}"); + QuitApplication(e); + } - state = State.Idle; - OnIdle(); + try + { + state = State.Idle; + OnIdle(); + } + catch (Exception e) + { + Debug.LogError($"[OnIdle] scenario {GetType()} thrown an exception {e.Message}"); + QuitApplication(e); + } return; } @@ -386,7 +453,15 @@ void IterationLoop() if (currentIterationFrame == 0) { ResetRandomStateOnIteration(); - OnIterationStart(); + try + { + OnIterationStart(); + } + catch (Exception e) + { + Debug.LogError($"[OnIterationStart] scenario {GetType()} thrown an exception {e.Message}"); + QuitApplication(e); + } int iterationStartCount = 0; do @@ -396,7 +471,16 @@ void IterationLoop() iterationStartCount++; foreach (var randomizer in activeRandomizers) { - randomizer.IterationStart(); + try + { + randomizer.IterationStart(); + } + catch (Exception e) + { + Debug.LogError($"[IterationStart] randomizer {randomizer.GetType()} thrown an exception {e.Message}"); + QuitApplication(e); + } + if (m_ShouldRestartIteration) break; @@ -418,9 +502,29 @@ void IterationLoop() } // Perform new frame tasks - OnUpdate(); + try + { + OnUpdate(); + } + catch (Exception e) + { + Debug.LogError($"[OnUpdate] scenario {GetType()} thrown an exception {e.Message}"); + QuitApplication(e); + } + foreach (var randomizer in activeRandomizers) - randomizer.Update(); + { + try + { + randomizer.Update(); + } + catch (Exception e) + { + Debug.LogError($"[OnUpdate] randomizer {randomizer.GetType()} thrown an exception {e.Message}"); + QuitApplication(e); + } + } + // Iterate scenario frame count if (!m_ShouldDelayIteration) diff --git a/com.unity.perception/Runtime/Settings/PerceptionSettings.cs b/com.unity.perception/Runtime/Settings/PerceptionSettings.cs index b1032aa1e..b500bae83 100644 --- a/com.unity.perception/Runtime/Settings/PerceptionSettings.cs +++ b/com.unity.perception/Runtime/Settings/PerceptionSettings.cs @@ -2,29 +2,159 @@ using UnityEditor; #endif using System; +using System.IO; using UnityEditor.Perception.GroundTruth; using UnityEngine; using UnityEngine.Perception.GroundTruth; using UnityEngine.Perception.GroundTruth.Consumers; +using UnityEngine.Perception.GroundTruth.DataModel; namespace UnityEngine.Perception.Settings { [Serializable] public class PerceptionSettings : MonoBehaviour { - static string gameObjectName = "_PerceptionSettings"; - + static string s_GameObjectName = "_PerceptionSettings"; static PerceptionSettings s_Instance; + static bool s_HideInHierarchy = true; +#if !UNITY_EDITOR + (bool, string) GetPathFromCommandLine() + { + (bool, string) errorResult = (false, string.Empty); + + var args = Environment.GetCommandLineArgs(); + var index = Array.FindIndex(args, x => x.Equals("--output-path")); + + if (index == -1) + { + Debug.Log($"--output-path was not provided on command line, using default location: {defaultOutputPath}"); + return errorResult; + } + + if (index == args.Length - 1) + { + var msg = $"--output-path was present on command line, but path was not defined, using default location: {defaultOutputPath}"; + Debug.LogError(msg); + return errorResult; + } + + var path = args[index + 1]; + if (Directory.Exists(path)) + { + return (true, path); + } + + try + { + Directory.CreateDirectory(path); + } + catch (Exception e) + { + var msg = $"An invalid path ({path}) was requested with --output-path, using default location: {defaultOutputPath}"; + Debug.LogError(msg + e); + return errorResult; + } + + return (true, path); + } + + public string GetOutputBasePath() + { +#if UNITY_SIMULATION_CORE_PRESENT + if (Unity.Simulation.Configuration.Instance.IsSimulationRunningInCloud()) + return defaultOutputPath; +#endif + var (isOk, path) = GetPathFromCommandLine(); + + return isOk ? path : defaultOutputPath; + } +#else + public string GetOutputBasePath() + { +#if UNITY_SIMULATION_CORE_PRESENT + if (Unity.Simulation.Configuration.Instance.IsSimulationRunningInCloud()) + return defaultOutputPath; +#endif + return userPreferences.TryGetValue($"{endpoint.GetType().FullName}.output_path", out string path) ? path : defaultOutputPath; + } +#endif + + /// + /// Sets the output path for the active endpoint type. This will set the path for the next simulation, it will + /// not affect a simulation that is currently executing. In order for this to take effect the caller should call + /// + /// + /// The output path + public void SetOutputBasePath(string path) + { + userPreferences.Add($"{endpoint.GetType().FullName}.output_path", path); +#if UNITY_EDITOR + Save(); +#endif + } + + public string defaultOutputPath + { + get + { + var persistentDataPath = Application.persistentDataPath; +#if UNITY_SIMULATION_CORE_PRESENT + if (Unity.Simulation.Configuration.Instance.IsSimulationRunningInCloud()) + persistentDataPath = Unity.Simulation.Configuration.Instance.GetStoragePath(); +#endif + return persistentDataPath; + } + } + + internal Metadata userPreferences { get; private set; } + + string m_CachedPathValue = string.Empty; + + string filePath + { + get + { + if (string.IsNullOrEmpty(m_CachedPathValue)) + { + m_CachedPathValue = Path.Combine(Application.dataPath, "..", "UserSettings", "PerceptionSettings.json"); + } + + return m_CachedPathValue; + + } + } + + void Initialize() + { + if (File.Exists(filePath)) + { + try + { + var fileStr = File.ReadAllText(filePath); + s_Instance.userPreferences = Metadata.FromJson(fileStr); + } + catch (Exception e) + { + Debug.Log($"Failed to load data file {e.Message}"); + s_Instance.userPreferences = new Metadata(); + } + } + else + { + s_Instance.userPreferences = new Metadata(); + } + } + public static PerceptionSettings instance { get { if (s_Instance == null) { - var obj = GameObject.Find(gameObjectName); + var obj = GameObject.Find(s_GameObjectName); if (obj == null) { - obj = new GameObject(gameObjectName); + obj = new GameObject(s_GameObjectName); } s_Instance = obj.GetComponent(); @@ -33,13 +163,23 @@ public static PerceptionSettings instance s_Instance = obj.AddComponent(); } - obj.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector; + s_Instance.Initialize(); } + s_Instance.gameObject.hideFlags = s_HideInHierarchy ? HideFlags.HideInHierarchy | HideFlags.HideInInspector : HideFlags.None; + return s_Instance; } } +#if UNITY_EDITOR + public void Save() + { + var json = userPreferences.ToJson(); + File.WriteAllText(filePath, json); + } +#endif + #if UNITY_EDITOR public static SerializedObject GetSerializedSettings() { diff --git a/com.unity.perception/Tests/Editor/PerceptionCameraEditorTests.cs b/com.unity.perception/Tests/Editor/PerceptionCameraEditorTests.cs index afd9d2d4d..34b2df69c 100644 --- a/com.unity.perception/Tests/Editor/PerceptionCameraEditorTests.cs +++ b/com.unity.perception/Tests/Editor/PerceptionCameraEditorTests.cs @@ -4,7 +4,9 @@ using System.Threading.Tasks; using NUnit.Framework; using UnityEditor; -// using UnityEditor.Perception.Visualizer; +#if !UNITY_EDITOR_LINUX +using UnityEditor.Perception.Visualizer; +#endif using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.Perception.GroundTruth; @@ -71,53 +73,52 @@ public IEnumerator EditorPause_DoesNotLogErrors() yield return new ExitPlayMode(); } - /** - [Test, Ignore("Some bug to fix in the test itself")] - public void VisualizerInstalledSuccessfully() + +#if !UNITY_EDITOR_LINUX + //[Test] + //[Category("Python")] + public void VisualizerInstallationTest() { var cameraObject = SetupCamera(null); - var perceptionCamera = cameraObject.GetComponent(); - InstallVisualizerAsync(); - // check if visualizer is installed to the correct path + cameraObject.GetComponent(); #if UNITY_EDITOR_WIN var packagesPath = Path.GetFullPath(Application.dataPath.Replace("/Assets", "/Library/PythonInstall/Scripts")); + packagesPath = packagesPath.Replace("/", "\\"); #elif UNITY_EDITOR_OSX var packagesPath = Path.GetFullPath(Application.dataPath.Replace("/Assets","/Library/PythonInstall/bin")); #endif - -#if UNITY_EDITOR_WIN - packagesPath = packagesPath.Replace("/", "\\"); -#endif - string path = Path.Combine(packagesPath, "datasetvisualizer.exe"); - Assert.IsTrue(File.Exists(path)); + // Install the Visualizer and check if it exists + InstallOrUninstallVisualizerAsync(packagesPath, installFlag:true); + string[] files = Directory.GetFiles(packagesPath, "datasetvisualizer.*"); + Assert.IsTrue(files.Length > 0); + // Uninstall the visualizer after check + InstallOrUninstallVisualizerAsync(packagesPath, installFlag:false); } - - static void InstallVisualizerAsync() + + static void InstallOrUninstallVisualizerAsync(string packagesPath, bool installFlag) { - // check if visualizer is installed to the correct path -#if UNITY_EDITOR_WIN - var packagesPath = Path.GetFullPath(Application.dataPath.Replace("/Assets", "/Library/PythonInstall/Scripts")); -#elif UNITY_EDITOR_OSX - var packagesPath = Path.GetFullPath(Application.dataPath.Replace("/Assets","/Library/PythonInstall/bin")); -#endif - -#if UNITY_EDITOR_WIN - packagesPath = packagesPath.Replace("/", "\\"); -#endif - //==============================INSTALL VISUALIZER IN PYTHON FOR UNITY====================================== const int steps = 3; var exitCode = 0; - EditorUtility.DisplayProgressBar("Setting up the Visualizer", "Installing Visualizer (This may take a few minutes)", 2f / steps); - Task.WaitAll(VisualizerInstaller.InstallationCommand(ref exitCode, packagesPath)); + // If install flag is true, install the visualizer + if (installFlag) + { + EditorUtility.DisplayProgressBar("Setting up the Visualizer", "Installing Visualizer (This may take a few minutes)", 2f / steps); + Task.WaitAll(VisualizerInstaller.InstallationCommand(ref exitCode, packagesPath, true)); + } + // if install flag is false, uninstall the visualizer + else + { + EditorUtility.DisplayProgressBar("Uninstall the Visualizer", "Uninstalling Visualizer (This may take a few minutes)", 2f / steps); + Task.WaitAll(VisualizerInstaller.UninstallCommand(ref exitCode, packagesPath)); + } if (exitCode != 0) { EditorUtility.ClearProgressBar(); return; } EditorUtility.ClearProgressBar(); - Debug.Log("Successfully installed visualizer tool!"); } - **/ +#endif #if MOQ_PRESENT [UnityTest] diff --git a/com.unity.perception/Tests/Runtime/GroundTruthTests/DatasetCaptureTests.cs b/com.unity.perception/Tests/Runtime/GroundTruthTests/DatasetCaptureTests.cs index c845c77af..3cc8d9621 100644 --- a/com.unity.perception/Tests/Runtime/GroundTruthTests/DatasetCaptureTests.cs +++ b/com.unity.perception/Tests/Runtime/GroundTruthTests/DatasetCaptureTests.cs @@ -1,13 +1,16 @@ using System; using System.Collections; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text.RegularExpressions; using NUnit.Framework; using Unity.Mathematics; using UnityEngine; using UnityEngine.Perception.GroundTruth; +using UnityEngine.Perception.GroundTruth.Consumers; using UnityEngine.Perception.GroundTruth.DataModel; +using UnityEngine.Perception.Settings; using UnityEngine.TestTools; // ReSharper disable InconsistentNaming // ReSharper disable NotAccessedField.Local @@ -68,18 +71,7 @@ public static void AreEqual(RgbSensor first, RgbSensor second) [TestFixture] public class DatasetCaptureTests { - static (RgbSensorDefinition, SensorHandle) RegisterSensor(string id, string modality, string sensorDescription, int firstCaptureFrame, CaptureTriggerMode captureTriggerMode, float simDeltaTime, int framesBetween, bool affectTiming = false) - { - var sensorDefinition = new RgbSensorDefinition(id, modality, sensorDescription) - { - firstCaptureFrame = firstCaptureFrame, - captureTriggerMode = captureTriggerMode, - simulationDeltaTime = simDeltaTime, - framesBetweenCaptures = framesBetween, - manualSensorsAffectTiming = affectTiming - }; - return (sensorDefinition, DatasetCapture.RegisterSensor(sensorDefinition)); - } + [UnityTest] public IEnumerator RegisterSensor_ReportsProperJson() @@ -97,7 +89,7 @@ public IEnumerator RegisterSensor_ReportsProperJson() // Need to reset simulation so that the override endpoint is used DatasetCapture.ResetSimulation(); - var (sensorDef, sensorHandle) = RegisterSensor(id, modality, def, firstFrame, mode, delta, framesBetween); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor(id, modality, def, firstFrame, mode, delta, framesBetween); Assert.IsTrue(sensorHandle.IsValid); yield return null; @@ -144,7 +136,7 @@ public void ResetSimulation_WithUnreportedCaptureAsync_LogsError() // Need to reset simulation so that the override endpoint is used DatasetCapture.ResetSimulation(); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); var f = sensorHandle.ReportSensorAsync(); DatasetCapture.ResetSimulation(); @@ -160,7 +152,7 @@ public IEnumerator ReportCaptureAsync_DoesNotError() // Need to reset simulation so that the override endpoint is used DatasetCapture.ResetSimulation(); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); var f = sensorHandle.ReportSensorAsync(); yield return null; @@ -180,7 +172,7 @@ public IEnumerator ReportCapture_ReportsProperJson() // Need to reset simulation so that the override endpoint is used DatasetCapture.ResetSimulation(); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "camera", "", 0, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "camera", "", 0, CaptureTriggerMode.Scheduled, 1, 0); var sensor = CreateMocRgbCapture(sensorDef); sensorHandle.ReportSensor(sensor); @@ -217,7 +209,7 @@ public IEnumerator StartNewSequence_ProperlyIncrementsSequence() //DatasetCapture.StartNewSequence(); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 2, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 2, 0); var sensor = new RgbSensor(sensorDef, Vector3.zero, Quaternion.identity); Assert.IsTrue(sensorHandle.ShouldCaptureThisFrame); @@ -262,7 +254,7 @@ public IEnumerator ReportAnnotation_AddsProperJsonToCapture() // Need to reset simulation so that the override endpoint is used DatasetCapture.ResetSimulation(); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); var sensor = new RgbSensor(sensorDef, Vector3.zero, Quaternion.identity); sensorHandle.ReportSensor(sensor); @@ -333,7 +325,7 @@ public IEnumerator ReportAnnotationValues_ReportsProperJson() // Need to reset simulation so that the override endpoint is used DatasetCapture.ResetSimulation(); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); var sensor = new RgbSensor(sensorDef, Vector3.zero, Quaternion.identity); sensorHandle.ReportSensor(sensor); @@ -375,7 +367,7 @@ public void ReportAnnotationFile_WhenCaptureNotExpected_Throws() { var def = new TestDef(); DatasetCapture.RegisterAnnotationDefinition(def); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 100, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 100, CaptureTriggerMode.Scheduled, 1, 0); Assert.Throws(() => sensorHandle.ReportAnnotation(def, null)); DatasetCapture.ResetSimulation(); @@ -394,7 +386,7 @@ public void ReportAnnotationValues_WhenCaptureNotExpected_Throws() new TestAnnotation.Entry { a = "a second string", b = 20 } } }; - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 100, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 100, CaptureTriggerMode.Scheduled, 1, 0); Assert.Throws(() => sensorHandle.ReportAnnotation(def, ann)); DatasetCapture.ResetSimulation(); } @@ -412,7 +404,7 @@ public void ReportAnnotationAsync_WhenCaptureNotExpected_Throws() new TestAnnotation.Entry { a = "a second string", b = 20 } } }; - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 100, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 100, CaptureTriggerMode.Scheduled, 1, 0); Assert.Throws(() => sensorHandle.ReportAnnotationAsync(def)); } @@ -431,7 +423,7 @@ public void ResetSimulation_WithUnreportedAnnotationAsync_LogsError() { var def = new TestDef(); DatasetCapture.RegisterAnnotationDefinition(def); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); var asyncAnnotation = sensorHandle.ReportAnnotationAsync(def); Assert.IsTrue(asyncAnnotation.IsValid()); @@ -444,7 +436,7 @@ public void ResetSimulation_WithUnreportedMetricAsync_LogsError() { var def = new TestMetricDef(); DatasetCapture.RegisterMetric(def); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); sensorHandle.ReportMetricAsync(def); DatasetCapture.ResetSimulation(); LogAssert.Expect(LogType.Error, new Regex("Simulation ended with pending .*")); @@ -462,7 +454,7 @@ public void AnnotationAsyncIsValid_ReturnsProperValue() var def = new TestDef(); DatasetCapture.RegisterAnnotationDefinition(def); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); var asyncAnnotation = sensorHandle.ReportAnnotationAsync(def); Assert.IsTrue(asyncAnnotation.IsValid()); @@ -478,7 +470,7 @@ public IEnumerator AnnotationAsyncReportValue_ReportsProperJson() // Need to reset simulation so that the override endpoint is used DatasetCapture.ResetSimulation(); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); var sensor = new RgbSensor(sensorDef, Vector3.zero, Quaternion.identity); sensorHandle.ReportSensor(sensor); @@ -530,7 +522,7 @@ public IEnumerator AnnotationAsyncReportResult_FindsCorrectPendingCaptureAfterSt var def = new TestDef(); DatasetCapture.RegisterAnnotationDefinition(def); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); // Record one capture for this frame var sensor = new RgbSensor(sensorDef, Vector3.zero, Quaternion.identity); @@ -621,7 +613,7 @@ public void ReportMetricValues_WhenCaptureNotExpected_Throws() { var def = new TestMetricDef(); DatasetCapture.RegisterMetric(def); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 100, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 100, CaptureTriggerMode.Scheduled, 1, 0); var metric = new GenericMetric(1, def); Assert.Throws(() => sensorHandle.ReportMetric(def, metric)); } @@ -631,7 +623,7 @@ public void ReportMetricAsync_WhenCaptureNotExpected_Throws() { var def = new TestMetricDef(); DatasetCapture.RegisterMetric(def); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 100, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 100, CaptureTriggerMode.Scheduled, 1, 0); Assert.Throws(() => sensorHandle.ReportMetricAsync(def)); } @@ -647,7 +639,7 @@ public void MetricAsyncIsValid_ReturnsProperValue() var def = new TestMetricDef(); DatasetCapture.RegisterMetric(def); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); var asyncMetric = sensorHandle.ReportMetricAsync(def); Assert.IsTrue(asyncMetric.IsValid()); @@ -677,7 +669,7 @@ public IEnumerator MetricReportValues_WithNoReportsInFrames_DoesNotIncrementStep var boolArrayDef = new MetricDefinition("bool_array_def", "bool_array_def"); var vec3Def = new MetricDefinition("vec3_def", "vec3_def"); - var sensorHandle = RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); + var sensorHandle = TestHelper.RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); yield return null; yield return null; @@ -750,7 +742,7 @@ public IEnumerator SensorHandleReportMetric_BeforeReportCapture_ReportsProperJso var def = new TestMetricDef(); DatasetCapture.RegisterMetric(def); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); @@ -761,7 +753,7 @@ public IEnumerator SensorHandleReportMetric_BeforeReportCapture_ReportsProperJso // var expectedLine = @"""step"": 0"; // var metricDefinition = DatasetCapture.RegisterMetricDefinition(""); - // var sensor = RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); + // var sensor = TestHelper.RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); yield return null; var metric = new GenericMetric(1, def); @@ -818,7 +810,7 @@ public IEnumerator MetricAsyncReportValues_ReportsProperJson( var metric = new GenericMetric(values, metDef); DatasetCapture.RegisterMetric(metDef); - var (sensorDef, sensorHandle) = RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor("camera", "", "", 0, CaptureTriggerMode.Scheduled, 1, 0); var annDef = new TestDef(); DatasetCapture.RegisterAnnotationDefinition(annDef); @@ -1067,5 +1059,61 @@ public void CreateAnnotationOrMetric_WithSpecValues_WritesProperTypes( Assert.AreEqual(6, a.specValues[1].pixel_value[2]); } } + +#if UNITY_EDITOR + // Perception only supports setting the output directory from the command line in non editor based simulations + [UnityTest] + public IEnumerator TestSetOutputDirectory() + { + + + const string id = "camera"; + const string modality = "camera"; + const string def = "Cam (FL2-14S3M-C)"; + const int firstFrame = 1; + const CaptureTriggerMode mode = CaptureTriggerMode.Scheduled; + const int delta = 1; + const int framesBetween = 0; + + // Clear dataset override from previous tests + DatasetCapture.OverrideEndpoint(null); + + PerceptionSettings.instance.endpoint = new PerceptionEndpoint(); + + var savePath = PerceptionSettings.instance.GetOutputBasePath(); + + var outputPath = Path.Combine(PerceptionSettings.instance.defaultOutputPath, $"test_{Guid.NewGuid()}"); + Directory.CreateDirectory(outputPath); + DatasetCapture.SetOutputPath(outputPath); + + DatasetCapture.ResetSimulation(); + + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor(id, modality, def, firstFrame, mode, delta, framesBetween); + Assert.IsTrue(sensorHandle.IsValid); + + yield return null; + + // grab a handle for the endpoint of the current run + var endpoint = (PerceptionEndpoint)DatasetCapture.activateEndpoint; + + DatasetCapture.ResetSimulation(); + Assert.IsFalse(sensorHandle.IsValid); + + var path = endpoint.datasetPath; + + // Verify that the output directory exists and a captures and a metrics file is written to it + Assert.IsTrue(path.Contains(outputPath)); + DirectoryAssert.Exists(path); + FileAssert.Exists(Path.Combine(path, "captures_000.json")); + FileAssert.Exists(Path.Combine(path, "metrics_000.json")); + + Directory.Delete(outputPath, true); + + DirectoryAssert.DoesNotExist(outputPath); + + DatasetCapture.SetOutputPath(savePath); + + } +#endif } } diff --git a/com.unity.perception/Tests/Runtime/GroundTruthTests/GroundTruthTestBase.cs b/com.unity.perception/Tests/Runtime/GroundTruthTests/GroundTruthTestBase.cs index 0032c8366..1d2e09945 100644 --- a/com.unity.perception/Tests/Runtime/GroundTruthTests/GroundTruthTestBase.cs +++ b/com.unity.perception/Tests/Runtime/GroundTruthTests/GroundTruthTestBase.cs @@ -5,8 +5,12 @@ using UnityEngine; using UnityEngine.Perception.GroundTruth; using UnityEngine.Perception.GroundTruth.Consumers; +using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.TestTools; +#if HDRP_PRESENT +using UnityEngine.Rendering.HighDefinition; +#endif using Object = UnityEngine.Object; namespace GroundTruthTests @@ -61,6 +65,17 @@ public GameObject SetupCamera(Action initPerceptionCamera, boo camera.orthographic = true; camera.orthographicSize = 1; +#if HDRP_PRESENT + //disable postprocessing on HDRP to ensure unlit objects have precise RGB colors + var hdAdditionalCameraData = cameraObject.AddComponent(); + hdAdditionalCameraData.customRenderingSettings = true; + + hdAdditionalCameraData.renderingPathCustomFrameSettingsOverrideMask + .mask[(uint)FrameSettingsField.Postprocess] = true; + + hdAdditionalCameraData.renderingPathCustomFrameSettings.SetEnabled(FrameSettingsField.Postprocess, false); +#endif + var perceptionCamera = cameraObject.AddComponent(); perceptionCamera.captureRgbImages = false; initPerceptionCamera?.Invoke(perceptionCamera); diff --git a/com.unity.perception/Tests/Runtime/GroundTruthTests/KeypointGroundTruthTests.cs b/com.unity.perception/Tests/Runtime/GroundTruthTests/KeypointGroundTruthTests.cs index 60444329a..fb2babead 100644 --- a/com.unity.perception/Tests/Runtime/GroundTruthTests/KeypointGroundTruthTests.cs +++ b/com.unity.perception/Tests/Runtime/GroundTruthTests/KeypointGroundTruthTests.cs @@ -15,6 +15,7 @@ public class KeyPointGroundTruthTests : GroundTruthTestBase, IPrebuildSetup, IPo { private const string kAnimatedCubeScenePath = "Packages/com.unity.perception/Tests/Runtime/TestAssets/AnimatedCubeScene.unity"; private const string kCubeScenePath = "Packages/com.unity.perception/Tests/Runtime/TestAssets/CubeScene.unity"; + private const string kUnlitObjectPath = "Packages/com.unity.perception/Tests/Runtime/TestAssets/UnlitObject.unity"; private const double k_Delta = .01; public void Setup() @@ -23,6 +24,7 @@ public void Setup() var scenes = UnityEditor.EditorBuildSettings.scenes.ToList(); scenes.Add(new UnityEditor.EditorBuildSettingsScene(kAnimatedCubeScenePath, true)); scenes.Add(new UnityEditor.EditorBuildSettingsScene(kCubeScenePath, true)); + scenes.Add(new UnityEditor.EditorBuildSettingsScene(kUnlitObjectPath, true)); UnityEditor.EditorBuildSettings.scenes = scenes.ToArray(); #endif } @@ -31,7 +33,7 @@ public void Cleanup() { #if UNITY_EDITOR var scenes = UnityEditor.EditorBuildSettings.scenes; - scenes = scenes.Where(s => s.path != kAnimatedCubeScenePath && s.path != kCubeScenePath).ToArray(); + scenes = scenes.Where(s => s.path != kAnimatedCubeScenePath && s.path != kCubeScenePath && s.path != kUnlitObjectPath).ToArray(); UnityEditor.EditorBuildSettings.scenes = scenes; #endif } diff --git a/com.unity.perception/Tests/Runtime/GroundTruthTests/MetadataTests.cs b/com.unity.perception/Tests/Runtime/GroundTruthTests/MetadataTests.cs index a769588d3..d8e52cf88 100644 --- a/com.unity.perception/Tests/Runtime/GroundTruthTests/MetadataTests.cs +++ b/com.unity.perception/Tests/Runtime/GroundTruthTests/MetadataTests.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using NUnit.Framework; +using UnityEngine; using UnityEngine.Perception.GroundTruth.DataModel; namespace GroundTruthTests @@ -164,6 +165,58 @@ public void TestTryGetMiss_NoKey() Assert.AreEqual(val, outVal); } + [Test] + public void TestReadWriteJson() + { + var m = new Metadata(); + m.Add("int_value", 7); + m.Add("uint_value", uint.MaxValue); + m.Add("float_value", 4.2f); + m.Add("string_value", "hello_world"); + m.Add("bool_value", false); + m.Add("int[]_valle", new [] {0, 1, 2, 3}); + m.Add("float[]_value", new [] {1.1f, 2.2f, 3,3f, 4.4f, 5.5f}); + m.Add("string[]_value", new [] {"this", "is", "an", "array"}); + m.Add("bool[]_value", new [] {false, true, true, false}); + + var nested = new Metadata(); + nested.Add("int_value", 42); + nested.Add("string_array", new [] {"life","universe", "everything"}); + + m.Add("nested", nested); + + var nested2 = new Metadata(); + nested2.Add("int_value", 43); + nested2.Add("int_value2", 44); + + var nestedArray = new[] { nested, nested2 }; + m.Add("nested_array", nestedArray); + + var json = m.ToJson(); + + var m2 = Metadata.FromJson(json); + + Assert.AreEqual(7, m2.GetInt("int_value")); + Assert.AreEqual(uint.MaxValue, m2.GetUInt("uint_value")); + Assert.AreEqual(4.2f, m2.GetFloat("float_value")); + Assert.AreEqual("hello_world", m2.GetString("string_value")); + Assert.AreEqual(false, m2.GetBool("bool_value")); + Assert.AreEqual(new [] {0,1,2,3}, m2.GetIntArray("int[]_valle")); + Assert.AreEqual(new [] {1.1f, 2.2f, 3,3f, 4.4f, 5.5f}, m2.GetFloatArray("float[]_value")); + Assert.AreEqual(new [] {"this", "is", "an", "array"}, m2.GetStringArray("string[]_value")); + Assert.AreEqual(new [] {false, true, true, false}, m2.GetBoolArray("bool[]_value")); + var n = m2.GetSubMetadata("nested"); + Assert.AreEqual(42, n.GetInt("int_value")); + Assert.AreEqual(new [] {"life", "universe", "everything"}, n.GetStringArray("string_array")); + var n2 = m2.GetSubMetadataArray("nested_array"); + Assert.AreEqual(2, n2.Length); + Assert.AreEqual(42, n2[0].GetInt("int_value")); + Assert.AreEqual(new [] {"life", "universe", "everything"}, n2[0].GetStringArray("string_array")); + Assert.AreEqual(43, n2[1].GetInt("int_value")); + Assert.AreEqual(44, n2[1].GetInt("int_value2")); + } + + [Test] public void TestTryGetMiss_WrongType() { var metadata = new SimulationMetadata(); diff --git a/com.unity.perception/Tests/Runtime/GroundTruthTests/PerceptionFormatTest.cs b/com.unity.perception/Tests/Runtime/GroundTruthTests/PerceptionFormatTest.cs index 873f40066..e21892689 100644 --- a/com.unity.perception/Tests/Runtime/GroundTruthTests/PerceptionFormatTest.cs +++ b/com.unity.perception/Tests/Runtime/GroundTruthTests/PerceptionFormatTest.cs @@ -33,6 +33,7 @@ public void Cleanup() if (Directory.Exists(m_Endpoint.currentPath)) Directory.Delete(m_Endpoint.currentPath, true); + DatasetCapture.OverrideEndpoint(null); } static (RgbSensorDefinition, SensorHandle) RegisterSensor(string id, string modality, string sensorDescription, int firstCaptureFrame, CaptureTriggerMode captureTriggerMode, float simDeltaTime, int framesBetween, bool affectTiming = false) diff --git a/com.unity.perception/Tests/Runtime/GroundTruthTests/PerceptionSettingsTests.cs b/com.unity.perception/Tests/Runtime/GroundTruthTests/PerceptionSettingsTests.cs new file mode 100644 index 000000000..a251637f7 --- /dev/null +++ b/com.unity.perception/Tests/Runtime/GroundTruthTests/PerceptionSettingsTests.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections; +using System.IO; +using System.Linq; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.Perception.GroundTruth; +using UnityEngine.Perception.GroundTruth.Consumers; +using UnityEngine.Perception.GroundTruth.DataModel; +using UnityEngine.Perception.Settings; +using UnityEngine.TestTools; + +namespace GroundTruthTests +{ + [TestFixture] + public class PerceptionSettingsTests + { + [UnityTest] + public IEnumerator TestSetEndpoint_CollectEndpoint() + { + const string id = "camera"; + const string modality = "camera"; + const string def = "Cam (FL2-14S3M-C)"; + const int firstFrame = 1; + const CaptureTriggerMode mode = CaptureTriggerMode.Scheduled; + const int delta = 1; + const int framesBetween = 0; + + PerceptionSettings.instance.endpoint = new CollectEndpoint(); + DatasetCapture.ResetSimulation(); + + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor(id, modality, def, firstFrame, mode, delta, framesBetween); + Assert.IsTrue(sensorHandle.IsValid); + + yield return null; + + // grab a handle for the endpoint of the current run + var collector = (CollectEndpoint)DatasetCapture.activateEndpoint; + + DatasetCapture.ResetSimulation(); + Assert.IsFalse(sensorHandle.IsValid); + + // Check metadata + var meta = collector.currentRun.metadata as SimulationMetadata; + Assert.NotNull(meta); + Assert.AreEqual(meta.perceptionVersion, DatasetCapture.perceptionVersion); + Assert.AreEqual(meta.unityVersion, Application.unityVersion); + + // Check sensor data + Assert.AreEqual(collector.sensors.Count, 1); + var sensor = collector.sensors.First(); + Assert.NotNull(sensor); + Assert.AreEqual(sensor.id, id); + Assert.AreEqual(sensor.modality, modality); + Assert.AreEqual(sensor.description, def); + Assert.AreEqual(sensor.firstCaptureFrame, firstFrame); + Assert.AreEqual(sensor.captureTriggerMode, mode); + Assert.AreEqual(sensor.simulationDeltaTime, delta); + Assert.AreEqual(sensor.framesBetweenCaptures, framesBetween); + } +#if UNITY_EDITOR + // Perception only supports setting the output directory from the command line in non editor based simulations + [UnityTest] + public IEnumerator TestSetOutputDirectory() + { + const string id = "camera"; + const string modality = "camera"; + const string def = "Cam (FL2-14S3M-C)"; + const int firstFrame = 1; + const CaptureTriggerMode mode = CaptureTriggerMode.Scheduled; + const int delta = 1; + const int framesBetween = 0; + + PerceptionSettings.instance.endpoint = new PerceptionEndpoint(); + + var savePath = PerceptionSettings.instance.GetOutputBasePath(); + + var outputPath = Path.Combine(PerceptionSettings.instance.defaultOutputPath, $"test_{Guid.NewGuid()}"); + Directory.CreateDirectory(outputPath); + PerceptionSettings.instance.SetOutputBasePath(outputPath); + + DatasetCapture.ResetSimulation(); + + var (sensorDef, sensorHandle) = TestHelper.RegisterSensor(id, modality, def, firstFrame, mode, delta, framesBetween); + Assert.IsTrue(sensorHandle.IsValid); + + yield return null; + + // grab a handle for the endpoint of the current run + var endpoint = (PerceptionEndpoint)DatasetCapture.activateEndpoint; + + DatasetCapture.ResetSimulation(); + Assert.IsFalse(sensorHandle.IsValid); + + var path = endpoint.datasetPath; + + // Verify that the output directory exists and a captures and a metrics file is written to it + Assert.IsTrue(path.Contains(outputPath)); + DirectoryAssert.Exists(path); + FileAssert.Exists(Path.Combine(path, "captures_000.json")); + FileAssert.Exists(Path.Combine(path, "metrics_000.json")); + + Directory.Delete(outputPath, true); + + DirectoryAssert.DoesNotExist(outputPath); + + PerceptionSettings.instance.SetOutputBasePath(savePath); + } +#endif + } +} + diff --git a/com.unity.perception/Tests/Runtime/GroundTruthTests/PerceptionSettingsTests.cs.meta b/com.unity.perception/Tests/Runtime/GroundTruthTests/PerceptionSettingsTests.cs.meta new file mode 100644 index 000000000..b3861d065 --- /dev/null +++ b/com.unity.perception/Tests/Runtime/GroundTruthTests/PerceptionSettingsTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c7ef2588a7db7dd48b43a426119e59e2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.perception/Tests/Runtime/GroundTruthTests/RgbOutputTests.cs b/com.unity.perception/Tests/Runtime/GroundTruthTests/RgbOutputTests.cs index 351a45b05..6bdfdf819 100644 --- a/com.unity.perception/Tests/Runtime/GroundTruthTests/RgbOutputTests.cs +++ b/com.unity.perception/Tests/Runtime/GroundTruthTests/RgbOutputTests.cs @@ -3,6 +3,7 @@ using NUnit.Framework; using Unity.Collections; using UnityEngine; +using UnityEngine.Experimental.Rendering; using UnityEngine.Perception.GroundTruth; using UnityEngine.Perception.GroundTruth.DataModel; using UnityEngine.Rendering; @@ -143,11 +144,10 @@ MsaaQuality msaa } #endif -#if HDRP_PRESENT - public class HdrpRgbOutputTests : RgbOutputTestBase + public class GenericRgbOutputTests : RgbOutputTestBase { [UnityTearDown] - public IEnumerator HdrpTeardown() + public IEnumerator GenericRgbOutputTeardown() { base.TearDown(); @@ -160,13 +160,18 @@ public IEnumerator HdrpTeardown() #region Blank Image Test [UnityTest] - public IEnumerator RgbOutput_DefaultProjectSettings_IsNotEmpty() + public IEnumerator RgbOutput_DefaultProjectSettings_IsNotEmpty([Values(false, true)] bool useCameraTargetTexture) { // Setup the camera and scene var camera = SetupCamera(cam => { cam.captureRgbImages = true; cam.captureTriggerMode = CaptureTriggerMode.Manual; + if (useCameraTargetTexture) + { + cam.GetComponent().targetTexture = + new RenderTexture(100, 100, 16); + } perceptionCamera = cam; }); AddTestObjectForCleanup(camera); @@ -183,6 +188,88 @@ public IEnumerator RgbOutput_DefaultProjectSettings_IsNotEmpty() ); } #endregion - } + + [UnityTest] + public IEnumerator RgbOutput_VerticalOrientationCorrect([Values(false, true)] bool useCameraTargetTexture) + { + // Setup the camera and scene + var camera = SetupCamera(pcam => + { + pcam.captureRgbImages = true; + pcam.captureTriggerMode = CaptureTriggerMode.Manual; + var camera = pcam.GetComponent(); + camera.orthographic = true; + camera.orthographicSize = 1f; + if (useCameraTargetTexture) + { + camera.GetComponent().targetTexture = + new RenderTexture(100, 100, 16); + } + perceptionCamera = pcam; + + }); + AddTestObjectForCleanup(camera); + //position camera to point straight at the top edge of plane1, such that plane1 takes up the bottom half of + //the image and plane2 takes up the top half + camera.transform.localPosition = Vector3.up * 10f; + + //the colors are chosen specifically such that they are not + var plane1 = TestHelper.CreateLabeledPlane(2f); + var colorBottom = new Color32(0, 0, 200, 255); + SetColor(plane1, colorBottom); + var plane2 = TestHelper.CreateLabeledPlane(2f); + var colorTop = new Color32(200, 0, 0, 255); + SetColor(plane2, colorTop); + plane2.transform.localPosition = plane2.transform.localPosition + Vector3.up * 20f; + AddTestObjectForCleanup(plane1); + AddTestObjectForCleanup(plane2); + + + + //TestHelper.LoadAndStartRenderDocCapture(); + try + { + Color32 bottomLeft = new Color32(); + Color32 topRight = new Color32(); + // Validate RGB output image by checking if its empty + yield return GenerateRgbOutputAndValidateData(imagePixels => + { + bottomLeft = imagePixels[0]; + topRight = imagePixels[imagePixels.Length - 1]; + } + ); + + //Accomodate for the rendering pipeline causing colors to change slightly during conversions + Assert.Greater(4, ColorDistance(colorBottom, bottomLeft), $"Expected {colorBottom}, got {bottomLeft}"); + Assert.Greater(4, ColorDistance(colorTop, topRight), $"Expected {colorTop}, got {topRight}"); + } + finally + { + //TestHelper.EndCaptureRenderDoc(); + } + } + + private int ColorDistance(Color32 color1, Color32 color2) + { + return Math.Abs(color1.a - color2.a) + + Math.Abs(color1.r - color2.r) + + Math.Abs(color1.g - color2.g) + + Math.Abs(color1.b - color2.b); + } + + private static void SetColor(GameObject gameObject, Color color) + { + var renderer = gameObject.GetComponent(); + string shaderName = null; +#if HDRP_PRESENT + shaderName = "HDRP/Unlit"; #endif +#if URP_PRESENT + shaderName = "Universal Render Pipeline/Unlit"; +#endif + var material = new Material(Shader.Find(shaderName)); + material.color = color; + renderer.sharedMaterial = material; + } + } } diff --git a/com.unity.perception/Tests/Runtime/GroundTruthTests/TestHelper.cs b/com.unity.perception/Tests/Runtime/GroundTruthTests/TestHelper.cs index 49b00b5c2..1dd4cdc2c 100644 --- a/com.unity.perception/Tests/Runtime/GroundTruthTests/TestHelper.cs +++ b/com.unity.perception/Tests/Runtime/GroundTruthTests/TestHelper.cs @@ -8,6 +8,7 @@ using UnityEngine; using UnityEngine.Experimental.Rendering; using UnityEngine.Perception.GroundTruth; +using UnityEngine.Perception.GroundTruth.DataModel; namespace GroundTruthTests { @@ -82,5 +83,18 @@ public static string NormalizeJson(string json, bool normalizeFormatting = false return json.Replace("\r\n", "\n"); } + + public static (RgbSensorDefinition, SensorHandle) RegisterSensor(string id, string modality, string sensorDescription, int firstCaptureFrame, CaptureTriggerMode captureTriggerMode, float simDeltaTime, int framesBetween, bool affectTiming = false) + { + var sensorDefinition = new RgbSensorDefinition(id, modality, sensorDescription) + { + firstCaptureFrame = firstCaptureFrame, + captureTriggerMode = captureTriggerMode, + simulationDeltaTime = simDeltaTime, + framesBetweenCaptures = framesBetween, + manualSensorsAffectTiming = affectTiming + }; + return (sensorDefinition, DatasetCapture.RegisterSensor(sensorDefinition)); + } } } diff --git a/com.unity.perception/Tests/Runtime/TestAssets/CubeSceneSettings.lighting b/com.unity.perception/Tests/Runtime/TestAssets/CubeSceneSettings.lighting index 5978c2069..32bc96a1d 100644 --- a/com.unity.perception/Tests/Runtime/TestAssets/CubeSceneSettings.lighting +++ b/com.unity.perception/Tests/Runtime/TestAssets/CubeSceneSettings.lighting @@ -8,7 +8,7 @@ LightingSettings: m_PrefabAsset: {fileID: 0} m_Name: CubeSceneSettings serializedVersion: 3 - m_GIWorkflowMode: 0 + m_GIWorkflowMode: 1 m_EnableBakedLightmaps: 0 m_EnableRealtimeLightmaps: 0 m_RealtimeEnvironmentLighting: 1 diff --git a/com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialHDRP.mat b/com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialHDRP.mat new file mode 100644 index 000000000..762e52ff2 --- /dev/null +++ b/com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialHDRP.mat @@ -0,0 +1,284 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-3043235147474254215 +MonoBehaviour: + m_ObjectHideFlags: 11 + 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: 11500000, guid: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 11 +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: UnlitMaterialHDRP + m_Shader: {fileID: 4800000, guid: c4edd00ff2db5b24391a4fcb1762e459, type: 3} + m_ShaderKeywords: _DISABLE_SSR_TRANSPARENT _NORMALMAP_TANGENT_SPACE + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: {} + disabledShaderPasses: + - DistortionVectors + - MOTIONVECTORS + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AnisotropyMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BentNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BentNormalMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _CoatMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DistortionVectorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissiveColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HeightMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _IridescenceMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _IridescenceThicknessMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecularColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SubsurfaceMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TangentMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ThicknessMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TransmittanceColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _UnlitColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _AORemapMax: 1 + - _AORemapMin: 0 + - _ATDistance: 1 + - _AddPrecomputedVelocity: 0 + - _AlbedoAffectEmissive: 0 + - _AlphaCutoff: 0.5 + - _AlphaCutoffEnable: 0 + - _AlphaCutoffPostpass: 0.5 + - _AlphaCutoffPrepass: 0.5 + - _AlphaCutoffShadow: 0.5 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _Anisotropy: 0 + - _BlendMode: 0 + - _CoatMask: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailAlbedoScale: 1 + - _DetailNormalScale: 1 + - _DetailSmoothnessScale: 1 + - _DiffusionProfile: 0 + - _DiffusionProfileHash: 0 + - _DisplacementLockObjectScale: 1 + - _DisplacementLockTilingScale: 1 + - _DisplacementMode: 0 + - _DistortionBlendMode: 0 + - _DistortionBlurBlendMode: 0 + - _DistortionBlurDstBlend: 1 + - _DistortionBlurRemapMax: 1 + - _DistortionBlurRemapMin: 0 + - _DistortionBlurScale: 1 + - _DistortionBlurSrcBlend: 1 + - _DistortionDepthTest: 1 + - _DistortionDstBlend: 1 + - _DistortionEnable: 0 + - _DistortionOnly: 0 + - _DistortionScale: 1 + - _DistortionSrcBlend: 1 + - _DistortionVectorBias: -1 + - _DistortionVectorScale: 2 + - _DoubleSidedEnable: 0 + - _DoubleSidedNormalMode: 1 + - _DstBlend: 0 + - _EmissiveColorMode: 1 + - _EmissiveExposureWeight: 1 + - _EmissiveIntensity: 1 + - _EmissiveIntensityUnit: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _EnableGeometricSpecularAA: 0 + - _EnergyConservingSpecularColor: 1 + - _HeightAmplitude: 0.02 + - _HeightCenter: 0.5 + - _HeightMapParametrization: 0 + - _HeightMax: 1 + - _HeightMin: -1 + - _HeightOffset: 0 + - _HeightPoMAmplitude: 2 + - _HeightTessAmplitude: 2 + - _HeightTessCenter: 0.5 + - _IncludeIndirectLighting: 1 + - _InvTilingScale: 1 + - _Ior: 1.5 + - _IridescenceMask: 1 + - _IridescenceThickness: 1 + - _LinkDetailsWithBase: 1 + - _MaterialID: 1 + - _Metallic: 0 + - _MetallicRemapMax: 1 + - _MetallicRemapMin: 0 + - _NormalMapSpace: 0 + - _NormalScale: 1 + - _OpaqueCullMode: 2 + - _PPDLodThreshold: 5 + - _PPDMaxSamples: 15 + - _PPDMinSamples: 5 + - _PPDPrimitiveLength: 1 + - _PPDPrimitiveWidth: 1 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _Smoothness: 0.5 + - _SmoothnessRemapMax: 1 + - _SmoothnessRemapMin: 0 + - _SpecularAAScreenSpaceVariance: 0.1 + - _SpecularAAThreshold: 0.2 + - _SpecularOcclusionMode: 1 + - _SrcBlend: 1 + - _StencilRef: 0 + - _StencilRefDepth: 0 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 32 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _SubsurfaceMask: 1 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TexWorldScale: 1 + - _TexWorldScaleEmissive: 1 + - _Thickness: 1 + - _TransmissionEnable: 1 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _UVBase: 0 + - _UVDetail: 0 + - _UVEmissive: 0 + - _UseEmissiveIntensity: 0 + - _UseShadowThreshold: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestModeDistortion: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _BaseColorMap_MipInfo: {r: 0, g: 0, b: 0, a: 0} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _DiffusionProfileAsset: {r: 0, g: 0, b: 0, a: 0} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _EmissiveColor: {r: 0, g: 0, b: 0, a: 1} + - _EmissiveColorLDR: {r: 0, g: 0, b: 0, a: 1} + - _InvPrimScale: {r: 1, g: 1, b: 0, a: 0} + - _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0} + - _SpecularColor: {r: 1, g: 1, b: 1, a: 1} + - _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0} + - _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1} + - _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0} + - _UVMappingMask: {r: 1, g: 0, b: 0, a: 0} + - _UVMappingMaskEmissive: {r: 1, g: 0, b: 0, a: 0} + - _UnlitColor: {r: 1, g: 1, b: 1, a: 1} + - _UnlitColorMap_MipInfo: {r: 0, g: 0, b: 0, a: 0} + m_BuildTextureStacks: [] diff --git a/com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialHDRP.mat.meta b/com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialHDRP.mat.meta new file mode 100644 index 000000000..f544a99a8 --- /dev/null +++ b/com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialHDRP.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 12585caa3f5d76c419d570652e893c2c +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialURP.mat b/com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialURP.mat new file mode 100644 index 000000000..2016ce2d1 --- /dev/null +++ b/com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialURP.mat @@ -0,0 +1,308 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-3043235147474254215 +MonoBehaviour: + m_ObjectHideFlags: 11 + 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: 11500000, guid: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 11 +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: UnlitMaterialURP + m_Shader: {fileID: 4800000, guid: 650dd9526735d5b46b79224bc6e94025, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: + RenderType: Opaque + disabledShaderPasses: + - DistortionVectors + - MOTIONVECTORS + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AnisotropyMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BentNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BentNormalMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _CoatMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DistortionVectorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissiveColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HeightMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _IridescenceMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _IridescenceThicknessMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecularColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SubsurfaceMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TangentMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ThicknessMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TransmittanceColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _UnlitColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _AORemapMax: 1 + - _AORemapMin: 0 + - _ATDistance: 1 + - _AddPrecomputedVelocity: 0 + - _AlbedoAffectEmissive: 0 + - _AlphaClip: 0 + - _AlphaCutoff: 0.5 + - _AlphaCutoffEnable: 0 + - _AlphaCutoffPostpass: 0.5 + - _AlphaCutoffPrepass: 0.5 + - _AlphaCutoffShadow: 0.5 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _Anisotropy: 0 + - _Blend: 0 + - _BlendMode: 0 + - _CoatMask: 0 + - _Cull: 2 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailAlbedoScale: 1 + - _DetailNormalScale: 1 + - _DetailSmoothnessScale: 1 + - _DiffusionProfile: 0 + - _DiffusionProfileHash: 0 + - _DisplacementLockObjectScale: 1 + - _DisplacementLockTilingScale: 1 + - _DisplacementMode: 0 + - _DistortionBlendMode: 0 + - _DistortionBlurBlendMode: 0 + - _DistortionBlurDstBlend: 1 + - _DistortionBlurRemapMax: 1 + - _DistortionBlurRemapMin: 0 + - _DistortionBlurScale: 1 + - _DistortionBlurSrcBlend: 1 + - _DistortionDepthTest: 1 + - _DistortionDstBlend: 1 + - _DistortionEnable: 0 + - _DistortionOnly: 0 + - _DistortionScale: 1 + - _DistortionSrcBlend: 1 + - _DistortionVectorBias: -1 + - _DistortionVectorScale: 2 + - _DoubleSidedEnable: 0 + - _DoubleSidedNormalMode: 1 + - _DstBlend: 0 + - _EmissiveColorMode: 1 + - _EmissiveExposureWeight: 1 + - _EmissiveIntensity: 1 + - _EmissiveIntensityUnit: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _EnableGeometricSpecularAA: 0 + - _EnergyConservingSpecularColor: 1 + - _HeightAmplitude: 0.02 + - _HeightCenter: 0.5 + - _HeightMapParametrization: 0 + - _HeightMax: 1 + - _HeightMin: -1 + - _HeightOffset: 0 + - _HeightPoMAmplitude: 2 + - _HeightTessAmplitude: 2 + - _HeightTessCenter: 0.5 + - _IncludeIndirectLighting: 1 + - _InvTilingScale: 1 + - _Ior: 1.5 + - _IridescenceMask: 1 + - _IridescenceThickness: 1 + - _LinkDetailsWithBase: 1 + - _MaterialID: 1 + - _Metallic: 0 + - _MetallicRemapMax: 1 + - _MetallicRemapMin: 0 + - _NormalMapSpace: 0 + - _NormalScale: 1 + - _OpaqueCullMode: 2 + - _PPDLodThreshold: 5 + - _PPDMaxSamples: 15 + - _PPDMinSamples: 5 + - _PPDPrimitiveLength: 1 + - _PPDPrimitiveWidth: 1 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _SampleGI: 0 + - _Smoothness: 0.5 + - _SmoothnessRemapMax: 1 + - _SmoothnessRemapMin: 0 + - _SpecularAAScreenSpaceVariance: 0.1 + - _SpecularAAThreshold: 0.2 + - _SpecularOcclusionMode: 1 + - _SrcBlend: 1 + - _StencilRef: 0 + - _StencilRefDepth: 0 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 32 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _SubsurfaceMask: 1 + - _SupportDecals: 1 + - _Surface: 0 + - _SurfaceType: 0 + - _TexWorldScale: 1 + - _TexWorldScaleEmissive: 1 + - _Thickness: 1 + - _TransmissionEnable: 1 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _UVBase: 0 + - _UVDetail: 0 + - _UVEmissive: 0 + - _UseEmissiveIntensity: 0 + - _UseShadowThreshold: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestModeDistortion: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _BaseColorMap_MipInfo: {r: 0, g: 0, b: 0, a: 0} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _DiffusionProfileAsset: {r: 0, g: 0, b: 0, a: 0} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _EmissiveColor: {r: 0, g: 0, b: 0, a: 1} + - _EmissiveColorLDR: {r: 0, g: 0, b: 0, a: 1} + - _InvPrimScale: {r: 1, g: 1, b: 0, a: 0} + - _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0} + - _SpecularColor: {r: 1, g: 1, b: 1, a: 1} + - _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0} + - _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1} + - _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0} + - _UVMappingMask: {r: 1, g: 0, b: 0, a: 0} + - _UVMappingMaskEmissive: {r: 1, g: 0, b: 0, a: 0} + - _UnlitColor: {r: 1, g: 1, b: 1, a: 1} + - _UnlitColorMap_MipInfo: {r: 0, g: 0, b: 0, a: 0} + m_BuildTextureStacks: [] +--- !u!114 &3179295668548055263 +MonoBehaviour: + m_ObjectHideFlags: 11 + 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: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 4 diff --git a/com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialURP.mat.meta b/com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialURP.mat.meta new file mode 100644 index 000000000..5f4c55c14 --- /dev/null +++ b/com.unity.perception/Tests/Runtime/TestAssets/UnlitMaterialURP.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2d4f0ad050d095b41b28f61f6c0dcb83 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.perception/Tests/Runtime/TestAssets/UnlitObject.unity b/com.unity.perception/Tests/Runtime/TestAssets/UnlitObject.unity new file mode 100644 index 000000000..aa39dd90b --- /dev/null +++ b/com.unity.perception/Tests/Runtime/TestAssets/UnlitObject.unity @@ -0,0 +1,318 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 4890085278179872738, guid: 280278c4790e89b428686b2f2d0b966a, + type: 2} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &653002062 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 653002066} + - component: {fileID: 653002065} + - component: {fileID: 653002064} + - component: {fileID: 653002063} + m_Layer: 0 + m_Name: QuadURP + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!64 &653002063 +MeshCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 653002062} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 4 + m_Convex: 0 + m_CookingOptions: 30 + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &653002064 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 653002062} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 257 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 2d4f0ad050d095b41b28f61f6c0dcb83, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &653002065 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 653002062} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &653002066 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 653002062} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -4.5, y: -0.08925885, z: 32.445724} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1712208939 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1712208943} + - component: {fileID: 1712208942} + - component: {fileID: 1712208941} + - component: {fileID: 1712208940} + m_Layer: 0 + m_Name: Quad + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!64 &1712208940 +MeshCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1712208939} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 4 + m_Convex: 0 + m_CookingOptions: 30 + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &1712208941 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1712208939} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 257 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 12585caa3f5d76c419d570652e893c2c, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1712208942 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1712208939} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &1712208943 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1712208939} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -1.9462699, y: -0.08925885, z: 32.445724} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/com.unity.perception/Tests/Runtime/TestAssets/UnlitObject.unity.meta b/com.unity.perception/Tests/Runtime/TestAssets/UnlitObject.unity.meta new file mode 100644 index 000000000..d3763aa6d --- /dev/null +++ b/com.unity.perception/Tests/Runtime/TestAssets/UnlitObject.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e4a2b411514b76d48af18fe256079246 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.perception/Tests/Runtime/Unity.Perception.Runtime.Tests.asmdef b/com.unity.perception/Tests/Runtime/Unity.Perception.Runtime.Tests.asmdef index 4fd7da24e..2412a5dd4 100644 --- a/com.unity.perception/Tests/Runtime/Unity.Perception.Runtime.Tests.asmdef +++ b/com.unity.perception/Tests/Runtime/Unity.Perception.Runtime.Tests.asmdef @@ -1,5 +1,6 @@ { "name": "Unity.Perception.Runtime.Tests", + "rootNamespace": "", "references": [ "UnityEngine.TestRunner", "Unity.Mathematics", @@ -8,7 +9,8 @@ "Unity.Perception.Runtime", "Unity.Perception.Editor", "Unity.RenderPipelines.HighDefinition.Runtime", - "Unity.RenderPipelines.Universal.Runtime" + "Unity.RenderPipelines.Universal.Runtime", + "Unity.RenderPipelines.Core.Runtime" ], "includePlatforms": [], "excludePlatforms": [], @@ -35,4 +37,4 @@ } ], "noEngineReferences": false -} +} \ No newline at end of file diff --git a/com.unity.perception/package.json b/com.unity.perception/package.json index 0b5f68fad..ae342693c 100644 --- a/com.unity.perception/package.json +++ b/com.unity.perception/package.json @@ -9,7 +9,7 @@ "displayName": "Perception", "name": "com.unity.perception", "unity": "2020.3", - "version": "0.10.0-preview.1", + "version": "0.11.1-preview.1", "samples": [ { "displayName": "Tutorial Files",