160 lines
5.2 KiB
C#
160 lines
5.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using UniGLTF;
|
|
using UnityEditor;
|
|
using UnityEditorInternal;
|
|
using UnityEngine;
|
|
|
|
|
|
namespace VRM
|
|
{
|
|
[CustomEditor(typeof(BlendShapeAvatar))]
|
|
public class BlendShapeAvatarEditor : PreviewEditor
|
|
{
|
|
ReorderableList m_clipList;
|
|
|
|
BlendShapeClipSelector m_selector;
|
|
|
|
SerializedBlendShapeEditor m_clipEditor;
|
|
|
|
protected override PreviewSceneManager.BakeValue GetBakeValue()
|
|
{
|
|
var clip = m_selector.Selected;
|
|
var value = new PreviewSceneManager.BakeValue();
|
|
if (clip != null)
|
|
{
|
|
value.BlendShapeBindings = clip.Values;
|
|
value.MaterialValueBindings = clip.MaterialValues;
|
|
value.Weight = 1.0f;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
void OnSelected(BlendShapeClip clip)
|
|
{
|
|
if (PreviewSceneManager == null)
|
|
{
|
|
m_clipEditor = null;
|
|
}
|
|
else if (clip != null)
|
|
{
|
|
m_clipEditor = new SerializedBlendShapeEditor(clip, PreviewSceneManager);
|
|
PreviewSceneManager.Bake(new PreviewSceneManager.BakeValue
|
|
{
|
|
BlendShapeBindings = clip.Values,
|
|
MaterialValueBindings = clip.MaterialValues,
|
|
Weight = 1.0f
|
|
});
|
|
}
|
|
else
|
|
{
|
|
m_clipEditor = null;
|
|
PreviewSceneManager.Bake(new PreviewSceneManager.BakeValue());
|
|
}
|
|
}
|
|
|
|
protected override void OnEnable()
|
|
{
|
|
m_selector = new BlendShapeClipSelector((BlendShapeAvatar)target, OnSelected);
|
|
|
|
var prop = serializedObject.FindProperty("Clips");
|
|
m_clipList = new ReorderableList(serializedObject, prop);
|
|
|
|
m_clipList.drawHeaderCallback = (rect) =>
|
|
EditorGUI.LabelField(rect, "BlendShapeClips");
|
|
|
|
m_clipList.elementHeight = BlendShapeClipDrawer.Height;
|
|
m_clipList.drawElementCallback = (rect, index, isActive, isFocused) =>
|
|
{
|
|
var element = prop.GetArrayElementAtIndex(index);
|
|
rect.height -= 4;
|
|
rect.y += 2;
|
|
EditorGUI.PropertyField(rect, element);
|
|
};
|
|
|
|
m_clipList.onAddCallback += (list) =>
|
|
{
|
|
// OpenFile dialog, create new BlendShapeClip
|
|
var dir = Path.GetDirectoryName(AssetDatabase.GetAssetPath(target));
|
|
var path = EditorUtility.SaveFilePanel(
|
|
"Create BlendShapeClip",
|
|
dir,
|
|
string.Format("BlendShapeClip#{0}.asset", list.count),
|
|
"asset");
|
|
BlendShapeClip clip = null;
|
|
if (!string.IsNullOrEmpty(path))
|
|
{
|
|
clip = BlendShapeAvatar.CreateBlendShapeClip(path.ToUnityRelativePath());
|
|
//clip.Prefab = AssetDatabase.LoadAssetAtPath<GameObject>(AssetDatabase.GetAssetPath(target));
|
|
}
|
|
|
|
// Add slot
|
|
prop.arraySize++;
|
|
// select last item
|
|
list.index = prop.arraySize - 1;
|
|
// get last item
|
|
var element = prop.GetArrayElementAtIndex(list.index);
|
|
element.objectReferenceValue = clip;
|
|
};
|
|
|
|
m_clipList.onSelectCallback += (list) =>
|
|
{
|
|
var a = list.serializedProperty;
|
|
var selected = a.GetArrayElementAtIndex(list.index);
|
|
OnSelected((BlendShapeClip)selected.objectReferenceValue);
|
|
};
|
|
|
|
//m_clipList.onCanRemoveCallback += list => true;
|
|
base.OnEnable();
|
|
|
|
OnSelected(m_selector.Selected);
|
|
}
|
|
|
|
int m_mode;
|
|
static readonly string[] MODES = new string[]{
|
|
"Editor",
|
|
"List"
|
|
};
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
serializedObject.Update();
|
|
|
|
base.OnInspectorGUI();
|
|
|
|
m_mode = GUILayout.Toolbar(m_mode, MODES);
|
|
switch (m_mode)
|
|
{
|
|
case 0:
|
|
m_selector.SelectGUI();
|
|
if (m_clipEditor != null)
|
|
{
|
|
Separator();
|
|
var result = m_clipEditor.Draw();
|
|
if (result.Changed)
|
|
{
|
|
PreviewSceneManager.Bake(new PreviewSceneManager.BakeValue
|
|
{
|
|
BlendShapeBindings = result.BlendShapeBindings,
|
|
MaterialValueBindings = result.MaterialValueBindings,
|
|
Weight = 1.0f,
|
|
});
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
m_clipList.DoLayoutList();
|
|
break;
|
|
|
|
default:
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
serializedObject.ApplyModifiedProperties();
|
|
}
|
|
}
|
|
}
|