A game about forced loneliness, made by TACStudios
at master 12 kB view raw
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using UnityEditor.U2D.Sprites; 5using UnityEditorInternal; 6using UnityEngine; 7using UnityEngine.UIElements; 8using Object = UnityEngine.Object; 9 10namespace UnityEditor.U2D.Common 11{ 12 internal class ImagePackerDebugEditor : EditorWindow 13 { 14 [MenuItem("internal:Window/2D/Common/Image Packer Debug Editor")] 15 static void Launch() 16 { 17 var window = EditorWindow.GetWindow<ImagePackerDebugEditor>(); 18 var pos = window.position; 19 pos.height = pos.width = 400; 20 window.position = pos; 21 window.Show(); 22 } 23 24 ReorderableList m_ReorderableList; 25 ImagePacker.ImagePackRect[] m_PackingRect = null; 26 List<RectInt> m_PackRects = new List<RectInt>(); 27 RectInt[] m_PackResult = null; 28 SpriteRect[] m_SpriteRects = null; 29 Texture2D m_Texture; 30 int m_TextureActualWidth = 0; 31 int m_TextureActualHeight = 0; 32 int m_PackWidth = 0; 33 int m_PackHeight = 0; 34 int m_Padding = 0; 35 Vector2 m_ConfigScroll = Vector2.zero; 36 float m_Zoom = 1; 37 IMGUIContainer m_PackArea; 38 int m_PackStep = -1; 39 protected const float k_MinZoomPercentage = 0.9f; 40 protected const float k_WheelZoomSpeed = 0.03f; 41 protected const float k_MouseZoomSpeed = 0.005f; 42 43 void OnEnable() 44 { 45 var visualContainer = new VisualElement() 46 { 47 name = "Container", 48 style = 49 { 50 flexGrow = 1, 51 flexDirection = FlexDirection.Row 52 } 53 }; 54 this.rootVisualElement.Add(visualContainer); 55 56 var imgui = new IMGUIContainer(OnConfigGUI) 57 { 58 name = "Config", 59 style = 60 { 61 width = 300 62 } 63 }; 64 65 visualContainer.Add(imgui); 66 67 m_PackArea = new IMGUIContainer(OnImagePackerGUI) 68 { 69 name = "ImagePacker", 70 style = 71 { 72 flexGrow = 1, 73 } 74 }; 75 visualContainer.Add(m_PackArea); 76 SetupConfigGUI(); 77 } 78 79 void SetupConfigGUI() 80 { 81 m_ReorderableList = new ReorderableList(m_PackRects, typeof(RectInt), false, false, true, true); 82 m_ReorderableList.elementHeightCallback = (int index) => 83 { 84 return EditorGUIUtility.singleLineHeight * 2 + 6; 85 }; 86 m_ReorderableList.drawElementCallback = DrawListElement; 87 88 m_ReorderableList.onAddCallback = (list) => 89 { 90 m_PackRects.Add(new RectInt()); 91 }; 92 m_ReorderableList.onRemoveCallback = (list) => 93 { 94 m_PackRects.RemoveAt(list.index); 95 }; 96 } 97 98 void DrawListElement(Rect rect, int index, bool isactive, bool isfocused) 99 { 100 var rectInt = m_PackRects[index]; 101 var name = m_SpriteRects == null || index >= m_SpriteRects.Length ? index.ToString() : m_SpriteRects[index]. 102 name; 103 rectInt.size = EditorGUI.Vector2IntField(rect, name, rectInt.size); 104 m_PackRects[index] = rectInt; 105 } 106 107 void OnConfigGUI() 108 { 109 EditorGUILayout.BeginVertical(); 110 m_ConfigScroll = EditorGUILayout.BeginScrollView(m_ConfigScroll); 111 m_ReorderableList.DoLayoutList(); 112 EditorGUILayout.EndScrollView(); 113 GUILayout.FlexibleSpace(); 114 115 m_PackStep = EditorGUILayout.IntSlider("Step", m_PackStep, 0, m_PackRects.Count); 116 EditorGUI.BeginChangeCheck(); 117 m_Texture = EditorGUILayout.ObjectField(new GUIContent("Texture"), (Object)m_Texture, typeof(Texture2D), false) as Texture2D; 118 if (EditorGUI.EndChangeCheck()) 119 UpdateSpriteRect(); 120 m_Padding = EditorGUILayout.IntField("Padding", m_Padding); 121 EditorGUILayout.BeginHorizontal(); 122 if (GUILayout.Button("<<")) 123 { 124 m_PackStep = m_PackStep <= 0 ? 0 : m_PackStep - 1; 125 Pack(); 126 } 127 if (GUILayout.Button("Pack")) 128 Pack(); 129 if (GUILayout.Button(">>")) 130 { 131 m_PackStep = m_PackStep > m_PackRects.Count ? m_PackRects.Count : m_PackStep + 1; 132 Pack(); 133 } 134 if (GUILayout.Button("Clear")) 135 { 136 m_PackRects.Clear(); 137 m_Texture = null; 138 m_PackingRect = null; 139 m_PackResult = null; 140 m_SpriteRects = null; 141 } 142 143 EditorGUILayout.EndHorizontal(); 144 EditorGUILayout.EndVertical(); 145 } 146 147 void UpdateSpriteRect() 148 { 149 var dataProvider = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(m_Texture)) as ISpriteEditorDataProvider; 150 if (dataProvider == null) 151 return; 152 dataProvider.InitSpriteEditorDataProvider(); 153 dataProvider.GetDataProvider<ITextureDataProvider>().GetTextureActualWidthAndHeight(out m_TextureActualWidth, out m_TextureActualHeight); 154 m_SpriteRects = dataProvider.GetDataProvider<ISpriteEditorDataProvider>().GetSpriteRects(); 155 m_PackRects.Clear(); 156 m_PackRects.AddRange(m_SpriteRects.Select(x => new RectInt((int)x.rect.x, (int)x.rect.y, (int)x.rect.width, (int)x.rect.height))); 157 m_PackResult = null; 158 m_PackStep = m_PackRects.Count; 159 } 160 161 void Pack() 162 { 163 int count = m_PackStep > 0 && m_PackStep < m_PackRects.Count ? m_PackStep : m_PackRects.Count; 164 m_PackingRect = new ImagePacker.ImagePackRect[m_PackRects.Count]; 165 for (int i = 0; i < m_PackRects.Count; ++i) 166 { 167 m_PackingRect[i] = new ImagePacker.ImagePackRect() 168 { 169 rect = m_PackRects[i], 170 index = i 171 }; 172 } 173 Array.Sort(m_PackingRect); 174 ImagePacker.Pack(m_PackingRect.Take(count).Select(x => x.rect).ToArray(), m_Padding, out m_PackResult, out m_PackWidth, out m_PackHeight); 175 } 176 177 void DrawLabel(Rect rect, string label) 178 { 179 rect.position = Handles.matrix.MultiplyPoint(rect.position); 180 GUI.Label(rect, label); 181 } 182 183 void OnImagePackerGUI() 184 { 185 if (m_PackResult == null) 186 return; 187 HandleZoom(); 188 var oldMatrix = Handles.matrix; 189 SetupHandlesMatrix(); 190 Handles.DrawSolidRectangleWithOutline(new Rect(0, 0, m_PackWidth, m_PackHeight), Color.gray, Color.black); 191 DrawLabel(new Rect(0, 0, m_PackWidth, m_PackHeight), m_PackWidth + "x" + m_PackHeight); 192 193 int index = 0; 194 195 foreach (var rect in m_PackResult) 196 { 197 Handles.DrawSolidRectangleWithOutline(new Rect(rect.x, rect.y, rect.width, rect.height), Color.white, Color.black); 198 var rect1 = new Rect(rect.x, rect.y + rect.height * 0.5f, rect.width, EditorGUIUtility.singleLineHeight); 199 DrawLabel(rect1, m_PackingRect[index].index.ToString()); 200 ++index; 201 } 202 203 index = 0; 204 if (m_Texture != null && m_SpriteRects != null) 205 { 206 var material = new Material(Shader.Find("Sprites/Default")); 207 material.mainTexture = m_Texture; 208 material.SetPass(0); 209 210 int mouseOverIndex = -1; 211 GL.PushMatrix(); 212 GL.LoadIdentity(); 213 GL.MultMatrix(GUI.matrix * Handles.matrix); 214 GL.Begin(GL.QUADS); 215 for (int i = 0; i < m_PackResult.Length; ++i) 216 { 217 index = m_PackingRect[i].index; 218 if (index >= m_SpriteRects.Length) 219 continue; 220 var rect = m_PackResult[i]; 221 GL.TexCoord(new Vector3(m_SpriteRects[index].rect.x / m_TextureActualWidth, m_SpriteRects[index].rect.y / m_TextureActualHeight, 0)); 222 GL.Vertex(new Vector3(rect.x, rect.y, 0)); 223 GL.TexCoord(new Vector3(m_SpriteRects[index].rect.xMax / m_TextureActualWidth, m_SpriteRects[index].rect.y / m_TextureActualHeight, 0)); 224 GL.Vertex(new Vector3(rect.x + rect.width, rect.y, 0)); 225 GL.TexCoord(new Vector3(m_SpriteRects[index].rect.xMax / m_TextureActualWidth, m_SpriteRects[index].rect.yMax / m_TextureActualHeight, 0)); 226 GL.Vertex(new Vector3(rect.x + rect.width, rect.y + rect.height, 0)); 227 GL.TexCoord(new Vector3(m_SpriteRects[index].rect.x / m_TextureActualWidth, m_SpriteRects[index].rect.yMax / m_TextureActualHeight, 0)); 228 GL.Vertex(new Vector3(rect.x, rect.y + rect.height, 0)); 229 var m = Handles.matrix.inverse.MultiplyPoint(Event.current.mousePosition); 230 if (rect.Contains(new Vector2Int((int)m.x, (int)m.y))) 231 { 232 mouseOverIndex = index; 233 } 234 ++index; 235 } 236 237 GL.End(); 238 GL.PopMatrix(); 239 if (mouseOverIndex >= 0) 240 { 241 var text = new GUIContent(m_SpriteRects[mouseOverIndex].name + " " + index); 242 var length = EditorStyles.textArea.CalcSize(text); 243 var rect1 = new Rect(m_PackResult[mouseOverIndex].x, m_PackResult[mouseOverIndex].y + m_PackResult[mouseOverIndex].height * 0.5f, length.x, length.y); 244 rect1.position = Handles.matrix.MultiplyPoint(rect1.position); 245 if (Event.current.type == EventType.Repaint) 246 EditorStyles.textArea.Draw(rect1, text, false, false, false, false); 247 } 248 } 249 250 Handles.matrix = oldMatrix; 251 } 252 253 void SetupHandlesMatrix() 254 { 255 Vector3 handlesPos = new Vector3(0, m_PackHeight * m_Zoom, 0f); 256 Vector3 handlesScale = new Vector3(m_Zoom, -m_Zoom, 1f); 257 Handles.matrix = Matrix4x4.TRS(handlesPos, Quaternion.identity, handlesScale); 258 } 259 260 protected void HandleZoom() 261 { 262 bool zoomMode = Event.current.alt && Event.current.button == 1; 263 if (zoomMode) 264 { 265 EditorGUIUtility.AddCursorRect(m_PackArea.worldBound, MouseCursor.Zoom); 266 } 267 268 if ( 269 ((Event.current.type == EventType.MouseUp || Event.current.type == EventType.MouseDown) && zoomMode) || 270 ((Event.current.type == EventType.KeyUp || Event.current.type == EventType.KeyDown) && Event.current.keyCode == KeyCode.LeftAlt) 271 ) 272 { 273 Repaint(); 274 } 275 276 if (Event.current.type == EventType.ScrollWheel || (Event.current.type == EventType.MouseDrag && Event.current.alt && Event.current.button == 1)) 277 { 278 float zoomMultiplier = 1f - Event.current.delta.y * (Event.current.type == EventType.ScrollWheel ? k_WheelZoomSpeed : -k_MouseZoomSpeed); 279 280 // Clamp zoom 281 float wantedZoom = m_Zoom * zoomMultiplier; 282 283 float currentZoom = Mathf.Clamp(wantedZoom, GetMinZoom(), 1); 284 285 if (currentZoom != m_Zoom) 286 { 287 m_Zoom = currentZoom; 288 Event.current.Use(); 289 } 290 } 291 } 292 293 protected float GetMinZoom() 294 { 295 if (m_Texture == null) 296 return 1.0f; 297 return Mathf.Min(m_PackArea.worldBound.width / m_PackWidth, m_PackArea.worldBound.height / m_PackHeight, 0.05f) * k_MinZoomPercentage; 298 } 299 } 300}