private static void DrawLine(VertexHelper vh, float yMin, float yMax, float offsetX, float ratio, float time, float size, Color color) { var xMin = offsetX + time * ratio - size / 2f; var xMax = xMin + size; vh.AddUIVertexQuad(UIVertexHelper.CreateVBO(color, new Vector2(xMin, yMin), new Vector2(xMax, yMin), new Vector2(xMax, yMax), new Vector2(xMin, yMax) )); }
protected override void OnPopulateMesh(VertexHelper vh) { vh.Clear(); if (style == null || _curves.Count == 0) { return; } // General var range = EstimateRange(); var margin = 20f; var width = rectTransform.rect.width; var height = rectTransform.rect.height - margin * 2f; var offsetX = -width / 2f; var precision = 2f; // Draw at every N pixels var minVertexYDelta = 0.8f; // How much distance is required to draw a point var handleSize = style.HandleSize; // X ratio var lastCurve = _curves[_curves.Count - 1]; var maxX = lastCurve.Value[lastCurve.Value.length - 1].time; var xRatio = width / maxX; // Y ratio var minY = range.x; var maxY = range.y; var yRatio = height / (maxY - minY); var offsetY = (-minY - (maxY - minY) / 2f) * yRatio; if (float.IsInfinity(yRatio)) { yRatio = 1f; offsetY = 0f; } // Zero line var halfWidth = rectTransform.rect.width / 2; vh.DrawLine(new[] { new Vector2(-halfWidth, offsetY), new Vector2(halfWidth, offsetY) }, style.ZeroLineSize, style.ZeroLineColor); // Seconds var halfHeight = rectTransform.rect.height / 2; for (var t = 0f; t <= maxX; t += 1f) { var x = offsetX + t * xRatio; vh.DrawLine(new[] { new Vector2(x, halfHeight), new Vector2(x, -halfHeight) }, style.SecondLineSize, style.SecondLineColor); } // Curves foreach (var curveInfo in _curves) { // Common var curve = curveInfo.Value; var color = curveInfo.Key; var last = curve[curve.length - 1]; // Draw line var step = maxX / width * precision; var points = new List <Vector2>(curve.length); var previousY = Mathf.Infinity; for (var time = 0f; time < maxX; time += step) { var value = curve.Evaluate(time); var y = offsetY + value * yRatio; if (Mathf.Abs(y - previousY) < minVertexYDelta) { continue; } var cur = new Vector2(offsetX + time * xRatio, y); previousY = y; points.Add(cur); } points.Add(new Vector2(offsetX + last.time * xRatio, offsetY + last.value * yRatio)); vh.DrawLine(points, style.CurveLineSize, color); // Draw handles for (var i = 0; i < curve.length; i++) { var keyframe = curve[i]; var center = new Vector2(offsetX + keyframe.time * xRatio, offsetY + keyframe.value * yRatio); vh.AddUIVertexQuad(UIVertexHelper.CreateVBO(color, new[] { center - new Vector2(-handleSize, -handleSize), center - new Vector2(-handleSize, handleSize), center - new Vector2(handleSize, handleSize), center - new Vector2(handleSize, -handleSize) })); } } // Border var halfBorder = style.BorderSize / 2f; var quarterBorder = halfBorder / 2f; vh.DrawLine(new[] { new Vector2(-halfWidth, -halfHeight + quarterBorder), new Vector2(halfWidth, -halfHeight + quarterBorder) }, style.BorderSize, style.BorderColor); vh.DrawLine(new[] { new Vector2(-halfWidth, halfHeight - quarterBorder), new Vector2(halfWidth, halfHeight - quarterBorder) }, style.BorderSize, style.BorderColor); vh.DrawLine(new[] { new Vector2(-halfWidth + halfBorder, halfHeight), new Vector2(-halfWidth + halfBorder, -halfHeight) }, style.BorderSize, style.BorderColor); vh.DrawLine(new[] { new Vector2(halfWidth - halfBorder, halfHeight), new Vector2(halfWidth - halfBorder, -halfHeight) }, style.BorderSize, style.BorderColor); }
protected override void OnPopulateMesh(VertexHelper vh) { vh.Clear(); if (style == null || _animationLength == 0) { return; } var width = rectTransform.rect.width; var padding = style.KeyframesRowPadding; var lineHeight = style.KeyframesRowLineSize; var pixelsPerSecond = width / _frames.Count; var tooManyKeyframes = pixelsPerSecond < 2f; var lineColor = _selected ? style.KeyframesRowLineColorSelected : tooManyKeyframes ? Color.red : style.KeyframesRowLineColor; vh.AddUIVertexQuad(UIVertexHelper.CreateVBO(lineColor, new Vector2(-width / 2f + padding, -lineHeight), new Vector2(width / 2f - padding, -lineHeight), new Vector2(width / 2f - padding, lineHeight), new Vector2(-width / 2f + padding, lineHeight) )); if (tooManyKeyframes) { return; } var ratio = (width - padding * 2f) / _animationLength; var size = style.KeyframeSize; var offsetX = -width / 2f + padding; foreach (var keyframe in _frames) { if (_currentFrame == keyframe) { continue; } if (_loop && keyframe == _animationLength) { continue; } var center = new Vector2(offsetX + keyframe * ratio, 0); vh.AddUIVertexQuad(UIVertexHelper.CreateVBO(style.KeyframeColor, center - new Vector2(0, -size), center - new Vector2(size, 0), center - new Vector2(0, size), center - new Vector2(-size, 0) )); } if (_loop) { var center = new Vector2(offsetX + _animationLength * ratio, 0); vh.AddUIVertexQuad(UIVertexHelper.CreateVBO(style.KeyframeColor, center - new Vector2(-2, -size), center - new Vector2(-2, size), center - new Vector2(2, size), center - new Vector2(2, -size) )); } if (_currentFrame != -1) { var center = new Vector2(offsetX + _currentFrame * ratio, 0); size = style.KeyframeSizeSelectedBack; vh.AddUIVertexQuad(UIVertexHelper.CreateVBO(selected ? style.KeyframeColorSelectedBack : style.KeyframeColorCurrentBack, center - new Vector2(0, -size), center - new Vector2(size, 0), center - new Vector2(0, size), center - new Vector2(-size, 0) )); size = style.KeyframeSizeSelectedFront; vh.AddUIVertexQuad(UIVertexHelper.CreateVBO(selected ? style.KeyframeColorSelectedFront : style.KeyframeColorCurrentFront, center - new Vector2(0, -size), center - new Vector2(size, 0), center - new Vector2(0, size), center - new Vector2(-size, 0) )); } }
protected override void OnPopulateMesh(VertexHelper vh) { vh.Clear(); if (style == null || _curves.Count == 0) { return; } // General var range = EstimateRange(); const float margin = 20f; var rect = rectTransform.rect; var width = rect.width; var height = rect.height - margin * 2f; var offsetX = -width / 2f; const float precision = 2f; // Draw at every N pixels const float maxVertexXDelta = 3f; // Whenever that distance is reached an additional point is drawn for constant curves const float minVertexYDelta = 0.8f; // How much distance is required to draw a point var handleSize = style.HandleSize; var halfWidth = rect.width / 2; var halfHeight = rect.height / 2; // X ratio var lastCurve = _curves[_curves.Count - 1]; if (lastCurve.Value.length < 2) { return; } var maxX = lastCurve.Value.duration; if (maxX == 0) { DrawBorder(vh, halfWidth, halfHeight); return; } var xRatio = width / maxX; // Y ratio var minY = range.x; var maxY = range.y; var yRatio = height / (maxY - minY); var offsetY = (-minY - (maxY - minY) / 2f) * yRatio; if (float.IsInfinity(yRatio) || maxY - minY < 0.00001f) { yRatio = 1f; offsetY = 0f; } // Zero line vh.DrawLine(new[] { new Vector2(-halfWidth, offsetY), new Vector2(halfWidth, offsetY) }, style.ZeroLineSize, style.ZeroLineColor); // Seconds var pixelsPerSecond = width / maxX; float timespan; if (pixelsPerSecond < 20) { timespan = 100f; } else if (pixelsPerSecond < 2) { timespan = 10f; } else { timespan = 1f; } for (var t = 0f; t <= maxX; t += timespan) { var x = offsetX + t * xRatio; vh.DrawLine(new[] { new Vector2(x, halfHeight), new Vector2(x, -halfHeight) }, style.SecondLineSize, style.SecondLineColor); } // Curves foreach (var curveInfo in _curves) { // Common var curve = curveInfo.Value; if (curve.length > 1000) { continue; } var curveColor = curveInfo.Key; var last = curve.GetKeyframeByKey(curve.length - 1); // Draw line var step = maxX / width * precision; var points = new List <Vector2>(curve.length); var previous = new Vector2(Mathf.NegativeInfinity, Mathf.Infinity); for (var time = 0f; time < maxX; time += step) { var value = curve.Evaluate(time); var cur = new Vector2(offsetX + time * xRatio, offsetY + value * yRatio); if (Mathf.Abs(cur.y - previous.y) < minVertexYDelta) { continue; } if (Mathf.Abs(cur.x - previous.x) > maxVertexXDelta) { points.Add(new Vector2(cur.x, previous.y)); } previous = cur; points.Add(cur); } var curN = new Vector2(offsetX + last.time * xRatio, offsetY + last.value * yRatio); if (Mathf.Abs(curN.x - previous.x) > maxVertexXDelta) { points.Add(new Vector2(curN.x, previous.y)); } points.Add(curN); vh.DrawLine(points, style.CurveLineSize, curveColor); // Draw handles for (var i = 0; i < curve.length; i++) { var keyframe = curve.GetKeyframeByKey(i); var handlePos = new Vector2(offsetX + keyframe.time * xRatio, offsetY + keyframe.value * yRatio); // Render bezier control points #if (RENDER_BEZIER_CONTROL_POINTS) if (i > 0) { var previousKey = curve.GetKeyframeByKey(i - 1); var previousPos = new Vector2(offsetX + (keyframe.time - (keyframe.time - previousKey.time) / 3f) * xRatio, offsetY + keyframe.controlPointIn * yRatio); vh.DrawLine(new[] { handlePos, previousPos }, 1f, Color.white); vh.AddUIVertexQuad(UIVertexHelper.CreateVBO(Color.white, new[] { previousPos - new Vector2(-handleSize / 2f, -handleSize / 2f), previousPos - new Vector2(-handleSize / 2f, handleSize / 2f), previousPos - new Vector2(handleSize / 2f, handleSize / 2f), previousPos - new Vector2(handleSize / 2f, -handleSize / 2f) })); } if (i < curve.length - 1) { var next = curve.GetKeyframeByKey(i + 1); var nextPos = new Vector2(offsetX + (keyframe.time + (next.time - keyframe.time) / 3f) * xRatio, offsetY + keyframe.controlPointOut * yRatio); vh.DrawLine(new[] { handlePos, nextPos }, 1f, Color.white); vh.AddUIVertexQuad(UIVertexHelper.CreateVBO(Color.white, new[] { nextPos - new Vector2(-handleSize / 2f, -handleSize / 2f), nextPos - new Vector2(-handleSize / 2f, handleSize / 2f), nextPos - new Vector2(handleSize / 2f, handleSize / 2f), nextPos - new Vector2(handleSize / 2f, -handleSize / 2f) })); } #endif // Render keyframe vh.AddUIVertexQuad(UIVertexHelper.CreateVBO(curveColor, handlePos - new Vector2(-handleSize, -handleSize), handlePos - new Vector2(-handleSize, handleSize), handlePos - new Vector2(handleSize, handleSize), handlePos - new Vector2(handleSize, -handleSize) )); } } DrawBorder(vh, halfWidth, halfHeight); }