Simplify data.

Remoing asset builder.
Simple data setup.
This commit is contained in:
max
2021-01-19 01:18:25 +01:00
parent 94f97c218a
commit 2d6e920017
15 changed files with 260 additions and 811 deletions

View File

@ -7,8 +7,6 @@ namespace TAO.VertexAnimation.Editor
public class VA_AnimationBookEditor : UnityEditor.Editor
{
private VA_AnimationBook animationBook = null;
private Vector2 textureGroupScollPos;
private Vector2 animationPagesScollPos;
void OnEnable()
{
@ -20,249 +18,10 @@ namespace TAO.VertexAnimation.Editor
serializedObject.Update();
// Texture Groups.
GeneralGUI();
DrawDefaultInspector();
EditorGUILayoutUtils.HorizontalLine(color: Color.gray);
TextureGroupsGUI();
EditorGUILayoutUtils.HorizontalLine(color: Color.gray);
SyncListSize();
AnimationPagesGUI();
EditorGUILayoutUtils.HorizontalLine(color: Color.gray);
MaterialGUI();
EditorGUILayoutUtils.HorizontalLine(color: Color.gray);
AssetBuilderGUI();
EditorGUILayoutUtils.HorizontalLine(color: Color.gray);
Texture2DGUI();
serializedObject.ApplyModifiedProperties();
}
private void SyncListSize()
{
foreach (var page in animationBook.editorData.animationPages)
{
if(page.textures.Count < animationBook.editorData.textureGroups.Count)
{
int diff = animationBook.editorData.textureGroups.Count - page.textures.Count;
for (int i = 0; i < diff; i++)
{
page.textures.Add(null);
}
}
else if(page.textures.Count > animationBook.editorData.textureGroups.Count)
{
int diff = page.textures.Count - animationBook.editorData.textureGroups.Count;
for (int i = 0; i < diff; i++)
{
page.textures.RemoveRange(page.textures.Count - diff, diff);
}
}
}
}
private void GeneralGUI()
{
SerializedProperty editorData = serializedObject.FindProperty("editorData");
using (new EditorGUILayout.VerticalScope())
{
EditorGUILayout.LabelField("General", EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.PropertyField(editorData.FindPropertyRelative("fps"));
EditorGUILayout.PropertyField(editorData.FindPropertyRelative("maxFrames"));
}
}
private void TextureGroupsGUI()
{
SerializedProperty editorData = serializedObject.FindProperty("editorData");
SerializedProperty textureGroups = editorData.FindPropertyRelative("textureGroups");
int removeWidth = 16;
int nameWidth = 152;
int optionWidth = 110;
int linearWidth = 50;
using (new EditorGUILayout.VerticalScope())
{
EditorGUILayout.LabelField("TextureGroups", EditorStyles.centeredGreyMiniLabel);
textureGroupScollPos = EditorGUILayout.BeginScrollView(textureGroupScollPos, false, false);
using (new EditorGUILayout.HorizontalScope(EditorStyles.toolbar))
{
EditorGUILayout.LabelField("", GUILayout.Width(removeWidth));
EditorGUILayout.LabelField("material parameter name", GUILayout.Width(nameWidth));
EditorGUILayout.LabelField("texture type", GUILayout.Width(optionWidth));
EditorGUILayout.LabelField("wrap mode", GUILayout.Width(optionWidth));
EditorGUILayout.LabelField("filter mode", GUILayout.Width(optionWidth));
EditorGUILayout.LabelField("is linear", GUILayout.MinWidth(linearWidth));
}
EditorGUILayout.EndScrollView();
textureGroupScollPos = EditorGUILayout.BeginScrollView(textureGroupScollPos, false, false);
for (int i = 0; i < textureGroups.arraySize; i++)
{
using (new EditorGUILayout.HorizontalScope())
{
if (GUILayout.Button("-", GUILayout.Width(removeWidth)))
{
textureGroups.DeleteArrayElementAtIndex(i);
continue;
}
EditorGUILayout.PropertyField(textureGroups.GetArrayElementAtIndex(i).FindPropertyRelative("shaderParamName"), GUIContent.none, GUILayout.Width(nameWidth));
EditorGUILayout.PropertyField(textureGroups.GetArrayElementAtIndex(i).FindPropertyRelative("textureType"), GUIContent.none, GUILayout.Width(optionWidth));
EditorGUILayout.PropertyField(textureGroups.GetArrayElementAtIndex(i).FindPropertyRelative("wrapMode"), GUIContent.none, GUILayout.Width(optionWidth));
EditorGUILayout.PropertyField(textureGroups.GetArrayElementAtIndex(i).FindPropertyRelative("filterMode"), GUIContent.none, GUILayout.Width(optionWidth));
EditorGUILayout.PropertyField(textureGroups.GetArrayElementAtIndex(i).FindPropertyRelative("isLinear"), GUIContent.none, GUILayout.MinWidth(linearWidth));
}
}
EditorGUILayout.EndScrollView();
if (GUILayout.Button("+", EditorStyles.miniButton))
{
animationBook.editorData.textureGroups.Add(new VA_AnimationBook.EditorTextureGroup
{
shaderParamName = "_ShaderPropertyName",
isLinear = false
});
}
}
}
private void AnimationPagesGUI()
{
SerializedProperty editorData = serializedObject.FindProperty("editorData");
SerializedProperty animationPages = editorData.FindPropertyRelative("animationPages");
int removeWidth = 16;
int nameWidth = 100;
int frameWidth = 50;
int textureWidth = 150;
using (new EditorGUILayout.VerticalScope())
{
EditorGUILayout.LabelField("AnimationPages", EditorStyles.centeredGreyMiniLabel);
animationPagesScollPos = EditorGUILayout.BeginScrollView(animationPagesScollPos, false, false);
using (new EditorGUILayout.HorizontalScope(EditorStyles.toolbar))
{
EditorGUILayout.LabelField("", GUILayout.Width(removeWidth));
EditorGUILayout.LabelField("name", GUILayout.Width(nameWidth));
EditorGUILayout.LabelField("frames", GUILayout.Width(frameWidth));
foreach (var t in animationBook.editorData.textureGroups)
{
EditorGUILayout.LabelField(t.shaderParamName, GUILayout.MinWidth(textureWidth));
}
}
EditorGUILayout.EndScrollView();
animationPagesScollPos = EditorGUILayout.BeginScrollView(animationPagesScollPos, false, false);
for (int i = 0; i < animationPages.arraySize; i++)
{
using (new EditorGUILayout.HorizontalScope())
{
if (GUILayout.Button("-", GUILayout.Width(removeWidth)))
{
animationPages.DeleteArrayElementAtIndex(i);
continue;
}
EditorGUILayout.PropertyField(animationPages.GetArrayElementAtIndex(i).FindPropertyRelative("name"), GUIContent.none, GUILayout.Width(nameWidth));
EditorGUILayout.PropertyField(animationPages.GetArrayElementAtIndex(i).FindPropertyRelative("frames"), GUIContent.none, GUILayout.Width(frameWidth));
SerializedProperty textures = animationPages.GetArrayElementAtIndex(i).FindPropertyRelative("textures");
for (int t = 0; t < textures.arraySize; t++)
{
EditorGUILayout.PropertyField(textures.GetArrayElementAtIndex(t).FindPropertyRelative("texture2D"), GUIContent.none, GUILayout.MinWidth(textureWidth));
}
}
}
EditorGUILayout.EndScrollView();
if (GUILayout.Button("+", EditorStyles.miniButton))
{
animationPages.InsertArrayElementAtIndex(animationPages.arraySize);
}
if (GUILayout.Button("auto fill", EditorStyles.miniButton))
{
Undo.RecordObject(animationBook, "AutoFill");
VA_AssetBuilder.AutoFill(ref animationBook);
EditorUtility.SetDirty(animationBook);
}
}
}
private void MaterialGUI()
{
SerializedProperty editorData = serializedObject.FindProperty("editorData");
using (new EditorGUILayout.VerticalScope())
{
EditorGUILayout.LabelField("Materials", EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.PropertyField(editorData.FindPropertyRelative("materials"));
}
}
private void AssetBuilderGUI()
{
using (new EditorGUILayout.HorizontalScope())
{
if (GUILayout.Button("build assets", EditorStyles.miniButtonLeft))
{
VA_AssetBuilder.GenerateBuildData();
}
if (GUILayout.Button("clear assets", EditorStyles.miniButtonRight))
{
VA_AssetBuilder.ClearBuildData();
}
}
}
private void Texture2DGUI()
{
SerializedProperty editorData = serializedObject.FindProperty("editorData");
if (HasPreviewGUI())
{
using (new EditorGUILayout.VerticalScope())
{
SerializedProperty texture2DArray = editorData.FindPropertyRelative("texture2DArray");
EditorGUILayout.LabelField("Texture2DArray", EditorStyles.centeredGreyMiniLabel);
using (new EditorGUI.DisabledScope(true))
{
EditorGUILayout.PropertyField(texture2DArray);
}
//previewIndex = EditorGUILayout.IntSlider("Preview" ,previewIndex, 0, texture2DArray.arraySize - 1);
}
}
}
//public override bool HasPreviewGUI()
//{
// bool hasPreview = false;
// if(animationBook.editorData.texture2DArray != null && animationBook.editorData.texture2DArray.Count > 0 && animationBook.editorData.texture2DArray[previewIndex] != null)
// {
// hasPreview = true;
// }
// return hasPreview;
//}
//public override void OnPreviewGUI(Rect r, GUIStyle background)
//{
// if (previewEditor == null || curviewIndex != previewIndex)
// {
// curviewIndex = previewIndex;
// previewEditor = CreateEditor(animationBook.editorData.texture2DArray[previewIndex]);
// }
// previewEditor.OnInteractivePreviewGUI(r, background);
//}
}
}

View File

@ -1,6 +1,7 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Linq;
namespace TAO.VertexAnimation.Editor
{
@ -26,7 +27,9 @@ namespace TAO.VertexAnimation.Editor
public Material material = null;
public Mesh[] meshes = null;
public VA_AnimationBook book = null;
public List<VA_Animation> animations = new List<VA_Animation>();
// TODO: release baked data from memory when done.
[SerializeField]
private AnimationBaker.BakedData bakedData;
@ -179,34 +182,64 @@ namespace TAO.VertexAnimation.Editor
book = CreateInstance<VA_AnimationBook>();
}
book.name = string.Format("{0}Book", name);
book.editorData = new VA_AnimationBook.EditorData
{
materials = new Material[1] { material }
};
foreach (Texture2D tex in bakedData.positionMaps)
{
book.editorData.animationPages.Add(new VA_AnimationBook.EditorAnimationPage
{
name = "",
frames = 0,
textures = new List<VA_AnimationBook.EditorTextureEntry>()
{
new VA_AnimationBook.EditorTextureEntry
{
texture2D = tex
}
}
});
}
VA_AssetBuilder.AutoFill(ref book);
book.name = string.Format("{0}_Book", name);
book.positionMap = positionMap;
book.TryAddMaterial(material);
if (!AssetDatabaseUtils.HasChildAsset(this, book))
{
AssetDatabase.AddObjectToAsset(book, this);
}
// Add animations.
List<NamingConventionUtils.TextureInfo> info = new List<NamingConventionUtils.TextureInfo>();
foreach (var t in bakedData.positionMaps)
{
info.Add(t.name.GetTextureInfo());
}
for (int i = 0; i < info.Count; i++)
{
string animationName = string.Format("{0}_{1}", name, info[i].name);
VA_AnimationData newData = new VA_AnimationData(animationName, info[i].frames, info[i].maxFrames, info[i].fps, i, -1);
if (TryGetAnimationWithName(animationName, out VA_Animation animation))
{
animation.SetData(newData);
}
else
{
animation = CreateInstance<VA_Animation>();
animation.name = animationName;
animation.SetData(newData);
animations.Add(animation);
}
book.TryAddAnimation(animation);
if (!AssetDatabaseUtils.HasChildAsset(book, animation))
{
AssetDatabase.AddObjectToAsset(animation, book);
}
}
// TODO: Remove unused animations.
}
private bool TryGetAnimationWithName(string name, out VA_Animation animation)
{
foreach (var a in animations)
{
if (a.name == name)
{
animation = a;
return true;
}
}
animation = null;
return false;
}
#endif
}

View File

@ -1,400 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using Unity.Collections;
namespace TAO.VertexAnimation.Editor
{
[InitializeOnLoad]
public class VA_AssetBuilder : IPreprocessBuildWithReport, IPostprocessBuildWithReport
{
private const string parentFolder = "Assets";
private const string childFolder = "VA_AssetBuilder";
private const string folderPath = parentFolder + "/" + childFolder;
#region EditorMenus
private const string buildClearKey = "VA_AssetsBuilderClearBuildAssets";
private const string editorGenerateKey = "VA_AssetsBuilderGenerateEditorAssets";
private const string editorClearKey = "VA_AssetsBuilderClearEditorAssets";
private const string editorMenuFolder = "TAO/Vertex Animation";
private const string buildClearMenuName = editorMenuFolder + "/ClearBuildAssets";
private const string editorGeneratePlayMenuName = editorMenuFolder + "/GenerateEditorAssetsOnStartPlay";
private const string editorClearPlayMenuName = editorMenuFolder + "/ClearEditorAssetsOnEndPlay";
public static bool ClearBuildAssets
{
get { return EditorPrefs.GetBool(buildClearKey, true); }
set { EditorPrefs.SetBool(buildClearKey, value); }
}
[MenuItem(buildClearMenuName)]
private static void ToggleClearBuildAssetsAction()
{
ClearBuildAssets = !ClearBuildAssets;
}
[MenuItem(buildClearMenuName, true)]
private static bool ToggleClearBuildAssetsValidate()
{
Menu.SetChecked(buildClearMenuName, ClearBuildAssets);
return true;
}
public static bool GenerateEditorPlayModeAssets
{
get { return EditorPrefs.GetBool(editorGenerateKey, true); }
set { EditorPrefs.SetBool(editorGenerateKey, value); }
}
[MenuItem(editorGeneratePlayMenuName)]
private static void ToggleGenerateEditorPlayModeAssetsAction()
{
GenerateEditorPlayModeAssets = !GenerateEditorPlayModeAssets;
}
[MenuItem(editorGeneratePlayMenuName, true)]
private static bool ToggleGenerateEditorPlayModeAssetsValidate()
{
Menu.SetChecked(editorGeneratePlayMenuName, GenerateEditorPlayModeAssets);
return true;
}
public static bool ClearEditorPlayModeAssets
{
get { return EditorPrefs.GetBool(editorClearKey, true); }
set { EditorPrefs.SetBool(editorClearKey, value); }
}
[MenuItem(editorClearPlayMenuName)]
private static void ToggleClearEditorPlayModeAssetsAction()
{
ClearEditorPlayModeAssets = !ClearEditorPlayModeAssets;
}
[MenuItem(editorClearPlayMenuName, true)]
private static bool ToggleClearEditorPlayModeAssetsValidate()
{
Menu.SetChecked(editorClearPlayMenuName, ClearEditorPlayModeAssets);
return true;
}
#endregion
#region EditorPlayMode
static VA_AssetBuilder()
{
EditorApplication.playModeStateChanged += OnPlayModeEnter;
}
private static void OnPlayModeEnter(PlayModeStateChange state)
{
switch (state)
{
case PlayModeStateChange.EnteredEditMode:
if (ClearEditorPlayModeAssets)
{
ClearBuildData();
}
break;
case PlayModeStateChange.ExitingEditMode:
if (GenerateEditorPlayModeAssets)
{
GenerateBuildData();
}
Debug.Log("VA_AssetBuilder generated editor data.");
break;
case PlayModeStateChange.EnteredPlayMode:
break;
case PlayModeStateChange.ExitingPlayMode:
break;
default:
break;
}
}
#endregion
#region BuildProcess
public int callbackOrder => 0;
public void OnPreprocessBuild(BuildReport report)
{
GenerateBuildData();
Debug.Log("VA_AssetBuilder generated play data.");
}
public void OnPostprocessBuild(BuildReport report)
{
if(!ClearBuildAssets)
{
return;
}
ClearBuildData();
Debug.Log("VA_AssetBuilder cleared play data.");
}
#endregion
#region MainFunctions
[MenuItem(editorMenuFolder + "/Generate Build Data", false, 65)]
public static void GenerateBuildData()
{
string filter = string.Format("t:{0}", typeof(VA_AnimationBook).Name);
string[] guids = AssetDatabase.FindAssets(filter);
foreach (var guid in guids)
{
VA_AnimationBook book = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid), typeof(VA_AnimationBook)) as VA_AnimationBook;
// Generate all assets.
GenerateTextures(ref book);
// Assign run time data.
ConvertEditorDataToPlayData(ref book);
// Save them to disk.
if (!AssetDatabase.IsValidFolder(folderPath))
{
AssetDatabase.CreateFolder(parentFolder, childFolder);
}
// Generate run time data.
List<string> savedAssets = new List<string>();
foreach (var t in book.editorData.texture2DArray)
{
string assetPath = string.Format("{0}/{1}.asset", folderPath, t.name);
// Delete existing asset.
if (!string.IsNullOrEmpty(AssetDatabase.AssetPathToGUID(assetPath)))
{
AssetDatabase.DeleteAsset(assetPath);
}
AssetDatabase.CreateAsset(t, assetPath);
savedAssets.Add(assetPath);
}
AssetDatabase.SaveAssets();
book.playData.texture2DArray = new List<Texture2DArray>();
foreach (var s in savedAssets)
{
var savedT = AssetDatabase.LoadAssetAtPath(s, typeof(Texture2DArray)) as Texture2DArray;
book.playData.texture2DArray.Add(savedT);
}
AssetDatabase.SaveAssets();
}
}
[MenuItem(editorMenuFolder + "/Clear Build Data", false, 66)]
public static void ClearBuildData()
{
string filter = string.Format("t:{0}", typeof(VA_AnimationBook).Name);
string[] guids = AssetDatabase.FindAssets(filter);
// Clear Generated Data.
foreach (var guid in guids)
{
VA_AnimationBook book = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid), typeof(VA_AnimationBook)) as VA_AnimationBook;
book.playData.texture2DArray = null;
}
// Remove generated assets from disk.
if (AssetDatabase.IsValidFolder(folderPath))
{
AssetDatabase.DeleteAsset(folderPath);
}
AssetDatabase.SaveAssets();
}
#endregion
#region GenerationHelperFunctions
// Assign the texture ID's to the texture entries.
private static void ReferenceDuplicates(ref VA_AnimationBook book)
{
for (int i = 0; i < book.editorData.textureGroups.Count; i++)
{
List<Texture2D> t = new List<Texture2D>();
for (int j = 0; j < book.editorData.animationPages.Count; j++)
{
// Check if exist.
if (!t.Contains(book.editorData.animationPages[j].textures[i].texture2D))
{
t.Add(book.editorData.animationPages[j].textures[i].texture2D);
}
// Add index reference.
book.editorData.animationPages[j].textures[i].textureArrayIndex = t.IndexOf(book.editorData.animationPages[j].textures[i].texture2D);
}
}
}
// Get the textures from a specific texture index.
private static List<Texture2D> GetTextures(ref VA_AnimationBook book, int textureIndex)
{
List<Texture2D> textures = new List<Texture2D>();
foreach (var ap in book.editorData.animationPages)
{
// Check if exist.
if (!textures.Contains(ap.textures[textureIndex].texture2D))
{
textures.Add(ap.textures[textureIndex].texture2D);
}
}
return textures;
}
// Generate texture arrays.
public static void GenerateTextures(ref VA_AnimationBook book)
{
ReferenceDuplicates(ref book);
book.editorData.texture2DArray = new List<Texture2DArray>();
for (int i = 0; i < book.editorData.textureGroups.Count; i++)
{
var t = GetTextures(ref book, i).ToArray();
if (VA_Texture2DArrayUtils.IsValidForTextureArray(t))
{
book.editorData.texture2DArray.Add(VA_Texture2DArrayUtils.CreateTextureArray(t, false, book.editorData.textureGroups[i].isLinear, book.editorData.textureGroups[i].wrapMode, book.editorData.textureGroups[i].filterMode, 1, book.name + book.editorData.textureGroups[i].shaderParamName));
}
}
}
// Auto fill names and frames.
public static void AutoFill(ref VA_AnimationBook book)
{
if (book.editorData.animationPages != null)
{
for (int i = 0; i < book.editorData.animationPages.Count; i++)
{
VA_AnimationBook.EditorAnimationPage ap = book.editorData.animationPages[i];
if (ap.textures != null && ap.textures.Count > 0)
{
string textureName = ap.textures[0].texture2D.name;
string[] parts = textureName.Split('_');
foreach (var p in parts)
{
if (p.StartsWith("N-"))
{
ap.name = p.Remove(0, 2);
}
else if (p.StartsWith("F-"))
{
if (int.TryParse(p.Remove(0, 2), out int frames))
{
ap.frames = frames;
}
}
else if (p.StartsWith("MF-"))
{
if (int.TryParse(p.Remove(0, 3), out int maxFrames))
{
book.editorData.maxFrames = maxFrames;
}
}
else if (p.StartsWith("FPS-"))
{
if (int.TryParse(p.Remove(0, 4), out int fps))
{
book.editorData.fps = fps;
}
}
}
}
book.editorData.animationPages[i] = ap;
}
}
}
public static int GetFirstAnimationMapIndex(in List<VA_AnimationBook.EditorTextureEntry> textures, in List<VA_AnimationBook.EditorTextureGroup> textureGroups)
{
for (int i = 0; i < textureGroups.Count; i++)
{
if (textureGroups[i].textureType == VA_AnimationBook.TextureType.AnimationMap)
{
return textures[i].textureArrayIndex;
}
}
return -1;
}
public static int GetFirstColorMapIndex(in List<VA_AnimationBook.EditorTextureEntry> textures, in List<VA_AnimationBook.EditorTextureGroup> textureGroups)
{
for (int i = 0; i < textureGroups.Count; i++)
{
if (textureGroups[i].textureType == VA_AnimationBook.TextureType.ColorMap)
{
return textures[i].textureArrayIndex;
}
}
return -1;
}
// Convert editor data into play data.
// NOTE: Textures need to be assigned with stored ones on build.
public static void ConvertEditorDataToPlayData(ref VA_AnimationBook book)
{
book.playData = new VA_AnimationBook.PlayData
{
fps = book.editorData.fps,
maxFrames = book.editorData.maxFrames,
materials = book.editorData.materials
};
foreach (var tg in book.editorData.textureGroups)
{
book.playData.textureGroups.Add(new VA_AnimationBook.PlayTextureGroup
{
shaderParamName = tg.shaderParamName,
textureType = tg.textureType
});
}
foreach (var ap in book.editorData.animationPages)
{
// NOTE: for some reason FixedString32 data gets lost when entering play mode.
// That is why this is here... and also the animationPages...
//book.playData.animations.Add(new VA_AnimationData
//{
// name = ap.name,
// frames = ap.frames,
// maxFrames = book.editorData.maxFrames,
// frameTime = 1.0f / book.editorData.maxFrames,
// duration = 1.0f / book.editorData.maxFrames * ap.frames,
// animationMapIndex = GetFirstAnimationMapIndex(in ap.textures, in book.editorData.textureGroups),
// colorMapIndex = GetFirstColorMapIndex(in ap.textures, in book.editorData.textureGroups)
//});
var pap = new VA_AnimationBook.PlayAnimationPage
{
name = ap.name,
frames = ap.frames,
textures = new List<VA_AnimationBook.PlayTextureEntry>()
};
foreach (var t in ap.textures)
{
pap.textures.Add(new VA_AnimationBook.PlayTextureEntry
{
textureArrayIndex = t.textureArrayIndex
});
}
book.playData.animationPages.Add(pap);
}
book.playData.texture2DArray = book.editorData.texture2DArray;
}
#endregion
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: f21cb651117dd1c4681e87105b7a3f10
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: