123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- using UnityEditor;
- using UnityEngine;
- using UnityEditor.Sprites;
- using System.Collections;
- using System.Collections.Generic;
-
- namespace UnityEditor.U2D
- {
- internal static class EditorSpriteGUIUtility
- {
- public enum FitMode
- {
- BestFit,
- FitHorizontal,
- FitVertical,
- Fill,
- Tiled
- }
-
- private static Material s_SpriteMaterial;
- public static Material spriteMaterial
- {
- get
- {
- if (s_SpriteMaterial == null)
- {
- s_SpriteMaterial = new Material(Shader.Find("Hidden/InternalSpritesInspector"));
- s_SpriteMaterial.hideFlags = HideFlags.DontSave;
- }
- s_SpriteMaterial.SetFloat("_AdjustLinearForGamma", PlayerSettings.colorSpace == ColorSpace.Linear ? 1.0f : 0.0f);
- return s_SpriteMaterial;
- }
- }
-
- public static Texture GetOriginalSpriteTexture(Sprite sprite)
- {
- return UnityEditor.Sprites.SpriteUtility.GetSpriteTexture(sprite, false);
- }
-
- public static Vector2[] GetOriginalSpriteUvs(Sprite sprite)
- {
- return UnityEditor.Sprites.SpriteUtility.GetSpriteUVs(sprite, false);
- }
-
- public static void DrawSpriteInRectPrepare(Rect rect, Sprite sprite, FitMode fitMode, bool excludeBorders, bool forceQuad, Mesh mesh)
- {
- var vertices = new List<Vector3>();
- var uvs = new List<Vector2>();
- var indices = new List<int>();
- mesh.Clear();
-
- if (!sprite)
- {
- mesh.UploadMeshData(false);
- return;
- }
-
- Vector2 scale = Vector2.one;
- Rect spriteRect = sprite.textureRect;
- Vector2 bottomLeftBorderOffset = sprite.rect.position + new Vector2(sprite.border.x, sprite.border.y) - spriteRect.position;
- Vector2 topRightBorderOffset = new Vector2(sprite.border.z, sprite.border.w) + (spriteRect.position + spriteRect.size) - (sprite.rect.position + sprite.rect.size);
-
- if (excludeBorders)
- {
- forceQuad = true;
- spriteRect.position = spriteRect.position + bottomLeftBorderOffset;
- spriteRect.size = spriteRect.size - bottomLeftBorderOffset - topRightBorderOffset;
- }
-
- bool tiled = false;
-
- if (fitMode == FitMode.Tiled)
- {
- tiled = true;
- forceQuad = true;
- fitMode = FitMode.BestFit;
- }
-
- if (fitMode == FitMode.BestFit)
- {
- float spriteRatio = spriteRect.width / spriteRect.height;
- float frameRatio = rect.width / rect.height;
-
- if (spriteRatio < frameRatio)
- fitMode = FitMode.FitVertical;
- else
- fitMode = FitMode.FitHorizontal;
- }
-
- if (fitMode == FitMode.FitHorizontal)
- scale = Vector2.one * (rect.width / spriteRect.width);
-
- if (fitMode == FitMode.FitVertical)
- scale = Vector2.one * (rect.height / spriteRect.height);
-
- if (fitMode == FitMode.Fill)
- {
- scale.x = rect.width / spriteRect.width;
- scale.y = rect.height / spriteRect.height;
- }
-
- Texture spriteTexture = GetOriginalSpriteTexture(sprite);
- if (spriteTexture == null)
- return;
-
- if (forceQuad)
- {
- Vector2 uvScale = new Vector2(1f / spriteTexture.width, 1f / spriteTexture.height);
- Vector2 uvPos = Vector2.Scale(spriteRect.position, uvScale);
- Vector2 uvSize = Vector2.Scale(spriteRect.size, uvScale);
- Vector2 uv0 = uvPos;
- Vector2 uv1 = uvPos + Vector2.up * uvSize.y;
- Vector2 uv2 = uvPos + Vector2.right * uvSize.x;
- Vector2 uv3 = uvPos + uvSize;
- Vector3 v0 = new Vector3(uv0.x * spriteTexture.width - spriteRect.position.x - spriteRect.width * 0.5f, uv0.y * spriteTexture.height - spriteRect.position.y - spriteRect.height * 0.5f, 0f);
- Vector3 v1 = new Vector3(uv1.x * spriteTexture.width - spriteRect.position.x - spriteRect.width * 0.5f, uv1.y * spriteTexture.height - spriteRect.position.y - spriteRect.height * 0.5f, 0f);
- Vector3 v2 = new Vector3(uv2.x * spriteTexture.width - spriteRect.position.x - spriteRect.width * 0.5f, uv2.y * spriteTexture.height - spriteRect.position.y - spriteRect.height * 0.5f, 0f);
- Vector3 v3 = new Vector3(uv3.x * spriteTexture.width - spriteRect.position.x - spriteRect.width * 0.5f, uv3.y * spriteTexture.height - spriteRect.position.y - spriteRect.height * 0.5f, 0f);
- v0 = Vector3.Scale(v0, scale);
- v1 = Vector3.Scale(v1, scale);
- v2 = Vector3.Scale(v2, scale);
- v3 = Vector3.Scale(v3, scale);
-
- //TODO: Support vertical tiling when horizontal fitted
- if (tiled && fitMode == FitMode.FitVertical)
- {
- Vector2 scaledRectSize = Vector2.Scale(rect.size, new Vector2(1f / scale.x, 1f / scale.y));
- float halfDistanceToFill = (scaledRectSize.x - spriteRect.width) * 0.5f;
- int halfFillSegmentCount = (int)Mathf.Ceil(halfDistanceToFill / spriteRect.width);
- int segmentCount = halfFillSegmentCount * 2 + 1;
- int vertexCount = segmentCount * 4;
-
- vertices.Capacity = vertexCount;
- uvs.Capacity = vertexCount;
- indices.Capacity = vertexCount;
-
- Vector3 offset = Vector3.zero;
- Vector3 offsetStep = Vector3.Scale(Vector3.right * spriteRect.width, scale);
-
- float distanceStep = spriteRect.width;
- float distanceToFill = halfDistanceToFill + distanceStep;
-
- int vertexIndex = 0;
-
- for (int i = 0; i <= halfFillSegmentCount; ++i)
- {
- float t = Mathf.Clamp01(distanceToFill / spriteRect.width);
-
- uvs.Add(uv0);
- uvs.Add(uv1);
- uvs.Add(Vector3.Lerp(uv0, uv2, t));
- uvs.Add(Vector3.Lerp(uv1, uv3, t));
-
- vertices.Add(v0 + offset);
- vertices.Add(v1 + offset);
- vertices.Add(Vector3.Lerp(v0, v2, t) + offset);
- vertices.Add(Vector3.Lerp(v1, v3, t) + offset);
-
- indices.Add(vertexIndex);
- indices.Add(vertexIndex + 2);
- indices.Add(vertexIndex + 1);
- indices.Add(vertexIndex + 2);
- indices.Add(vertexIndex + 3);
- indices.Add(vertexIndex + 1);
-
- vertexIndex += 4;
-
- if (i > 0)
- {
- uvs.Add(Vector2.Lerp(uv0, uv2, 1f - t));
- uvs.Add(Vector2.Lerp(uv1, uv3, 1f - t));
- uvs.Add(uv2);
- uvs.Add(uv3);
-
- vertices.Add(Vector3.Lerp(v0, v2, 1f - t) - offset);
- vertices.Add(Vector3.Lerp(v1, v3, 1f - t) - offset);
- vertices.Add(v2 - offset);
- vertices.Add(v3 - offset);
-
- indices.Add(vertexIndex);
- indices.Add(vertexIndex + 2);
- indices.Add(vertexIndex + 1);
- indices.Add(vertexIndex + 2);
- indices.Add(vertexIndex + 3);
- indices.Add(vertexIndex + 1);
-
- vertexIndex += 4;
- }
-
- offset += offsetStep;
- distanceToFill -= distanceStep;
- }
- }
- else
- {
- vertices.AddRange(new Vector3[] { v0, v1, v2, v3 });
- uvs.AddRange(new Vector2[] { uv0, uv1, uv2, uv3 });
- indices.AddRange(new int[] { 0, 2, 1, 2, 3, 1 });
- }
- }
- else
- {
- ushort[] triangles = sprite.triangles;
- indices.Capacity = triangles.Length;
-
- for (int i = 0; i < triangles.Length; ++i)
- indices.Add((int)triangles[i]);
-
- uvs.AddRange(GetOriginalSpriteUvs(sprite));
- vertices.Capacity = uvs.Count;
-
- for (int i = 0; i < uvs.Count; ++i)
- {
- Vector3 v = new Vector3(uvs[i].x * spriteTexture.width - spriteRect.position.x - spriteRect.width * 0.5f, uvs[i].y * spriteTexture.height - spriteRect.position.y - spriteRect.height * 0.5f, 0f);
- vertices.Add(Vector3.Scale(v, scale));
- }
- }
-
- mesh.SetVertices(vertices);
- mesh.SetUVs(0, uvs);
- mesh.SetTriangles(indices, 0);
- mesh.UploadMeshData(false);
- }
-
- public static void DrawMesh(Mesh mesh, Material material, Vector3 position, Quaternion rotation, Vector3 scale)
- {
- if (Event.current.type != EventType.Repaint)
- return;
-
- Matrix4x4 matrix = new Matrix4x4();
- matrix.SetTRS(position, rotation, scale);
- material.SetPass(0);
- Graphics.DrawMeshNow(mesh, matrix);
- }
- }
- }
|