Skip to content

Instantly share code, notes, and snippets.

@stramit
Created August 25, 2014 23:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stramit/d2e1a94cdf3dbe08caac to your computer and use it in GitHub Desktop.
Save stramit/d2e1a94cdf3dbe08caac to your computer and use it in GitHub Desktop.
Image
using System;
using System.Collections.Generic;
namespace UnityEngine.UI
{
/// <summary>
/// Image is a textured element in the UI hierarchy.
/// </summary>
[AddComponentMenu("UI/Image", 10)]
public class Image : MaskableGraphic, ISerializationCallbackReceiver, ILayoutElement
{
public enum Type
{
Simple,
Sliced,
Tiled,
Filled
}
public enum FillMethod
{
Horizontal,
Vertical,
Radial90,
Radial180,
Radial360,
}
public enum OriginHorizontal
{
Left,
Right,
}
public enum OriginVertical
{
Bottom,
Top,
}
public enum Origin90
{
BottomLeft,
TopLeft,
TopRight,
BottomRight,
}
public enum Origin180
{
Bottom,
Left,
Top,
Right,
}
public enum Origin360
{
Bottom,
Right,
Top,
Left,
}
[RenamedSerializedData("m_Frame")]
[SerializeField] private Sprite m_Sprite;
public Sprite sprite { get { return m_Sprite; } set { SetPropertyUtility.SetClass (ref m_Sprite, value, m_DirtyAllCallback); } }
[NonSerialized]
private Sprite m_OverrideSprite;
public Sprite overrideSprite { get { return m_OverrideSprite == null ? sprite : m_OverrideSprite; } set {SetPropertyUtility.SetClass(ref m_OverrideSprite, value, m_DirtyAllCallback); } }
/// How the Image is drawn.
[SerializeField] private Type m_Type = Type.Simple;
public Type type { get { return m_Type; } set { SetPropertyUtility.SetStruct(ref m_Type, value, m_DirtyVertsCallback); } }
[SerializeField] private bool m_PreserveAspect = false;
public bool preserveAspect { get { return m_PreserveAspect; } set { SetPropertyUtility.SetStruct(ref m_PreserveAspect, value, m_DirtyVertsCallback); } }
[SerializeField] private bool m_FillCenter = true;
public bool fillCenter { get { return m_FillCenter; } set { SetPropertyUtility.SetStruct(ref m_FillCenter, value, m_DirtyVertsCallback); } }
/// Filling method for filled sprites.
[SerializeField] private FillMethod m_FillMethod = FillMethod.Radial360;
public FillMethod fillMethod { get { return m_FillMethod; } set { SetPropertyUtility.SetStruct(ref m_FillMethod, value, m_DirtyVertsCallback); m_FillOrigin = 0; } }
/// Amount of the Image shown. 0-1 range with 0 being nothing shown, and 1 being the full Image.
[Range(0, 1)]
[SerializeField] private float m_FillAmount = 1.0f;
public float fillAmount { get { return m_FillAmount; } set { SetPropertyUtility.SetStruct(ref m_FillAmount, Mathf.Clamp01(value), m_DirtyVertsCallback); } }
/// Whether the Image should be filled clockwise (true) or counter-clockwise (false).
[SerializeField] private bool m_FillClockwise = true;
public bool fillClockwise { get { return m_FillClockwise; } set { SetPropertyUtility.SetStruct(ref m_FillClockwise, value, m_DirtyVertsCallback); } }
/// Controls the origin point of the Fill process. Value means different things with each fill method.
[SerializeField] private int m_FillOrigin;
public int fillOrigin { get { return m_FillOrigin; } set { SetPropertyUtility.SetStruct(ref m_FillOrigin, value, m_DirtyVertsCallback); } }
protected Image()
{}
/// <summary>
/// Image's texture comes from the UnityEngine.Image.
/// </summary>
public override Texture mainTexture
{
get
{
return overrideSprite == null ? s_WhiteTexture : overrideSprite.texture;
}
}
/// <summary>
/// Whether the Image has a border to work with.
/// </summary>
public bool hasBorder
{
get
{
if (overrideSprite != null)
{
Vector4 v = overrideSprite.border;
return v.sqrMagnitude > 0f;
}
return false;
}
}
public void OnBeforeSerialize() {}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
if (m_FillOrigin < 0)
m_FillOrigin = 0;
else if (m_FillMethod == FillMethod.Horizontal && m_FillOrigin > 1)
m_FillOrigin = 0;
else if (m_FillMethod == FillMethod.Vertical && m_FillOrigin > 1)
m_FillOrigin = 0;
else if (m_FillOrigin > 3)
m_FillOrigin = 0;
m_FillAmount = Mathf.Clamp(m_FillAmount, 0f, 1f);
}
/// Image's dimensions used for drawing. X = left, Y = bottom, Z = right, W = top.
private Vector4 GetDrawingDimensions(bool shouldPreserveAspect)
{
var padding = overrideSprite == null ? Vector4.zero : Sprites.DataUtility.GetPadding(overrideSprite);
var size = overrideSprite == null ? Vector2.zero : new Vector2(overrideSprite.rect.width, overrideSprite.rect.height);
Rect r = GetPixelAdjustedRect();
//Debug.Log(string.Format("r:{2}, size:{0}, padding:{1}", size, padding, r));
int spriteW = Mathf.RoundToInt (size.x);
int spriteH = Mathf.RoundToInt (size.y);
var v = new Vector4 (
padding.x / spriteW,
padding.y / spriteH,
(spriteW - padding.z) / spriteW,
(spriteH - padding.w) / spriteH);
if (shouldPreserveAspect && size.sqrMagnitude > 0.0f)
{
var spriteRatio = size.x / size.y;
var rectRatio = r.width / r.height;
if (spriteRatio > rectRatio)
{
var oldHeight = r.height;
r.height = r.width * (1.0f / spriteRatio);
r.y += (oldHeight - r.height) * rectTransform.pivot.y;
}
else
{
var oldWidth = r.width;
r.width = r.height * spriteRatio;
r.x += (oldWidth - r.width) * rectTransform.pivot.x;
}
}
v = new Vector4 (
r.x + r.width * v.x,
r.y + r.height * v.y,
r.x + r.width * v.z,
r.y + r.height * v.w
);
return v;
}
public override void SetNativeSize()
{
if (overrideSprite != null)
{
int w = Mathf.RoundToInt (overrideSprite.rect.width);
int h = Mathf.RoundToInt (overrideSprite.rect.height);
rectTransform.anchorMax = rectTransform.anchorMin;
rectTransform.sizeDelta = new Vector2 (w, h);
SetAllDirty ();
}
}
/// <summary>
/// Update the UI renderer mesh.
/// </summary>
protected override void OnFillVBO (List<UIVertex> vbo)
{
if (overrideSprite == null)
{
base.OnFillVBO (vbo);
return;
}
switch (type)
{
case Type.Simple:
GenerateSimpleSprite(vbo, m_PreserveAspect);
break;
case Type.Sliced:
GenerateSlicedSprite(vbo);
break;
case Type.Tiled:
GenerateTiledSprite(vbo);
break;
case Type.Filled:
GenerateFilledSprite(vbo, m_PreserveAspect);
break;
}
}
#region Various fill functions
/// <summary>
/// Generate vertices for a simple Image.
/// </summary>
void GenerateSimpleSprite (List<UIVertex> vbo, bool preserveAspect)
{
var vert = UIVertex.simpleVert;
vert.color = color;
Vector4 v = GetDrawingDimensions(preserveAspect);
var uv = (overrideSprite != null) ? Sprites.DataUtility.GetOuterUV(overrideSprite) : Vector4.zero;
vert.position = new Vector3(v.x, v.y);
vert.uv0 = new Vector2(uv.x, uv.y);
vbo.Add(vert);
vert.position = new Vector3(v.x, v.w);
vert.uv0 = new Vector2(uv.x, uv.w);
vbo.Add(vert);
vert.position = new Vector3(v.z, v.w);
vert.uv0 = new Vector2(uv.z, uv.w);
vbo.Add(vert);
vert.position = new Vector3(v.z, v.y);
vert.uv0 = new Vector2(uv.z, uv.y);
vbo.Add(vert);
}
/// <summary>
/// Generate vertices for a 9-sliced Image.
/// </summary>
static readonly Vector2[] s_VertScratch = new Vector2[4];
static readonly Vector2[] s_UVScratch = new Vector2[4];
void GenerateSlicedSprite (List<UIVertex> vbo)
{
if (!hasBorder)
{
GenerateSimpleSprite(vbo, false);
return;
}
Vector4 outer, inner, padding, border;
if (overrideSprite != null)
{
outer = Sprites.DataUtility.GetOuterUV (overrideSprite);
inner = Sprites.DataUtility.GetInnerUV (overrideSprite);
padding = Sprites.DataUtility.GetPadding (overrideSprite);
border = overrideSprite.border;
}
else
{
outer = Vector4.zero;
inner = Vector4.zero;
padding = Vector4.zero;
border = Vector4.zero;
}
Rect rect = GetPixelAdjustedRect();
border = GetAdjustedBorders (border / pixelsPerUnit, rect);
s_VertScratch[0] = new Vector2(padding.x, padding.y);
s_VertScratch[3] = new Vector2(rect.width - padding.z, rect.height - padding.w);
s_VertScratch[1].x = border.x;
s_VertScratch[1].y = border.y;
s_VertScratch[2].x = rect.width - border.z;
s_VertScratch[2].y = rect.height - border.w;
for (int i = 0; i < 4; ++i)
{
s_VertScratch[i].x += rect.x;
s_VertScratch[i].y += rect.y;
}
s_UVScratch[0] = new Vector2(outer.x, outer.y);
s_UVScratch[1] = new Vector2(inner.x, inner.y);
s_UVScratch[2] = new Vector2(inner.z, inner.w);
s_UVScratch[3] = new Vector2(outer.z, outer.w);
var uiv = UIVertex.simpleVert;
uiv.color = color;
for (int x = 0; x < 3; ++x)
{
int x2 = x + 1;
for (int y = 0; y < 3; ++y)
{
if (!m_FillCenter && x == 1 && y == 1)
{
continue;
}
int y2 = y + 1;
AddQuad (vbo, uiv,
new Vector2(s_VertScratch[x].x, s_VertScratch[y].y),
new Vector2(s_VertScratch[x2].x, s_VertScratch[y2].y),
new Vector2(s_UVScratch[x].x, s_UVScratch[y].y),
new Vector2(s_UVScratch[x2].x, s_UVScratch[y2].y));
}
}
}
/// <summary>
/// Generate vertices for a tiled Image.
/// </summary>
void GenerateTiledSprite (List<UIVertex> vbo)
{
Vector4 outer, inner, border;
Vector2 spriteSize;
if (overrideSprite != null)
{
outer = Sprites.DataUtility.GetOuterUV(overrideSprite);
inner = Sprites.DataUtility.GetInnerUV(overrideSprite);
border = overrideSprite.border;
spriteSize = overrideSprite.rect.size;
}
else
{
outer = Vector4.zero;
inner = Vector4.zero;
border = Vector4.zero;
spriteSize = Vector2.one * 100;
}
Rect rect = GetPixelAdjustedRect();
float tileWidth = (spriteSize.x - border.x - border.z) / pixelsPerUnit;
float tileHeight = (spriteSize.y - border.y - border.w) / pixelsPerUnit;
border = GetAdjustedBorders (border / pixelsPerUnit, rect);
var uvMin = new Vector2(inner.x, inner.y);
var uvMax = new Vector2(inner.z, inner.w);
var v = UIVertex.simpleVert;
v.color = color;
// Min to max max range for tiled region in coordinates relative to lower left corner.
float xMin = border.x;
float xMax = rect.width - border.z;
float yMin = border.y;
float yMax = rect.height - border.w;
// Safety check. Useful so Unity doesn't run out of memory if the sprites are too small.
// Max tiles are 100 x 100.
if ((xMax - xMin) > tileWidth * 100 || (yMax - yMin) > tileHeight * 100)
{
tileWidth = (xMax - xMin) / 100;
tileHeight = (yMax - yMin) / 100;
}
var clipped = uvMax;
if (m_FillCenter)
{
for (float y1 = yMin; y1 < yMax; y1 += tileHeight)
{
float y2 = y1 + tileHeight;
if (y2 > yMax)
{
clipped.y = uvMin.y + (uvMax.y - uvMin.y) * (yMax - y1) / (y2 - y1);
y2 = yMax;
}
clipped.x = uvMax.x;
for (float x1 = xMin; x1 < xMax; x1 += tileWidth)
{
float x2 = x1 + tileWidth;
if (x2 > xMax)
{
clipped.x = uvMin.x + (uvMax.x - uvMin.x) * (xMax - x1) / (x2 - x1);
x2 = xMax;
}
AddQuad (vbo, v, new Vector2 (x1, y1) + rect.position, new Vector2 (x2, y2) + rect.position, uvMin, clipped);
}
}
}
if (!hasBorder)
return;
// Left and right tiled border
clipped = uvMax;
for (float y1 = yMin; y1 < yMax; y1 += tileHeight)
{
float y2 = y1 + tileHeight;
if (y2 > yMax)
{
clipped.y = uvMin.y + (uvMax.y - uvMin.y) * (yMax - y1) / (y2 - y1);
y2 = yMax;
}
AddQuad (vbo, v,
new Vector2 (0, y1) + rect.position,
new Vector2 (xMin, y2) + rect.position,
new Vector2 (outer.x, uvMin.y),
new Vector2 (uvMin.x, clipped.y));
AddQuad (vbo, v,
new Vector2 (xMax, y1) + rect.position,
new Vector2 (rect.width, y2) + rect.position,
new Vector2 (uvMax.x, uvMin.y),
new Vector2 (outer.z, clipped.y));
}
// Bottom and top tiled border
clipped = uvMax;
for (float x1 = xMin; x1 < xMax; x1 += tileWidth)
{
float x2 = x1 + tileWidth;
if (x2 > xMax)
{
clipped.x = uvMin.x + (uvMax.x - uvMin.x) * (xMax - x1) / (x2 - x1);
x2 = xMax;
}
AddQuad (vbo, v,
new Vector2 (x1, 0) + rect.position,
new Vector2 (x2, yMin) + rect.position,
new Vector2 (uvMin.x, outer.y),
new Vector2 (clipped.x, uvMin.y));
AddQuad (vbo, v,
new Vector2 (x1, yMax) + rect.position,
new Vector2 (x2, rect.height) + rect.position,
new Vector2 (uvMin.x, uvMax.y),
new Vector2 (clipped.x, outer.w));
}
// Corners
AddQuad (vbo, v,
new Vector2 (0, 0) + rect.position,
new Vector2 (xMin, yMin) + rect.position,
new Vector2 (outer.x, outer.y),
new Vector2 (uvMin.x, uvMin.y));
AddQuad (vbo, v,
new Vector2 (xMax, 0) + rect.position,
new Vector2 (rect.width, yMin) + rect.position,
new Vector2 (uvMax.x, outer.y),
new Vector2 (outer.z, uvMin.y));
AddQuad (vbo, v,
new Vector2 (0, yMax) + rect.position,
new Vector2 (xMin, rect.height) + rect.position,
new Vector2 (outer.x, uvMax.y),
new Vector2 (uvMin.x, outer.w));
AddQuad (vbo, v,
new Vector2 (xMax, yMax) + rect.position,
new Vector2 (rect.width, rect.height) + rect.position,
new Vector2 (uvMax.x, uvMax.y),
new Vector2 (outer.z, outer.w));
}
void AddQuad (List<UIVertex> vbo, UIVertex v, Vector2 posMin, Vector2 posMax, Vector2 uvMin, Vector2 uvMax)
{
v.position = new Vector3 (posMin.x, posMin.y, 0);
v.uv0 = new Vector2 (uvMin.x, uvMin.y);
vbo.Add (v);
v.position = new Vector3 (posMin.x, posMax.y, 0);
v.uv0 = new Vector2 (uvMin.x, uvMax.y);
vbo.Add (v);
v.position = new Vector3 (posMax.x, posMax.y, 0);
v.uv0 = new Vector2 (uvMax.x, uvMax.y);
vbo.Add (v);
v.position = new Vector3 (posMax.x, posMin.y, 0);
v.uv0 = new Vector2 (uvMax.x, uvMin.y);
vbo.Add (v);
}
Vector4 GetAdjustedBorders (Vector4 border, Rect rect)
{
for (int axis = 0; axis <= 1; axis++)
{
// If the rect is smaller than the combined borders, then there's not room for the borders at their normal size.
// In order to avoid artefacts with overlapping borders, we scale the borders down to fit.
float combinedBorders = border[axis] + border[axis+2];
if (rect.size[axis] < combinedBorders && combinedBorders != 0)
{
float borderScaleRatio = rect.size[axis] / combinedBorders;
border[axis] *= borderScaleRatio;
border[axis+2] *= borderScaleRatio;
}
}
return border;
}
/// <summary>
/// Generate vertices for a filled Image.
/// </summary>
static readonly Vector2[] s_Xy = new Vector2[4];
static readonly Vector2[] s_Uv = new Vector2[4];
void GenerateFilledSprite (List<UIVertex> vbo, bool preserveAspect)
{
if (m_FillAmount < 0.001f)
return;
Vector4 v = GetDrawingDimensions(preserveAspect);
Vector4 outer = overrideSprite != null ? Sprites.DataUtility.GetOuterUV(overrideSprite) : Vector4.zero;
UIVertex uiv = UIVertex.simpleVert;
uiv.color = color;
float tx0 = outer.x;
float ty0 = outer.y;
float tx1 = outer.z;
float ty1 = outer.w;
// Horizontal and vertical filled sprites are simple -- just end the Image prematurely
if (m_FillMethod == FillMethod.Horizontal || m_FillMethod == FillMethod.Vertical)
{
if (fillMethod == FillMethod.Horizontal)
{
float fill = (tx1 - tx0) * m_FillAmount;
if (m_FillOrigin == 1)
{
v.x = v.z - (v.z - v.x) * m_FillAmount;
tx0 = tx1 - fill;
}
else
{
v.z = v.x + (v.z - v.x) * m_FillAmount;
tx1 = tx0 + fill;
}
}
else if (fillMethod == FillMethod.Vertical)
{
float fill = (ty1 - ty0) * m_FillAmount;
if (m_FillOrigin == 1)
{
v.y = v.w - (v.w - v.y) * m_FillAmount;
ty0 = ty1 - fill;
}
else
{
v.w = v.y + (v.w - v.y) * m_FillAmount;
ty1 = ty0 + fill;
}
}
}
s_Xy[0] = new Vector2(v.x, v.y);
s_Xy[1] = new Vector2(v.x, v.w);
s_Xy[2] = new Vector2(v.z, v.w);
s_Xy[3] = new Vector2(v.z, v.y);
s_Uv[0] = new Vector2(tx0, ty0);
s_Uv[1] = new Vector2(tx0, ty1);
s_Uv[2] = new Vector2(tx1, ty1);
s_Uv[3] = new Vector2(tx1, ty0);
if (m_FillAmount < 1f)
{
if (fillMethod == FillMethod.Radial90)
{
if (RadialCut(s_Xy, s_Uv, m_FillAmount, m_FillClockwise, m_FillOrigin))
{
for (int i = 0; i < 4; ++i)
{
uiv.position = s_Xy[i];
uiv.uv0 = s_Uv[i];
vbo.Add(uiv);
}
}
return;
}
if (fillMethod == FillMethod.Radial180)
{
for (int side = 0; side < 2; ++side)
{
float fx0, fx1, fy0, fy1;
int even = m_FillOrigin > 1 ? 1 : 0;
if (m_FillOrigin == 0 || m_FillOrigin == 2)
{
fy0 = 0f;
fy1 = 1f;
if (side == even) { fx0 = 0f; fx1 = 0.5f; }
else { fx0 = 0.5f; fx1 = 1f; }
}
else
{
fx0 = 0f;
fx1 = 1f;
if (side == even) { fy0 = 0.5f; fy1 = 1f; }
else { fy0 = 0f; fy1 = 0.5f; }
}
s_Xy[0].x = Mathf.Lerp(v.x, v.z, fx0);
s_Xy[1].x = s_Xy[0].x;
s_Xy[2].x = Mathf.Lerp(v.x, v.z, fx1);
s_Xy[3].x = s_Xy[2].x;
s_Xy[0].y = Mathf.Lerp(v.y, v.w, fy0);
s_Xy[1].y = Mathf.Lerp(v.y, v.w, fy1);
s_Xy[2].y = s_Xy[1].y;
s_Xy[3].y = s_Xy[0].y;
s_Uv[0].x = Mathf.Lerp(tx0, tx1, fx0);
s_Uv[1].x = s_Uv[0].x;
s_Uv[2].x = Mathf.Lerp(tx0, tx1, fx1);
s_Uv[3].x = s_Uv[2].x;
s_Uv[0].y = Mathf.Lerp(ty0, ty1, fy0);
s_Uv[1].y = Mathf.Lerp(ty0, ty1, fy1);
s_Uv[2].y = s_Uv[1].y;
s_Uv[3].y = s_Uv[0].y;
float val = m_FillClockwise ? fillAmount * 2f - side : m_FillAmount * 2f - (1 - side);
if (RadialCut(s_Xy, s_Uv, Mathf.Clamp01(val), m_FillClockwise, ((side + m_FillOrigin + 3) % 4)))
{
for (int i = 0; i < 4; ++i)
{
uiv.position = s_Xy[i];
uiv.uv0 = s_Uv[i];
vbo.Add(uiv);
}
}
}
return;
}
if (fillMethod == FillMethod.Radial360)
{
for (int corner = 0; corner < 4; ++corner)
{
float fx0, fx1, fy0, fy1;
if (corner < 2) { fx0 = 0f; fx1 = 0.5f; }
else { fx0 = 0.5f; fx1 = 1f; }
if (corner == 0 || corner == 3) { fy0 = 0f; fy1 = 0.5f; }
else { fy0 = 0.5f; fy1 = 1f; }
s_Xy[0].x = Mathf.Lerp(v.x, v.z, fx0);
s_Xy[1].x = s_Xy[0].x;
s_Xy[2].x = Mathf.Lerp(v.x, v.z, fx1);
s_Xy[3].x = s_Xy[2].x;
s_Xy[0].y = Mathf.Lerp(v.y, v.w, fy0);
s_Xy[1].y = Mathf.Lerp(v.y, v.w, fy1);
s_Xy[2].y = s_Xy[1].y;
s_Xy[3].y = s_Xy[0].y;
s_Uv[0].x = Mathf.Lerp(tx0, tx1, fx0);
s_Uv[1].x = s_Uv[0].x;
s_Uv[2].x = Mathf.Lerp(tx0, tx1, fx1);
s_Uv[3].x = s_Uv[2].x;
s_Uv[0].y = Mathf.Lerp(ty0, ty1, fy0);
s_Uv[1].y = Mathf.Lerp(ty0, ty1, fy1);
s_Uv[2].y = s_Uv[1].y;
s_Uv[3].y = s_Uv[0].y;
float val = m_FillClockwise ?
m_FillAmount * 4f - ((corner + m_FillOrigin) % 4) :
m_FillAmount * 4f - (3 - ((corner + m_FillOrigin) % 4));
if (RadialCut(s_Xy, s_Uv, Mathf.Clamp01(val), m_FillClockwise, ((corner + 2) % 4)))
{
for (int i = 0; i < 4; ++i)
{
uiv.position = s_Xy[i];
uiv.uv0 = s_Uv[i];
vbo.Add(uiv);
}
}
}
return;
}
}
// Fill the buffer with the quad for the Image
for (int i = 0; i < 4; ++i)
{
uiv.position = s_Xy[i];
uiv.uv0 = s_Uv[i];
vbo.Add(uiv);
}
}
/// <summary>
/// Adjust the specified quad, making it be radially filled instead.
/// </summary>
static bool RadialCut (Vector2[] xy, Vector2[] uv, float fill, bool invert, int corner)
{
// Nothing to fill
if (fill < 0.001f) return false;
// Even corners invert the fill direction
if ((corner & 1) == 1) invert = !invert;
// Nothing to adjust
if (!invert && fill > 0.999f) return true;
// Convert 0-1 value into 0 to 90 degrees angle in radians
float angle = Mathf.Clamp01(fill);
if (invert) angle = 1f - angle;
angle *= 90f * Mathf.Deg2Rad;
// Calculate the effective X and Y factors
float cos = Mathf.Cos(angle);
float sin = Mathf.Sin(angle);
RadialCut(xy, cos, sin, invert, corner);
RadialCut(uv, cos, sin, invert, corner);
return true;
}
/// <summary>
/// Adjust the specified quad, making it be radially filled instead.
/// </summary>
static void RadialCut (Vector2[] xy, float cos, float sin, bool invert, int corner)
{
int i0 = corner;
int i1 = ((corner + 1) % 4);
int i2 = ((corner + 2) % 4);
int i3 = ((corner + 3) % 4);
if ((corner & 1) == 1)
{
if (sin > cos)
{
cos /= sin;
sin = 1f;
if (invert)
{
xy[i1].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);
xy[i2].x = xy[i1].x;
}
}
else if (cos > sin)
{
sin /= cos;
cos = 1f;
if (!invert)
{
xy[i2].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);
xy[i3].y = xy[i2].y;
}
}
else
{
cos = 1f;
sin = 1f;
}
if (!invert) xy[i3].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);
else xy[i1].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);
}
else
{
if (cos > sin)
{
sin /= cos;
cos = 1f;
if (!invert)
{
xy[i1].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);
xy[i2].y = xy[i1].y;
}
}
else if (sin > cos)
{
cos /= sin;
sin = 1f;
if (invert)
{
xy[i2].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);
xy[i3].x = xy[i2].x;
}
}
else
{
cos = 1f;
sin = 1f;
}
if (invert) xy[i3].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);
else xy[i1].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);
}
}
#endregion
public void CalculateLayoutInputHorizontal () {}
public void CalculateLayoutInputVertical () {}
public float minWidth { get { return 0; } }
public float preferredWidth
{
get
{
if (overrideSprite == null)
return 0;
if (type == Type.Sliced || type == Type.Tiled)
return Sprites.DataUtility.GetMinSize(overrideSprite).x;
return overrideSprite.rect.size.x;
}
}
public float flexibleWidth { get { return 1; } }
public float minHeight { get { return 0; } }
public float preferredHeight
{
get
{
if (overrideSprite == null)
return 0;
if (type == Type.Sliced || type == Type.Tiled)
return Sprites.DataUtility.GetMinSize (overrideSprite).y;
return overrideSprite.rect.size.y;
}
}
public float flexibleHeight { get { return 1; } }
public int layoutPriority { get { return 0; } }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment