[GUI] Preserve selection order of AnimationClips (#24)

This commit is contained in:
VaDiM 2023-12-30 18:34:56 +03:00
parent c2d3b8c5f9
commit 115074fdc0
3 changed files with 54 additions and 25 deletions

View File

@ -89,6 +89,10 @@ namespace AssetStudioGUI
private AlphanumComparatorFast alphanumComparator = new AlphanumComparatorFast(); private AlphanumComparatorFast alphanumComparator = new AlphanumComparatorFast();
#endif #endif
//asset list selection
private List<int> selectedIndicesPrevList = new List<int>();
private List<AssetItem> selectedAnimationAssetsList = new List<AssetItem>();
//asset list filter //asset list filter
private System.Timers.Timer delayTimer; private System.Timers.Timer delayTimer;
private bool enableFiltering; private bool enableFiltering;
@ -695,6 +699,8 @@ namespace AssetStudioGUI
sortColumn = e.Column; sortColumn = e.Column;
assetListView.BeginUpdate(); assetListView.BeginUpdate();
assetListView.SelectedIndices.Clear(); assetListView.SelectedIndices.Clear();
selectedIndicesPrevList.Clear();
selectedAnimationAssetsList.Clear();
if (sortColumn == 4) //FullSize if (sortColumn == 4) //FullSize
{ {
visibleAssets.Sort((a, b) => visibleAssets.Sort((a, b) =>
@ -1366,6 +1372,8 @@ namespace AssetStudioGUI
assetListView.Items.Clear(); assetListView.Items.Clear();
classesListView.Items.Clear(); classesListView.Items.Clear();
classesListView.Groups.Clear(); classesListView.Groups.Clear();
selectedAnimationAssetsList.Clear();
selectedIndicesPrevList.Clear();
previewPanel.BackgroundImage = Properties.Resources.preview; previewPanel.BackgroundImage = Properties.Resources.preview;
imageTexture?.Dispose(); imageTexture?.Dispose();
imageTexture = null; imageTexture = null;
@ -1459,7 +1467,6 @@ namespace AssetStudioGUI
private void exportAnimatorwithAnimationClipMenuItem_Click(object sender, EventArgs e) private void exportAnimatorwithAnimationClipMenuItem_Click(object sender, EventArgs e)
{ {
AssetItem animator = null; AssetItem animator = null;
List<AssetItem> animationList = new List<AssetItem>();
var selectedAssets = GetSelectedAssets(); var selectedAssets = GetSelectedAssets();
foreach (var assetPreloadData in selectedAssets) foreach (var assetPreloadData in selectedAssets)
{ {
@ -1467,10 +1474,6 @@ namespace AssetStudioGUI
{ {
animator = assetPreloadData; animator = assetPreloadData;
} }
else if (assetPreloadData.Type == ClassIDType.AnimationClip)
{
animationList.Add(assetPreloadData);
}
} }
if (animator != null) if (animator != null)
@ -1481,7 +1484,7 @@ namespace AssetStudioGUI
{ {
saveDirectoryBackup = saveFolderDialog.Folder; saveDirectoryBackup = saveFolderDialog.Folder;
var exportPath = Path.Combine(saveFolderDialog.Folder, "Animator") + Path.DirectorySeparatorChar; var exportPath = Path.Combine(saveFolderDialog.Folder, "Animator") + Path.DirectorySeparatorChar;
ExportAnimatorWithAnimationClip(animator, animationList, exportPath); ExportAnimatorWithAnimationClip(animator, selectedAnimationAssetsList, exportPath);
} }
} }
} }
@ -1661,16 +1664,46 @@ namespace AssetStudioGUI
private void assetListView_SelectedIndexChanged(object sender, EventArgs e) private void assetListView_SelectedIndexChanged(object sender, EventArgs e)
{ {
if (assetListView.SelectedIndices.Count > 1) ProcessSelectedItems();
StatusStripUpdate($"Selected {assetListView.SelectedIndices.Count} assets.");
} }
private void assetListView_VirtualItemsSelectionRangeChanged(object sender, ListViewVirtualItemsSelectionRangeChangedEventArgs e) private void assetListView_VirtualItemsSelectionRangeChanged(object sender, ListViewVirtualItemsSelectionRangeChangedEventArgs e)
{
ProcessSelectedItems();
}
private void ProcessSelectedItems()
{ {
if (assetListView.SelectedIndices.Count > 1) if (assetListView.SelectedIndices.Count > 1)
{
StatusStripUpdate($"Selected {assetListView.SelectedIndices.Count} assets."); StatusStripUpdate($"Selected {assetListView.SelectedIndices.Count} assets.");
} }
var selectedIndicesList = assetListView.SelectedIndices.Cast<int>().ToList();
var addedIndices = selectedIndicesList.Except(selectedIndicesPrevList).ToArray();
foreach (var itemIndex in addedIndices)
{
selectedIndicesPrevList.Add(itemIndex);
var selectedItem = (AssetItem)assetListView.Items[itemIndex];
if (selectedItem.Type == ClassIDType.AnimationClip)
{
selectedAnimationAssetsList.Add(selectedItem);
}
}
var removedIndices = selectedIndicesPrevList.Except(selectedIndicesList).ToArray();
foreach (var itemIndex in removedIndices)
{
selectedIndicesPrevList.Remove(itemIndex);
var unselectedItem = (AssetItem)assetListView.Items[itemIndex];
if (unselectedItem.Type == ClassIDType.AnimationClip)
{
selectedAnimationAssetsList.Remove(unselectedItem);
}
}
}
private List<AssetItem> GetSelectedAssets() private List<AssetItem> GetSelectedAssets()
{ {
var selectedAssets = new List<AssetItem>(assetListView.SelectedIndices.Count); var selectedAssets = new List<AssetItem>(assetListView.SelectedIndices.Count);

View File

@ -626,6 +626,7 @@ namespace AssetStudioGUI
{ {
Progress.Reset(); Progress.Reset();
Logger.Info($"Exporting {animator.Text}"); Logger.Info($"Exporting {animator.Text}");
Logger.Debug($"Selected AnimationClip(s):\n\"{string.Join("\"\n\"", animationList.Select(x => x.Text))}\"");
try try
{ {
ExportAnimator(animator, exportPath, animationList); ExportAnimator(animator, exportPath, animationList);

View File

@ -16,7 +16,7 @@ namespace AssetStudio
private ImageFormat imageFormat; private ImageFormat imageFormat;
private Avatar avatar; private Avatar avatar;
private HashSet<AnimationClip> animationClipHashSet = new HashSet<AnimationClip>(); private AnimationClip[] animationClipUniqArray = Array.Empty<AnimationClip>();
private Dictionary<AnimationClip, string> boundAnimationPathDic = new Dictionary<AnimationClip, string>(); private Dictionary<AnimationClip, string> boundAnimationPathDic = new Dictionary<AnimationClip, string>();
private Dictionary<uint, string> bonePathHash = new Dictionary<uint, string>(); private Dictionary<uint, string> bonePathHash = new Dictionary<uint, string>();
private Dictionary<Texture2D, string> textureNameDictionary = new Dictionary<Texture2D, string>(); private Dictionary<Texture2D, string> textureNameDictionary = new Dictionary<Texture2D, string>();
@ -40,10 +40,7 @@ namespace AssetStudio
} }
if (animationList != null) if (animationList != null)
{ {
foreach (var animationClip in animationList) animationClipUniqArray = animationList.Distinct().ToArray();
{
animationClipHashSet.Add(animationClip);
}
} }
ConvertAnimations(); ConvertAnimations();
} }
@ -70,10 +67,7 @@ namespace AssetStudio
} }
if (animationList != null) if (animationList != null)
{ {
foreach (var animationClip in animationList) animationClipUniqArray = animationList.Distinct().ToArray();
{
animationClipHashSet.Add(animationClip);
}
} }
ConvertAnimations(); ConvertAnimations();
} }
@ -88,10 +82,7 @@ namespace AssetStudio
} }
else else
{ {
foreach (var animationClip in animationList) animationClipUniqArray = animationList.Distinct().ToArray();
{
animationClipHashSet.Add(animationClip);
}
} }
ConvertAnimations(); ConvertAnimations();
} }
@ -160,6 +151,7 @@ namespace AssetStudio
if (m_GameObject.m_Animation != null) if (m_GameObject.m_Animation != null)
{ {
var animationList = new List<AnimationClip>();
foreach (var animation in m_GameObject.m_Animation.m_Animations) foreach (var animation in m_GameObject.m_Animation.m_Animations)
{ {
if (animation.TryGet(out var animationClip)) if (animation.TryGet(out var animationClip))
@ -168,9 +160,10 @@ namespace AssetStudio
{ {
boundAnimationPathDic.Add(animationClip, GetTransformPath(m_Transform)); boundAnimationPathDic.Add(animationClip, GetTransformPath(m_Transform));
} }
animationClipHashSet.Add(animationClip); animationList.Add(animationClip);
} }
} }
animationClipUniqArray = animationList.Distinct().ToArray();
} }
foreach (var pptr in m_Transform.m_Children) foreach (var pptr in m_Transform.m_Children)
@ -184,6 +177,7 @@ namespace AssetStudio
{ {
if (m_Animator.m_Controller.TryGet(out var m_Controller)) if (m_Animator.m_Controller.TryGet(out var m_Controller))
{ {
var animationList = new List<AnimationClip>();
switch (m_Controller) switch (m_Controller)
{ {
case AnimatorOverrideController m_AnimatorOverrideController: case AnimatorOverrideController m_AnimatorOverrideController:
@ -194,7 +188,7 @@ namespace AssetStudio
{ {
if (pptr.TryGet(out var m_AnimationClip)) if (pptr.TryGet(out var m_AnimationClip))
{ {
animationClipHashSet.Add(m_AnimationClip); animationList.Add(m_AnimationClip);
} }
} }
} }
@ -207,12 +201,13 @@ namespace AssetStudio
{ {
if (pptr.TryGet(out var m_AnimationClip)) if (pptr.TryGet(out var m_AnimationClip))
{ {
animationClipHashSet.Add(m_AnimationClip); animationList.Add(m_AnimationClip);
} }
} }
break; break;
} }
} }
animationClipUniqArray = animationList.Distinct().ToArray();
} }
} }
@ -769,7 +764,7 @@ namespace AssetStudio
private void ConvertAnimations() private void ConvertAnimations()
{ {
foreach (var animationClip in animationClipHashSet) foreach (var animationClip in animationClipUniqArray)
{ {
var iAnim = new ImportedKeyframedAnimation(); var iAnim = new ImportedKeyframedAnimation();
var name = animationClip.m_Name; var name = animationClip.m_Name;