123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using UnityEditor.Rendering.Universal;
- using ClipPath = UnityEditor.Rendering.AnimationClipUpgrader.ClipPath;
- using ClipProxy = UnityEditor.Rendering.AnimationClipUpgrader.AnimationClipProxy;
- using UnityObject = UnityEngine.Object;
-
- namespace UnityEditor.Rendering.Universal
- {
- internal sealed class AnimationClipConverter : RenderPipelineConverter
- {
- public override string name => "Animation Clip Converter";
- public override string info => "This converter updates all animation clips so that they reference the correct Materials.";
- public override string category { get; }
- public override Type container => typeof(BuiltInToURPConverterContainer);
-
- List<GlobalObjectId> m_AssetsToConvert = new List<GlobalObjectId>(64);
-
- IDictionary<AnimationClipUpgrader.IAnimationClip, (ClipPath Path, EditorCurveBinding[] Bindings, SerializedShaderPropertyUsage Usage, IDictionary<EditorCurveBinding, string> PropertyRenames)> m_ClipData =
- new Dictionary<AnimationClipUpgrader.IAnimationClip, (ClipPath Path, EditorCurveBinding[] Bindings, SerializedShaderPropertyUsage Usage, IDictionary<EditorCurveBinding, string> PropertyRenames)>();
-
- public override void OnInitialize(InitializeConverterContext ctx, Action callback)
- {
- // get paths to all animation clips
- var clipPaths = AssetDatabase.FindAssets("t:AnimationClip")
- .Select(p => (ClipPath)AssetDatabase.GUIDToAssetPath(p))
- .ToArray();
-
- // retrieve clip assets with material animation
- m_ClipData = AnimationClipUpgrader.GetAssetDataForClipsFiltered(clipPaths);
-
- // collect all clips and add them to the context
- var keys = m_ClipData.Keys.ToArray();
- var clipIds = new GlobalObjectId[keys.Length];
- GlobalObjectId.GetGlobalObjectIdsSlow(keys.Select(c => c.Clip as UnityObject).ToArray(), clipIds);
- for (int i = 0; i < keys.Length; ++i)
- {
- AnimationClipUpgrader.IAnimationClip key = keys[i];
- var cd = m_ClipData[key];
- var clip = key.Clip;
- var item = new ConverterItemDescriptor()
- {
- name = clip.name,
- info = cd.Path,
- };
- // TODO: need to know how materials will be upgraded in order to generate warnings
- m_AssetsToConvert.Add(clipIds[i]);
-
- ctx.AddAssetToConvert(item);
- }
-
- callback.Invoke();
- }
-
- public override void OnPreRun()
- {
- // get paths to all animation clips
- var clipPaths = new HashSet<ClipPath>(m_ClipData.Values.Select(cd => cd.Path));
-
- // get paths to all prefabs and scenes in order to inspect clip usage
- var prefabPaths = AssetDatabase.FindAssets("t:Prefab")
- .Select(p => (AnimationClipUpgrader.PrefabPath)AssetDatabase.GUIDToAssetPath(p))
- .ToArray();
- var scenePaths = AssetDatabase.FindAssets("t:Scene")
- .Select(p => (AnimationClipUpgrader.ScenePath)AssetDatabase.GUIDToAssetPath(p))
- .ToArray();
-
- // create table mapping all upgrade paths to new shaders
- var upgraders = new UniversalRenderPipelineMaterialUpgrader().upgraders;
- var allUpgradePathsToNewShaders = UpgradeUtility.GetAllUpgradePathsToShaders(upgraders);
-
- // TODO: could pass in upgrade paths used by materials in the future
-
- // retrieve interdependencies with prefabs to figure out which clips can be safely upgraded
- AnimationClipUpgrader.GetClipDependencyMappings(clipPaths, prefabPaths, out var clipPrefabDependents, out var prefabDependencies);
- AnimationClipUpgrader.GatherClipsUsageInDependentPrefabs(
- clipPrefabDependents, prefabDependencies, m_ClipData, allUpgradePathsToNewShaders, default, default);
-
- // do the same for clips used by scenes
- AnimationClipUpgrader.GetClipDependencyMappings(clipPaths, scenePaths, out var clipSceneDependents, out var sceneDependencies);
- AnimationClipUpgrader.GatherClipsUsageInDependentScenes(
- clipSceneDependents, sceneDependencies, m_ClipData, allUpgradePathsToNewShaders, default, default);
- }
-
- HashSet<(AnimationClipUpgrader.IAnimationClip Clip, ClipPath Path, SerializedShaderPropertyUsage Usage)> m_Upgraded =
- new HashSet<(AnimationClipUpgrader.IAnimationClip Clip, ClipPath Path, SerializedShaderPropertyUsage Usage)>();
-
- HashSet<(AnimationClipUpgrader.IAnimationClip Clip, ClipPath Path, SerializedShaderPropertyUsage Usage)> m_NotUpgraded =
- new HashSet<(AnimationClipUpgrader.IAnimationClip Clip, ClipPath Path, SerializedShaderPropertyUsage Usage)>();
-
- IDictionary<AnimationClipUpgrader.IAnimationClip, (ClipPath Path, EditorCurveBinding[] Bindings, SerializedShaderPropertyUsage Usage, IDictionary<EditorCurveBinding, string> PropertyRenames)> m_TempClipData =
- new Dictionary<AnimationClipUpgrader.IAnimationClip, (ClipPath Path, EditorCurveBinding[] Bindings, SerializedShaderPropertyUsage Usage, IDictionary<EditorCurveBinding, string> PropertyRenames)>();
-
- public override void OnRun(ref RunItemContext ctx)
- {
- // filter flags are used to determine which clips to skip over during upgrade process
- // we want to process all clips that are not ambiguously upgraded
- const SerializedShaderPropertyUsage kFilterFlags =
- ~(
- SerializedShaderPropertyUsage.UsedByUpgraded
- | SerializedShaderPropertyUsage.UsedByNonUpgraded
- );
-
- const SerializedShaderPropertyUsage kSuccessFlags =
- SerializedShaderPropertyUsage.UsedByUpgraded;
-
- var clipKey = (ClipProxy)GlobalObjectId.GlobalObjectIdentifierToObjectSlow(m_AssetsToConvert[ctx.item.index]);
-
- m_TempClipData.Clear();
- m_TempClipData[clipKey] = m_ClipData[clipKey];
-
- m_Upgraded.Clear();
- m_NotUpgraded.Clear();
-
- AnimationClipUpgrader.UpgradeClips(m_TempClipData, kFilterFlags, m_Upgraded, m_NotUpgraded, default);
-
- var usage = m_TempClipData[clipKey].Usage;
-
- // Success
- if ((usage & kSuccessFlags) != 0 && (usage & kFilterFlags) == 0)
- return;
-
- if (usage == SerializedShaderPropertyUsage.Unknown)
- {
- ctx.didFail = true;
- ctx.info = L10n.Tr("The animation clip is not used by any objects with renderers currently in the project, so it may not be safe to automatically upgrade.");
- return;
- }
-
- var sb = new StringBuilder();
-
- sb.Append(L10n.Tr("The animation clip was not modified for one or more reasons:"));
-
- if ((usage & SerializedShaderPropertyUsage.UsedByAmbiguouslyUpgraded) != 0)
- {
- ctx.didFail = true;
- sb.Append(L10n.Tr("\n - The animation clip is used by objects with materials that took different upgrade paths for the animated property."));
- }
-
- if ((usage & SerializedShaderPropertyUsage.UsedByNonUpgraded) != 0)
- {
- ctx.didFail = true;
- sb.Append(L10n.Tr("\n - The animation clip is used by objects with materials that have not been upgraded."));
- }
-
- if (ctx.didFail)
- ctx.info = sb.ToString();
- }
-
- public override void OnClicked(int index)
- {
- var id = m_AssetsToConvert[index];
-
- var clip = GlobalObjectId.GlobalObjectIdentifierToObjectSlow(id);
- if (clip == null)
- return;
-
- EditorGUIUtility.PingObject(clip);
- }
- }
- }
|