Merged in adibacco/unity-ui-extensions (pull request #17)
Added support for multiple segments drawingrelease
commit
2145c4671b
|
@ -45,6 +45,8 @@ namespace UnityEngine.UI.Extensions
|
||||||
|
|
||||||
[SerializeField, Tooltip("Points to draw lines between\n Can be improved using the Resolution Option")]
|
[SerializeField, Tooltip("Points to draw lines between\n Can be improved using the Resolution Option")]
|
||||||
internal Vector2[] m_points;
|
internal Vector2[] m_points;
|
||||||
|
[SerializeField, Tooltip("Segments to be drawn\n This is a list of arrays of points")]
|
||||||
|
internal List<Vector2[]> m_segments;
|
||||||
|
|
||||||
[SerializeField, Tooltip("Thickness of the line")]
|
[SerializeField, Tooltip("Thickness of the line")]
|
||||||
internal float lineThickness = 2;
|
internal float lineThickness = 2;
|
||||||
|
@ -116,46 +118,55 @@ namespace UnityEngine.UI.Extensions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnPopulateMesh(VertexHelper vh)
|
/// <summary>
|
||||||
|
/// List of Segments to be drawn.
|
||||||
|
/// </summary>
|
||||||
|
public List<Vector2[]> Segments
|
||||||
{
|
{
|
||||||
if (m_points == null)
|
get
|
||||||
return;
|
|
||||||
GeneratedUVs();
|
|
||||||
Vector2[] pointsToDraw = m_points;
|
|
||||||
//If Bezier is desired, pick the implementation
|
|
||||||
if (BezierMode != BezierType.None && BezierMode != BezierType.Catenary && m_points.Length > 3)
|
|
||||||
{
|
{
|
||||||
BezierPath bezierPath = new BezierPath();
|
return m_segments;
|
||||||
|
}
|
||||||
|
|
||||||
bezierPath.SetControlPoints(pointsToDraw);
|
set
|
||||||
|
{
|
||||||
|
m_segments = value;
|
||||||
|
SetAllDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PopulateMesh(VertexHelper vh, Vector2[] pointsToDraw)
|
||||||
|
{
|
||||||
|
//If Bezier is desired, pick the implementation
|
||||||
|
if (BezierMode != BezierType.None && BezierMode != BezierType.Catenary && pointsToDraw.Length > 3) {
|
||||||
|
BezierPath bezierPath = new BezierPath ();
|
||||||
|
|
||||||
|
bezierPath.SetControlPoints (pointsToDraw);
|
||||||
bezierPath.SegmentsPerCurve = bezierSegmentsPerCurve;
|
bezierPath.SegmentsPerCurve = bezierSegmentsPerCurve;
|
||||||
List<Vector2> drawingPoints;
|
List<Vector2> drawingPoints;
|
||||||
switch (BezierMode)
|
switch (BezierMode) {
|
||||||
{
|
|
||||||
case BezierType.Basic:
|
case BezierType.Basic:
|
||||||
drawingPoints = bezierPath.GetDrawingPoints0();
|
drawingPoints = bezierPath.GetDrawingPoints0 ();
|
||||||
break;
|
break;
|
||||||
case BezierType.Improved:
|
case BezierType.Improved:
|
||||||
drawingPoints = bezierPath.GetDrawingPoints1();
|
drawingPoints = bezierPath.GetDrawingPoints1 ();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
drawingPoints = bezierPath.GetDrawingPoints2();
|
drawingPoints = bezierPath.GetDrawingPoints2 ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pointsToDraw = drawingPoints.ToArray();
|
pointsToDraw = drawingPoints.ToArray ();
|
||||||
}
|
}
|
||||||
if (BezierMode == BezierType.Catenary && m_points.Length == 2)
|
if (BezierMode == BezierType.Catenary && pointsToDraw.Length == 2) {
|
||||||
{
|
CableCurve cable = new CableCurve (pointsToDraw);
|
||||||
CableCurve cable = new CableCurve(pointsToDraw);
|
|
||||||
cable.slack = Resoloution;
|
cable.slack = Resoloution;
|
||||||
cable.steps = BezierSegmentsPerCurve;
|
cable.steps = BezierSegmentsPerCurve;
|
||||||
pointsToDraw = cable.Points();
|
pointsToDraw = cable.Points ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImproveResolution != ResolutionMode.None)
|
if (ImproveResolution != ResolutionMode.None) {
|
||||||
{
|
pointsToDraw = IncreaseResolution (pointsToDraw);
|
||||||
pointsToDraw = IncreaseResolution(pointsToDraw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// scale based on the size of the rect or use absolute, this is switchable
|
// scale based on the size of the rect or use absolute, this is switchable
|
||||||
|
@ -164,120 +175,120 @@ namespace UnityEngine.UI.Extensions
|
||||||
var offsetX = -rectTransform.pivot.x * sizeX;
|
var offsetX = -rectTransform.pivot.x * sizeX;
|
||||||
var offsetY = -rectTransform.pivot.y * sizeY;
|
var offsetY = -rectTransform.pivot.y * sizeY;
|
||||||
|
|
||||||
vh.Clear();
|
|
||||||
|
|
||||||
// Generate the quads that make up the wide line
|
// Generate the quads that make up the wide line
|
||||||
var segments = new List<UIVertex[]>();
|
var segments = new List<UIVertex[]> ();
|
||||||
if (lineList)
|
if (lineList) {
|
||||||
{
|
for (var i = 1; i < pointsToDraw.Length; i += 2) {
|
||||||
for (var i = 1; i < pointsToDraw.Length; i += 2)
|
var start = pointsToDraw [i - 1];
|
||||||
{
|
var end = pointsToDraw [i];
|
||||||
var start = pointsToDraw[i - 1];
|
start = new Vector2 (start.x * sizeX + offsetX, start.y * sizeY + offsetY);
|
||||||
var end = pointsToDraw[i];
|
end = new Vector2 (end.x * sizeX + offsetX, end.y * sizeY + offsetY);
|
||||||
start = new Vector2(start.x * sizeX + offsetX, start.y * sizeY + offsetY);
|
|
||||||
end = new Vector2(end.x * sizeX + offsetX, end.y * sizeY + offsetY);
|
|
||||||
|
|
||||||
if (lineCaps)
|
if (lineCaps) {
|
||||||
{
|
segments.Add (CreateLineCap (start, end, SegmentType.Start));
|
||||||
segments.Add(CreateLineCap(start, end, SegmentType.Start));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//segments.Add(CreateLineSegment(start, end, SegmentType.Full));
|
//segments.Add(CreateLineSegment(start, end, SegmentType.Full));
|
||||||
segments.Add(CreateLineSegment(start, end, SegmentType.Middle));
|
segments.Add (CreateLineSegment (start, end, SegmentType.Middle));
|
||||||
|
|
||||||
if (lineCaps)
|
if (lineCaps) {
|
||||||
{
|
segments.Add (CreateLineCap (start, end, SegmentType.End));
|
||||||
segments.Add(CreateLineCap(start, end, SegmentType.End));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
for (var i = 1; i < pointsToDraw.Length; i++) {
|
||||||
{
|
var start = pointsToDraw [i - 1];
|
||||||
for (var i = 1; i < pointsToDraw.Length; i++)
|
var end = pointsToDraw [i];
|
||||||
{
|
start = new Vector2 (start.x * sizeX + offsetX, start.y * sizeY + offsetY);
|
||||||
var start = pointsToDraw[i - 1];
|
end = new Vector2 (end.x * sizeX + offsetX, end.y * sizeY + offsetY);
|
||||||
var end = pointsToDraw[i];
|
|
||||||
start = new Vector2(start.x * sizeX + offsetX, start.y * sizeY + offsetY);
|
|
||||||
end = new Vector2(end.x * sizeX + offsetX, end.y * sizeY + offsetY);
|
|
||||||
|
|
||||||
if (lineCaps && i == 1)
|
if (lineCaps && i == 1) {
|
||||||
{
|
segments.Add (CreateLineCap (start, end, SegmentType.Start));
|
||||||
segments.Add(CreateLineCap(start, end, SegmentType.Start));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
segments.Add(CreateLineSegment(start, end, SegmentType.Middle));
|
segments.Add (CreateLineSegment (start, end, SegmentType.Middle));
|
||||||
//segments.Add(CreateLineSegment(start, end, SegmentType.Full));
|
//segments.Add(CreateLineSegment(start, end, SegmentType.Full));
|
||||||
|
|
||||||
if (lineCaps && i == pointsToDraw.Length - 1)
|
if (lineCaps && i == pointsToDraw.Length - 1) {
|
||||||
{
|
segments.Add (CreateLineCap (start, end, SegmentType.End));
|
||||||
segments.Add(CreateLineCap(start, end, SegmentType.End));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the line segments to the vertex helper, creating any joins as needed
|
// Add the line segments to the vertex helper, creating any joins as needed
|
||||||
for (var i = 0; i < segments.Count; i++)
|
for (var i = 0; i < segments.Count; i++) {
|
||||||
{
|
if (!lineList && i < segments.Count - 1) {
|
||||||
if (!lineList && i < segments.Count - 1)
|
var vec1 = segments [i] [1].position - segments [i] [2].position;
|
||||||
{
|
var vec2 = segments [i + 1] [2].position - segments [i + 1] [1].position;
|
||||||
var vec1 = segments[i][1].position - segments[i][2].position;
|
var angle = Vector2.Angle (vec1, vec2) * Mathf.Deg2Rad;
|
||||||
var vec2 = segments[i + 1][2].position - segments[i + 1][1].position;
|
|
||||||
var angle = Vector2.Angle(vec1, vec2) * Mathf.Deg2Rad;
|
|
||||||
|
|
||||||
// Positive sign means the line is turning in a 'clockwise' direction
|
// Positive sign means the line is turning in a 'clockwise' direction
|
||||||
var sign = Mathf.Sign(Vector3.Cross(vec1.normalized, vec2.normalized).z);
|
var sign = Mathf.Sign (Vector3.Cross (vec1.normalized, vec2.normalized).z);
|
||||||
|
|
||||||
// Calculate the miter point
|
// Calculate the miter point
|
||||||
var miterDistance = lineThickness / (2 * Mathf.Tan(angle / 2));
|
var miterDistance = lineThickness / (2 * Mathf.Tan (angle / 2));
|
||||||
var miterPointA = segments[i][2].position - vec1.normalized * miterDistance * sign;
|
var miterPointA = segments [i] [2].position - vec1.normalized * miterDistance * sign;
|
||||||
var miterPointB = segments[i][3].position + vec1.normalized * miterDistance * sign;
|
var miterPointB = segments [i] [3].position + vec1.normalized * miterDistance * sign;
|
||||||
|
|
||||||
var joinType = LineJoins;
|
var joinType = LineJoins;
|
||||||
if (joinType == JoinType.Miter)
|
if (joinType == JoinType.Miter) {
|
||||||
{
|
|
||||||
// Make sure we can make a miter join without too many artifacts.
|
// Make sure we can make a miter join without too many artifacts.
|
||||||
if (miterDistance < vec1.magnitude / 2 && miterDistance < vec2.magnitude / 2 && angle > MIN_MITER_JOIN)
|
if (miterDistance < vec1.magnitude / 2 && miterDistance < vec2.magnitude / 2 && angle > MIN_MITER_JOIN) {
|
||||||
{
|
segments [i] [2].position = miterPointA;
|
||||||
segments[i][2].position = miterPointA;
|
segments [i] [3].position = miterPointB;
|
||||||
segments[i][3].position = miterPointB;
|
segments [i + 1] [0].position = miterPointB;
|
||||||
segments[i + 1][0].position = miterPointB;
|
segments [i + 1] [1].position = miterPointA;
|
||||||
segments[i + 1][1].position = miterPointA;
|
} else {
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
joinType = JoinType.Bevel;
|
joinType = JoinType.Bevel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (joinType == JoinType.Bevel)
|
if (joinType == JoinType.Bevel) {
|
||||||
{
|
if (miterDistance < vec1.magnitude / 2 && miterDistance < vec2.magnitude / 2 && angle > MIN_BEVEL_NICE_JOIN) {
|
||||||
if (miterDistance < vec1.magnitude / 2 && miterDistance < vec2.magnitude / 2 && angle > MIN_BEVEL_NICE_JOIN)
|
if (sign < 0) {
|
||||||
{
|
segments [i] [2].position = miterPointA;
|
||||||
if (sign < 0)
|
segments [i + 1] [1].position = miterPointA;
|
||||||
{
|
} else {
|
||||||
segments[i][2].position = miterPointA;
|
segments [i] [3].position = miterPointB;
|
||||||
segments[i + 1][1].position = miterPointA;
|
segments [i + 1] [0].position = miterPointB;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
segments[i][3].position = miterPointB;
|
|
||||||
segments[i + 1][0].position = miterPointB;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var join = new UIVertex[] { segments[i][2], segments[i][3], segments[i + 1][0], segments[i + 1][1] };
|
var join = new UIVertex[] { segments [i] [2], segments [i] [3], segments [i + 1] [0], segments [i + 1] [1] };
|
||||||
vh.AddUIVertexQuad(join);
|
vh.AddUIVertexQuad (join);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vh.AddUIVertexQuad(segments[i]);
|
vh.AddUIVertexQuad (segments [i]);
|
||||||
}
|
}
|
||||||
if (vh.currentVertCount > 64000)
|
if (vh.currentVertCount > 64000) {
|
||||||
{
|
Debug.LogError ("Max Verticies size is 64000, current mesh vertcies count is [" + vh.currentVertCount + "] - Cannot Draw");
|
||||||
Debug.LogError("Max Verticies size is 64000, current mesh vertcies count is [" + vh.currentVertCount + "] - Cannot Draw");
|
vh.Clear ();
|
||||||
vh.Clear();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPopulateMesh(VertexHelper vh)
|
||||||
|
{
|
||||||
|
if (m_points != null && m_points.Length > 0) {
|
||||||
|
GeneratedUVs ();
|
||||||
|
vh.Clear ();
|
||||||
|
|
||||||
|
PopulateMesh (vh, m_points);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (m_segments != null && m_segments.Count > 0) {
|
||||||
|
GeneratedUVs ();
|
||||||
|
vh.Clear ();
|
||||||
|
|
||||||
|
for (int s = 0; s < m_segments.Count; s++) {
|
||||||
|
Vector2[] pointsToDraw = m_segments [s];
|
||||||
|
PopulateMesh (vh, pointsToDraw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private UIVertex[] CreateLineCap(Vector2 start, Vector2 end, SegmentType type)
|
private UIVertex[] CreateLineCap(Vector2 start, Vector2 end, SegmentType type)
|
||||||
|
|
Loading…
Reference in New Issue