BITFALL/Assets/Plugins/CW/PaintIn3D/Examples/Scripts/P3dGenerateMask.cs

166 lines
5.4 KiB
C#
Raw Normal View History

using UnityEngine;
using UnityEngine.Events;
using System.Collections.Generic;
using CW.Common;
namespace PaintIn3D
{
/// <summary>This component can generate a mask texture from the specified mesh. This can be used with the <b>P3dPaintableTexture</b> component's <b>Advanced / LocalMask</b> setting.</summary>
//[ExecuteInEditMode]
[HelpURL(P3dCommon.HelpUrlPrefix + "P3dGenerateMask")]
[AddComponentMenu(P3dCommon.ComponentMenuPrefix + "Generate Mask")]
public class P3dGenerateMask : MonoBehaviour
{
public enum ApplyType
{
Manually,
Siblings,
SiblingsAndDescendants
}
[System.Serializable]
public class RenderTextureEvent : UnityEvent<RenderTexture> {}
/// <summary>The mask will be generated from this mesh.</summary>
public Mesh Mesh { set { mesh = value; } get { return mesh; } } [SerializeField] private Mesh mesh;
/// <summary>The mask will be generated from this submesh of the mesh.</summary>
public int Submesh { set { submesh = value; } get { return submesh; } } [SerializeField] private int submesh;
/// <summary>The texture channel of the mesh the mask will be generated from.</summary>
public P3dCoord Coord { set { coord = value; } get { return coord; } } [SerializeField] private P3dCoord coord;
/// <summary>The size of the generated texture.</summary>
public Vector2Int Size { set { size = value; } get { return size; } } [SerializeField] private Vector2Int size = new Vector2Int(512, 512);
/// <summary>The format of the generated texture.</summary>
public RenderTextureFormat Format { set { format = value; } get { return format; } } [SerializeField] private RenderTextureFormat format = RenderTextureFormat.R8;
/// <summary>Should the generated mask be automatically applied?
/// Manually = Use the <b>OnGenerated</b> event to apply the mask to specific components.
/// Siblings = The mask will be applied to all <b>P3dPaintableTexture</b> components on this GameObject.
/// SiblingsAndDescendants = Like <b>Siblings</b>, but also all child GameObjects.</summary>
public ApplyType ApplyTo { set { applyTo = value; } get { return applyTo; } } [SerializeField] private ApplyType applyTo = ApplyType.Siblings;
/// <summary>After the mask is generated, this event will be invoked.</summary>
public RenderTextureEvent OnGenerated { get { if (onGenerated == null) onGenerated = new RenderTextureEvent(); return onGenerated; } } [SerializeField] private RenderTextureEvent onGenerated;
[System.NonSerialized]
private RenderTexture generatedTexture;
private static List<P3dPaintableTexture> tempPaintableTextures = new List<P3dPaintableTexture>();
/// <summary>This allows you to access the generated texture.</summary>
public RenderTexture GeneratedTexture
{
get
{
return generatedTexture;
}
}
/// <summary>This method will destroy the generated texture.</summary>
[ContextMenu("Clear")]
public void Clear()
{
DestroyImmediate(generatedTexture);
generatedTexture = null;
}
/// <summary>This method will generate a mask texture based on the specified settings.</summary>
[ContextMenu("Generate")]
public RenderTexture Generate()
{
TryGenerate();
return generatedTexture;
}
public bool TryGenerate()
{
Clear();
if (size.x > 0 && size.y > 0)
{
generatedTexture = new RenderTexture(size.x, size.y, 0, format);
generatedTexture.name = "Generated Mask";
P3dCommandReplace.Blit(generatedTexture, default(Texture), Color.black);
P3dBlit.White(generatedTexture, mesh, submesh, coord);
if (applyTo != ApplyType.Manually)
{
if (applyTo == ApplyType.SiblingsAndDescendants)
{
GetComponentsInChildren(tempPaintableTextures);
}
else
{
GetComponents(tempPaintableTextures);
}
foreach (var tempPaintableTexture in tempPaintableTextures)
{
tempPaintableTexture.LocalMaskTexture = generatedTexture;
}
}
if (onGenerated != null)
{
onGenerated.Invoke(generatedTexture);
}
return true;
}
return false;
}
protected virtual void OnEnable()
{
Generate();
}
protected virtual void OnDisable()
{
Clear();
}
}
}
#if UNITY_EDITOR
namespace PaintIn3D
{
using UnityEditor;
using TARGET = P3dGenerateMask;
[CanEditMultipleObjects]
[CustomEditor(typeof(TARGET))]
public class P3dGenerateMask_Editor : CwEditor
{
protected override void OnInspector()
{
TARGET tgt; TARGET[] tgts; GetTargets(out tgt, out tgts);
BeginError(Any(tgts, t => t.Mesh == null));
Draw("mesh", "The mask will be generated from this mesh.");
EndError();
Draw("submesh", "The mask will be generated from this submesh of the mesh.");
Draw("coord", "The texture channel of the mesh the mask will be generated from.");
Draw("size", "The size of the generated texture.");
Draw("format", "The format of the generated texture.");
Draw("applyTo", "Should the generated mask be automatically applied?\n\nManually = Use the <b>OnGenerated</b> event to apply the mask to specific components.\n\nSiblings = The mask will be applied to all <b>P3dPaintableTexture</b> components on this GameObject.\n\nSiblingsAndDescendants = Like <b>Siblings</b>, but also all child GameObjects.");
BeginDisabled();
EditorGUI.ObjectField(Reserve(18), new GUIContent("Generated Texture", "This allows you to access the generated texture."), tgt.GeneratedTexture, typeof(Texture), false);
EndDisabled();
Separator();
Draw("onGenerated");
}
}
}
#endif