12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970 |
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
-
- namespace XUGL
- {
- /// <summary>
- /// UGUI Graphics Library.
- /// |UGUI 图形库
- /// </summary>
- public static class UGL
- {
- /// <summary>
- /// 曲线方向
- /// </summary>
- public enum Direction
- {
- /// <summary>
- /// 沿X轴方向
- /// </summary>
- XAxis,
- /// <summary>
- /// 沿Y轴方向
- /// </summary>
- YAxis,
- /// <summary>
- /// 随机无序的。如一个闭合的环状曲线。
- /// </summary>
- Random
- }
- private static readonly Color32 s_ClearColor32 = new Color32(0, 0, 0, 0);
- private static readonly Vector2 s_ZeroVector2 = Vector2.zero;
- private static UIVertex[] s_Vertex = new UIVertex[4];
- private static List<Vector3> s_CurvesPosList = new List<Vector3>();
-
- /// <summary>
- /// Draw a arrow. 画箭头
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="startPoint">起始位置</param>
- /// <param name="arrowPoint">箭头位置</param>
- /// <param name="width">箭头宽</param>
- /// <param name="height">箭头长</param>
- /// <param name="offset">相对箭头位置的偏移</param>
- /// <param name="dent">箭头凹度</param>
- /// <param name="color">颜色</param>
- public static void DrawArrow(VertexHelper vh, Vector3 startPoint, Vector3 arrowPoint, float width,
- float height, float offset, float dent, Color32 color)
- {
- var dir = (arrowPoint - startPoint).normalized;
- var sharpPos = arrowPoint + (offset + height / 4) * dir;
- var middle = sharpPos + (dent - height) * dir;
- var diff = Vector3.Cross(dir, Vector3.forward).normalized * width / 2;
- var left = sharpPos - height * dir + diff;
- var right = sharpPos - height * dir - diff;
- DrawTriangle(vh, middle, sharpPos, left, color);
- DrawTriangle(vh, middle, sharpPos, right, color);
- }
-
- /// <summary>
- /// Draw a line. 画直线
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="startPoint">起点</param>
- /// <param name="endPoint">终点</param>
- /// <param name="width">线宽</param>
- /// <param name="color">颜色</param>
- public static void DrawLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, Color32 color)
- {
- DrawLine(vh, startPoint, endPoint, width, color, color);
- }
-
- /// <summary>
- /// Draw a line. 画直线
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="startPoint">起点</param>
- /// <param name="endPoint">终点</param>
- /// <param name="width">线宽</param>
- /// <param name="color">颜色</param>
- /// <param name="toColor">渐变颜色</param>
- public static void DrawLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, Color32 color, Color32 toColor)
- {
- if (startPoint == endPoint) return;
- Vector3 v = Vector3.Cross(endPoint - startPoint, Vector3.forward).normalized * width;
- s_Vertex[0].position = startPoint - v;
- s_Vertex[1].position = endPoint - v;
- s_Vertex[2].position = endPoint + v;
- s_Vertex[3].position = startPoint + v;
-
- for (int j = 0; j < 4; j++)
- {
- s_Vertex[j].color = j == 0 || j == 3 ? color : toColor;
- s_Vertex[j].uv0 = s_ZeroVector2;
- }
- vh.AddUIVertexQuad(s_Vertex);
- }
-
- /// <summary>
- /// Draw a line defined by three points. 画一条由3个点确定的折线
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="startPoint">起始点</param>
- /// <param name="middlePoint">中间转折点</param>
- /// <param name="endPoint">终点</param>
- /// <param name="width">线宽</param>
- /// <param name="color">颜色</param>
- public static void DrawLine(VertexHelper vh, Vector3 startPoint, Vector3 middlePoint, Vector3 endPoint,
- float width, Color32 color)
- {
- var dir1 = (middlePoint - startPoint).normalized;
- var dir2 = (endPoint - middlePoint).normalized;
- var dir1v = Vector3.Cross(dir1, Vector3.forward).normalized;
- var dir2v = Vector3.Cross(dir2, Vector3.forward).normalized;
- var dir3 = (dir1 + dir2).normalized;
- var isDown = Vector3.Cross(dir1, dir2).z <= 0;
- var angle = (180 - Vector3.Angle(dir1, dir2)) * Mathf.Deg2Rad / 2;
- var diff = width / Mathf.Sin(angle);
- var dirDp = Vector3.Cross(dir3, Vector3.forward).normalized;
- var dnPos = middlePoint + (isDown ? dirDp : -dirDp) * diff;
- var upPos1 = middlePoint + (isDown ? -dir1v : dir1v) * width;
- var upPos2 = middlePoint + (isDown ? -dir2v : dir2v) * width;
- var startUp = startPoint - dir1v * width;
- var startDn = startPoint + dir1v * width;
- var endUp = endPoint - dir2v * width;
- var endDn = endPoint + dir2v * width;
- if (isDown)
- {
- DrawQuadrilateral(vh, startDn, startUp, upPos1, dnPos, color);
- DrawQuadrilateral(vh, dnPos, upPos2, endUp, endDn, color);
- DrawTriangle(vh, dnPos, upPos1, upPos2, color);
- }
- else
- {
- DrawQuadrilateral(vh, startDn, startUp, dnPos, upPos1, color);
- DrawQuadrilateral(vh, upPos2, dnPos, endUp, endDn, color);
- DrawTriangle(vh, dnPos, upPos1, upPos2, color);
- }
- }
-
- public static void DrawLine(VertexHelper vh, List<Vector3> points, float width, Color32 color, bool smooth, bool closepath = false)
- {
- for (int i = points.Count - 1; i >= 1; i--)
- {
- if (UGLHelper.IsValueEqualsVector3(points[i], points[i - 1]))
- points.RemoveAt(i);
- }
- if (points.Count < 2) return;
- else if (points.Count <= 2)
- {
- DrawLine(vh, points[0], points[1], width, color);
- }
- else if (smooth)
- {
- DrawCurves(vh, points, width, color, 2, 2, Direction.XAxis, float.NaN, closepath);
- }
- else
- {
- var ltp = Vector3.zero;
- var lbp = Vector3.zero;
- var ntp = Vector3.zero;
- var nbp = Vector3.zero;
- var itp = Vector3.zero;
- var ibp = Vector3.zero;
- var ctp = Vector3.zero;
- var cbp = Vector3.zero;
- if (closepath && !UGLHelper.IsValueEqualsVector3(points[points.Count - 1], points[0]))
- {
- points.Add(points[0]);
- }
- for (int i = 1; i < points.Count - 1; i++)
- {
- bool bitp = true, bibp = true;
- UGLHelper.GetLinePoints(points[i - 1], points[i], points[i + 1], width,
- ref ltp, ref lbp,
- ref ntp, ref nbp,
- ref itp, ref ibp,
- ref ctp, ref cbp,
- ref bitp, ref bibp);
- if (i == 1)
- {
- vh.AddVert(ltp, color, Vector2.zero);
- vh.AddVert(lbp, color, Vector2.zero);
- }
- if (bitp == bibp)
- {
- AddVertToVertexHelper(vh, itp, ibp, color);
- }
- else
- {
- if (bitp)
- {
- AddVertToVertexHelper(vh, itp, ctp, color);
- AddVertToVertexHelper(vh, itp, cbp, color);
- }
- else
- {
- AddVertToVertexHelper(vh, ctp, ibp, color);
- AddVertToVertexHelper(vh, cbp, ibp, color);
- }
- }
- }
- AddVertToVertexHelper(vh, ntp, nbp, color);
- }
- }
-
- public static void AddVertToVertexHelper(VertexHelper vh, Vector3 top,
- Vector3 bottom, Color32 color, bool needTriangle = true)
- {
- AddVertToVertexHelper(vh, top, bottom, color, color, needTriangle);
- }
-
- public static void AddVertToVertexHelper(VertexHelper vh, Vector3 top,
- Vector3 bottom, Color32 topColor, Color32 bottomColor, bool needTriangle = true)
- {
- var lastVertCount = vh.currentVertCount;
- vh.AddVert(top, topColor, Vector2.zero);
- vh.AddVert(bottom, bottomColor, Vector2.zero);
- if (needTriangle)
- {
- var indexRt = lastVertCount;
- var indexRb = indexRt + 1;
- var indexLt = indexRt - 2;
- var indexLb = indexLt + 1;
- vh.AddTriangle(indexLt, indexRb, indexLb);
- vh.AddTriangle(indexLt, indexRt, indexRb);
- }
- }
-
- /// <summary>
- /// Draw a dash line. 画虚线
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="startPoint">起始点</param>
- /// <param name="endPoint">结束点</param>
- /// <param name="width">线宽</param>
- /// <param name="color">起始颜色</param>
- /// <param name="toColor">结束颜色</param>
- /// <param name="lineLength">实线部分长度,默认为线宽的12倍</param>
- /// <param name="gapLength">间隙部分长度,默认为线宽的3倍</param>
- /// <param name="posList">可选,输出的关键点</param>
- public static void DrawDashLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width,
- Color32 color, Color32 toColor, float lineLength = 0f, float gapLength = 0f, List<Vector3> posList = null)
- {
- float dist = Vector3.Distance(startPoint, endPoint);
- if (dist < 0.1f) return;
- if (lineLength == 0) lineLength = 12 * width;
- if (gapLength == 0) gapLength = 3 * width;
- int segment = Mathf.CeilToInt(dist / (lineLength + gapLength));
- Vector3 dir = (endPoint - startPoint).normalized;
- Vector3 sp = startPoint, np;
- var isGradient = !color.Equals(toColor);
- if (posList != null) posList.Clear();
- for (int i = 1; i <= segment; i++)
- {
- if (posList != null) posList.Add(sp);
- np = startPoint + dir * dist * i / segment;
- var dashep = np - dir * gapLength;
- DrawLine(vh, sp, dashep, width, isGradient ? Color32.Lerp(color, toColor, i * 1.0f / segment) : color);
- sp = np;
- }
- if (posList != null) posList.Add(endPoint);
- DrawLine(vh, sp, endPoint, width, toColor);
- }
-
- /// <summary>
- /// Draw a dot line. 画点线
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="startPoint">起始点</param>
- /// <param name="endPoint">结束点</param>
- /// <param name="width">线宽</param>
- /// <param name="color">起始颜色</param>
- /// <param name="toColor">结束颜色</param>
- /// <param name="lineLength">实线部分长度,默认为线宽的3倍</param>
- /// <param name="gapLength">间隙部分长度,默认为线宽的3倍</param>
- /// <param name="posList">可选,输出的关键点</param>
- public static void DrawDotLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width,
- Color32 color, Color32 toColor, float lineLength = 0f, float gapLength = 0f, List<Vector3> posList = null)
- {
- var dist = Vector3.Distance(startPoint, endPoint);
- if (dist < 0.1f) return;
- if (lineLength == 0) lineLength = 3 * width;
- if (gapLength == 0) gapLength = 3 * width;
- var segment = Mathf.CeilToInt(dist / (lineLength + gapLength));
- var dir = (endPoint - startPoint).normalized;
- var sp = startPoint;
- var np = Vector3.zero;
- var isGradient = !color.Equals(toColor);
- if (posList != null) posList.Clear();
- for (int i = 1; i <= segment; i++)
- {
- if (posList != null) posList.Add(sp);
- np = startPoint + dir * dist * i / segment;
- var dashep = np - dir * gapLength;
- DrawLine(vh, sp, dashep, width, isGradient ? Color32.Lerp(color, toColor, i * 1.0f / segment) : color);
- sp = np;
- }
- if (posList != null) posList.Add(endPoint);
- DrawLine(vh, sp, endPoint, width, toColor);
- }
-
- /// <summary>
- /// Draw a dash-dot line. 画点划线
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="startPoint">起始点</param>
- /// <param name="endPoint">结束点</param>
- /// <param name="width">线宽</param>
- /// <param name="color">颜色</param>
- /// <param name="dashLength">划线长,默认15倍线宽</param>
- /// <param name="dotLength">点线长,默认3倍线宽</param>
- /// <param name="gapLength">间隙长,默认5倍线宽</param>
- /// <param name="posList">可选,输出的关键点</param>
- public static void DrawDashDotLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width,
- Color32 color, float dashLength = 0f, float dotLength = 0, float gapLength = 0f,
- List<Vector3> posList = null)
- {
- float dist = Vector3.Distance(startPoint, endPoint);
- if (dist < 0.1f) return;
- if (dashLength == 0) dashLength = 15 * width;
- if (dotLength == 0) dotLength = 3 * width;
- if (gapLength == 0) gapLength = 5 * width;
- int segment = Mathf.CeilToInt(dist / (dashLength + 2 * gapLength + dotLength));
- Vector3 dir = (endPoint - startPoint).normalized;
- Vector3 sp = startPoint, np;
- if (posList != null) posList.Clear();
- for (int i = 1; i <= segment; i++)
- {
- if (posList != null) posList.Add(sp);
- np = startPoint + dir * dist * i / segment;
- var dashep = np - dir * (2 * gapLength + dotLength);
- DrawLine(vh, sp, dashep, width, color);
- if (posList != null) posList.Add(dashep);
- var dotsp = dashep + gapLength * dir;
- var dotep = dotsp + dotLength * dir;
- DrawLine(vh, dotsp, dotep, width, color);
- if (posList != null) posList.Add(dotsp);
- sp = np;
- }
- if (posList != null) posList.Add(endPoint);
- DrawLine(vh, sp, endPoint, width, color);
- }
-
- /// <summary>
- /// Draw a dash-dot-dot line. 画双点划线
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="startPoint">起始点</param>
- /// <param name="endPoint">结束点</param>
- /// <param name="width">线宽</param>
- /// <param name="color">颜色</param>
- /// <param name="dashLength">折线长,默认15倍线宽</param>
- /// <param name="dotLength">点线长,默认3倍线宽</param>
- /// <param name="gapLength">间隙长,默认5倍线宽</param>
- /// <param name="posList">可选,输出的关键点</param>
- public static void DrawDashDotDotLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width,
- Color32 color, float dashLength = 0f, float dotLength = 0f, float gapLength = 0f,
- List<Vector3> posList = null)
- {
- float dist = Vector3.Distance(startPoint, endPoint);
- if (dist < 0.1f) return;
- if (dashLength == 0) dashLength = 15 * width;
- if (dotLength == 0) dotLength = 3 * width;
- if (gapLength == 0) gapLength = 5 * width;
- int segment = Mathf.CeilToInt(dist / (dashLength + 3 * gapLength + 2 * dotLength));
- Vector3 dir = (endPoint - startPoint).normalized;
- Vector3 sp = startPoint, np;
- if (posList != null) posList.Clear();
- for (int i = 1; i <= segment; i++)
- {
- if (posList != null) posList.Add(sp);
- np = startPoint + dir * dist * i / segment;
- var dashep = np - dir * (3 * gapLength + 2 * dotLength);
- DrawLine(vh, sp, dashep, width, color);
- if (posList != null) posList.Add(dashep);
- var dotsp = dashep + gapLength * dir;
- var dotep = dotsp + dotLength * dir;
- DrawLine(vh, dotsp, dotep, width, color);
- if (posList != null) posList.Add(dotep);
- var dotsp2 = dotep + gapLength * dir;
- var dotep2 = dotsp2 + dotLength * dir;
- DrawLine(vh, dotsp2, dotep2, width, color);
- if (posList != null) posList.Add(dotep2);
- sp = np;
- }
- if (posList != null) posList.Add(endPoint);
- DrawLine(vh, sp, endPoint, width, color);
- }
-
- /// <summary>
- /// Draw a zebar-line. 画斑马线
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="startPoint">起始点</param>
- /// <param name="endPoint">结束点</param>
- /// <param name="width">线宽</param>
- /// <param name="zebraWidth">斑马条纹宽</param>
- /// <param name="zebraGap">间隙宽</param>
- /// <param name="color">起始颜色</param>
- /// <param name="toColor">结束颜色</param>
- public static void DrawZebraLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width,
- float zebraWidth, float zebraGap, Color32 color, Color32 toColor, float maxDistance)
- {
- var dist = Vector3.Distance(startPoint, endPoint);
- if (dist < 0.1f) return;
- if (zebraWidth == 0) zebraWidth = 3 * width;
- if (zebraGap == 0) zebraGap = 3 * width;
- var allSegment = Mathf.CeilToInt(maxDistance / (zebraWidth + zebraGap));
- var segment = Mathf.CeilToInt(dist / maxDistance * allSegment);
- var dir = (endPoint - startPoint).normalized;
- var sp = startPoint;
- var np = Vector3.zero;
- var isGradient = !color.Equals(toColor);
- zebraWidth = (maxDistance - zebraGap * (allSegment - 1)) / allSegment;
- for (int i = 1; i <= segment; i++)
- {
- np = sp + dir * zebraWidth;
- DrawLine(vh, sp, np, width, isGradient ? Color32.Lerp(color, toColor, i * 1.0f / allSegment) : color);
- sp = np + dir * zebraGap;
- }
- }
-
- /// <summary>
- /// Draw a diamond. 画菱形(钻石形状)
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="center">中心点</param>
- /// <param name="size">尺寸</param>
- /// <param name="color">颜色</param>
- public static void DrawDiamond(VertexHelper vh, Vector3 center, float size, Color32 color)
- {
- DrawDiamond(vh, center, size, color, color);
- }
-
- /// <summary>
- /// Draw a diamond. 画菱形(钻石形状)
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="center">中心点</param>
- /// <param name="size">尺寸</param>
- /// <param name="color">渐变色1</param>
- /// <param name="toColor">渐变色2</param>
- public static void DrawDiamond(VertexHelper vh, Vector3 center, float size, Color32 color, Color32 toColor)
- {
- var p1 = new Vector2(center.x - size, center.y);
- var p2 = new Vector2(center.x, center.y + size);
- var p3 = new Vector2(center.x + size, center.y);
- var p4 = new Vector2(center.x, center.y - size);
- DrawTriangle(vh, p4, p1, p2, color, color, toColor);
- DrawTriangle(vh, p3, p4, p2, color, color, toColor);
- }
-
- /// <summary>
- /// Draw a square. 画正方形
- /// </summary>
- /// <param name="center">中心点</param>
- /// <param name="radius">半径</param>
- /// <param name="color">颜色</param>
- public static void DrawSquare(VertexHelper vh, Vector3 center, float radius, Color32 color)
- {
- DrawSquare(vh, center, radius, color, color, true);
- }
-
- /// <summary>
- /// Draw a square. 画带渐变的正方形
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="center">中心点</param>
- /// <param name="radius">半径</param>
- /// <param name="color">渐变色1</param>
- /// <param name="toColor">渐变色2</param>
- /// <param name="vertical">渐变是否为垂直方向</param>
- public static void DrawSquare(VertexHelper vh, Vector3 center, float radius, Color32 color,
- Color32 toColor, bool vertical = true)
- {
- Vector3 p1, p2, p3, p4;
- if (vertical)
- {
- p1 = new Vector3(center.x + radius, center.y - radius);
- p2 = new Vector3(center.x - radius, center.y - radius);
- p3 = new Vector3(center.x - radius, center.y + radius);
- p4 = new Vector3(center.x + radius, center.y + radius);
- }
- else
- {
- p1 = new Vector3(center.x - radius, center.y - radius);
- p2 = new Vector3(center.x - radius, center.y + radius);
- p3 = new Vector3(center.x + radius, center.y + radius);
- p4 = new Vector3(center.x + radius, center.y - radius);
- }
- DrawQuadrilateral(vh, p1, p2, p3, p4, color, toColor);
- }
-
- /// <summary>
- /// Draw a rectangle. 画带长方形
- /// </summary>
- /// <param name="p1">起始点</param>
- /// <param name="p2">结束点</param>
- /// <param name="radius">半径</param>
- /// <param name="color">颜色</param>
- public static void DrawRectangle(VertexHelper vh, Vector3 p1, Vector3 p2, float radius, Color32 color)
- {
- DrawRectangle(vh, p1, p2, radius, color, color);
- }
-
- /// <summary>
- /// Draw a rectangle. 画带渐变的长方形
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="p1">起始点</param>
- /// <param name="p2">结束点</param>
- /// <param name="radius">半径</param>
- /// <param name="color">渐变色1</param>
- /// <param name="toColor">渐变色2</param>
- public static void DrawRectangle(VertexHelper vh, Vector3 p1, Vector3 p2, float radius, Color32 color,
- Color32 toColor)
- {
- var dir = (p2 - p1).normalized;
- var dirv = Vector3.Cross(dir, Vector3.forward).normalized;
-
- var p3 = p1 + dirv * radius;
- var p4 = p1 - dirv * radius;
- var p5 = p2 - dirv * radius;
- var p6 = p2 + dirv * radius;
- DrawQuadrilateral(vh, p3, p4, p5, p6, color, toColor);
- }
-
- /// <summary>
- /// Draw a rectangle. 画长方形
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="p">中心点</param>
- /// <param name="xRadius">x宽</param>
- /// <param name="yRadius">y宽</param>
- /// <param name="color">颜色</param>
- /// <param name="vertical">是否垂直方向</param>
- public static void DrawRectangle(VertexHelper vh, Vector3 p, float xRadius, float yRadius,
- Color32 color, bool vertical = true)
- {
- DrawRectangle(vh, p, xRadius, yRadius, color, color, vertical);
- }
-
- /// <summary>
- /// Draw a rectangle. 画带渐变的长方形
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="p">中心点</param>
- /// <param name="xRadius">x宽</param>
- /// <param name="yRadius">y宽</param>
- /// <param name="color">渐变色1</param>
- /// <param name="toColor">渐变色2</param>
- /// <param name="vertical">是否垂直方向</param>
- public static void DrawRectangle(VertexHelper vh, Vector3 p, float xRadius, float yRadius,
- Color32 color, Color32 toColor, bool vertical = true)
- {
- Vector3 p1, p2, p3, p4;
- if (vertical)
- {
- p1 = new Vector3(p.x + xRadius, p.y - yRadius);
- p2 = new Vector3(p.x - xRadius, p.y - yRadius);
- p3 = new Vector3(p.x - xRadius, p.y + yRadius);
- p4 = new Vector3(p.x + xRadius, p.y + yRadius);
- }
- else
- {
- p1 = new Vector3(p.x - xRadius, p.y - yRadius);
- p2 = new Vector3(p.x - xRadius, p.y + yRadius);
- p3 = new Vector3(p.x + xRadius, p.y + yRadius);
- p4 = new Vector3(p.x + xRadius, p.y - yRadius);
- }
-
- DrawQuadrilateral(vh, p1, p2, p3, p4, color, toColor);
- }
-
- public static void DrawRectangle(VertexHelper vh, Rect rect, Color32 color)
- {
- DrawRectangle(vh, rect.center, rect.width / 2, rect.height / 2, color, color, true);
- }
-
- public static void DrawRectangle(VertexHelper vh, Rect rect, Color32 color, Color32 toColor)
- {
- DrawRectangle(vh, rect.center, rect.width / 2, rect.height / 2, color, toColor, true);
- }
-
- public static void DrawRectangle(VertexHelper vh, Rect rect, float border, Color32 color)
- {
- DrawRectangle(vh, rect, border, color, color);
- }
-
- public static void DrawRectangle(VertexHelper vh, Rect rect, float border, Color32 color, Color32 toColor)
- {
- DrawRectangle(vh, rect.center, rect.width / 2 - border, rect.height / 2 - border, color, toColor, true);
- }
-
- /// <summary>
- /// Draw a quadrilateral. 画任意的四边形
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="p1"></param>
- /// <param name="p2"></param>
- /// <param name="p3"></param>
- /// <param name="p4"></param>
- /// <param name="color"></param>
- public static void DrawQuadrilateral(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
- Color32 color)
- {
- DrawQuadrilateral(vh, p1, p2, p3, p4, color, color);
- }
-
- /// <summary>
- /// Draw a quadrilateral. 画任意带渐变的四边形
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="p1"></param>
- /// <param name="p2"></param>
- /// <param name="p3"></param>
- /// <param name="p4"></param>
- /// <param name="startColor"></param>
- /// <param name="toColor"></param>
- public static void DrawQuadrilateral(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
- Color32 startColor, Color32 toColor)
- {
- DrawQuadrilateral(vh, p1, p2, p3, p4, startColor, startColor, toColor, toColor);
- }
-
- public static void DrawQuadrilateral(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
- Color32 color1, Color32 color2, Color32 color3, Color32 color4)
- {
- s_Vertex[0].position = p1;
- s_Vertex[1].position = p2;
- s_Vertex[2].position = p3;
- s_Vertex[3].position = p4;
- s_Vertex[0].color = color1;
- s_Vertex[1].color = color2;
- s_Vertex[2].color = color3;
- s_Vertex[3].color = color4;
- for (int j = 0; j < 4; j++)
- {
- s_Vertex[j].uv0 = s_ZeroVector2;
- }
- vh.AddUIVertexQuad(s_Vertex);
- }
-
- public static void InitCornerRadius(float[] cornerRadius, float width, float height, bool horizontal,
- bool invert, ref float brLt, ref float brRt, ref float brRb, ref float brLb, ref bool needRound)
- {
- if (cornerRadius == null || cornerRadius.Length == 0) return;
- if (invert)
- {
- if (horizontal)
- {
- brLt = cornerRadius.Length > 0 ? cornerRadius[1] : 0;
- brRt = cornerRadius.Length > 1 ? cornerRadius[0] : 0;
- brRb = cornerRadius.Length > 2 ? cornerRadius[3] : 0;
- brLb = cornerRadius.Length > 3 ? cornerRadius[2] : 0;
- }
- else
- {
- brLt = cornerRadius.Length > 0 ? cornerRadius[3] : 0;
- brRt = cornerRadius.Length > 1 ? cornerRadius[2] : 0;
- brRb = cornerRadius.Length > 2 ? cornerRadius[1] : 0;
- brLb = cornerRadius.Length > 3 ? cornerRadius[0] : 0;
- }
- }
- else
- {
- brLt = cornerRadius.Length > 0 ? cornerRadius[0] : 0;
- brRt = cornerRadius.Length > 1 ? cornerRadius[1] : 0;
- brRb = cornerRadius.Length > 2 ? cornerRadius[2] : 0;
- brLb = cornerRadius.Length > 3 ? cornerRadius[3] : 0;
- }
-
- needRound = brLb != 0 || brRt != 0 || brRb != 0 || brLb != 0;
- if (needRound)
- {
- var min = Mathf.Min(width, height);
- if (brLt == 1 && brRt == 1 && brRb == 1 && brLb == 1)
- {
- brLt = brRt = brRb = brLb = min / 2;
- return;
- }
- if (brLt > 0 && brLt <= 1) brLt = brLt * min;
- if (brRt > 0 && brRt <= 1) brRt = brRt * min;
- if (brRb > 0 && brRb <= 1) brRb = brRb * min;
- if (brLb > 0 && brLb <= 1) brLb = brLb * min;
- if (horizontal)
- {
- if (brLb + brLt >= height)
- {
- var total = brLb + brLt;
- brLb = height * (brLb / total);
- brLt = height * (brLt / total);
- }
- if (brRt + brRb >= height)
- {
- var total = brRt + brRb;
- brRt = height * (brRt / total);
- brRb = height * (brRb / total);
- }
- if (brLt + brRt >= width)
- {
- var total = brLt + brRt;
- brLt = width * (brLt / total);
- brRt = width * (brRt / total);
- }
- if (brRb + brLb >= width)
- {
- var total = brRb + brLb;
- brRb = width * (brRb / total);
- brLb = width * (brLb / total);
- }
- }
- else
- {
- if (brLt + brRt >= width)
- {
- var total = brLt + brRt;
- brLt = width * (brLt / total);
- brRt = width * (brRt / total);
- }
- if (brRb + brLb >= width)
- {
- var total = brRb + brLb;
- brRb = width * (brRb / total);
- brLb = width * (brLb / total);
- }
- if (brLb + brLt >= height)
- {
- var total = brLb + brLt;
- brLb = height * (brLb / total);
- brLt = height * (brLt / total);
- }
- if (brRt + brRb >= height)
- {
- var total = brRt + brRb;
- brRt = height * (brRt / total);
- brRb = height * (brRb / total);
- }
- }
- }
- }
-
- public static void DrawRoundRectangle(VertexHelper vh, Rect rect,
- Color32 color, Color32 toColor, float rotate = 0, float[] cornerRadius = null, bool isYAxis = false,
- float smoothness = 2, bool invert = false)
- {
- DrawRoundRectangle(vh, rect.center, rect.width, rect.height, color, toColor, rotate, cornerRadius,
- isYAxis, smoothness, invert);
- }
-
- /// <summary>
- /// 绘制圆角矩形
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="center"></param>
- /// <param name="rectWidth"></param>
- /// <param name="rectHeight"></param>
- /// <param name="color"></param>
- /// <param name="toColor"></param>
- /// <param name="rotate"></param>
- /// <param name="cornerRadius"></param>
- /// <param name="horizontal"></param>
- /// <param name="smoothness"></param>
- /// <param name="invert"></param>
- public static void DrawRoundRectangle(VertexHelper vh, Vector3 center, float rectWidth, float rectHeight,
- Color32 color, Color32 toColor, float rotate = 0, float[] cornerRadius = null, bool horizontal = false,
- float smoothness = 2, bool invert = false)
- {
- if (invert)
- {
- var temp = toColor;
- toColor = color;
- color = temp;
- }
- var isGradient = !UGLHelper.IsValueEqualsColor(color, toColor);
- var halfWid = rectWidth / 2;
- var halfHig = rectHeight / 2;
- float brLt = 0, brRt = 0, brRb = 0, brLb = 0;
- bool needRound = false;
- InitCornerRadius(cornerRadius, rectWidth, rectHeight, horizontal, invert, ref brLt, ref brRt, ref brRb,
- ref brLb, ref needRound);
- var tempCenter = Vector3.zero;
- var lbIn = new Vector3(center.x - halfWid, center.y - halfHig);
- var ltIn = new Vector3(center.x - halfWid, center.y + halfHig);
- var rtIn = new Vector3(center.x + halfWid, center.y + halfHig);
- var rbIn = new Vector3(center.x + halfWid, center.y - halfHig);
- if (needRound)
- {
- var lbIn2 = lbIn;
- var ltIn2 = ltIn;
- var rtIn2 = rtIn;
- var rbIn2 = rbIn;
- var roundLb = lbIn;
- var roundLt = ltIn;
- var roundRt = rtIn;
- var roundRb = rbIn;
- if (brLt > 0)
- {
- roundLt = new Vector3(center.x - halfWid + brLt, center.y + halfHig - brLt);
- ltIn = roundLt + brLt * Vector3.left;
- ltIn2 = roundLt + brLt * Vector3.up;
- }
- if (brRt > 0)
- {
- roundRt = new Vector3(center.x + halfWid - brRt, center.y + halfHig - brRt);
- rtIn = roundRt + brRt * Vector3.up;
- rtIn2 = roundRt + brRt * Vector3.right;
- }
- if (brRb > 0)
- {
- roundRb = new Vector3(center.x + halfWid - brRb, center.y - halfHig + brRb);
- rbIn = roundRb + brRb * Vector3.right;
- rbIn2 = roundRb + brRb * Vector3.down;
- }
- if (brLb > 0)
- {
- roundLb = new Vector3(center.x - halfWid + brLb, center.y - halfHig + brLb);
- lbIn = roundLb + brLb * Vector3.left;
- lbIn2 = roundLb + brLb * Vector3.down;
- }
-
- if (horizontal)
- {
- var maxLeft = Mathf.Max(brLt, brLb);
- var maxRight = Mathf.Max(brRt, brRb);
- var ltInRight = ltIn + maxLeft * Vector3.right;
- var lbInRight = lbIn + maxLeft * Vector3.right;
- var rtIn2Left = rtIn2 + maxRight * Vector3.left;
- var rbInLeft = rbIn + maxRight * Vector3.left;
-
- var roundLbRight = roundLb + (maxLeft - brLb) * Vector3.right;
- var lbIn2Right = lbIn2 + (maxLeft - brLb) * Vector3.right;
- if (roundLbRight.x > roundRb.x) roundLbRight.x = roundRb.x;
- if (lbIn2Right.x > roundRb.x) lbIn2Right.x = roundRb.x;
-
- var ltIn2Right = ltIn2 + (maxLeft - brLt) * Vector3.right;
- var roundLtRight = roundLt + (maxLeft - brLt) * Vector3.right;
- if (ltIn2Right.x > roundRt.x) ltIn2Right.x = roundRt.x;
- if (roundLtRight.x > roundRt.x) roundLtRight.x = roundRt.x;
-
- var roundRtLeft = roundRt + (maxRight - brRt) * Vector3.left;
- var rtInLeft = rtIn + (maxRight - brRt) * Vector3.left;
- if (roundRtLeft.x < roundLt.x) roundRtLeft.x = roundLt.x;
- if (rtInLeft.x < roundLt.x) rtInLeft.x = roundLt.x;
-
- var rbIn2Left = rbIn2 + (maxRight - brRb) * Vector3.left;
- var roundRbLeft = roundRb + (maxRight - brRb) * Vector3.left;
- if (rbIn2Left.x < roundLb.x) rbIn2Left.x = roundLb.x;
- if (roundRbLeft.x < roundLb.x) roundRbLeft.x = roundLb.x;
- if (!isGradient)
- {
- DrawSector(vh, roundLt, brLt, color, color, 270, 360, 1, horizontal, smoothness);
- DrawSector(vh, roundRt, brRt, toColor, toColor, 0, 90, 1, horizontal, smoothness);
- DrawSector(vh, roundRb, brRb, toColor, toColor, 90, 180, 1, horizontal, smoothness);
- DrawSector(vh, roundLb, brLb, color, color, 180, 270, 1, horizontal, smoothness);
-
- DrawQuadrilateral(vh, ltIn, ltInRight, lbInRight, lbIn, color, color);
- DrawQuadrilateral(vh, lbIn2, roundLb, roundLbRight, lbIn2Right, color, color);
- DrawQuadrilateral(vh, roundLt, ltIn2, ltIn2Right, roundLtRight, color, color);
-
- DrawQuadrilateral(vh, rbInLeft, rtIn2Left, rtIn2, rbIn, toColor, toColor);
- DrawQuadrilateral(vh, roundRtLeft, rtInLeft, rtIn, roundRt, toColor, toColor);
- DrawQuadrilateral(vh, rbIn2Left, roundRbLeft, roundRb, rbIn2, toColor, toColor);
-
- var clt = new Vector3(center.x - halfWid + maxLeft, center.y + halfHig);
- var crt = new Vector3(center.x + halfWid - maxRight, center.y + halfHig);
- var crb = new Vector3(center.x + halfWid - maxRight, center.y - halfHig);
- var clb = new Vector3(center.x - halfWid + maxLeft, center.y - halfHig);
- if (crt.x > clt.x)
- {
- DrawQuadrilateral(vh, clb, clt, crt, crb, color, toColor);
- }
- }
- else
- {
- var tempLeftColor = Color32.Lerp(color, toColor, maxLeft / rectWidth);
- var upLeftColor = Color32.Lerp(color, tempLeftColor, brLt / maxLeft);
- var downLeftColor = Color32.Lerp(color, tempLeftColor, brLb / maxLeft);
-
- var tempRightColor = Color32.Lerp(color, toColor, (rectWidth - maxRight) / rectWidth);
- var upRightColor = Color32.Lerp(tempRightColor, toColor, (maxRight - brRt) / maxRight);
- var downRightColor = Color32.Lerp(tempRightColor, toColor, (maxRight - brRb) / maxRight);
-
- DrawSector(vh, roundLt, brLt, color, upLeftColor, 270, 360, 1, horizontal, smoothness);
- DrawSector(vh, roundRt, brRt, upRightColor, toColor, 0, 90, 1, horizontal, smoothness);
- DrawSector(vh, roundRb, brRb, downRightColor, toColor, 90, 180, 1, horizontal, smoothness);
- DrawSector(vh, roundLb, brLb, color, downLeftColor, 180, 270, 1, horizontal, smoothness);
-
- DrawQuadrilateral(vh, lbIn, ltIn, ltInRight, lbInRight, color, tempLeftColor);
- DrawQuadrilateral(vh, lbIn2, roundLb, roundLbRight, lbIn2Right, downLeftColor,
- roundLbRight.x == roundRb.x ? downRightColor : tempLeftColor);
- DrawQuadrilateral(vh, roundLt, ltIn2, ltIn2Right, roundLtRight, upLeftColor,
- ltIn2Right.x == roundRt.x ? upRightColor : tempLeftColor);
-
- DrawQuadrilateral(vh, rbInLeft, rtIn2Left, rtIn2, rbIn, tempRightColor, toColor);
- DrawQuadrilateral(vh, roundRtLeft, rtInLeft, rtIn, roundRt,
- roundRtLeft.x == roundLt.x ? upLeftColor : tempRightColor, upRightColor);
- DrawQuadrilateral(vh, rbIn2Left, roundRbLeft, roundRb, rbIn2,
- rbIn2Left.x == roundLb.x ? downLeftColor : tempRightColor, downRightColor);
-
- var clt = new Vector3(center.x - halfWid + maxLeft, center.y + halfHig);
- var crt = new Vector3(center.x + halfWid - maxRight, center.y + halfHig);
- var crb = new Vector3(center.x + halfWid - maxRight, center.y - halfHig);
- var clb = new Vector3(center.x - halfWid + maxLeft, center.y - halfHig);
- if (crt.x > clt.x)
- {
- DrawQuadrilateral(vh, clb, clt, crt, crb, tempLeftColor, tempRightColor);
- }
- }
- }
- else
- {
- var maxup = Mathf.Max(brLt, brRt);
- var maxdown = Mathf.Max(brLb, brRb);
- var clt = new Vector3(center.x - halfWid, center.y + halfHig - maxup);
- var crt = new Vector3(center.x + halfWid, center.y + halfHig - maxup);
- var crb = new Vector3(center.x + halfWid, center.y - halfHig + maxdown);
- var clb = new Vector3(center.x - halfWid, center.y - halfHig + maxdown);
- var lbIn2Up = lbIn2 + maxdown * Vector3.up;
- var rbIn2Up = rbIn2 + maxdown * Vector3.up;
- var rtInDown = rtIn + maxup * Vector3.down;
- var ltIn2Down = ltIn2 + maxup * Vector3.down;
-
- var roundLtDown = roundLt + (maxup - brLt) * Vector3.down;
- var ltInDown = ltIn + (maxup - brLt) * Vector3.down;
- if (roundLtDown.y < roundLb.y) roundLtDown.y = roundLb.y;
- if (ltInDown.y < roundLb.y) ltInDown.y = roundLb.y;
-
- var rtIn2Down = rtIn2 + (maxup - brRt) * Vector3.down;
- var roundRtDown = roundRt + (maxup - brRt) * Vector3.down;
- if (rtIn2Down.y < roundRb.y) rtIn2Down.y = roundRb.y;
- if (roundRtDown.y < roundRb.y) roundRtDown.y = roundRb.y;
-
- var lbInUp = lbIn + (maxdown - brLb) * Vector3.up;
- var roundLbUp = roundLb + (maxdown - brLb) * Vector3.up;
- if (lbInUp.y > roundLt.y) lbInUp.y = roundLt.y;
- if (roundLbUp.y > roundLt.y) roundLbUp.y = roundLt.y;
-
- var roundRbUp = roundRb + (maxdown - brRb) * Vector3.up;
- var rbInUp = rbIn + (maxdown - brRb) * Vector3.up;
- if (roundRbUp.y > roundRt.y) roundRbUp.y = roundRt.y;
- if (rbInUp.y > roundRt.y) rbInUp.y = roundRt.y;
-
- if (!isGradient)
- {
- DrawSector(vh, roundLt, brLt, toColor, toColor, 270, 360, 1, horizontal, smoothness);
- DrawSector(vh, roundRt, brRt, toColor, toColor, 0, 90, 1, horizontal, smoothness);
- DrawSector(vh, roundRb, brRb, color, color, 90, 180, 1, horizontal, smoothness);
- DrawSector(vh, roundLb, brLb, color, color, 180, 270, 1, horizontal, smoothness);
-
- DrawQuadrilateral(vh, ltIn2, rtIn, rtInDown, ltIn2Down, toColor, toColor);
- DrawQuadrilateral(vh, ltIn, roundLt, roundLtDown, ltInDown, toColor, toColor);
- DrawQuadrilateral(vh, roundRt, rtIn2, rtIn2Down, roundRtDown, toColor, toColor);
-
- DrawQuadrilateral(vh, lbIn2, lbIn2Up, rbIn2Up, rbIn2, color, color);
- DrawQuadrilateral(vh, lbIn, lbInUp, roundLbUp, roundLb, color, color);
- DrawQuadrilateral(vh, roundRb, roundRbUp, rbInUp, rbIn, color, color);
- if (clt.y > clb.y)
- {
- DrawQuadrilateral(vh, clt, crt, crb, clb, toColor, color);
- }
- }
- else
- {
- var tempUpColor = Color32.Lerp(color, toColor, (rectHeight - maxup) / rectHeight);
- var leftUpColor = Color32.Lerp(tempUpColor, toColor, (maxup - brLt) / maxup);
- var rightUpColor = Color32.Lerp(tempUpColor, toColor, (maxup - brRt) / maxup);
- var tempDownColor = Color32.Lerp(color, toColor, maxdown / rectHeight);
- var leftDownColor = Color32.Lerp(color, tempDownColor, brLb / maxdown);
- var rightDownColor = Color32.Lerp(color, tempDownColor, brRb / maxdown);
-
- DrawSector(vh, roundLt, brLt, leftUpColor, toColor, 270, 360, 1, horizontal, smoothness);
- DrawSector(vh, roundRt, brRt, rightUpColor, toColor, 0, 90, 1, horizontal, smoothness);
- DrawSector(vh, roundRb, brRb, rightDownColor, color, 90, 180, 1, horizontal, smoothness);
- DrawSector(vh, roundLb, brLb, leftDownColor, color, 180, 270, 1, horizontal, smoothness);
-
- DrawQuadrilateral(vh, ltIn2, rtIn, rtInDown, ltIn2Down, toColor, tempUpColor);
- DrawQuadrilateral(vh, ltIn, roundLt, roundLtDown, ltInDown, leftUpColor,
- roundLtDown.y == roundLb.y ? leftDownColor : tempUpColor);
- DrawQuadrilateral(vh, roundRt, rtIn2, rtIn2Down, roundRtDown, rightUpColor,
- rtIn2Down.y == roundRb.y ? rightDownColor : tempUpColor);
-
- DrawQuadrilateral(vh, rbIn2, lbIn2, lbIn2Up, rbIn2Up, color, tempDownColor);
- DrawQuadrilateral(vh, roundLb, lbIn, lbInUp, roundLbUp, leftDownColor,
- lbInUp.y == roundLt.y ? leftUpColor : tempDownColor);
- DrawQuadrilateral(vh, rbIn, roundRb, roundRbUp, rbInUp, rightDownColor,
- roundRbUp.y == roundRt.y ? rightUpColor : tempDownColor);
- if (clt.y > clb.y)
- {
- DrawQuadrilateral(vh, clt, crt, crb, clb, tempUpColor, tempDownColor);
- }
- }
- }
- }
- else
- {
- if (horizontal)
- DrawQuadrilateral(vh, lbIn, ltIn, rtIn, rbIn, color, toColor);
- else
- DrawQuadrilateral(vh, rbIn, lbIn, ltIn, rtIn, color, toColor);
- }
- }
-
- /// <summary>
- /// 绘制(圆角)边框
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="center"></param>
- /// <param name="rectWidth"></param>
- /// <param name="rectHeight"></param>
- /// <param name="borderWidth"></param>
- /// <param name="color"></param>
- /// <param name="rotate"></param>
- /// <param name="cornerRadius"></param>
- /// <param name="invertCorner"></param>
- /// <param name="extWidth"></param>
- public static void DrawBorder(VertexHelper vh, Vector3 center, float rectWidth, float rectHeight,
- float borderWidth, Color32 color, float rotate = 0, float[] cornerRadius = null,
- bool horizontal = false, float smoothness = 1f, bool invertCorner = false, float extWidth = 0)
- {
- DrawBorder(vh, center, rectWidth, rectHeight, borderWidth, color, s_ClearColor32, rotate,
- cornerRadius, horizontal, smoothness, invertCorner, extWidth);
- }
-
- /// <summary>
- /// 绘制(圆角)边框
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="rect"></param>
- /// <param name="borderWidth"></param>
- /// <param name="color"></param>
- /// <param name="rotate"></param>
- /// <param name="cornerRadius"></param>
- /// <param name="horizontal"></param>
- /// <param name="smoothness"></param>
- /// <param name="invertCorner"></param>
- /// <param name="extWidth"></param>
- public static void DrawBorder(VertexHelper vh, Rect rect,
- float borderWidth, Color32 color, float rotate = 0, float[] cornerRadius = null,
- bool horizontal = false, float smoothness = 1f, bool invertCorner = false, float extWidth = 0)
- {
- DrawBorder(vh, rect.center, rect.width, rect.height, borderWidth, color, s_ClearColor32, rotate,
- cornerRadius, horizontal, smoothness, invertCorner, extWidth);
- }
-
- /// <summary>
- /// 绘制(圆角)边框
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="center"></param>
- /// <param name="rectWidth"></param>
- /// <param name="rectHeight"></param>
- /// <param name="borderWidth"></param>
- /// <param name="color"></param>
- /// <param name="toColor"></param>
- /// <param name="rotate"></param>
- /// <param name="cornerRadius"></param>
- /// <param name="horizontal"></param>
- /// <param name="smoothness"></param>
- /// <param name="invertCorner"></param>
- /// <param name="extWidth"></param>
- public static void DrawBorder(VertexHelper vh, Vector3 center, float rectWidth, float rectHeight,
- float borderWidth, Color32 color, Color32 toColor, float rotate = 0, float[] cornerRadius = null,
- bool horizontal = false, float smoothness = 1f, bool invertCorner = false, float extWidth = 0)
- {
- if (borderWidth == 0 || UGLHelper.IsClearColor(color)) return;
- var halfWid = rectWidth / 2;
- var halfHig = rectHeight / 2;
- var lbIn = new Vector3(center.x - halfWid - extWidth, center.y - halfHig - extWidth);
- var lbOt = new Vector3(center.x - halfWid - borderWidth - extWidth, center.y - halfHig - borderWidth - extWidth);
- var ltIn = new Vector3(center.x - halfWid - extWidth, center.y + halfHig + extWidth);
- var ltOt = new Vector3(center.x - halfWid - borderWidth - extWidth, center.y + halfHig + borderWidth + extWidth);
- var rtIn = new Vector3(center.x + halfWid + extWidth, center.y + halfHig + extWidth);
- var rtOt = new Vector3(center.x + halfWid + borderWidth + extWidth, center.y + halfHig + borderWidth + extWidth);
- var rbIn = new Vector3(center.x + halfWid + extWidth, center.y - halfHig - extWidth);
- var rbOt = new Vector3(center.x + halfWid + borderWidth + extWidth, center.y - halfHig - borderWidth - extWidth);
- float brLt = 0, brRt = 0, brRb = 0, brLb = 0;
- bool needRound = false;
- InitCornerRadius(cornerRadius, rectWidth, rectHeight, horizontal, invertCorner, ref brLt, ref brRt, ref brRb,
- ref brLb, ref needRound);
- var tempCenter = Vector3.zero;
- if (UGLHelper.IsClearColor(toColor))
- {
- toColor = color;
- }
- if (needRound)
- {
- var lbIn2 = lbIn;
- var lbOt2 = lbOt;
- var ltIn2 = ltIn;
- var ltOt2 = ltOt;
- var rtIn2 = rtIn;
- var rtOt2 = rtOt;
- var rbIn2 = rbIn;
- var rbOt2 = rbOt;
- //if (brLt > 0)
- {
- tempCenter = new Vector3(center.x - halfWid + brLt, center.y + halfHig - brLt);
- brLt += extWidth;
- DrawDoughnut(vh, tempCenter, brLt, brLt + borderWidth, horizontal ? color : toColor, s_ClearColor32,
- 270, 360, smoothness);
- ltIn = tempCenter + brLt * Vector3.left;
- ltOt = tempCenter + (brLt + borderWidth) * Vector3.left;
- ltIn2 = tempCenter + brLt * Vector3.up;
- ltOt2 = tempCenter + (brLt + borderWidth) * Vector3.up;
- }
- //if (brRt > 0)
- {
- tempCenter = new Vector3(center.x + halfWid - brRt, center.y + halfHig - brRt);
- brRt += extWidth;
- DrawDoughnut(vh, tempCenter, brRt, brRt + borderWidth, toColor, s_ClearColor32, 0, 90, smoothness);
- rtIn = tempCenter + brRt * Vector3.up;
- rtOt = tempCenter + (brRt + borderWidth) * Vector3.up;
- rtIn2 = tempCenter + brRt * Vector3.right;
- rtOt2 = tempCenter + (brRt + borderWidth) * Vector3.right;
- }
- //if (brRb > 0)
- {
- tempCenter = new Vector3(center.x + halfWid - brRb, center.y - halfHig + brRb);
- brRb += extWidth;
- DrawDoughnut(vh, tempCenter, brRb, brRb + borderWidth, horizontal ? toColor : color, s_ClearColor32,
- 90, 180, smoothness);
- rbIn = tempCenter + brRb * Vector3.right;
- rbOt = tempCenter + (brRb + borderWidth) * Vector3.right;
- rbIn2 = tempCenter + brRb * Vector3.down;
- rbOt2 = tempCenter + (brRb + borderWidth) * Vector3.down;
- }
- //if (brLb > 0)
- {
- tempCenter = new Vector3(center.x - halfWid + brLb, center.y - halfHig + brLb);
- brLb += extWidth;
- DrawDoughnut(vh, tempCenter, brLb, brLb + borderWidth, color, s_ClearColor32, 180, 270, smoothness);
- lbIn = tempCenter + brLb * Vector3.left;
- lbOt = tempCenter + (brLb + borderWidth) * Vector3.left;
- lbIn2 = tempCenter + brLb * Vector3.down;
- lbOt2 = tempCenter + (brLb + borderWidth) * Vector3.down;
- }
- if (horizontal)
- {
- DrawQuadrilateral(vh, lbIn, lbOt, ltOt, ltIn, color, color);
- DrawQuadrilateral(vh, ltIn2, ltOt2, rtOt, rtIn, color, toColor);
- DrawQuadrilateral(vh, rtIn2, rtOt2, rbOt, rbIn, toColor, toColor);
- DrawQuadrilateral(vh, rbIn2, rbOt2, lbOt2, lbIn2, toColor, color);
- }
- else
- {
- DrawQuadrilateral(vh, lbIn, lbOt, ltOt, ltIn, color, toColor);
- DrawQuadrilateral(vh, ltIn2, ltOt2, rtOt, rtIn, toColor, toColor);
- DrawQuadrilateral(vh, rtIn2, rtOt2, rbOt, rbIn, toColor, color);
- DrawQuadrilateral(vh, rbIn2, rbOt2, lbOt2, lbIn2, color, color);
- }
- }
- else
- {
- if (rotate > 0)
- {
- lbIn = UGLHelper.RotateRound(lbIn, center, Vector3.forward, rotate);
- lbOt = UGLHelper.RotateRound(lbOt, center, Vector3.forward, rotate);
- ltIn = UGLHelper.RotateRound(ltIn, center, Vector3.forward, rotate);
- ltOt = UGLHelper.RotateRound(ltOt, center, Vector3.forward, rotate);
- rtIn = UGLHelper.RotateRound(rtIn, center, Vector3.forward, rotate);
- rtOt = UGLHelper.RotateRound(rtOt, center, Vector3.forward, rotate);
- rbIn = UGLHelper.RotateRound(rbIn, center, Vector3.forward, rotate);
- rbOt = UGLHelper.RotateRound(rbOt, center, Vector3.forward, rotate);
- }
- if (horizontal)
- {
- DrawQuadrilateral(vh, lbIn, lbOt, ltOt, ltIn, color, color);
- DrawQuadrilateral(vh, ltIn, ltOt, rtOt, rtIn, color, toColor);
- DrawQuadrilateral(vh, rtIn, rtOt, rbOt, rbIn, toColor, toColor);
- DrawQuadrilateral(vh, rbIn, rbOt, lbOt, lbIn, toColor, color);
- }
- else
- {
- DrawQuadrilateral(vh, lbIn, lbOt, ltOt, ltIn, color, toColor);
- DrawQuadrilateral(vh, ltIn, ltOt, rtOt, rtIn, toColor, toColor);
- DrawQuadrilateral(vh, rtIn, rtOt, rbOt, rbIn, toColor, color);
- DrawQuadrilateral(vh, rbIn, rbOt, lbOt, lbIn, color, color);
- }
- }
- }
-
- public static void DrawTriangle(VertexHelper vh, Vector3 p1,
- Vector3 p2, Vector3 p3, Color32 color)
- {
- DrawTriangle(vh, p1, p2, p3, color, color, color);
- }
-
- public static void DrawTriangle(VertexHelper vh, Vector3 pos, float size, Color32 color)
- {
- DrawTriangle(vh, pos, size, color, color);
- }
-
- public static void DrawTriangle(VertexHelper vh, Vector3 pos, float size, Color32 color, Color32 toColor)
- {
- var x = size * Mathf.Cos(30 * Mathf.PI / 180);
- var y = size * Mathf.Sin(30 * Mathf.PI / 180);
- var p1 = new Vector2(pos.x - x, pos.y - y);
- var p2 = new Vector2(pos.x, pos.y + size);
- var p3 = new Vector2(pos.x + x, pos.y - y);
- DrawTriangle(vh, p1, p2, p3, color, toColor, color);
- }
-
- public static void DrawTriangle(VertexHelper vh, Vector3 p1,
- Vector3 p2, Vector3 p3, Color32 color, Color32 color2, Color32 color3)
- {
- UIVertex v1 = new UIVertex();
- v1.position = p1;
- v1.color = color;
- v1.uv0 = s_ZeroVector2;
- UIVertex v2 = new UIVertex();
- v2.position = p2;
- v2.color = color2;
- v2.uv0 = s_ZeroVector2;
- UIVertex v3 = new UIVertex();
- v3.position = p3;
- v3.color = color3;
- v3.uv0 = s_ZeroVector2;
- int startIndex = vh.currentVertCount;
- vh.AddVert(v1);
- vh.AddVert(v2);
- vh.AddVert(v3);
- vh.AddTriangle(startIndex, startIndex + 1, startIndex + 2);
- }
-
- public static void DrawCricle(VertexHelper vh, Vector3 center, float radius, Color32 color,
- float smoothness = 2f)
- {
- DrawCricle(vh, center, radius, color, color, 0, s_ClearColor32, smoothness);
- }
-
- public static void DrawCricle(VertexHelper vh, Vector3 center, float radius, Color32 color,
- Color32 toColor, float smoothness = 2f)
- {
- DrawSector(vh, center, radius, color, toColor, 0, 360, 0, s_ClearColor32, smoothness);
- }
-
- public static void DrawCricle(VertexHelper vh, Vector3 center, float radius, Color32 color,
- Color32 toColor, float borderWidth, Color32 borderColor, float smoothness = 2f)
- {
- DrawSector(vh, center, radius, color, toColor, 0, 360, borderWidth, borderColor, smoothness);
- }
-
- public static void DrawCricle(VertexHelper vh, Vector3 center, float radius, Color32 color,
- float borderWidth, Color32 borderColor, float smoothness = 2f)
- {
- DrawCricle(vh, center, radius, color, color, borderWidth, borderColor, smoothness);
- }
-
- public static void DrawEmptyCricle(VertexHelper vh, Vector3 center, float radius, float tickness,
- Color32 color, Color32 emptyColor, float smoothness = 2f)
- {
- DrawDoughnut(vh, center, radius - tickness, radius, color, color, emptyColor, 0, 360, 0, s_ClearColor32,
- 0, smoothness);
- }
-
- public static void DrawEmptyCricle(VertexHelper vh, Vector3 center, float radius, float tickness,
- Color32 color, Color32 emptyColor, float borderWidth, Color32 borderColor, float smoothness = 2f)
- {
- DrawDoughnut(vh, center, radius - tickness, radius, color, color, emptyColor, 0, 360, borderWidth,
- borderColor, 0, smoothness);
- }
-
- public static void DrawEmptyCricle(VertexHelper vh, Vector3 center, float radius, float tickness,
- Color32 color, Color32 toColor, Color32 emptyColor, float smoothness = 2f)
- {
- DrawDoughnut(vh, center, radius - tickness, radius, color, toColor, emptyColor, 0, 360, 0,
- s_ClearColor32, 0, smoothness);
- }
-
- public static void DrawEmptyCricle(VertexHelper vh, Vector3 center, float radius, float tickness,
- Color32 color, Color32 toColor, Color32 emptyColor, float borderWidth, Color32 borderColor,
- float smoothness = 2f)
- {
- DrawDoughnut(vh, center, radius - tickness, radius, color, toColor, emptyColor, 0, 360, borderWidth,
- borderColor, 0, smoothness);
- }
-
- public static void DrawSector(VertexHelper vh, Vector3 center, float radius, Color32 color,
- float startDegree, float toDegree, float smoothness = 2f)
- {
- DrawSector(vh, center, radius, color, color, startDegree, toDegree, 0, s_ClearColor32, smoothness);
- }
-
- public static void DrawSector(VertexHelper vh, Vector3 center, float radius, Color32 color, Color32 toColor,
- float startDegree, float toDegree, int gradientType = 0, bool isYAxis = false, float smoothness = 2f)
- {
- DrawSector(vh, center, radius, color, toColor, startDegree, toDegree, 0, s_ClearColor32, 0, smoothness,
- gradientType, isYAxis);
- }
-
- public static void DrawSector(VertexHelper vh, Vector3 center, float radius, Color32 color,
- float startDegree, float toDegree, float borderWidth, Color32 borderColor, float smoothness = 2f)
- {
- DrawSector(vh, center, radius, color, color, startDegree, toDegree, borderWidth, borderColor, smoothness);
- }
-
- public static void DrawSector(VertexHelper vh, Vector3 center, float radius, Color32 color, Color32 toColor,
- float startDegree, float toDegree, float borderWidth, Color32 borderColor, float smoothness = 2f)
- {
- DrawSector(vh, center, radius, color, toColor, startDegree, toDegree, borderWidth, borderColor, 0, smoothness);
- }
-
- /// <summary>
- /// 绘制扇形(可带边框、有空白边距、3种类型渐变)
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="center">中心点</param>
- /// <param name="radius">半径</param>
- /// <param name="color">颜色</param>
- /// <param name="toColor">渐变颜色</param>
- /// <param name="startDegree">开始角度</param>
- /// <param name="toDegree">结束角度</param>
- /// <param name="borderWidth">边框宽度</param>
- /// <param name="borderColor">边框颜色</param>
- /// <param name="gap">边距</param>
- /// <param name="smoothness">光滑度</param>
- /// <param name="gradientType">渐变类型,0:向圆形渐变,1:水平或垂直渐变,2:开始角度向结束角度渐变</param>
- /// <param name="isYAxis">水平渐变还是垂直渐变,gradientType为1时生效</param>
- public static void DrawSector(VertexHelper vh, Vector3 center, float radius, Color32 color, Color32 toColor,
- float startDegree, float toDegree, float borderWidth, Color32 borderColor, float gap,
- float smoothness, int gradientType = 0, bool isYAxis = false)
- {
- if (radius == 0) return;
- var isCircle = Mathf.Abs(toDegree - startDegree) >= 360;
- if (gap > 0 && isCircle) gap = 0;
- radius -= borderWidth;
- smoothness = (smoothness < 0 ? 2f : smoothness);
- int segments = (int) ((2 * Mathf.PI * radius) * (Mathf.Abs(toDegree - startDegree) / 360) / smoothness);
- if (segments < 1) segments = 1;
- float startAngle = startDegree * Mathf.Deg2Rad;
- float toAngle = toDegree * Mathf.Deg2Rad;
- float realStartAngle = startAngle;
- float realToAngle = toAngle;
- float halfAngle = (toAngle - startAngle) / 2;
- float borderAngle = 0;
- float spaceAngle = 0;
-
- var p2 = center + radius * UGLHelper.GetDire(startAngle);
- var p3 = Vector3.zero;
- var p4 = Vector3.zero;
- var spaceCenter = center;
- var realCenter = center;
- var lastP4 = center;
- var lastColor = color;
- var needBorder = borderWidth != 0;
- var needSpace = gap != 0;
- var borderLineWidth = needSpace ? borderWidth : borderWidth / 2;
- var lastPos = Vector3.zero;
- var middleDire = UGLHelper.GetDire(startAngle + halfAngle);
- if (needBorder || needSpace)
- {
- float spaceDiff = 0f;
- float borderDiff = 0f;
- if (needSpace)
- {
- spaceDiff = gap / Mathf.Sin(halfAngle);
- spaceCenter = center + spaceDiff * middleDire;
- realCenter = spaceCenter;
- spaceAngle = 2 * Mathf.Asin(gap / (2 * radius));
- realStartAngle = startAngle + spaceAngle;
- realToAngle = toAngle - spaceAngle;
- if (realToAngle < realStartAngle) realToAngle = realStartAngle;
- p2 = UGLHelper.GetPos(center, radius, realStartAngle);
- }
- if (needBorder && !isCircle)
- {
- borderDiff = borderLineWidth / Mathf.Sin(halfAngle);
- realCenter += borderDiff * middleDire;
- borderAngle = 2 * Mathf.Asin(borderLineWidth / (2 * radius));
- realStartAngle = realStartAngle + borderAngle;
- realToAngle = realToAngle - borderAngle;
- if (realToAngle < realStartAngle)
- {
- realToAngle = realStartAngle;
- p2 = UGLHelper.GetPos(center, radius, realStartAngle);
- }
- else
- {
- var borderX1 = UGLHelper.GetPos(center, radius, realStartAngle);
- DrawQuadrilateral(vh, realCenter, spaceCenter, p2, borderX1, borderColor);
- p2 = borderX1;
-
- var borderX2 = UGLHelper.GetPos(center, radius, realToAngle);
- var pEnd = UGLHelper.GetPos(center, radius, toAngle - spaceAngle);
- DrawQuadrilateral(vh, realCenter, borderX2, pEnd, spaceCenter, borderColor);
- }
- }
- }
- float segmentAngle = (realToAngle - realStartAngle) / segments;
- bool isLeft = startDegree >= 180;
- for (int i = 0; i <= segments; i++)
- {
- float currAngle = realStartAngle + i * segmentAngle;
- p3 = center + radius * UGLHelper.GetDire(currAngle);
- if (gradientType == 1)
- {
- if (isYAxis)
- {
- p4 = new Vector3(p3.x, realCenter.y);
- var dist = p4.x - realCenter.x;
- var tcolor = Color32.Lerp(color, toColor, dist >= 0 ?
- dist / radius :
- Mathf.Min(radius + dist, radius) / radius);
- if (isLeft && (i == segments || i == 0)) tcolor = toColor;
- DrawQuadrilateral(vh, lastP4, p2, p3, p4, lastColor, tcolor);
- lastP4 = p4;
- lastColor = tcolor;
- }
- else
- {
- p4 = new Vector3(realCenter.x, p3.y);
- var tcolor = Color32.Lerp(color, toColor, Mathf.Abs(p4.y - realCenter.y) / radius);
- DrawQuadrilateral(vh, lastP4, p2, p3, p4, lastColor, tcolor);
- lastP4 = p4;
- lastColor = tcolor;
- }
- }
- else if (gradientType == 2)
- {
- var tcolor = Color32.Lerp(color, toColor, i / segments);
- DrawQuadrilateral(vh, realCenter, p2, p3, realCenter, lastColor, tcolor);
- lastColor = tcolor;
- }
- else
- {
- AddVertToVertexHelper(vh, p3, realCenter, color, toColor, i > 0);
- }
- p2 = p3;
-
- }
- if (needBorder || needSpace)
- {
- if (realToAngle > realStartAngle)
- {
- var borderX2 = center + radius * UGLHelper.GetDire(realToAngle);
- DrawTriangle(vh, realCenter, p2, borderX2, toColor, color, color);
- if (needBorder)
- {
- var realStartDegree = (realStartAngle - borderAngle) * Mathf.Rad2Deg;
- var realToDegree = (realToAngle + borderAngle) * Mathf.Rad2Deg;
- DrawDoughnut(vh, center, radius, radius + borderWidth, borderColor, s_ClearColor32,
- realStartDegree, realToDegree, smoothness);
- }
- }
- }
- }
-
- public static void DrawRoundCap(VertexHelper vh, Vector3 center, float width, float radius, float angle,
- bool clockwise, Color32 color, bool end)
- {
- var px = Mathf.Sin(angle * Mathf.Deg2Rad) * radius;
- var py = Mathf.Cos(angle * Mathf.Deg2Rad) * radius;
- var pos = new Vector3(px, py) + center;
- if (end)
- {
- if (clockwise)
- DrawSector(vh, pos, width, color, angle, angle + 180, 0, s_ClearColor32);
- else
- DrawSector(vh, pos, width, color, angle, angle - 180, 0, s_ClearColor32);
- }
- else
- {
- if (clockwise)
- DrawSector(vh, pos, width, color, angle + 180, angle + 360, 0, s_ClearColor32);
- else
- DrawSector(vh, pos, width, color, angle - 180, angle - 360, 0, s_ClearColor32);
- }
- }
-
- public static void DrawDoughnut(VertexHelper vh, Vector3 center, float insideRadius, float outsideRadius,
- Color32 color, Color32 emptyColor, float smoothness = 2f)
- {
- DrawDoughnut(vh, center, insideRadius, outsideRadius, color, color, emptyColor, 0, 360, 0,
- s_ClearColor32, 0, smoothness);
- }
-
- public static void DrawDoughnut(VertexHelper vh, Vector3 center, float insideRadius, float outsideRadius,
- Color32 color, Color32 emptyColor, float startDegree,
- float toDegree, float smoothness = 1f)
- {
- DrawDoughnut(vh, center, insideRadius, outsideRadius, color, color, emptyColor, startDegree, toDegree,
- 0, s_ClearColor32, 0, smoothness);
- }
-
- public static void DrawDoughnut(VertexHelper vh, Vector3 center, float insideRadius, float outsideRadius,
- Color32 color, Color32 emptyColor, float startDegree,
- float toDegree, float borderWidth, Color32 borderColor, float smoothness = 2f)
- {
- DrawDoughnut(vh, center, insideRadius, outsideRadius, color, color, emptyColor, startDegree, toDegree,
- borderWidth, borderColor, 0, smoothness);
- }
-
- public static void DrawDoughnut(VertexHelper vh, Vector3 center, float insideRadius, float outsideRadius,
- Color32 color, Color32 toColor, Color32 emptyColor, float smoothness = 2f)
- {
- DrawDoughnut(vh, center, insideRadius, outsideRadius, color, toColor, emptyColor, 0, 360, 0,
- s_ClearColor32, 0, smoothness);
- }
-
- public static void DrawDoughnut(VertexHelper vh, Vector3 center, float insideRadius, float outsideRadius,
- Color32 color, Color32 toColor, Color32 emptyColor, float startDegree, float toDegree, float borderWidth,
- Color32 borderColor, float gap, float smoothness, bool roundCap = false, bool clockwise = true)
- {
- if (toDegree - startDegree == 0) return;
- if (gap > 0 && Mathf.Abs(toDegree - startDegree) >= 360) gap = 0;
- if (insideRadius <= 0)
- {
- DrawSector(vh, center, outsideRadius, color, toColor, startDegree, toDegree, borderWidth, borderColor,
- gap, smoothness);
- return;
- }
- outsideRadius -= borderWidth;
- insideRadius += borderWidth;
- smoothness = smoothness < 0 ? 2f : smoothness;
- Vector3 p1, p2, p3, p4, e1, e2;
- var isCircle = Mathf.Abs(toDegree - startDegree) >= 360;
- var needBorder = borderWidth != 0;
- var needSpace = gap != 0;
- var diffAngle = Mathf.Abs(toDegree - startDegree) * Mathf.Deg2Rad;
-
- int segments = (int) ((2 * Mathf.PI * outsideRadius) * (diffAngle * Mathf.Rad2Deg / 360) / smoothness);
- if (segments < 1) segments = 1;
- float startAngle = startDegree * Mathf.Deg2Rad;
- float toAngle = toDegree * Mathf.Deg2Rad;
-
- float realStartOutAngle = startAngle;
- float realToOutAngle = toAngle;
- float realStartInAngle = startAngle;
- float realToInAngle = toAngle;
- float halfAngle = (toAngle - startAngle) / 2;
- float borderAngle = 0, borderInAngle = 0, borderHalfAngle = 0;
- float spaceAngle = 0, spaceInAngle = 0, spaceHalfAngle = 0;
-
- var spaceCenter = center;
- var realCenter = center;
- var startDire = new Vector3(Mathf.Sin(startAngle), Mathf.Cos(startAngle)).normalized;
- var toDire = new Vector3(Mathf.Sin(toAngle), Mathf.Cos(toAngle)).normalized;
- var middleDire = new Vector3(Mathf.Sin(startAngle + halfAngle), Mathf.Cos(startAngle + halfAngle)).normalized;
- p1 = center + insideRadius * startDire;
- p2 = center + outsideRadius * startDire;
- e1 = center + insideRadius * toDire;
- e2 = center + outsideRadius * toDire;
- if (roundCap)
- {
- var roundRadius = (outsideRadius - insideRadius) / 2;
- var roundAngleRadius = insideRadius + roundRadius;
- var roundAngle = Mathf.Atan(roundRadius / roundAngleRadius);
- if (diffAngle < 2 * roundAngle)
- {
- roundCap = false;
- }
- }
- if (needBorder || needSpace)
- {
- if (needSpace)
- {
- var spaceDiff = gap / Mathf.Sin(halfAngle);
- spaceCenter = center + Mathf.Abs(spaceDiff) * middleDire;
- realCenter = spaceCenter;
- spaceAngle = 2 * Mathf.Asin(gap / (2 * outsideRadius));
- spaceInAngle = 2 * Mathf.Asin(gap / (2 * insideRadius));
- spaceHalfAngle = 2 * Mathf.Asin(gap / (2 * (insideRadius + (outsideRadius - insideRadius) / 2)));
- if (clockwise)
- {
- p1 = UGLHelper.GetPos(center, insideRadius, startAngle + spaceInAngle, false);
- e1 = UGLHelper.GetPos(center, insideRadius, toAngle - spaceInAngle, false);
- realStartOutAngle = startAngle + spaceAngle;
- realToOutAngle = toAngle - spaceAngle;
- realStartInAngle = startAngle + spaceInAngle;
- realToInAngle = toAngle - spaceInAngle;
- }
- else
- {
- p1 = UGLHelper.GetPos(center, insideRadius, startAngle - spaceInAngle, false);
- e1 = UGLHelper.GetPos(center, insideRadius, toAngle + spaceInAngle, false);
- realStartOutAngle = startAngle - spaceAngle;
- realToOutAngle = toAngle + spaceAngle;
- realStartInAngle = startAngle - spaceInAngle;
- realToOutAngle = toAngle + spaceInAngle;
- }
- p2 = UGLHelper.GetPos(center, outsideRadius, realStartOutAngle, false);
- e2 = UGLHelper.GetPos(center, outsideRadius, realToOutAngle, false);
- }
- if (needBorder && !isCircle)
- {
- var borderDiff = borderWidth / Mathf.Sin(halfAngle);
- realCenter += Mathf.Abs(borderDiff) * middleDire;
- borderAngle = 2 * Mathf.Asin(borderWidth / (2 * outsideRadius));
- borderInAngle = 2 * Mathf.Asin(borderWidth / (2 * insideRadius));
- borderHalfAngle = 2 * Mathf.Asin(borderWidth / (2 * (insideRadius + (outsideRadius - insideRadius) / 2)));
- if (clockwise)
- {
- realStartOutAngle = realStartOutAngle + borderAngle;
- realToOutAngle = realToOutAngle - borderAngle;
- realStartInAngle = startAngle + spaceInAngle + borderInAngle;
- realToInAngle = toAngle - spaceInAngle - borderInAngle;
- var newp1 = UGLHelper.GetPos(center, insideRadius, startAngle + spaceInAngle + borderInAngle, false);
- var newp2 = UGLHelper.GetPos(center, outsideRadius, realStartOutAngle, false);
- if (!roundCap) DrawQuadrilateral(vh, newp2, newp1, p1, p2, borderColor);
- p1 = newp1;
- p2 = newp2;
- if (toAngle - spaceInAngle - 2 * borderInAngle > realStartOutAngle)
- {
- var newe1 = UGLHelper.GetPos(center, insideRadius, toAngle - spaceInAngle - borderInAngle, false);
- var newe2 = UGLHelper.GetPos(center, outsideRadius, realToOutAngle, false);
- if (!roundCap) DrawQuadrilateral(vh, newe2, e2, e1, newe1, borderColor);
- e1 = newe1;
- e2 = newe2;
- }
- }
- else
- {
- realStartOutAngle = realStartOutAngle - borderAngle;
- realToOutAngle = realToOutAngle + borderAngle;
- realStartInAngle = startAngle - spaceInAngle - borderInAngle;
- realToInAngle = toAngle + spaceInAngle + borderInAngle;
- var newp1 = UGLHelper.GetPos(center, insideRadius, startAngle - spaceInAngle - borderInAngle, false);
- var newp2 = UGLHelper.GetPos(center, outsideRadius, realStartOutAngle, false);
- if (!roundCap) DrawQuadrilateral(vh, newp2, newp1, p1, p2, borderColor);
- p1 = newp1;
- p2 = newp2;
- if (toAngle + spaceInAngle + 2 * borderInAngle < realStartOutAngle)
- {
- var newe1 = UGLHelper.GetPos(center, insideRadius, toAngle + spaceInAngle + borderInAngle, false);
- var newe2 = UGLHelper.GetPos(center, outsideRadius, realToOutAngle, false);
- if (!roundCap) DrawQuadrilateral(vh, newe2, e2, e1, newe1, borderColor);
- e1 = newe1;
- e2 = newe2;
- }
- }
- }
- }
- if (roundCap)
- {
- var roundRadius = (outsideRadius - insideRadius) / 2;
- var roundAngleRadius = insideRadius + roundRadius;
- var roundAngle = Mathf.Atan(roundRadius / roundAngleRadius);
- if (clockwise)
- {
- realStartOutAngle = startAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle;
- realStartInAngle = startAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle;
- }
- else
- {
- realStartOutAngle = startAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle;
- realStartInAngle = startAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle;
- }
- var roundTotalDegree = realStartOutAngle * Mathf.Rad2Deg;
- var roundCenter = center + roundAngleRadius * UGLHelper.GetDire(realStartOutAngle);
- var sectorStartDegree = clockwise ? roundTotalDegree + 180 : roundTotalDegree;
- var sectorToDegree = clockwise ? roundTotalDegree + 360 : roundTotalDegree + 180;
- DrawSector(vh, roundCenter, roundRadius, color, sectorStartDegree, sectorToDegree, smoothness / 2);
- if (needBorder)
- {
- DrawDoughnut(vh, roundCenter, roundRadius, roundRadius + borderWidth, borderColor,
- s_ClearColor32, sectorStartDegree, sectorToDegree, smoothness / 2);
- }
- p1 = UGLHelper.GetPos(center, insideRadius, realStartOutAngle);
- p2 = UGLHelper.GetPos(center, outsideRadius, realStartOutAngle);
-
- if (clockwise)
- {
- realToOutAngle = toAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle;
- realToInAngle = toAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle;
- if (realToOutAngle < realStartOutAngle) realToOutAngle = realStartOutAngle;
- }
- else
- {
- realToOutAngle = toAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle;
- realToInAngle = toAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle;
- if (realToOutAngle > realStartOutAngle) realToOutAngle = realStartOutAngle;
- }
- roundTotalDegree = realToOutAngle * Mathf.Rad2Deg;
- roundCenter = center + roundAngleRadius * UGLHelper.GetDire(realToOutAngle);
- sectorStartDegree = clockwise ? roundTotalDegree : roundTotalDegree + 180;
- sectorToDegree = clockwise ? roundTotalDegree + 180 : roundTotalDegree + 360;
- DrawSector(vh, roundCenter, roundRadius, toColor, sectorStartDegree, sectorToDegree, smoothness / 2);
- if (needBorder)
- {
- DrawDoughnut(vh, roundCenter, roundRadius, roundRadius + borderWidth, borderColor,
- s_ClearColor32, sectorStartDegree, sectorToDegree, smoothness / 2);
- }
- e1 = UGLHelper.GetPos(center, insideRadius, realToOutAngle);
- e2 = UGLHelper.GetPos(center, outsideRadius, realToOutAngle);
- }
- var segmentAngle = (realToInAngle - realStartInAngle) / segments;
- var isGradient = !UGLHelper.IsValueEqualsColor(color, toColor);
- for (int i = 0; i <= segments; i++)
- {
- float currAngle = realStartInAngle + i * segmentAngle;
- p3 = new Vector3(center.x + outsideRadius * Mathf.Sin(currAngle),
- center.y + outsideRadius * Mathf.Cos(currAngle));
- p4 = new Vector3(center.x + insideRadius * Mathf.Sin(currAngle),
- center.y + insideRadius * Mathf.Cos(currAngle));
- if (isGradient)
- {
- var tcolor = Color32.Lerp(color, toColor, i * 1.0f / segments);
- if (i == 0 && (needSpace || needBorder))
- UGL.DrawTriangle(vh, p1, p2, p3, color, tcolor, tcolor);
- AddVertToVertexHelper(vh, p3, p4, tcolor, tcolor, i > 0);
- }
- else
- {
- if (i == 0 && (needSpace || needBorder))
- UGL.DrawTriangle(vh, p1, p2, p3, color);
- AddVertToVertexHelper(vh, p3, p4, color, color, i > 0);
- }
- p1 = p4;
- p2 = p3;
- }
- if (!UGLHelper.IsClearColor(emptyColor))
- {
- for (int i = 0; i <= segments; i++)
- {
- float currAngle = realStartInAngle + i * segmentAngle;
- p4 = new Vector3(center.x + insideRadius * Mathf.Sin(currAngle),
- center.y + insideRadius * Mathf.Cos(currAngle));
- AddVertToVertexHelper(vh, center, p4, emptyColor, emptyColor, i > 0);
- }
- }
- if (needBorder || needSpace || roundCap)
- {
- if (clockwise)
- {
- var isInAngleFixed = toAngle - spaceInAngle - 2 * borderInAngle > realStartOutAngle;
- if (isInAngleFixed) DrawQuadrilateral(vh, p2, e2, e1, p1, color, toColor);
- else DrawTriangle(vh, p2, e2, p1, color, color, toColor);
- if (needBorder)
- {
- var realStartDegree = (realStartOutAngle - (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg;
- var realToDegree = (realToOutAngle + (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg;
- if (realToDegree < realStartOutAngle) realToDegree = realStartOutAngle;
- var inStartDegree = roundCap ? realStartDegree : (startAngle + spaceInAngle) * Mathf.Rad2Deg;
- var inToDegree = roundCap ? realToDegree : (toAngle - spaceInAngle) * Mathf.Rad2Deg;
- if (inToDegree < inStartDegree) inToDegree = inStartDegree;
- if (isInAngleFixed) DrawDoughnut(vh, center, insideRadius - borderWidth, insideRadius, borderColor,
- s_ClearColor32, inStartDegree, inToDegree, smoothness);
- DrawDoughnut(vh, center, outsideRadius, outsideRadius + borderWidth, borderColor, s_ClearColor32,
- realStartDegree, realToDegree, smoothness);
- }
- }
- else
- {
- var isInAngleFixed = toAngle + spaceInAngle + 2 * borderInAngle < realStartOutAngle;
- if (isInAngleFixed) DrawQuadrilateral(vh, p2, e2, e1, p1, color, toColor);
- else DrawTriangle(vh, p2, e2, p1, color, color, toColor);
- if (needBorder)
- {
- var realStartDegree = (realStartOutAngle + (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg;
- var realToDegree = (realToOutAngle - (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg;
- var inStartDegree = roundCap ? realStartDegree : (startAngle - spaceInAngle) * Mathf.Rad2Deg;
- var inToDegree = roundCap ? realToDegree : (toAngle + spaceInAngle) * Mathf.Rad2Deg;
- if (inToDegree > inStartDegree) inToDegree = inStartDegree;
- if (isInAngleFixed)
- {
- DrawDoughnut(vh, center, insideRadius - borderWidth, insideRadius, borderColor,
- s_ClearColor32, inStartDegree, inToDegree, smoothness);
- }
- DrawDoughnut(vh, center, outsideRadius, outsideRadius + borderWidth, borderColor,
- s_ClearColor32, realStartDegree, realToDegree, smoothness);
- }
- }
- }
- }
-
- /// <summary>
- /// 画贝塞尔曲线
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="sp">起始点</param>
- /// <param name="ep">结束点</param>
- /// <param name="cp1">控制点1</param>
- /// <param name="cp2">控制点2</param>
- /// <param name="lineWidth">曲线宽</param>
- /// <param name="lineColor">曲线颜色</param>
- public static void DrawCurves(VertexHelper vh, Vector3 sp, Vector3 ep, Vector3 cp1, Vector3 cp2,
- float lineWidth, Color32 lineColor, float smoothness, Direction dire = Direction.XAxis)
- {
- var dist = Vector3.Distance(sp, ep);
- var segment = (int) (dist / (smoothness <= 0 ? 2f : smoothness));
- UGLHelper.GetBezierList2(ref s_CurvesPosList, sp, ep, segment, cp1, cp2);
- DrawCurvesInternal(vh, s_CurvesPosList, lineWidth, lineColor, dire);
- }
-
- /// <summary>
- /// 画贝塞尔曲线
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="points">坐标点列表</param>
- /// <param name="width">曲线宽</param>
- /// <param name="color">曲线颜色</param>
- /// <param name="smoothStyle">曲线样式</param>
- /// <param name="smoothness">平滑度</param>
- /// <param name="dire">曲线方向</param>
- /// <param name="currProgress">当前绘制进度</param>
- /// <param name="closed">曲线是否闭合</param>
- public static void DrawCurves(VertexHelper vh, List<Vector3> points, float width, Color32 color,
- float smoothStyle, float smoothness, Direction dire, float currProgress = float.NaN,
- bool closed = false)
- {
- var count = points.Count;
- var size = (closed?count : count - 1);
- if (closed)
- dire = Direction.Random;
- for (int i = 0; i < size; i++)
- {
- var sp = points[i];
- var ep = closed?(i == size - 1 ? points[0] : points[i + 1]) : points[i + 1];
- var lsp = i > 0 ? points[i - 1] : (closed?points[count - 1] : sp);
- var nep = i < points.Count - 2 ? points[i + 2] : (closed?points[(i + 2) % count] : ep);
- var smoothness2 = smoothness;
- if (currProgress != float.NaN)
- {
- switch (dire)
- {
- case Direction.XAxis:
- smoothness2 = ep.x <= currProgress ? smoothness : smoothness * 0.5f;
- break;
- case Direction.YAxis:
- smoothness2 = ep.y <= currProgress ? smoothness : smoothness * 0.5f;
- break;
- case Direction.Random:
- smoothness2 = smoothness * 0.5f;
- break;
- }
- }
- if (dire == Direction.YAxis)
- UGLHelper.GetBezierListVertical(ref s_CurvesPosList, sp, ep, smoothness2, smoothStyle);
- else
- UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness2, smoothStyle, false, dire == Direction.Random);
-
- DrawCurvesInternal(vh, s_CurvesPosList, width, color, dire, currProgress);
- }
- }
-
- private static void DrawCurvesInternal(VertexHelper vh, List<Vector3> curvesPosList, float lineWidth,
- Color32 lineColor, Direction dire, float currProgress = float.NaN)
- {
- if (curvesPosList.Count > 1)
- {
- var start = curvesPosList[0];
- var to = Vector3.zero;
- var dir = curvesPosList[1] - start;
- var diff = Vector3.Cross(dir, Vector3.forward).normalized * lineWidth;
- var startUp = start - diff;
- var startDn = start + diff;
- var toUp = Vector3.zero;
- var toDn = Vector3.zero;
-
- var lastVertCount = vh.currentVertCount;
- AddVertToVertexHelper(vh, startUp, startDn, lineColor, false);
- for (int i = 1; i < curvesPosList.Count; i++)
- {
- to = curvesPosList[i];
- if (currProgress != float.NaN)
- {
- if (dire == Direction.YAxis && to.y > currProgress)
- break;
- if (dire == Direction.XAxis && to.x > currProgress)
- break;
- }
-
- diff = Vector3.Cross(to - start, Vector3.forward).normalized * lineWidth;
- toUp = to - diff;
- toDn = to + diff;
-
- AddVertToVertexHelper(vh, toUp, toDn, lineColor);
-
- startUp = toUp;
- startDn = toDn;
- start = to;
- }
- AddVertToVertexHelper(vh, toUp, toDn, lineColor);
- }
- }
-
- public static void DrawSvgPath(VertexHelper vh, string path)
- {
- SVG.DrawPath(vh, path);
- }
-
- public static void DrawEllipse(VertexHelper vh, Vector3 center, float w, float h, Color32 color, float smoothness = 1)
- {
- DrawEllipse(vh, center, w, h, color, smoothness, 0, s_ClearColor32, 0, 360);
- }
-
- public static void DrawEllipse(VertexHelper vh, Vector3 center, float w, float h, Color32 color, float smoothness,
- float borderWidth, Color32 borderColor,
- float startAngle, float endAngle)
- {
- startAngle = (startAngle + 360) % 360;
- endAngle = (endAngle + 360) % 360;
- if (endAngle < startAngle)
- endAngle += 360;
- if (endAngle <= startAngle)
- return;
-
- var angle = startAngle;
- var lp = Vector2.zero;
- var fill = color.a != 0;
- var border = borderWidth != 0 && borderColor.a != 0;
- if (!fill && !border)
- return;
-
- var startTriangleIndex = vh.currentVertCount;
- if (fill)
- {
- vh.AddVert(center, color, Vector2.zero);
- }
- if (smoothness < 0.5f)
- smoothness = 0.5f;
-
- var i = 0;
- while (angle <= endAngle)
- {
- var rad = angle * Mathf.Deg2Rad;
- var x = center.x + w * Mathf.Cos(rad);
- var y = center.y + h * Mathf.Sin(rad);
- var p1 = new Vector3(x, y);
- vh.AddVert(p1, color, Vector2.zero);
- if (border)
- {
- var dire = (p1 - center).normalized;
- var diff = dire * borderWidth;
- var p2 = p1 + diff;
- vh.AddVert(p1, borderColor, Vector2.zero);
- vh.AddVert(p2, borderColor, Vector2.zero);
-
- if (i > 0)
- {
- var index = startTriangleIndex + i * 3 + 2;
- vh.AddTriangle(index - 3, index + 1, index - 2);
- vh.AddTriangle(index - 3, index, index + 1);
- if (fill)
- vh.AddTriangle(startTriangleIndex, index - 1, index - 4);
- }
- }
- else if (i > 0 && fill)
- {
- var index = startTriangleIndex + i;
- vh.AddTriangle(startTriangleIndex, index + 1, index);
- }
- i++;
- angle += smoothness;
- }
- }
-
- /// <summary>
- /// 填充任意多边形(目前只支持凸多边形)
- /// </summary>
- /// <param name="vh"></param>
- /// <param name="points"></param>
- /// <param name="color"></param>
- public static void DrawPolygon(VertexHelper vh, List<Vector3> points, Color32 color)
- {
- if (points.Count < 3 || UGLHelper.IsClearColor(color)) return;
- var cv = vh.currentVertCount;
- foreach (var pos in points)
- {
- vh.AddVert(pos, color, Vector2.zero);
- }
- for (int i = 2; i < points.Count; i++)
- {
- vh.AddTriangle(cv, cv + i - 1, cv + i);
- }
- }
- }
- }
|