You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
6.9 KiB
C#

/******************************************************************************/
/*
Project - MudBun
Publisher - Long Bunny Labs
http://LongBunnyLabs.com
Author - Ming-Lun "Allen" Chou
http://AllenChou.net
*/
/******************************************************************************/
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace MudBun
{
[CustomEditor(typeof(MudRenderer), true)]
[CanEditMultipleObjects]
public class MudRendererEditor : MudRendererBaseEditor
{
protected override void LockMesh()
{
base.LockMesh();
foreach (var renderer in targets.Select(x => (MudRenderer) x))
{
if (renderer == null)
continue;
if (renderer.MeshLocked)
continue;
DoLockMesh(renderer.transform, renderer.RecursiveLockMeshByEditor);
}
}
private void DoLockMesh(Transform t, bool recursive, int depth = 0)
{
if (t == null)
return;
if (recursive)
{
for (int i = 0; i < t.childCount; ++i)
DoLockMesh(t.GetChild(i), recursive, depth + 1);
}
var renderer = t.GetComponent<MudRenderer>();
if (renderer == null || !renderer.isActiveAndEnabled)
return;
bool createNewObject = MeshGenerationCreateNewObject.boolValue;
bool autoRigging = MeshGenerationAutoRigging.boolValue;
bool generateCollider = MeshGenerationCreateCollider.boolValue;
bool generateColliderMeshAsset = GenerateColliderMeshAssetByEditor.boolValue;
bool generateMeshAsset = GenerateMeshAssetByEditor.boolValue;
var prevMeshGenerationRenderableMeshMode = renderer.MeshGenerationRenderableMeshMode;
if (createNewObject)
renderer.MeshGenerationRenderableMeshMode = MudRendererBase.RenderableMeshMode.MeshRenderer;
renderer.MarkNeedsCompute();
bool optimizeMeshForRendering = !GenerateMeshAssetByEditor.boolValue; // generated mesh assets are automatically optimized by the import pipeline
renderer.LockMesh(autoRigging, false, null, MeshGenerationGenerateTextureUV.boolValue, MeshGenerationGenerateLightMapUV.boolValue, MeshGenerationWeldVertices.boolValue, optimizeMeshForRendering);
if (createNewObject)
renderer.MeshGenerationRenderableMeshMode = prevMeshGenerationRenderableMeshMode;
// finish all access to serialized properties before they get disposed upon asset database refresh
if (generateCollider)
{
var colliderMesh = renderer.AddCollider(renderer.gameObject, false, null, MeshGenerationForceConvexCollider.boolValue, MeshGenerationCreateRigidBody.boolValue);
if (colliderMesh != null
&& generateColliderMeshAsset)
{
renderer.ValidateAssetNames();
string rootFolder = "Assets";
string assetsFolder = "MudBun Generated Assets";
string folderPath = $"{rootFolder}/{assetsFolder}";
string assetName = renderer.GenerateColliderMeshAssetByEditorName;
if (!AssetDatabase.IsValidFolder(folderPath))
AssetDatabase.CreateFolder(rootFolder, assetsFolder);
string meshAssetPath = $"{folderPath}/{assetName}.mesh";
AssetDatabase.CreateAsset(colliderMesh, meshAssetPath);
AssetDatabase.Refresh();
Debug.Log($"MudBun: Saved collider mesh asset - \"{folderPath}/{assetName}.mesh\"");
}
}
if (generateMeshAsset)
{
renderer.ValidateAssetNames();
string rootFolder = "Assets";
string assetsFolder = "MudBun Generated Assets";
string folderPath = $"{rootFolder}/{assetsFolder}";
string assetName = renderer.GenerateMeshAssetByEditorName;
if (!AssetDatabase.IsValidFolder(folderPath))
AssetDatabase.CreateFolder(rootFolder, assetsFolder);
Mesh mesh = null;
Material mat = null;
var meshFilter = renderer.GetComponent<MeshFilter>();
var meshRenderer = renderer.GetComponent<MeshRenderer>();
var skinnedMeshRenderer = renderer.GetComponent<SkinnedMeshRenderer>();
if (meshRenderer != null)
{
if (meshFilter != null)
{
mesh = meshFilter.sharedMesh;
}
mat = meshRenderer.sharedMaterial;
}
else if (skinnedMeshRenderer != null)
{
mesh = skinnedMeshRenderer.sharedMesh;
mat = skinnedMeshRenderer.sharedMaterial;
}
if (mesh != null)
{
string meshAssetPath = $"{folderPath}/{assetName}.mesh";
AssetDatabase.CreateAsset(mesh, meshAssetPath);
AssetDatabase.Refresh();
Debug.Log($"MudBun: Saved mesh asset - \"{folderPath}/{assetName}.mesh\"");
// somehow serialized properties get invalidated after asset database operations
InitSerializedProperties();
var savedMesh = AssetDatabase.LoadAssetAtPath<Mesh>(meshAssetPath);
if (savedMesh != null)
{
if (meshFilter != null)
meshFilter.sharedMesh = savedMesh;
}
}
if (mat != null)
{
if (meshRenderer != null)
meshRenderer.sharedMaterial = mat;
else if (skinnedMeshRenderer != null)
skinnedMeshRenderer.sharedMaterial = mat;
}
}
if (depth == 0
&& createNewObject)
{
var clone = Instantiate(renderer.gameObject);
clone.name = renderer.name + " (Locked Mesh Clone)";
if (autoRigging)
{
var cloneRenderer = clone.GetComponent<MudRenderer>();
cloneRenderer.RescanBrushesImmediate();
cloneRenderer.DestroyAllBrushesImmediate();
}
else
{
DestroyAllChildren(clone.transform);
}
Undo.RegisterCreatedObjectUndo(clone, clone.name);
DestroyImmediate(clone.GetComponent<MudRenderer>());
Selection.activeObject = clone;
renderer.UnlockMesh();
}
}
protected override void GenerateSdf()
{
var renderer = (MudRendererBase)target;
if (renderer == null)
return;
renderer.ValidateAssetNames();
string rootFolder = "Assets";
string assetsFolder = "MudBun Generated Assets";
string folderPath = $"{rootFolder}/{assetsFolder}";
string assetName = renderer.GenerateSdfByEditorName;
if (!AssetDatabase.IsValidFolder(folderPath))
AssetDatabase.CreateFolder(rootFolder, assetsFolder);
Vector3Int size = GenerateSdfTextureSize.vector3IntValue;
var sdf = new Texture3D(size.x, size.y, size.z, TextureFormat.RFloat, false);
renderer.GenerateSdf(sdf, GenerateSdfCenter.vector3Value, GenerateSdfDimension.vector3Value);
string sdfAssetPath = $"{folderPath}/{assetName}.asset";
AssetDatabase.CreateAsset(sdf, sdfAssetPath);
AssetDatabase.Refresh();
renderer.MarkNeedsCompute();
Debug.Log($"MudBun: Saved SDF texture - \"{folderPath}/{assetName}.asset\"");
}
}
}