public void DrawOnQuad(ref MadList<Vector3> vertices, ref MadList<Color32> colors, ref MadList<Vector2> uv, ref MadList<int> triangles) { bool invert = fillType == FillType.RadialCCW; var matrix = TransformMatrix(); var bounds = GetBounds(); var topLeftQuad = new Quad(invert); var topRightQuad = new Quad(invert); var bottomRightQuad = new Quad(invert); var bottomLeftQuad = new Quad(invert); topLeftQuad.anchor = Quad.Point.BottomRight; topRightQuad.anchor = Quad.Point.BottomLeft; bottomRightQuad.anchor = Quad.Point.TopLeft; bottomLeftQuad.anchor = Quad.Point.TopRight; var topLeftQuad2 = new Quad(topLeftQuad); var topRightQuad2 = new Quad(topRightQuad); var bottomRightQuad2 = new Quad(bottomRightQuad); var bottomLeftQuad2 = new Quad(bottomLeftQuad); // creating 8 quads instead of 8 because when using offset it may display one additional quad // and the simplest way is to create 8 quads and wrap around Quad[] ordered = new Quad[8]; if (!invert) { ordered[0] = topRightQuad; ordered[1] = bottomRightQuad; ordered[2] = bottomLeftQuad; ordered[3] = topLeftQuad; ordered[4] = topRightQuad2; ordered[5] = bottomRightQuad2; ordered[6] = bottomLeftQuad2; ordered[7] = topLeftQuad2; } else { ordered[7] = topRightQuad2; ordered[6] = bottomRightQuad2; ordered[5] = bottomLeftQuad2; ordered[4] = topLeftQuad2; ordered[3] = topRightQuad; ordered[2] = bottomRightQuad; ordered[1] = bottomLeftQuad; ordered[0] = topLeftQuad; } float rOffset = radialFillOffset % 1; if (rOffset < 0) { rOffset += 1; } float fillValue = Mathf.Clamp01(this.fillValue) * radialFillLength; float fillStart = rOffset * 4; float fillEnd = (rOffset + fillValue) * 4; for (int i = Mathf.FloorToInt(fillStart); i < Mathf.CeilToInt(fillEnd); ++i) { var quad = ordered[i % 8]; if (i < fillStart) { quad.offset = fillStart - i; } else { quad.offset = 0; } if (fillEnd > i + 1) { quad.progress = 1 - quad.offset; } else { quad.progress = fillEnd - i - quad.offset; } } float sx = initialSize.x; float sy = initialSize.y; float sx2 = sx / 2; float sy2 = sy / 2; // collect points anv uvs List<Vector2[]> genPoints = new List<Vector2[]>(); List<Vector2[]> genUvs = new List<Vector2[]>(); genPoints.Add(topRightQuad.Points(sx2, sy, sx, sy2)); genUvs.Add(topRightQuad.Points(0.5f, 1, 1, 0.5f)); genPoints.Add(topRightQuad2.Points(sx2, sy, sx, sy2)); genUvs.Add(topRightQuad2.Points(0.5f, 1, 1, 0.5f)); genPoints.Add(bottomRightQuad.Points(sx2, sy2, sx, 0)); genUvs.Add(bottomRightQuad.Points(0.5f, 0.5f, 1, 0)); genPoints.Add(bottomRightQuad2.Points(sx2, sy2, sx, 0)); genUvs.Add(bottomRightQuad2.Points(0.5f, 0.5f, 1, 0)); genPoints.Add(bottomLeftQuad.Points(0, sy2, sx2, 0)); genUvs.Add(bottomLeftQuad.Points(0, 0.5f, 0.5f, 0)); genPoints.Add(bottomLeftQuad2.Points(0, sy2, sx2, 0)); genUvs.Add(bottomLeftQuad2.Points(0, 0.5f, 0.5f, 0)); genPoints.Add(topLeftQuad.Points(0, sy, sx2, sy2)); genUvs.Add(topLeftQuad.Points(0, 1, 0.5f, 0.5f)); genPoints.Add(topLeftQuad2.Points(0, sy, sx2, sy2)); genUvs.Add(topLeftQuad2.Points(0, 1, 0.5f, 0.5f)); // add ass triangles Color32 color32 = (Color32) tint; for (int i = 0; i < 8; ++i) { var points = genPoints[i]; var uvs = genUvs[i]; if (points.Length == 0) { continue; } int offset = vertices.Count; for (int j = 0; j < points.Length; ++j) { vertices.Add(matrix.MultiplyPoint(PivotPointTranslate(points[j], bounds))); uv.Add(FixUV(uvs[j])); colors.Add(color32); } triangles.Add(0 + offset); triangles.Add(1 + offset); triangles.Add(2 + offset); // for quads if (points.Length > 3) { triangles.Add(0 + offset); triangles.Add(2 + offset); triangles.Add(3 + offset); } } }
public virtual void DrawOn(ref MadList<Vector3> vertices, ref MadList<Color32> colors, ref MadList<Vector2> uv, ref MadList<int> triangles, out Material material) { UpdatePivotPoint(); if (fillType == FillType.None || fillValue > 0) { if ((fillType == FillType.RadialCW || fillType == FillType.RadialCCW) && (fillValue != 1 || radialFillLength != 1)) { DrawOnQuad(ref vertices, ref colors, ref uv, ref triangles); } else { DrawOnRegular(ref vertices, ref colors, ref uv, ref triangles); } } material = GetMaterial(); }
public void DrawOnRegular(ref MadList<Vector3> vertices, ref MadList<Color32> colors, ref MadList<Vector2> uv, ref MadList<int> triangles) { var matrix = TransformMatrix(); var bounds = GetBounds(); float vLeft = 0; float vTop = initialSize.y; float vRight = initialSize.x; float vBottom = 0; float uvLeft = textureOffset.x; float uvTop = textureOffset.y + textureRepeat.y; float uvRight = textureOffset.x + textureRepeat.x; float uvBottom = textureOffset.y; fillValue = Mathf.Clamp01(fillValue); if (fillValue != 1) { switch (fillType) { case FillType.LeftToRight: vRight *= LiveCoordX(fillValue); uvRight += LiveCoordX(fillValue) - 1; break; case FillType.RightToLeft: vLeft += LiveCoordX(1 - fillValue) * initialSize.x; uvLeft += LiveCoordX(1 - fillValue); break; case FillType.BottomToTop: vTop *= LiveCoordY(fillValue); uvTop += LiveCoordY(fillValue) - 1; break; case FillType.TopToBottom: vBottom += LiveCoordY(1 - fillValue) * initialSize.y; uvBottom += LiveCoordY(1 - fillValue); break; case FillType.ExpandHorizontal: { float fv = 0.5f + fillValue / 2; vRight *= LiveCoordX(fv); uvRight += LiveCoordX(fv) - 1; vLeft += LiveCoordX(1 - fv) * initialSize.x; uvLeft += LiveCoordX(1 - fv); } break; case FillType.ExpandVertical: { float fv = 0.5f + fillValue / 2; vTop *= LiveCoordY(fv); uvTop += LiveCoordY(fv) - 1; vBottom += LiveCoordY(1 - fv) * initialSize.y; uvBottom += LiveCoordY(1 - fv); } break; case FillType.None: // change nothing break; } } // left-bottom vertices.Add(matrix.MultiplyPoint(PivotPointTranslate(new Vector3(vLeft, vBottom, 0), bounds))); // left-top vertices.Add(matrix.MultiplyPoint(PivotPointTranslate(new Vector3(vLeft, vTop, 0), bounds))); // right - top vertices.Add(matrix.MultiplyPoint(PivotPointTranslate(new Vector3(vRight, vTop, 0), bounds))); // right - bottom vertices.Add(matrix.MultiplyPoint(PivotPointTranslate(new Vector3(vRight, vBottom, 0), bounds))); Color32 color32 = (Color32) tint; colors.Add(color32); colors.Add(color32); colors.Add(color32); colors.Add(color32); uv.Add(FixUV(new Vector2(uvLeft, uvBottom))); uv.Add(FixUV(new Vector2(uvLeft, uvTop))); uv.Add(FixUV(new Vector2(uvRight, uvTop))); uv.Add(FixUV(new Vector2(uvRight, uvBottom))); int offset = vertices.Count - 4; triangles.Add(0 + offset); triangles.Add(1 + offset); triangles.Add(2 + offset); triangles.Add(0 + offset); triangles.Add(2 + offset); triangles.Add(3 + offset); }
public MadList<Vector2> Points(float left, float top, float right, float bottom, MadList<Vector2> list) { list.Clear(); if (progress == 0) { return list; } else if (progress == 1) { list.Add(new Vector2(left, bottom)); list.Add(new Vector2(left, top)); list.Add(new Vector2(right, top)); list.Add(new Vector2(right, bottom)); } else { float progressY = Y(progress + offset); float hy = left + (right - left) * progressY; float vy = bottom + (top - bottom) * progressY; float progressOffset = offset + progress; float offsetY = Y(offset); float ohy = left + (right - left) * offsetY; float ovy = bottom + (top - bottom) * offsetY; switch (anchor) { case Point.BottomLeft: if (!invert) { if (progressOffset < 0.5f) { list.Add(new Vector2(left, bottom)); list.Add(new Vector2(ohy, top)); list.Add(new Vector2(hy, top)); list.Add(new Vector2(hy, top)); } else { if (offset < 0.5f) { list.Add(new Vector2(left, bottom)); list.Add(new Vector2(ohy, top)); list.Add(new Vector2(right, top)); list.Add(new Vector2(right, vy)); } else { list.Add(new Vector2(left, bottom)); list.Add(new Vector2(right, ovy)); list.Add(new Vector2(right, vy)); list.Add(new Vector2(right, vy)); } } } else { if (progressOffset < 0.5f) { list.Add(new Vector2(left, bottom)); list.Add(new Vector2(right, ovy)); list.Add(new Vector2(right, vy)); list.Add(new Vector2(right, vy)); } else { if (offset < 0.5f) { list.Add(new Vector2(left, bottom)); list.Add(new Vector2(right, ovy)); list.Add(new Vector2(right, top)); list.Add(new Vector2(hy, top)); } else { list.Add(new Vector2(left, bottom)); list.Add(new Vector2(ohy, top)); list.Add(new Vector2(hy, top)); list.Add(new Vector2(hy, top)); } } } break; case Point.TopLeft: if (!invert) { if (progressOffset < 0.5f) { list.Add(new Vector2(left, top)); list.Add(new Vector2(right, top - ovy)); list.Add(new Vector2(right, top - vy)); list.Add(new Vector2(right, top - vy)); } else { if (offset < 0.5f) { list.Add(new Vector2(left, top)); list.Add(new Vector2(right, top - ovy)); list.Add(new Vector2(right, bottom)); list.Add(new Vector2(hy, bottom)); } else { list.Add(new Vector2(left, top)); list.Add(new Vector2(ohy, bottom)); list.Add(new Vector2(hy, bottom)); list.Add(new Vector2(hy, bottom)); } } } else { if (progressOffset < 0.5f) { list.Add(new Vector2(left, top)); list.Add(new Vector2(ohy, bottom)); list.Add(new Vector2(hy, bottom)); list.Add(new Vector2(hy, bottom)); } else { if (offset < 0.5f) { list.Add(new Vector2(left, top)); list.Add(new Vector2(ohy, bottom)); list.Add(new Vector2(right, bottom)); list.Add(new Vector2(right, top - vy)); } else { list.Add(new Vector2(left, top)); list.Add(new Vector2(right, top - ovy)); list.Add(new Vector2(right, top - vy)); list.Add(new Vector2(right, top - vy)); } } } break; case Point.TopRight: if (!invert) { if (progressOffset < 0.5f) { list.Add(new Vector2(right, top)); list.Add(new Vector2(right - ohy, bottom)); list.Add(new Vector2(right - hy, bottom)); list.Add(new Vector2(right - hy, bottom)); } else { if (offset < 0.5f) { list.Add(new Vector2(right, top)); list.Add(new Vector2(right - ohy, bottom)); list.Add(new Vector2(left, bottom)); list.Add(new Vector2(left, top - vy)); } else { list.Add(new Vector2(right, top)); list.Add(new Vector2(left, top - ovy)); list.Add(new Vector2(left, top - vy)); list.Add(new Vector2(left, top - vy)); } } } else { if (progressOffset < 0.5f) { list.Add(new Vector2(right, top)); list.Add(new Vector2(left, top - ovy)); list.Add(new Vector2(left, top - vy)); list.Add(new Vector2(left, top - vy)); } else { if (offset < 0.5f) { list.Add(new Vector2(right, top)); list.Add(new Vector2(left, top - ovy)); list.Add(new Vector2(left, bottom)); list.Add(new Vector2(right - hy, bottom)); } else { list.Add(new Vector2(right, top)); list.Add(new Vector2(right - ohy, bottom)); list.Add(new Vector2(right - hy, bottom)); list.Add(new Vector2(right - hy, bottom)); } } } break; case Point.BottomRight: if (!invert) { if (progressOffset < 0.5f) { list.Add(new Vector2(right, bottom)); list.Add(new Vector2(left, ovy)); list.Add(new Vector2(left, vy)); list.Add(new Vector2(left, vy)); } else { if (offset < 0.5f) { list.Add(new Vector2(right, bottom)); list.Add(new Vector2(left, ovy)); list.Add(new Vector2(left, top)); list.Add(new Vector2(right - hy, top)); } else { list.Add(new Vector2(right, bottom)); list.Add(new Vector2(right - ohy, top)); list.Add(new Vector2(right - hy, top)); list.Add(new Vector2(right - hy, top)); } } } else { if (progressOffset < 0.5f) { list.Add(new Vector2(right, bottom)); list.Add(new Vector2(right - ohy, top)); list.Add(new Vector2(right - hy, top)); list.Add(new Vector2(right - hy, top)); } else { if (offset < 0.5f) { list.Add(new Vector2(right, bottom)); list.Add(new Vector2(right - ohy, top)); list.Add(new Vector2(left, top)); list.Add(new Vector2(left, vy)); } else { list.Add(new Vector2(right, bottom)); list.Add(new Vector2(left, ovy)); list.Add(new Vector2(left, vy)); list.Add(new Vector2(left, vy)); } } } break; default: Debug.LogError("Unknown anchor: " + anchor); break; } } return list; }
public override void DrawOn(ref MadList<Vector3> vertices, ref MadList<Color32> colors, ref MadList<Vector2> uv, ref MadList<int> triangles, out Material material) { UpdateTextIfNeeded(); UpdatePivotPoint(); var matrix = TransformMatrix(); var bounds = GetBounds(); material = font.material; float x = 0; float y = linesCount * scale - scale; for (int i = 0; i < linesCount; ++i) { string text = lines[i]; float lineWidth = lineWidths[i]; switch (align) { case Align.Left: x = 0; break; case Align.Center: x = (bounds.width - lineWidth) / 2; break; case Align.Right: x = bounds.width - lineWidth; break; default: Debug.LogError("Unknown align: " + align); x = 0; break; } for (int j = 0; j < text.Length; ++j) { char c = text[j]; int offset = vertices.Count; var glyph = font.GlyphFor(c); if (glyph == null) { Debug.LogWarning("Glyph not found: '" + c + "' (code " + (int) c + ")"); continue; } // float w = (scale / glyph.height) * glyph.width * font.textureAspect; float xAdvance; var gBounds = GlyphBounds(glyph, out xAdvance); if (c != ' ') { // render anything but space float left = x + gBounds.x; float bottom = y + gBounds.y; float right = left + gBounds.width; float top = bottom + gBounds.height; vertices.Add(matrix.MultiplyPoint(PivotPointTranslate(new Vector3(left, bottom, 0), bounds))); vertices.Add(matrix.MultiplyPoint(PivotPointTranslate(new Vector3(left, top, 0), bounds))); vertices.Add(matrix.MultiplyPoint(PivotPointTranslate(new Vector3(right, top, 0), bounds))); vertices.Add(matrix.MultiplyPoint(PivotPointTranslate(new Vector3(right, bottom, 0), bounds))); colors.Add(tint); colors.Add(tint); colors.Add(tint); colors.Add(tint); uv.Add(new Vector2(glyph.uMin, glyph.vMin)); uv.Add(new Vector2(glyph.uMin, glyph.vMax)); uv.Add(new Vector2(glyph.uMax, glyph.vMax)); uv.Add(new Vector2(glyph.uMax, glyph.vMin)); triangles.Add(0 + offset); triangles.Add(1 + offset); triangles.Add(2 + offset); triangles.Add(0 + offset); triangles.Add(2 + offset); triangles.Add(3 + offset); // x += gBounds.width + letterSpacing; } else { // x += gBounds.width; // no letter spacing for blank characters } x += xAdvance; } // end of line y -= scale; } }
private void AddToVbo(List<UIVertex> vbo, MadList<Vector2> points, MadList<Vector2> uvs) { UIVertex vert = UIVertex.simpleVert; for (int i = 0; i < points.Count; ++i) { var point = points[i]; var uv = uvs[i]; vert.position = point; vert.uv0 = new Vector2(uv.x, uv.y); vert.color = color; vbo.Add(vert); } }
private void PreparePointsAndUvs(MadList<Vector2> points, MadList<Vector2> uvs, Vector4 outerUv) { uvs.Clear(); var drawingDimensions = GetDrawingDimensions(false); float left = drawingDimensions.x; float right = drawingDimensions.z; float bottom = drawingDimensions.y; float top = drawingDimensions.w; float width = right - left; float height = top - bottom; float uvw = outerUv.z - outerUv.x; float uvh = outerUv.w - outerUv.y; for (int i = 0; i < points.Count; i++) { var v = points[i]; var uv = new Vector2(outerUv.x + uvw * v.x, outerUv.y + uvh * v.y); if (uvOffset != Vector2.zero) { uv.x += uvOffset.x; uv.y += uvOffset.y; } v.x *= width; v.y *= height; v.x += left; v.y += bottom; points[i] = v; uvs.Add(uv); } }
private void FillQuad(List<UIVertex> vbo) { bool invert = growDirection == EnergyBarBase.GrowDirection.RadialCCW; var topLeftQuad = new Quad(invert); var topRightQuad = new Quad(invert); var bottomRightQuad = new Quad(invert); var bottomLeftQuad = new Quad(invert); topLeftQuad.anchor = Quad.Point.BottomRight; topRightQuad.anchor = Quad.Point.BottomLeft; bottomRightQuad.anchor = Quad.Point.TopLeft; bottomLeftQuad.anchor = Quad.Point.TopRight; var topLeftQuad2 = new Quad(topLeftQuad); var topRightQuad2 = new Quad(topRightQuad); var bottomRightQuad2 = new Quad(bottomRightQuad); var bottomLeftQuad2 = new Quad(bottomLeftQuad); // creating 8 quads instead of 8 because when using offset it may display one additional quad // and the simplest way is to create 8 quads and wrap around Quad[] ordered = new Quad[8]; if (!invert) { ordered[0] = topRightQuad; ordered[1] = bottomRightQuad; ordered[2] = bottomLeftQuad; ordered[3] = topLeftQuad; ordered[4] = topRightQuad2; ordered[5] = bottomRightQuad2; ordered[6] = bottomLeftQuad2; ordered[7] = topLeftQuad2; } else { ordered[7] = topRightQuad2; ordered[6] = bottomRightQuad2; ordered[5] = bottomLeftQuad2; ordered[4] = topLeftQuad2; ordered[3] = topRightQuad; ordered[2] = bottomRightQuad; ordered[1] = bottomLeftQuad; ordered[0] = topLeftQuad; } float rOffset = radialFillOffset % 1; if (rOffset < 0) { rOffset += 1; } float fillValue = Mathf.Clamp01(this.fillValue) * radialFillLength; float fillStart = rOffset * 4; float fillEnd = (rOffset + fillValue) * 4; for (int i = Mathf.FloorToInt(fillStart); i < Mathf.CeilToInt(fillEnd); ++i) { Quad quad = ordered[i % 8]; if (i < fillStart) { quad.offset = fillStart - i; } else { quad.offset = 0; } if (fillEnd > i + 1) { quad.progress = 1 - quad.offset; } else { quad.progress = fillEnd - i - quad.offset; } } float sx = 1; float sy = 1; float sx2 = sx / 2; float sy2 = sy / 2; // collect points anv uvs MadList<Vector2> points = new MadList<Vector2>(4); MadList<Vector2> uvs = new MadList<Vector2>(4); vbo.Clear(); Vector4 outerUv = DataUtility.GetOuterUV(sprite); outerUv = FixUV(outerUv); topRightQuad.Points(sx2, sy, sx, sy2, points); PreparePointsAndUvs(points, uvs, outerUv); AddToVbo(vbo, points, uvs); topRightQuad2.Points(sx2, sy, sx, sy2, points); PreparePointsAndUvs(points, uvs, outerUv); AddToVbo(vbo, points, uvs); bottomRightQuad.Points(sx2, sy2, sx, 0, points); PreparePointsAndUvs(points, uvs, outerUv); AddToVbo(vbo, points, uvs); bottomRightQuad2.Points(sx2, sy2, sx, 0, points); PreparePointsAndUvs(points, uvs, outerUv); AddToVbo(vbo, points, uvs); bottomLeftQuad.Points(0, sy2, sx2, 0, points); PreparePointsAndUvs(points, uvs, outerUv); AddToVbo(vbo, points, uvs); bottomLeftQuad2.Points(0, sy2, sx2, 0, points); PreparePointsAndUvs(points, uvs, outerUv); AddToVbo(vbo, points, uvs); topLeftQuad.Points(0, sy, sx2, sy2, points); PreparePointsAndUvs(points, uvs, outerUv); AddToVbo(vbo, points, uvs); topLeftQuad2.Points(0, sy, sx2, sy2, points); PreparePointsAndUvs(points, uvs, outerUv); AddToVbo(vbo, points, uvs); }