// Magica Cloth.
// Copyright (c) MagicaSoft, 2020-2022.
// https://magicasoft.jp
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace MagicaCloth
{
///
/// メッシュクロスのエディタ拡張
///
[CustomEditor(typeof(MagicaMeshCloth))]
public class MagicaMeshClothInspector : ClothEditor
{
protected override void OnEnable()
{
base.OnEnable();
}
public override void OnInspectorGUI()
{
MagicaMeshCloth scr = target as MagicaMeshCloth;
// データ状態
EditorInspectorUtility.DispVersionStatus(scr);
EditorInspectorUtility.DispDataStatus(scr);
serializedObject.Update();
// データ検証
if (EditorApplication.isPlaying == false)
VerifyData();
// モニターボタン
EditorInspectorUtility.MonitorButtonInspector();
// メイン
MainInspector();
// コライダー
ColliderInspector();
// スキニング
SkinningInspector();
// パラメータ
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorPresetUtility.DrawPresetButton(scr, scr.Params);
{
var cparam = serializedObject.FindProperty("clothParams");
if (EditorInspectorUtility.AlgorithmInspector(cparam, scr.HasChangedParam(ClothParams.ParamType.Algorithm), ConvertToLatestAlgorithmParameters))
scr.Params.SetChangeParam(ClothParams.ParamType.Algorithm);
if (EditorInspectorUtility.RadiusInspector(cparam))
scr.Params.SetChangeParam(ClothParams.ParamType.Radius);
if (EditorInspectorUtility.MassInspector(cparam))
scr.Params.SetChangeParam(ClothParams.ParamType.Mass);
if (EditorInspectorUtility.GravityInspector(cparam))
scr.Params.SetChangeParam(ClothParams.ParamType.Gravity);
if (EditorInspectorUtility.ExternalForceInspector(cparam))
scr.Params.SetChangeParam(ClothParams.ParamType.ExternalForce);
if (EditorInspectorUtility.DragInspector(cparam))
scr.Params.SetChangeParam(ClothParams.ParamType.Drag);
if (EditorInspectorUtility.MaxVelocityInspector(cparam))
scr.Params.SetChangeParam(ClothParams.ParamType.MaxVelocity);
if (EditorInspectorUtility.WorldInfluenceInspector(cparam, scr.HasChangedParam(ClothParams.ParamType.WorldInfluence)))
scr.Params.SetChangeParam(ClothParams.ParamType.WorldInfluence);
if (EditorInspectorUtility.DistanceDisableInspector(cparam, scr.HasChangedParam(ClothParams.ParamType.DistanceDisable)))
scr.Params.SetChangeParam(ClothParams.ParamType.DistanceDisable);
if (EditorInspectorUtility.ClampDistanceInspector(cparam, scr.HasChangedParam(ClothParams.ParamType.ClampDistance)))
scr.Params.SetChangeParam(ClothParams.ParamType.ClampDistance);
if (EditorInspectorUtility.ClampPositionInspector(cparam, false, scr.HasChangedParam(ClothParams.ParamType.ClampPosition)))
scr.Params.SetChangeParam(ClothParams.ParamType.ClampPosition);
if (EditorInspectorUtility.ClampRotationInspector(cparam, scr.HasChangedParam(ClothParams.ParamType.ClampRotation), scr.ClothData))
scr.Params.SetChangeParam(ClothParams.ParamType.ClampRotation);
if (EditorInspectorUtility.RestoreDistanceInspector(cparam, scr.HasChangedParam(ClothParams.ParamType.RestoreDistance)))
scr.Params.SetChangeParam(ClothParams.ParamType.RestoreDistance);
if (EditorInspectorUtility.RestoreRotationInspector(cparam, scr.HasChangedParam(ClothParams.ParamType.RestoreRotation), scr.ClothData))
scr.Params.SetChangeParam(ClothParams.ParamType.RestoreRotation);
if (EditorInspectorUtility.TriangleBendInspector(cparam, scr.HasChangedParam(ClothParams.ParamType.TriangleBend), scr.ClothData))
scr.Params.SetChangeParam(ClothParams.ParamType.TriangleBend);
//if (EditorInspectorUtility.VolumeInspector(cparam))
// scr.Params.SetChangeParam(ClothParams.ParamType.Volume);
if (EditorInspectorUtility.CollisionInspector(cparam, scr.HasChangedParam(ClothParams.ParamType.ColliderCollision)))
scr.Params.SetChangeParam(ClothParams.ParamType.ColliderCollision);
if (EditorInspectorUtility.PenetrationInspector(serializedObject, cparam, scr.HasChangedParam(ClothParams.ParamType.Penetration)))
scr.Params.SetChangeParam(ClothParams.ParamType.Penetration);
//if (EditorInspectorUtility.BaseSkinningInspector(serializedObject, cparam))
// scr.Params.SetChangeParam(ClothParams.ParamType.BaseSkinning);
if (EditorInspectorUtility.RotationInterpolationInspector(cparam, scr.HasChangedParam(ClothParams.ParamType.RotationInterpolation)))
scr.Params.SetChangeParam(ClothParams.ParamType.RotationInterpolation);
}
serializedObject.ApplyModifiedProperties();
// データ作成
if (EditorApplication.isPlaying == false)
{
EditorGUI.BeginDisabledGroup(CheckCreate() == false);
EditorGUILayout.Space();
EditorGUILayout.Space();
GUI.backgroundColor = Color.red;
if (GUILayout.Button("Create"))
{
Undo.RecordObject(scr, "CreateMeshCloth");
// 共有選択データが存在しない場合は作成する
if (scr.ClothSelection == null)
InitSelectorData();
BuildManager.CreateComponent(scr);
}
GUI.backgroundColor = Color.white;
EditorGUI.EndDisabledGroup();
}
else
{
EditorGUILayout.Space();
EditorGUILayout.Space();
GUI.backgroundColor = Color.blue;
if (GUILayout.Button("Reset Position"))
{
scr.ResetCloth();
}
GUI.backgroundColor = Color.white;
}
EditorGUILayout.Space();
}
//=========================================================================================
///
/// 作成を実行できるか判定する
///
///
protected override bool CheckCreate()
{
MagicaMeshCloth scr = target as MagicaMeshCloth;
if (PointSelector.EditEnable)
return false;
if (scr.Deformer == null)
return false;
if (scr.Deformer.VerifyData() != Define.Error.None)
return false;
if (scr.IsValidPointSelect() == false)
return false;
return true;
}
///
/// データ検証
///
private void VerifyData()
{
MagicaMeshCloth scr = target as MagicaMeshCloth;
if (scr.VerifyData() != Define.Error.None)
{
// 検証エラー
serializedObject.ApplyModifiedProperties();
}
}
//=========================================================================================
void MainInspector()
{
MagicaMeshCloth scr = target as MagicaMeshCloth;
EditorGUILayout.LabelField("Main Setup", EditorStyles.boldLabel);
// 仮想メッシュ
EditorGUILayout.PropertyField(serializedObject.FindProperty("virtualDeformer"));
EditorGUILayout.Space();
// チーム項目
TeamBasicInspector();
// ポイント選択
if (scr.Deformer != null)
{
EditorGUI.BeginDisabledGroup(scr.Deformer.VerifyData() != Define.Error.None);
DrawInspectorGUI(scr.Deformer);
EditorGUI.EndDisabledGroup();
}
EditorGUILayout.Space();
// カリング
CullingInspector();
}
//=============================================================================================
///
/// 選択データの初期化
/// 配列はすでに頂点数分が確保されゼロクリアされています。
///
///
protected override void OnResetSelector(List selectorData)
{
MagicaMeshCloth scr = target as MagicaMeshCloth;
// すでに選択クラスがある場合は内容をコピーする
if (scr.ClothSelection != null)
{
var sel = scr.ClothSelection.GetSelectionData(scr.Deformer.MeshData, scr.Deformer.GetRenderDeformerMeshList());
for (int i = 0; i < selectorData.Count; i++)
selectorData[i] = sel[i];
}
}
///
/// 選択データの決定
///
///
protected override void OnFinishSelector(List selectorData)
{
MagicaMeshCloth scr = target as MagicaMeshCloth;
// 必ず新規データを作成する(ヒエラルキーでのコピー対策)
var sel = CreateSelection(scr, "clothSelection");
// 選択データコピー
sel.SetSelectionData(scr.Deformer.MeshData, selectorData, scr.Deformer.GetRenderDeformerMeshList());
// 現在のデータと比較し差異がない場合は抜ける
if (scr.ClothSelection != null && scr.ClothSelection.Compare(sel))
return;
//if (scr.ClothSelection != null)
// Undo.RecordObject(scr.ClothSelection, "Set Selector");
// 保存
var cdata = serializedObject.FindProperty("clothSelection");
cdata.objectReferenceValue = sel;
serializedObject.ApplyModifiedProperties();
}
}
}