Support complex linear gradients, gradient zoom, and a switch of whether to modify vertices
parent
1f16a65f0f
commit
48acafbb85
|
@ -5,29 +5,40 @@
|
||||||
/// -Offset is now limited to -1,1
|
/// -Offset is now limited to -1,1
|
||||||
/// -Multiple color blend modes
|
/// -Multiple color blend modes
|
||||||
///
|
///
|
||||||
/// Remember that the colors are applied per-vertex so if you have multiple points on your gradient where the color changes and there aren't enough vertices, you won't see all of the colors.
|
/// Remember that for radial and diamond gradients, colors are applied per-vertex so if you have multiple points on your gradient where the color changes and there aren't enough vertices, you won't see all of the colors.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace UnityEngine.UI.Extensions
|
namespace UnityEngine.UI.Extensions
|
||||||
{
|
{
|
||||||
[AddComponentMenu("UI/Effects/Extensions/Gradient2")]
|
[AddComponentMenu("UI/Effects/Extensions/Gradient2")]
|
||||||
public class Gradient2 : BaseMeshEffect {
|
public class Gradient2 : BaseMeshEffect
|
||||||
|
{
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
Type _gradientType;
|
Type _gradientType;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
Blend _blendMode = Blend.Multiply;
|
Blend _blendMode = Blend.Multiply;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("Add vertices to display complex gradients. Turn off if your shape is already very complex, like text.")]
|
||||||
|
bool _modifyVertices = true;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
[Range(-1, 1)]
|
[Range(-1, 1)]
|
||||||
float _offset = 0f;
|
float _offset = 0f;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
[Range(0.1f, 10)]
|
||||||
|
float _zoom = 1f;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
UnityEngine.Gradient _effectGradient = new UnityEngine.Gradient() { colorKeys = new GradientColorKey[] { new GradientColorKey(Color.black, 0), new GradientColorKey(Color.white, 1) } };
|
UnityEngine.Gradient _effectGradient = new UnityEngine.Gradient() { colorKeys = new GradientColorKey[] { new GradientColorKey(Color.black, 0), new GradientColorKey(Color.white, 1) } };
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
public Blend BlendMode {
|
public Blend BlendMode
|
||||||
|
{
|
||||||
get { return _blendMode; }
|
get { return _blendMode; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
@ -36,7 +47,8 @@ namespace UnityEngine.UI.Extensions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnityEngine.Gradient EffectGradient {
|
public UnityEngine.Gradient EffectGradient
|
||||||
|
{
|
||||||
get { return _effectGradient; }
|
get { return _effectGradient; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
@ -45,7 +57,8 @@ namespace UnityEngine.UI.Extensions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type GradientType {
|
public Type GradientType
|
||||||
|
{
|
||||||
get { return _gradientType; }
|
get { return _gradientType; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
@ -54,7 +67,18 @@ namespace UnityEngine.UI.Extensions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float Offset {
|
public bool ModifyVertices
|
||||||
|
{
|
||||||
|
get { return _modifyVertices; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_modifyVertices = value;
|
||||||
|
graphic.SetVerticesDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Offset
|
||||||
|
{
|
||||||
get { return _offset; }
|
get { return _offset; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
@ -62,9 +86,20 @@ namespace UnityEngine.UI.Extensions
|
||||||
graphic.SetVerticesDirty();
|
graphic.SetVerticesDirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float Zoom
|
||||||
|
{
|
||||||
|
get { return _zoom; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_zoom = value;
|
||||||
|
graphic.SetVerticesDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public override void ModifyMesh(VertexHelper helper) {
|
public override void ModifyMesh(VertexHelper helper)
|
||||||
|
{
|
||||||
if (!IsActive() || helper.currentVertCount == 0)
|
if (!IsActive() || helper.currentVertCount == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -73,132 +108,97 @@ namespace UnityEngine.UI.Extensions
|
||||||
helper.GetUIVertexStream(_vertexList);
|
helper.GetUIVertexStream(_vertexList);
|
||||||
|
|
||||||
int nCount = _vertexList.Count;
|
int nCount = _vertexList.Count;
|
||||||
switch(GradientType) {
|
switch (GradientType)
|
||||||
case Type.Horizontal: {
|
{
|
||||||
float left = _vertexList[0].position.x;
|
case Type.Horizontal:
|
||||||
float right = _vertexList[0].position.x;
|
case Type.Vertical:
|
||||||
float x = 0f;
|
{
|
||||||
|
Rect bounds = GetBounds(_vertexList);
|
||||||
|
float min = bounds.xMin;
|
||||||
|
float w = bounds.width;
|
||||||
|
Func<UIVertex, float> GetPosition = v => v.position.x;
|
||||||
|
|
||||||
for(int i = nCount - 1; i >= 1; --i) {
|
if (GradientType == Type.Vertical)
|
||||||
x = _vertexList[i].position.x;
|
{
|
||||||
|
min = bounds.yMin;
|
||||||
if(x > right) right = x;
|
w = bounds.height;
|
||||||
else if(x < left) left = x;
|
GetPosition = v => v.position.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float width = 1f / w / Zoom;
|
||||||
|
float zoomOffset = ((w * Zoom) - w) * width * 0.5f;
|
||||||
|
float offset = Offset - zoomOffset;
|
||||||
|
|
||||||
|
if (ModifyVertices)
|
||||||
|
{
|
||||||
|
SplitTrianglesAtGradientStops(_vertexList, bounds, zoomOffset, helper);
|
||||||
}
|
}
|
||||||
|
|
||||||
float width = 1f / (right - left);
|
|
||||||
UIVertex vertex = new UIVertex();
|
UIVertex vertex = new UIVertex();
|
||||||
|
for (int i = 0; i < helper.currentVertCount; i++)
|
||||||
for(int i = 0; i < helper.currentVertCount; i++) {
|
{
|
||||||
helper.PopulateUIVertex(ref vertex, i);
|
helper.PopulateUIVertex(ref vertex, i);
|
||||||
|
vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate((GetPosition(vertex) - min) * width - offset));
|
||||||
vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate((vertex.position.x - left) * width - Offset));
|
|
||||||
|
|
||||||
helper.SetUIVertex(vertex, i);
|
helper.SetUIVertex(vertex, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Type.Vertical: {
|
case Type.Diamond:
|
||||||
float bottom = _vertexList[0].position.y;
|
{
|
||||||
float top = _vertexList[0].position.y;
|
Rect bounds = GetBounds(_vertexList);
|
||||||
float y = 0f;
|
|
||||||
|
|
||||||
for(int i = nCount - 1; i >= 1; --i) {
|
float height = 1f / bounds.height / Zoom;
|
||||||
y = _vertexList[i].position.y;
|
float radius = bounds.center.y / 2f;
|
||||||
|
Vector3 center = (Vector3.right + Vector3.up) * radius + Vector3.forward * _vertexList[0].position.z;
|
||||||
if(y > top) top = y;
|
|
||||||
else if(y < bottom) bottom = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
float height = 1f / (top - bottom);
|
|
||||||
UIVertex vertex = new UIVertex();
|
|
||||||
|
|
||||||
for(int i = 0; i < helper.currentVertCount; i++) {
|
|
||||||
helper.PopulateUIVertex(ref vertex, i);
|
|
||||||
|
|
||||||
vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate((vertex.position.y - bottom) * height - Offset));
|
|
||||||
|
|
||||||
helper.SetUIVertex(vertex, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Type.Diamond: {
|
|
||||||
|
|
||||||
float bottom = _vertexList[0].position.y;
|
|
||||||
float top = _vertexList[0].position.y;
|
|
||||||
float y = 0f;
|
|
||||||
|
|
||||||
for(int i = nCount - 1; i >= 1; --i) {
|
|
||||||
y = _vertexList[i].position.y;
|
|
||||||
|
|
||||||
if(y > top) top = y;
|
|
||||||
else if(y < bottom) bottom = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
float height = 1f / (top - bottom);
|
|
||||||
|
|
||||||
|
if (ModifyVertices)
|
||||||
|
{
|
||||||
helper.Clear();
|
helper.Clear();
|
||||||
for (int i = 0; i < nCount; i++) helper.AddVert(_vertexList[i]);
|
for (int i = 0; i < nCount; i++) helper.AddVert(_vertexList[i]);
|
||||||
|
|
||||||
float center = (bottom + top) / 2f;
|
|
||||||
UIVertex centralVertex = new UIVertex();
|
UIVertex centralVertex = new UIVertex();
|
||||||
centralVertex.position = (Vector3.right + Vector3.up) * center + Vector3.forward * _vertexList[0].position.z;
|
centralVertex.position = center;
|
||||||
centralVertex.normal = _vertexList[0].normal;
|
centralVertex.normal = _vertexList[0].normal;
|
||||||
|
centralVertex.uv0 = new Vector2(0.5f, 0.5f);
|
||||||
centralVertex.color = Color.white;
|
centralVertex.color = Color.white;
|
||||||
helper.AddVert(centralVertex);
|
helper.AddVert(centralVertex);
|
||||||
|
|
||||||
for (int i = 1; i < nCount; i++) helper.AddTriangle(i - 1, i, nCount);
|
for (int i = 1; i < nCount; i++) helper.AddTriangle(i - 1, i, nCount);
|
||||||
helper.AddTriangle(0, nCount - 1, nCount);
|
helper.AddTriangle(0, nCount - 1, nCount);
|
||||||
|
}
|
||||||
|
|
||||||
UIVertex vertex = new UIVertex();
|
UIVertex vertex = new UIVertex();
|
||||||
|
|
||||||
for(int i = 0; i < helper.currentVertCount; i++) {
|
for (int i = 0; i < helper.currentVertCount; i++)
|
||||||
|
{
|
||||||
helper.PopulateUIVertex(ref vertex, i);
|
helper.PopulateUIVertex(ref vertex, i);
|
||||||
|
|
||||||
vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate(
|
vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate(
|
||||||
Vector3.Distance(vertex.position, centralVertex.position) * height - Offset));
|
Vector3.Distance(vertex.position, center) * height - Offset));
|
||||||
|
|
||||||
helper.SetUIVertex(vertex, i);
|
helper.SetUIVertex(vertex, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Type.Radial: {
|
case Type.Radial:
|
||||||
|
{
|
||||||
|
Rect bounds = GetBounds(_vertexList);
|
||||||
|
|
||||||
float left = _vertexList[0].position.x;
|
float width = 1f / bounds.width / Zoom;
|
||||||
float right = _vertexList[0].position.x;
|
float height = 1f / bounds.height / Zoom;
|
||||||
float bottom = _vertexList[0].position.y;
|
|
||||||
float top = _vertexList[0].position.y;
|
|
||||||
|
|
||||||
float x = 0f;
|
|
||||||
float y = 0f;
|
|
||||||
|
|
||||||
for(int i = nCount - 1; i >= 1; --i) {
|
|
||||||
x = _vertexList[i].position.x;
|
|
||||||
|
|
||||||
if(x > right) right = x;
|
|
||||||
else if(x < left) left = x;
|
|
||||||
|
|
||||||
y = _vertexList[i].position.y;
|
|
||||||
|
|
||||||
if(y > top) top = y;
|
|
||||||
else if(y < bottom) bottom = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
float width = 1f / (right - left);
|
|
||||||
float height = 1f / (top - bottom);
|
|
||||||
|
|
||||||
|
if (ModifyVertices)
|
||||||
|
{
|
||||||
helper.Clear();
|
helper.Clear();
|
||||||
|
|
||||||
float centerX = (right + left) / 2f;
|
float radiusX = bounds.width / 2f;
|
||||||
float centerY = (bottom + top) / 2f;
|
float radiusY = bounds.height / 2f;
|
||||||
float radiusX = (right - left) / 2f;
|
|
||||||
float radiusY = (top - bottom) / 2f;
|
|
||||||
UIVertex centralVertex = new UIVertex();
|
UIVertex centralVertex = new UIVertex();
|
||||||
centralVertex.position = Vector3.right * centerX + Vector3.up * centerY + Vector3.forward * _vertexList[0].position.z;
|
centralVertex.position = Vector3.right * bounds.center.x + Vector3.up * bounds.center.y + Vector3.forward * _vertexList[0].position.z;
|
||||||
centralVertex.normal = _vertexList[0].normal;
|
centralVertex.normal = _vertexList[0].normal;
|
||||||
|
centralVertex.uv0 = new Vector2(0.5f, 0.5f);
|
||||||
centralVertex.color = Color.white;
|
centralVertex.color = Color.white;
|
||||||
|
|
||||||
int steps = 64;
|
int steps = 64;
|
||||||
|
@ -206,11 +206,12 @@ namespace UnityEngine.UI.Extensions
|
||||||
{
|
{
|
||||||
UIVertex curVertex = new UIVertex();
|
UIVertex curVertex = new UIVertex();
|
||||||
float angle = (float)i * 360f / (float)steps;
|
float angle = (float)i * 360f / (float)steps;
|
||||||
float curX = Mathf.Cos(Mathf.Deg2Rad * angle) * radiusX;
|
float cosX = Mathf.Cos(Mathf.Deg2Rad * angle);
|
||||||
float curY = Mathf.Sin(Mathf.Deg2Rad * angle) * radiusY;
|
float cosY = Mathf.Sin(Mathf.Deg2Rad * angle);
|
||||||
|
|
||||||
curVertex.position = Vector3.right * curX + Vector3.up * curY + Vector3.forward * _vertexList[0].position.z;
|
curVertex.position = Vector3.right * cosX * radiusX + Vector3.up * cosY * radiusY + Vector3.forward * _vertexList[0].position.z;
|
||||||
curVertex.normal = _vertexList[0].normal;
|
curVertex.normal = _vertexList[0].normal;
|
||||||
|
curVertex.uv0 = new Vector2((cosX + 1) * 0.5f, (cosY + 1) * 0.5f);
|
||||||
curVertex.color = Color.white;
|
curVertex.color = Color.white;
|
||||||
helper.AddVert(curVertex);
|
helper.AddVert(curVertex);
|
||||||
}
|
}
|
||||||
|
@ -219,16 +220,18 @@ namespace UnityEngine.UI.Extensions
|
||||||
|
|
||||||
for (int i = 1; i < steps; i++) helper.AddTriangle(i - 1, i, steps);
|
for (int i = 1; i < steps; i++) helper.AddTriangle(i - 1, i, steps);
|
||||||
helper.AddTriangle(0, steps - 1, steps);
|
helper.AddTriangle(0, steps - 1, steps);
|
||||||
|
}
|
||||||
|
|
||||||
UIVertex vertex = new UIVertex();
|
UIVertex vertex = new UIVertex();
|
||||||
|
|
||||||
for(int i = 0; i < helper.currentVertCount; i++) {
|
for (int i = 0; i < helper.currentVertCount; i++)
|
||||||
|
{
|
||||||
helper.PopulateUIVertex(ref vertex, i);
|
helper.PopulateUIVertex(ref vertex, i);
|
||||||
|
|
||||||
vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate(
|
vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate(
|
||||||
Mathf.Sqrt(
|
Mathf.Sqrt(
|
||||||
Mathf.Pow(Mathf.Abs(vertex.position.x - centerX) * width, 2f) +
|
Mathf.Pow(Mathf.Abs(vertex.position.x - bounds.center.x) * width, 2f) +
|
||||||
Mathf.Pow(Mathf.Abs(vertex.position.y - centerY) * height, 2f)) * 2f - Offset));
|
Mathf.Pow(Mathf.Abs(vertex.position.y - bounds.center.y) * height, 2f)) * 2f - Offset));
|
||||||
|
|
||||||
helper.SetUIVertex(vertex, i);
|
helper.SetUIVertex(vertex, i);
|
||||||
}
|
}
|
||||||
|
@ -237,22 +240,291 @@ namespace UnityEngine.UI.Extensions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Color BlendColor(Color colorA, Color colorB) {
|
Rect GetBounds(List<UIVertex> vertices)
|
||||||
switch(BlendMode) {
|
{
|
||||||
|
float left = vertices[0].position.x;
|
||||||
|
float right = left;
|
||||||
|
float bottom = vertices[0].position.y;
|
||||||
|
float top = bottom;
|
||||||
|
|
||||||
|
for (int i = vertices.Count - 1; i >= 1; --i)
|
||||||
|
{
|
||||||
|
float x = vertices[i].position.x;
|
||||||
|
float y = vertices[i].position.y;
|
||||||
|
|
||||||
|
if (x > right) right = x;
|
||||||
|
else if (x < left) left = x;
|
||||||
|
|
||||||
|
if (y > top) top = y;
|
||||||
|
else if (y < bottom) bottom = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Rect(left, bottom, right - left, top - bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplitTrianglesAtGradientStops(List<UIVertex> _vertexList, Rect bounds, float zoomOffset, VertexHelper helper)
|
||||||
|
{
|
||||||
|
List<float> stops = FindStops(zoomOffset, bounds);
|
||||||
|
if (stops.Count > 0)
|
||||||
|
{
|
||||||
|
helper.Clear();
|
||||||
|
|
||||||
|
int nCount = _vertexList.Count;
|
||||||
|
for (int i = 0; i < nCount; i += 3)
|
||||||
|
{
|
||||||
|
float[] positions = GetPositions(_vertexList, i);
|
||||||
|
List<int> originIndices = new List<int>(3);
|
||||||
|
List<UIVertex> starts = new List<UIVertex>(3);
|
||||||
|
List<UIVertex> ends = new List<UIVertex>(2);
|
||||||
|
|
||||||
|
for (int s = 0; s < stops.Count; s++)
|
||||||
|
{
|
||||||
|
int initialCount = helper.currentVertCount;
|
||||||
|
bool hadEnds = ends.Count > 0;
|
||||||
|
bool earlyStart = false;
|
||||||
|
|
||||||
|
// find any start vertices for this stop
|
||||||
|
for (int p = 0; p < 3; p++)
|
||||||
|
{
|
||||||
|
if (!originIndices.Contains(p) && positions[p] < stops[s])
|
||||||
|
{
|
||||||
|
// make sure the first index crosses the stop
|
||||||
|
int p1 = (p + 1) % 3;
|
||||||
|
var start = _vertexList[p + i];
|
||||||
|
if (positions[p1] > stops[s])
|
||||||
|
{
|
||||||
|
originIndices.Insert(0, p);
|
||||||
|
starts.Insert(0, start);
|
||||||
|
earlyStart = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
originIndices.Add(p);
|
||||||
|
starts.Add(start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// bail if all before or after the stop
|
||||||
|
if (originIndices.Count == 0)
|
||||||
|
continue;
|
||||||
|
if (originIndices.Count == 3)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// report any start vertices
|
||||||
|
foreach (var start in starts)
|
||||||
|
helper.AddVert(start);
|
||||||
|
|
||||||
|
// make two ends, splitting at the stop
|
||||||
|
ends.Clear();
|
||||||
|
foreach (int index in originIndices)
|
||||||
|
{
|
||||||
|
int oppositeIndex = (index + 1) % 3;
|
||||||
|
if (positions[oppositeIndex] < stops[s])
|
||||||
|
oppositeIndex = (oppositeIndex + 1) % 3;
|
||||||
|
ends.Add(CreateSplitVertex(_vertexList[index + i], _vertexList[oppositeIndex + i], stops[s]));
|
||||||
|
}
|
||||||
|
if (ends.Count == 1)
|
||||||
|
{
|
||||||
|
int oppositeIndex = (originIndices[0] + 2) % 3;
|
||||||
|
ends.Add(CreateSplitVertex(_vertexList[originIndices[0] + i], _vertexList[oppositeIndex + i], stops[s]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// report end vertices
|
||||||
|
foreach (var end in ends)
|
||||||
|
helper.AddVert(end);
|
||||||
|
|
||||||
|
// make triangles
|
||||||
|
if (hadEnds)
|
||||||
|
{
|
||||||
|
helper.AddTriangle(initialCount - 2, initialCount, initialCount + 1);
|
||||||
|
helper.AddTriangle(initialCount - 2, initialCount + 1, initialCount - 1);
|
||||||
|
if (starts.Count > 0)
|
||||||
|
{
|
||||||
|
if (earlyStart)
|
||||||
|
helper.AddTriangle(initialCount - 2, initialCount + 3, initialCount);
|
||||||
|
else
|
||||||
|
helper.AddTriangle(initialCount + 1, initialCount + 3, initialCount - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int vertexCount = helper.currentVertCount;
|
||||||
|
helper.AddTriangle(initialCount, vertexCount - 2, vertexCount - 1);
|
||||||
|
if (starts.Count > 1)
|
||||||
|
helper.AddTriangle(initialCount, vertexCount - 1, initialCount + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
starts.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up after looping through gradient stops
|
||||||
|
if (ends.Count > 0)
|
||||||
|
{
|
||||||
|
// find any final vertices after the gradient stops
|
||||||
|
if (starts.Count == 0)
|
||||||
|
{
|
||||||
|
for (int p = 0; p < 3; p++)
|
||||||
|
{
|
||||||
|
if (!originIndices.Contains(p) && positions[p] > stops[stops.Count - 1])
|
||||||
|
{
|
||||||
|
int p1 = (p + 1) % 3;
|
||||||
|
UIVertex end = _vertexList[p + i];
|
||||||
|
if (positions[p1] > stops[stops.Count - 1])
|
||||||
|
starts.Insert(0, end);
|
||||||
|
else
|
||||||
|
starts.Add(end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// report final vertices
|
||||||
|
foreach (var start in starts)
|
||||||
|
helper.AddVert(start);
|
||||||
|
|
||||||
|
// make final triangle(s)
|
||||||
|
int vertexCount = helper.currentVertCount;
|
||||||
|
if (starts.Count > 1)
|
||||||
|
{
|
||||||
|
helper.AddTriangle(vertexCount - 4, vertexCount - 2, vertexCount - 1);
|
||||||
|
helper.AddTriangle(vertexCount - 4, vertexCount - 1, vertexCount - 3);
|
||||||
|
}
|
||||||
|
else if (starts.Count > 0)
|
||||||
|
{
|
||||||
|
helper.AddTriangle(vertexCount - 3, vertexCount - 1, vertexCount - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if the triangle wasn't split, add it as-is
|
||||||
|
helper.AddVert(_vertexList[i]);
|
||||||
|
helper.AddVert(_vertexList[i + 1]);
|
||||||
|
helper.AddVert(_vertexList[i + 2]);
|
||||||
|
int vertexCount = helper.currentVertCount;
|
||||||
|
helper.AddTriangle(vertexCount - 3, vertexCount - 2, vertexCount - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float[] GetPositions(List<UIVertex> _vertexList, int index)
|
||||||
|
{
|
||||||
|
float[] positions = new float[3];
|
||||||
|
if (GradientType == Type.Horizontal)
|
||||||
|
{
|
||||||
|
positions[0] = _vertexList[index].position.x;
|
||||||
|
positions[1] = _vertexList[index + 1].position.x;
|
||||||
|
positions[2] = _vertexList[index + 2].position.x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
positions[0] = _vertexList[index].position.y;
|
||||||
|
positions[1] = _vertexList[index + 1].position.y;
|
||||||
|
positions[2] = _vertexList[index + 2].position.y;
|
||||||
|
}
|
||||||
|
return positions;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<float> FindStops(float zoomOffset, Rect bounds)
|
||||||
|
{
|
||||||
|
List<float> stops = new List<float>();
|
||||||
|
var scaledOffset = Offset * Zoom;
|
||||||
|
foreach (var color in EffectGradient.colorKeys)
|
||||||
|
{
|
||||||
|
if (color.time >= (1 - (zoomOffset + scaledOffset)))
|
||||||
|
break;
|
||||||
|
if (color.time > (zoomOffset - scaledOffset))
|
||||||
|
stops.Add(((color.time - 0.5f) * Zoom) + 0.5f + scaledOffset);
|
||||||
|
}
|
||||||
|
foreach (var alpha in EffectGradient.alphaKeys)
|
||||||
|
{
|
||||||
|
if (alpha.time >= (1 - (zoomOffset + scaledOffset)))
|
||||||
|
break;
|
||||||
|
if (alpha.time > (zoomOffset - scaledOffset))
|
||||||
|
stops.Add(((alpha.time - 0.5f) * Zoom) + 0.5f + scaledOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
float min = bounds.xMin;
|
||||||
|
float size = bounds.width;
|
||||||
|
if (GradientType == Type.Vertical)
|
||||||
|
{
|
||||||
|
min = bounds.yMin;
|
||||||
|
size = bounds.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
stops.Sort();
|
||||||
|
for (int i = 0; i < stops.Count; i++)
|
||||||
|
{
|
||||||
|
stops[i] = (stops[i] * size) + min;
|
||||||
|
|
||||||
|
if (i > 0 && Math.Abs(stops[i] - stops[i - 1]) < 2)
|
||||||
|
{
|
||||||
|
stops.RemoveAt(i);
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stops;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIVertex CreateSplitVertex(UIVertex vertex1, UIVertex vertex2, float stop)
|
||||||
|
{
|
||||||
|
if (GradientType == Type.Horizontal)
|
||||||
|
{
|
||||||
|
float sx = vertex1.position.x - stop;
|
||||||
|
float dx = vertex1.position.x - vertex2.position.x;
|
||||||
|
float dy = vertex1.position.y - vertex2.position.y;
|
||||||
|
float uvx = vertex1.uv0.x - vertex2.uv0.x;
|
||||||
|
float uvy = vertex1.uv0.y - vertex2.uv0.y;
|
||||||
|
float ratio = sx / dx;
|
||||||
|
float splitY = vertex1.position.y - (dy * ratio);
|
||||||
|
|
||||||
|
UIVertex splitVertex = new UIVertex();
|
||||||
|
splitVertex.position = new Vector3(stop, splitY, vertex1.position.z);
|
||||||
|
splitVertex.normal = vertex1.normal;
|
||||||
|
splitVertex.uv0 = new Vector2(vertex1.uv0.x - (uvx * ratio), vertex1.uv0.y - (uvy * ratio));
|
||||||
|
splitVertex.color = Color.white;
|
||||||
|
return splitVertex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float sy = vertex1.position.y - stop;
|
||||||
|
float dy = vertex1.position.y - vertex2.position.y;
|
||||||
|
float dx = vertex1.position.x - vertex2.position.x;
|
||||||
|
float uvx = vertex1.uv0.x - vertex2.uv0.x;
|
||||||
|
float uvy = vertex1.uv0.y - vertex2.uv0.y;
|
||||||
|
float ratio = sy / dy;
|
||||||
|
float splitX = vertex1.position.x - (dx * ratio);
|
||||||
|
|
||||||
|
UIVertex splitVertex = new UIVertex();
|
||||||
|
splitVertex.position = new Vector3(splitX, stop, vertex1.position.z);
|
||||||
|
splitVertex.normal = vertex1.normal;
|
||||||
|
splitVertex.uv0 = new Vector2(vertex1.uv0.x - (uvx * ratio), vertex1.uv0.y - (uvy * ratio));
|
||||||
|
splitVertex.color = Color.white;
|
||||||
|
return splitVertex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Color BlendColor(Color colorA, Color colorB)
|
||||||
|
{
|
||||||
|
switch (BlendMode)
|
||||||
|
{
|
||||||
default: return colorB;
|
default: return colorB;
|
||||||
case Blend.Add: return colorA + colorB;
|
case Blend.Add: return colorA + colorB;
|
||||||
case Blend.Multiply: return colorA * colorB;
|
case Blend.Multiply: return colorA * colorB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Type {
|
public enum Type
|
||||||
|
{
|
||||||
Horizontal,
|
Horizontal,
|
||||||
Vertical,
|
Vertical,
|
||||||
Radial,
|
Radial,
|
||||||
Diamond
|
Diamond
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Blend {
|
public enum Blend
|
||||||
|
{
|
||||||
Override,
|
Override,
|
||||||
Add,
|
Add,
|
||||||
Multiply
|
Multiply
|
||||||
|
|
Loading…
Reference in New Issue