Singularity/Library/PackageCache/com.unity.2d.animation@7.0.10/Editor/SkinningModule/MeshPreviewTool/MeshPreviewTool.cs
2024-05-06 11:45:45 -07:00

348 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.U2D.Animation
{
internal class MeshPreviewTool : BaseTool
{
[SerializeField]
private Material m_Material;
private List<SpriteCache> m_Sprites;
private IMeshPreviewBehaviour m_DefaultPreviewBehaviour = new DefaultPreviewBehaviour();
public IMeshPreviewBehaviour previewBehaviourOverride { get; set; }
public override IMeshPreviewBehaviour previewBehaviour
{
get
{
if (previewBehaviourOverride != null)
return previewBehaviourOverride;
return m_DefaultPreviewBehaviour;
}
}
internal override void OnCreate()
{
m_Material = new Material(Shader.Find("Hidden/SkinningModule-GUITextureClip"));
m_Material.hideFlags = HideFlags.DontSave;
}
internal override void OnDestroy()
{
base.OnDestroy();
Debug.Assert(m_Material != null);
DestroyImmediate(m_Material);
}
protected override void OnActivate()
{
m_Sprites = new List<SpriteCache>(skinningCache.GetSprites());
DirtyMeshesAll();
skinningCache.events.meshChanged.AddListener(MeshChanged);
skinningCache.events.characterPartChanged.AddListener(CharacterPartChanged);
skinningCache.events.skeletonPreviewPoseChanged.AddListener(SkeletonChanged);
skinningCache.events.skeletonBindPoseChanged.AddListener(SkeletonChanged);
skinningCache.events.skinningModeChanged.AddListener(SkinningModuleModeChanged);
skinningCache.events.boneColorChanged.AddListener(BoneColorChanged);
}
protected override void OnDeactivate()
{
skinningCache.events.meshChanged.RemoveListener(MeshChanged);
skinningCache.events.skeletonPreviewPoseChanged.RemoveListener(SkeletonChanged);
skinningCache.events.skeletonBindPoseChanged.RemoveListener(SkeletonChanged);
skinningCache.events.skinningModeChanged.RemoveListener(SkinningModuleModeChanged);
skinningCache.events.boneColorChanged.RemoveListener(BoneColorChanged);
}
protected override void OnGUI()
{
Prepare();
if (Event.current.type == EventType.Repaint)
DrawSpriteMeshes();
}
public void DrawOverlay()
{
if (Event.current.type != EventType.Repaint)
return;
if (skinningCache.mode == SkinningMode.SpriteSheet)
{
foreach (var sprite in m_Sprites)
{
if (previewBehaviour.Overlay(sprite))
DrawSpriteMesh(sprite);
}
}
else
{
var character = skinningCache.character;
Debug.Assert(character != null);
var parts = character.parts;
foreach (var part in parts)
{
if (part.isVisible && previewBehaviour.Overlay(part.sprite))
DrawSpriteMesh(part.sprite);
}
}
}
public void OverlayWireframe()
{
if (Event.current.type != EventType.Repaint)
return;
foreach (var sprite in m_Sprites)
if (previewBehaviour.OverlayWireframe(sprite))
DrawWireframe(sprite);
}
private void CharacterPartChanged(CharacterPartCache characterPart)
{
var meshPreview = characterPart.sprite.GetMeshPreview();
Debug.Assert(meshPreview != null);
meshPreview.SetSkinningDirty();
}
private void MeshChanged(MeshCache mesh)
{
var meshPreview = mesh.sprite.GetMeshPreview();
Debug.Assert(meshPreview != null);
meshPreview.SetMeshDirty();
}
private void SkeletonChanged(SkeletonCache skeleton)
{
DirtySkinningAll();
}
private void SkinningModuleModeChanged(SkinningMode mode)
{
DirtyMeshesAll();
}
private void BoneColorChanged(BoneCache bone)
{
DirtyColorsAll();
}
private void DirtyColorsAll()
{
foreach (var sprite in m_Sprites)
{
var meshPreview = sprite.GetMeshPreview();
if (meshPreview != null)
meshPreview.SetColorsDirty();
}
}
private void DirtyMeshesAll()
{
foreach (var sprite in m_Sprites)
{
var meshPreview = sprite.GetMeshPreview();
if (meshPreview != null)
meshPreview.SetMeshDirty();
}
}
private void DirtySkinningAll()
{
foreach (var sprite in m_Sprites)
{
var meshPreview = sprite.GetMeshPreview();
Debug.Assert(meshPreview != null);
meshPreview.SetSkinningDirty();
}
}
private void Prepare()
{
foreach (var sprite in m_Sprites)
{
var meshPreview = sprite.GetMeshPreview();
Debug.Assert(meshPreview != null);
meshPreview.enableSkinning = true;
meshPreview.Prepare();
}
}
private void DrawDefaultSpriteMeshes()
{
Debug.Assert(Event.current.type == EventType.Repaint);
if (skinningCache.mode == SkinningMode.SpriteSheet)
{
foreach (var sprite in m_Sprites)
DrawDefaultSpriteMesh(sprite);
}
else
{
var character = skinningCache.character;
Debug.Assert(character != null);
var parts = character.parts;
foreach (var part in parts)
{
if (part.isVisible)
DrawDefaultSpriteMesh(part.sprite);
}
}
}
private void DrawDefaultSpriteMesh(SpriteCache sprite)
{
Debug.Assert(m_Material != null);
var meshPreview = sprite.GetMeshPreview();
var meshCache = sprite.GetMesh();
var skeleton = skinningCache.GetEffectiveSkeleton(sprite);
Debug.Assert(meshPreview != null);
if (meshPreview.canSkin == false || skeleton.isPosePreview == false)
{
m_Material.mainTexture = meshCache.textureDataProvider.texture;
m_Material.SetFloat("_Opacity", 1f);
m_Material.SetFloat("_VertexColorBlend", 0f);
m_Material.color = new Color(1f, 1f, 1f, 1f);
DrawingUtility.DrawMesh(meshPreview.defaultMesh, m_Material, sprite.GetLocalToWorldMatrixFromMode());
}
}
private void DrawSpriteMeshes()
{
Debug.Assert(Event.current.type == EventType.Repaint);
if (skinningCache.mode == SkinningMode.SpriteSheet)
{
foreach (var sprite in m_Sprites)
{
if (previewBehaviour.Overlay(sprite))
continue;
DrawSpriteMesh(sprite);
}
}
else
{
var character = skinningCache.character;
Debug.Assert(character != null);
var parts = character.parts;
var selected = skinningCache.selectedSprite;
var selectedVisible = false;
foreach (var part in parts)
{
if (previewBehaviour.Overlay(part.sprite))
continue;
if (part.sprite == selected)
selectedVisible = part.isVisible;
else if (part.isVisible)
DrawSpriteMesh(part.sprite);
}
if (selectedVisible && selected != null)
DrawSpriteMesh(selected);
}
}
private void DrawSpriteMesh(SpriteCache sprite)
{
var weightMapOpacity = previewBehaviour.GetWeightMapOpacity(sprite);
DrawSpriteMesh(sprite, weightMapOpacity);
if (previewBehaviour.DrawWireframe(sprite))
DrawWireframe(sprite);
}
private void DrawSpriteMesh(SpriteCache sprite, float weightMapOpacity)
{
Debug.Assert(m_Material != null);
var meshPreview = sprite.GetMeshPreview();
var meshCache = sprite.GetMesh();
Debug.Assert(meshPreview != null);
if (meshPreview.mesh == null || meshPreview.mesh.vertexCount == 0)
{
DrawDefaultSpriteMesh(sprite);
}
else
{
m_Material.mainTexture = meshCache.textureDataProvider.texture;
m_Material.SetFloat("_Opacity", 1f);
m_Material.SetFloat("_VertexColorBlend", weightMapOpacity);
m_Material.color = Color.white;
DrawingUtility.DrawMesh(meshPreview.mesh, m_Material, sprite.GetLocalToWorldMatrixFromMode());
}
}
private void DrawSelectedSpriteWeightMap()
{
var selectedSprite = skinningCache.selectedSprite;
if (selectedSprite != null)
{
var opacity = GetWeightOpacityFromCurrentTool();
if (opacity > 0f)
DrawSpriteMesh(selectedSprite, opacity);
}
}
private float GetWeightOpacityFromCurrentTool()
{
return IsWeightTool() ? VisibilityToolSettings.meshOpacity : 0f;
}
private bool IsWeightTool()
{
var currentTool = skinningCache.selectedTool;
if (currentTool == skinningCache.GetTool(Tools.WeightSlider) ||
currentTool == skinningCache.GetTool(Tools.WeightBrush) ||
currentTool == skinningCache.GetTool(Tools.BoneInfluence) ||
currentTool == skinningCache.GetTool(Tools.SpriteInfluence) ||
currentTool == skinningCache.GetTool(Tools.GenerateWeights))
return true;
return false;
}
private void DrawWireframe(SpriteCache sprite)
{
Debug.Assert(Event.current.type == EventType.Repaint);
Debug.Assert(sprite != null);
var meshPreview = sprite.GetMeshPreview();
Debug.Assert(meshPreview != null);
m_Material.mainTexture = null;
m_Material.SetFloat("_Opacity", 0.35f);
m_Material.SetFloat("_VertexColorBlend", 0f);
m_Material.color = Color.white;
GL.wireframe = true;
DrawingUtility.DrawMesh(meshPreview.mesh, m_Material, sprite.GetLocalToWorldMatrixFromMode());
GL.wireframe = false;
}
}
}