282 lines
11 KiB
C#
282 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using UnityEditor.Rendering.Converter;
|
|
using UnityEngine;
|
|
|
|
namespace UnityEditor.Rendering.Universal
|
|
{
|
|
/// <summary>
|
|
/// Filter for the list of converters used in batch mode.
|
|
/// </summary>
|
|
/// <seealso cref="Converters.RunInBatchMode(UnityEditor.Rendering.Universal.ConverterContainerId, List{UnityEditor.Rendering.Universal.ConverterId}, UnityEditor.Rendering.Universal.ConverterFilter)"/>
|
|
public enum ConverterFilter
|
|
{
|
|
/// <summary>
|
|
/// Use this to include converters matching the filter.
|
|
/// </summary>
|
|
Inclusive,
|
|
|
|
/// <summary>
|
|
/// Use this to exclude converters matching the filter.
|
|
/// </summary>
|
|
Exclusive
|
|
}
|
|
|
|
/// <summary>
|
|
/// The container to run in batch mode.
|
|
/// </summary>
|
|
/// <seealso cref="Converters.RunInBatchMode(UnityEditor.Rendering.Universal.ConverterContainerId)"/>
|
|
public enum ConverterContainerId
|
|
{
|
|
/// <summary>
|
|
/// Use this for Built-in to URP converter.
|
|
/// </summary>
|
|
BuiltInToURP,
|
|
|
|
/// <summary>
|
|
/// Use this for Built-in to 2D (URP) converter.
|
|
/// </summary>
|
|
BuiltInToURP2D,
|
|
|
|
/// <summary>
|
|
/// Use this for Built-in and 3D URP to 2D (URP) converter.
|
|
/// </summary>
|
|
BuiltInAndURPToURP2D,
|
|
|
|
/// <summary>
|
|
/// Use this to upgrade 2D (URP) assets.
|
|
/// </summary>
|
|
UpgradeURP2DAssets,
|
|
}
|
|
|
|
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
|
|
internal class BatchModeConverterInfo : Attribute
|
|
{
|
|
public Type converterType { get; }
|
|
public ConverterContainerId containerName {get;}
|
|
|
|
public BatchModeConverterInfo(ConverterContainerId containerName, Type converterType)
|
|
{
|
|
this.converterType = converterType;
|
|
this.containerName = containerName;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The converter to run in batch mode.
|
|
/// </summary>
|
|
/// <seealso cref="Converters.RunInBatchMode(UnityEditor.Rendering.Universal.ConverterContainerId, List{UnityEditor.Rendering.Universal.ConverterId}, UnityEditor.Rendering.Universal.ConverterFilter)"/>
|
|
public enum ConverterId
|
|
{
|
|
/// <summary>
|
|
/// Use this for the material converters.
|
|
/// </summary>
|
|
[BatchModeConverterInfo(ConverterContainerId.BuiltInToURP,typeof(BuiltInToURP3DMaterialUpgrader))]
|
|
Material,
|
|
|
|
/// <summary>
|
|
/// Use this for the render settings converters.
|
|
/// </summary>
|
|
[BatchModeConverterInfo(ConverterContainerId.BuiltInToURP, typeof(RenderSettingsConverter))]
|
|
RenderSettings,
|
|
|
|
/// <summary>
|
|
/// Use this for the animation clip converters.
|
|
/// </summary>
|
|
[BatchModeConverterInfo(ConverterContainerId.BuiltInToURP, typeof(AnimationClipConverter))]
|
|
AnimationClip,
|
|
|
|
/// <summary>
|
|
/// Use this for readonly material converters.
|
|
/// </summary>
|
|
[BatchModeConverterInfo(ConverterContainerId.BuiltInToURP, typeof(ReadonlyMaterialConverter))]
|
|
ReadonlyMaterial,
|
|
|
|
/// <summary>
|
|
/// Use this for 2D material conversion
|
|
/// </summary>
|
|
[BatchModeConverterInfo(ConverterContainerId.BuiltInToURP2D, typeof(BuiltInToURP2DMaterialUpgrader))]
|
|
ReadonlyMaterial2D,
|
|
|
|
/// <summary>
|
|
/// Use this for 3D URP material conversion
|
|
/// </summary>
|
|
[BatchModeConverterInfo(ConverterContainerId.UpgradeURP2DAssets, typeof(BuiltInAndURP3DTo2DMaterialUpgrader))]
|
|
URPToReadonlyMaterial2D,
|
|
|
|
#if PPV2_EXISTS
|
|
/// <summary>
|
|
/// Use this for post processing V2 converters.
|
|
/// </summary>
|
|
[BatchModeConverterInfo(ConverterContainerId.BuiltInToURP, typeof(PPv2Converter))]
|
|
PPv2,
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Use this for parametric to freeform light converters.
|
|
/// </summary>
|
|
[BatchModeConverterInfo(ConverterContainerId.UpgradeURP2DAssets, typeof(ParametricToFreeformLightUpgrader))]
|
|
ParametricToFreeformLight,
|
|
}
|
|
|
|
/// <summary>
|
|
/// Class for the converter framework.
|
|
/// </summary>
|
|
public static class Converters
|
|
{
|
|
private static void DumpAvailableConverters()
|
|
{
|
|
StringBuilder sb = new();
|
|
foreach (var converter in TypeCache.GetTypesDerivedFrom<IRenderPipelineConverter>())
|
|
{
|
|
if (converter.IsAbstract || converter.IsInterface)
|
|
continue;
|
|
|
|
sb.AppendLine(converter.AssemblyQualifiedName);
|
|
}
|
|
|
|
Debug.Log(sb.ToString());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Call this method to run all the converters in a specific container in batch mode.
|
|
/// </summary>
|
|
/// <param name="containerName">The name of the container which will be batched. All Converters in this Container will run if prerequisites are met.</param>
|
|
public static void RunInBatchMode(ConverterContainerId containerName)
|
|
{
|
|
RunInBatchMode(containerName, new List<ConverterId>() { }, ConverterFilter.Exclusive);
|
|
}
|
|
|
|
internal static bool TryGetTypeInContainer(ConverterId value, ConverterContainerId containerName, out Type type)
|
|
{
|
|
type = null;
|
|
var memberInfo = typeof(ConverterId).GetMember(value.ToString());
|
|
if (memberInfo.Length > 0)
|
|
{
|
|
var attr = memberInfo[0].GetCustomAttribute<BatchModeConverterInfo>();
|
|
if (attr != null)
|
|
{
|
|
if(attr.containerName == containerName)
|
|
type = attr.converterType;
|
|
}
|
|
}
|
|
return type != null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Call this method to run a specific list of converters in a specific container in batch mode.
|
|
/// </summary>
|
|
/// <param name="containerName">The name of the container which will be batched.</param>
|
|
/// <param name="converterList">The list of converters that will be either included or excluded from batching. These converters need to be part of the passed in container for them to run.</param>
|
|
/// <param name="converterFilter">The enum that decide if the list of converters will be included or excluded when batching.</param>
|
|
public static void RunInBatchMode(ConverterContainerId containerName, List<ConverterId> converterList, ConverterFilter converterFilter)
|
|
{
|
|
var types = FilterConverters(containerName, converterList, converterFilter);
|
|
RunInBatchMode(types);
|
|
}
|
|
|
|
internal static List<Type> FilterConverters(ConverterContainerId containerName, List<ConverterId> converterList, ConverterFilter converterFilter)
|
|
{
|
|
Array converters = Enum.GetValues(typeof(ConverterId));
|
|
|
|
List<Type> converterTypes = new();
|
|
foreach (object value in converters)
|
|
{
|
|
var converterEnum = (ConverterId)value;
|
|
if (TryGetTypeInContainer(converterEnum, containerName, out var type))
|
|
{
|
|
bool inFilter = converterList.Contains(converterEnum);
|
|
if ((converterFilter == ConverterFilter.Inclusive) ^ !inFilter)
|
|
converterTypes.Add(type);
|
|
}
|
|
}
|
|
|
|
return converterTypes;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Call this method to run a specific list of converters in batch mode.
|
|
/// </summary>
|
|
/// <param name="converterTypes">The list of converters to run</param>
|
|
/// <returns>False if there were errors.</returns>
|
|
internal static bool RunInBatchMode(List<Type> converterTypes)
|
|
{
|
|
Debug.LogWarning("Using this API can lead to incomplete or unpredictable conversion outcomes. For reliable results, please perform the conversion via the dedicated window: Window > Rendering > Render Pipeline Converter.");
|
|
|
|
List<IRenderPipelineConverter> convertersToExecute = new();
|
|
|
|
bool errors = false;
|
|
foreach (var type in converterTypes)
|
|
{
|
|
try
|
|
{
|
|
var instance = Activator.CreateInstance(type) as IRenderPipelineConverter;
|
|
if (instance == null)
|
|
{
|
|
Debug.LogWarning($"{type} is not a converter type.");
|
|
errors = true;
|
|
}
|
|
else
|
|
convertersToExecute.Add(instance);
|
|
}
|
|
catch
|
|
{
|
|
Debug.LogWarning($"Unable to create instance of type {type}.");
|
|
errors = true;
|
|
}
|
|
}
|
|
|
|
if (errors)
|
|
{
|
|
Debug.LogWarning($"Please use any of the given Converter Types.");
|
|
DumpAvailableConverters();
|
|
}
|
|
|
|
BatchConverters(convertersToExecute);
|
|
|
|
return !errors;
|
|
}
|
|
|
|
internal static void BatchConverters(List<IRenderPipelineConverter> converters)
|
|
{
|
|
foreach (var converter in converters)
|
|
{
|
|
var sb = new StringBuilder($"Conversion results for item: {converter}:{Environment.NewLine}");
|
|
|
|
converter.Scan(OnConverterCompleteDataCollection);
|
|
|
|
void OnConverterCompleteDataCollection(List<IRenderPipelineConverterItem> items)
|
|
{
|
|
converter.BeforeConvert();
|
|
foreach (var item in items)
|
|
{
|
|
var status = converter.Convert(item, out var message);
|
|
switch (status)
|
|
{
|
|
case Status.Pending:
|
|
throw new InvalidOperationException("Converter returned a pending status when converting. This is not supported.");
|
|
case Status.Error:
|
|
case Status.Warning:
|
|
sb.AppendLine($"- {item.name} ({status}) ({message})");
|
|
break;
|
|
case Status.Success:
|
|
{
|
|
sb.AppendLine($"- {item.name} ({status})");
|
|
message = "Conversion successful!";
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
converter.AfterConvert();
|
|
|
|
Debug.Log(sb.ToString());
|
|
}
|
|
}
|
|
|
|
AssetDatabase.SaveAssets();
|
|
}
|
|
}
|
|
}
|