/// <summary> /// transfers the data from our segments to the vertices for display /// </summary> void calculateVertices() { if (!_areVertsDirty) { return; } var entityPosition = fixPosition == Vector2.Zero ? entity.transform.position : fixPosition; var center = new Vector3(entityPosition, 0f); var radVec = new Vector3(0, -ribbonRadius, 0); // starting triangle, the head _vertices[0].Position = center + radVec; _vertices[0].Color = Color.Red; _vertices[1].Position = center + radVec; _vertices[1].Color = Color.Yellow; _vertices[2].Position = center + radVec; _vertices[2].Color = Color.Green; var maxX = float.MinValue; var minX = float.MaxValue; var maxY = float.MinValue; var minY = float.MaxValue; var index = 3; var segCount = 1; foreach (var seg in _segments) { var ratio = 1 - (1 / (float)_ribbonLength * segCount); seg.radius = ratio * ribbonRadius; ColorExt.lerp(ref startColor, ref endColor, out _vertices[index].Color, 1 - ratio); _vertices[index].Position = seg.topPoint; _vertices[index + 1].Position = seg.bottomPoint; _vertices[index + 1].Color = _vertices[index].Color; // update min/max for any visible verts maxX = Mathf.maxOf(maxX, _vertices[index].Position.X, _vertices[index + 1].Position.X); minX = Mathf.minOf(minX, _vertices[index].Position.X, _vertices[index + 1].Position.X); maxY = Mathf.maxOf(maxY, _vertices[index].Position.Y, _vertices[index + 1].Position.Y); minY = Mathf.minOf(minY, _vertices[index].Position.Y, _vertices[index + 1].Position.Y); // increment counters index += 2; segCount++; } _bounds.x = minX; _bounds.y = minY; _bounds.width = maxX - minX; _bounds.height = maxY - minY; _areVertsDirty = false; }
/// <summary> /// transfers the data from our segments to the vertices for display /// </summary> void CalculateVertices() { if (!_areVertsDirty) { return; } var center = new Vector3(Entity.Position.ToXna(), 0f); var radVec = new Vector3(0, -RibbonRadius, 0); // starting triangle, the head _vertices[0].Position = center + radVec; _vertices[0].Color = Color.Red; _vertices[1].Position = center + radVec; _vertices[1].Color = Color.Yellow; _vertices[2].Position = center + radVec; _vertices[2].Color = Color.Green; var maxX = float.MinValue; var minX = float.MaxValue; var maxY = float.MinValue; var minY = float.MaxValue; var index = 3; var segCount = 1; foreach (var seg in _segments) { var ratio = 1 - (1 / (float)_ribbonLength * segCount); seg.Radius = ratio * RibbonRadius; ColorExt.Lerp(ref StartColor, ref EndColor, out _vertices[index].Color, 1 - ratio); _vertices[index].Position = seg.TopPoint; _vertices[index + 1].Position = seg.BottomPoint; _vertices[index + 1].Color = _vertices[index].Color; // update min/max for any visible verts maxX = Mathf.MaxOf(maxX, _vertices[index].Position.X, _vertices[index + 1].Position.X); minX = Mathf.MinOf(minX, _vertices[index].Position.X, _vertices[index + 1].Position.X); maxY = Mathf.MaxOf(maxY, _vertices[index].Position.Y, _vertices[index + 1].Position.Y); minY = Mathf.MinOf(minY, _vertices[index].Position.Y, _vertices[index + 1].Position.Y); // increment counters index += 2; segCount++; } _bounds.X = minX; _bounds.Y = minY; _bounds.Width = maxX - minX; _bounds.Height = maxY - minY; _areVertsDirty = false; }
void calculateVertices() { if (!_areVertsDirty || _points.length < 2) { return; } _areVertsDirty = false; _indices.reset(); _vertices.reset(); var maxX = float.MinValue; var minX = float.MaxValue; var maxY = float.MinValue; var minY = float.MaxValue; if (_useStartEndWidths) { _maxWidth = System.Math.Max(_startWidth, _endWidth); } // calculate line length first and simulataneously get our min/max points for the bounds var lineLength = 0f; var halfMaxWidth = _maxWidth * 0.5f; _points.buffer[0].lengthFromPreviousPoint = 0; for (var i = 0; i < _points.length - 1; i++) { var distance = Vector2.Distance(_points.buffer[i].position, _points.buffer[i + 1].position); _points.buffer[i + 1].lengthFromPreviousPoint = distance; lineLength += distance; maxX = Mathf.maxOf(maxX, _points.buffer[i].position.X + halfMaxWidth, _points.buffer[i + 1].position.X + halfMaxWidth); minX = Mathf.minOf(minX, _points.buffer[i].position.X - halfMaxWidth, _points.buffer[i + 1].position.X - halfMaxWidth); maxY = Mathf.maxOf(maxY, _points.buffer[i].position.Y + halfMaxWidth, _points.buffer[i + 1].position.Y + halfMaxWidth); minY = Mathf.minOf(minY, _points.buffer[i].position.Y - halfMaxWidth, _points.buffer[i + 1].position.Y - halfMaxWidth); } _bounds.x = minX; _bounds.y = minY; _bounds.width = maxX - minX; _bounds.height = maxY - minY; // special case: single segment if (_points.length == 2) { if (_useStartEndWidths) { _points.buffer[0].width = _startWidth; _points.buffer[1].width = _endWidth; } if (_useStartEndColors) { _points.buffer[0].color = _startColor; _points.buffer[1].color = _endColor; } _firstSegment.setPoints(ref _points.buffer[0], ref _points.buffer[1]); addSingleSegmentLine(ref _firstSegment, _points.buffer[1].color); return; } var distanceSoFar = 0f; var fusedPoint = Vector2.Zero; var vertIndex = 0; var thirdPoint = new SegmentPoint(); for (var i = 0; i < _points.length - 1; i++) { var firstPoint = _points.buffer[i]; var secondPoint = _points.buffer[i + 1]; var hasThirdPoint = _points.length > i + 2; if (hasThirdPoint) { thirdPoint = _points.buffer[i + 2]; } // we need the distance along the line of both the first and second points. distanceSoFar will always be for the furthest point // which is the previous point before adding the current segment distance. var firstPointDistance = distanceSoFar; distanceSoFar += secondPoint.lengthFromPreviousPoint; var firstPointRatio = firstPointDistance / lineLength; var secondPointRatio = distanceSoFar / lineLength; var thirdPointRatio = 0f; if (hasThirdPoint) { thirdPointRatio = (distanceSoFar + thirdPoint.lengthFromPreviousPoint) / lineLength; } if (_useStartEndColors) { ColorExt.lerp(ref _startColor, ref _endColor, out firstPoint.color, firstPointRatio); ColorExt.lerp(ref _startColor, ref _endColor, out secondPoint.color, secondPointRatio); if (hasThirdPoint) { ColorExt.lerp(ref _startColor, ref _endColor, out thirdPoint.color, thirdPointRatio); } } if (_useStartEndWidths) { firstPoint.width = Mathf.lerp(_startWidth, _endWidth, firstPointRatio); secondPoint.width = Mathf.lerp(_startWidth, _endWidth, secondPointRatio); if (hasThirdPoint) { thirdPoint.width = Mathf.lerp(_startWidth, _endWidth, thirdPointRatio); } } if (i == 0) { _firstSegment.setPoints(ref firstPoint, ref secondPoint); _secondSegment.setPoints(ref secondPoint, ref thirdPoint); } else { Utils.swap(ref _firstSegment, ref _secondSegment); if (hasThirdPoint) { _secondSegment.setPoints(ref secondPoint, ref thirdPoint); } } // dont recalculate the fusedPoint for the last segment since there will be no third point to work with if (hasThirdPoint) { var shouldFuseBottom = Vector2Ext.isTriangleCCW(firstPoint.position, secondPoint.position, thirdPoint.position); _secondSegment.setFusedData(shouldFuseBottom, ref _firstSegment); } // special care needs to be take with the first segment since it has a different vert count if (i == 0) { addFirstSegment(ref _firstSegment, ref _secondSegment, ref vertIndex); } else { addSegment(ref _firstSegment, ref vertIndex); } _lastSegment.cloneFrom(ref _firstSegment); } }