A game about forced loneliness, made by TACStudios
1using System;
2using UnityEditor.U2D.Common;
3using UnityEditor.U2D.Layout;
4using UnityEngine;
5
6namespace UnityEditor.U2D.Animation
7{
8 internal class GenerateWeightsTool : MeshToolWrapper
9 {
10 private const float kWeightTolerance = 0.01f;
11 private SpriteMeshDataController m_SpriteMeshDataController = new SpriteMeshDataController();
12 private IWeightsGenerator m_WeightGenerator;
13 private GenerateWeightsPanel m_GenerateWeightsPanel;
14
15 internal override void OnCreate()
16 {
17 m_WeightGenerator = new BoundedBiharmonicWeightsGenerator();
18 }
19
20 public override void Initialize(LayoutOverlay layout)
21 {
22 base.Initialize(layout);
23
24 m_GenerateWeightsPanel = GenerateWeightsPanel.GenerateFromUXML();
25
26 layout.rightOverlay.Add(m_GenerateWeightsPanel);
27
28 BindElements();
29 m_GenerateWeightsPanel.SetHiddenFromLayout(true);
30 }
31
32 private void BindElements()
33 {
34 Debug.Assert(m_GenerateWeightsPanel != null);
35
36 m_GenerateWeightsPanel.onGenerateWeights += () =>
37 {
38 HandleWeights(GenerateWeights, TextContent.generateWeights);
39 };
40
41 m_GenerateWeightsPanel.onNormalizeWeights += () =>
42 {
43 HandleWeights(NormalizeWeights, TextContent.normalizeWeights);
44 };
45
46 m_GenerateWeightsPanel.onClearWeights += () =>
47 {
48 HandleWeights(ClearWeights, TextContent.clearWeights);
49 };
50 }
51
52 protected override void OnActivate()
53 {
54 base.OnActivate();
55 m_GenerateWeightsPanel.SetHiddenFromLayout(false);
56 skinningCache.events.skinningModeChanged.AddListener(OnModeChanged);
57 skinningCache.events.selectedSpriteChanged.AddListener(OnSpriteSelectionChanged);
58 m_GenerateWeightsPanel.Update(skinningCache.mode == SkinningMode.Character);
59 OnSpriteSelectionChanged(skinningCache.selectedSprite);
60 }
61
62 protected override void OnDeactivate()
63 {
64 base.OnDeactivate();
65 skinningCache.events.skinningModeChanged.RemoveListener(OnModeChanged);
66 skinningCache.events.selectedSpriteChanged.RemoveListener(OnSpriteSelectionChanged);
67 m_GenerateWeightsPanel.SetHiddenFromLayout(true);
68 }
69
70 void OnModeChanged(SkinningMode mode)
71 {
72 m_GenerateWeightsPanel.Update(mode == SkinningMode.Character);
73 }
74
75 void OnSpriteSelectionChanged(SpriteCache sprite)
76 {
77 m_GenerateWeightsPanel.generateButtonText = sprite != null ? TextContent.generate : TextContent.generateAll;
78 }
79
80 private void HandleWeights(Action<SpriteCache> action, string undoName)
81 {
82 using (skinningCache.UndoScope(undoName))
83 {
84 var selectedSprite = skinningCache.selectedSprite;
85 if (selectedSprite != null)
86 HandleWeightsForSprite(selectedSprite, action);
87 else
88 {
89 var sprites = skinningCache.GetSprites();
90
91 foreach (var sprite in sprites)
92 {
93 if (sprite.IsVisible())
94 HandleWeightsForSprite(sprite, action);
95 }
96 }
97 }
98 }
99
100 private void HandleWeightsForSprite(SpriteCache sprite, Action<SpriteCache> action)
101 {
102 Debug.Assert(sprite != null);
103
104 using (new DefaultPoseScope(skinningCache.GetEffectiveSkeleton(sprite)))
105 {
106 action(sprite);
107 }
108
109 skinningCache.events.meshChanged.Invoke(sprite.GetMesh());
110 }
111
112 private void GenerateWeights(SpriteCache sprite)
113 {
114 using (m_GenerateWeightsPanel.associateBones ? new AssociateBonesScope(sprite) : null)
115 {
116 m_SpriteMeshDataController.spriteMeshData = sprite.GetMesh();
117 m_SpriteMeshDataController.CalculateWeights(m_WeightGenerator, skinningCache.vertexSelection, kWeightTolerance);
118 m_SpriteMeshDataController.SortTrianglesByDepth();
119 }
120 }
121
122 private void NormalizeWeights(SpriteCache sprite)
123 {
124 m_SpriteMeshDataController.spriteMeshData = sprite.GetMesh();
125 m_SpriteMeshDataController.NormalizeWeights(skinningCache.vertexSelection);
126 m_SpriteMeshDataController.SortTrianglesByDepth();
127 }
128
129 private void ClearWeights(SpriteCache sprite)
130 {
131 m_SpriteMeshDataController.spriteMeshData = sprite.GetMesh();
132 m_SpriteMeshDataController.ClearWeights(skinningCache.vertexSelection);
133 }
134
135 protected override void OnGUI()
136 {
137 m_MeshPreviewBehaviour.showWeightMap = true;
138 m_MeshPreviewBehaviour.overlaySelected = true;
139 skeletonMode = SkeletonMode.EditPose;
140 meshMode = SpriteMeshViewMode.EditGeometry;
141 disableMeshEditor = true;
142 skeletonTool.skeletonStyle = SkeletonStyles.WeightMap;
143
144 DoSkeletonGUI();
145 DoMeshGUI();
146 }
147 }
148}