static void InterpolatePoints( ref PointsList.PointsData lineData, Vector2 prevPosition, Vector2 position, Vector2 nextPosition, PointListProperties pointListProperties, int index ) { tmpBackV.x = prevPosition.x - position.x; tmpBackV.y = prevPosition.y - position.y; float backLength = Mathf.Sqrt(tmpBackV.x * tmpBackV.x + tmpBackV.y * tmpBackV.y); tmpBackNormV.x = tmpBackV.x / backLength; tmpBackNormV.y = tmpBackV.y / backLength; tmpForwV.x = nextPosition.x - position.x; tmpForwV.y = nextPosition.y - position.y; float forwLength = Mathf.Sqrt(tmpForwV.x * tmpForwV.x + tmpForwV.y * tmpForwV.y); tmpForwNormV.x = tmpForwV.x / forwLength; tmpForwNormV.y = tmpForwV.y / forwLength; float cos = (tmpBackNormV.x * tmpForwNormV.x + tmpBackNormV.y * tmpForwNormV.y); float angle = Mathf.Acos(cos); // ignore points along straight line if (cos <= -0.9999f) { return; } if (pointListProperties.RoundingDistance > 0.0f) { AddRoundedPoints( ref lineData, tmpBackNormV, position, tmpForwNormV, pointListProperties, angle, Mathf.Min(backLength, forwLength) * 0.49f ); } else { if (angle < pointListProperties.MaxAngle) { lineData.Positions.Add(position + tmpBackNormV * 0.5f); lineData.Positions.Add(position + tmpForwNormV * 0.5f); } else { lineData.Positions.Add(position); } } }
static void AddRoundedPoints( ref PointsList.PointsData lineData, Vector2 backNormV, Vector2 position, Vector2 forwNormV, PointListProperties pointListProperties, float angle, float maxDistance ) { float roundingDistance = Mathf.Min(maxDistance, pointListProperties.RoundingDistance); tmpBackPos.x = position.x + backNormV.x * roundingDistance; tmpBackPos.y = position.y + backNormV.y * roundingDistance; tmpForwPos.x = position.x + forwNormV.x * roundingDistance; tmpForwPos.y = position.y + forwNormV.y * roundingDistance; pointListProperties.CornerRounding.UpdateAdjusted(roundingDistance / 4.0f, 0.0f, (GeoUtils.TwoPI - angle) / Mathf.PI); float interpolator; int resolution = pointListProperties.CornerRounding.AdjustedResolution; float resolutionF = (float)pointListProperties.CornerRounding.AdjustedResolution - 1.0f; if (lineData.Positions.Capacity < lineData.Positions.Count + resolution) { lineData.Positions.Capacity = lineData.Positions.Count + resolution; } for (int i = 0; i < resolution; i++) { interpolator = (float)i / resolutionF; tmpPos.x = Mathf.LerpUnclamped( Mathf.LerpUnclamped(tmpBackPos.x, position.x, interpolator), Mathf.LerpUnclamped(position.x, tmpForwPos.x, interpolator), interpolator ); tmpPos.y = Mathf.LerpUnclamped( Mathf.LerpUnclamped(tmpBackPos.y, position.y, interpolator), Mathf.LerpUnclamped(position.y, tmpForwPos.y, interpolator), interpolator ); lineData.Positions.Add(tmpPos); } }
public static bool SetLineData( PointListProperties pointListProperties, ref PointsList.PointsData lineData ) { if ( pointListProperties.Positions == null || pointListProperties.Positions.Length <= 1 ) { return(false); } bool needsUpdate = lineData.NeedsUpdate || lineData.Positions == null; if (needsUpdate) { SetPositions( pointListProperties, ref lineData ); } int numPositions = lineData.NumPositions; if ( lineData.PositionNormals == null || lineData.PositionNormals.Length != numPositions ) { lineData.PositionTangents = new Vector2[numPositions]; lineData.PositionNormals = new Vector2[numPositions]; lineData.PositionDistances = new float[numPositions]; lineData.NormalizedPositionDistances = new float[numPositions]; for (int i = 0; i < numPositions; i++) { lineData.PositionNormals[i] = UI.GeoUtils.ZeroV2; lineData.PositionTangents[i] = UI.GeoUtils.ZeroV2; } needsUpdate = true; } if (needsUpdate) { int numPositionsMinusOne = numPositions - 1; lineData.TotalLength = 0.0f; float distance; Vector2 lastUnitTangent = UI.GeoUtils.ZeroV2; Vector2 currentUnitTangent = UI.GeoUtils.ZeroV2; // set data for first point if (!lineData.IsClosed) { lineData.PositionTangents[0].x = lineData.Positions[0].x - lineData.Positions[1].x; lineData.PositionTangents[0].y = lineData.Positions[0].y - lineData.Positions[1].y; distance = Mathf.Sqrt( lineData.PositionTangents[0].x * lineData.PositionTangents[0].x + lineData.PositionTangents[0].y * lineData.PositionTangents[0].y ); lineData.PositionDistances[0] = distance; lineData.TotalLength += distance; lineData.PositionNormals[0].x = lineData.PositionTangents[0].y / distance; lineData.PositionNormals[0].y = -lineData.PositionTangents[0].x / distance; lastUnitTangent.x = -lineData.PositionTangents[0].x / distance; lastUnitTangent.y = -lineData.PositionTangents[0].y / distance; lineData.StartCapOffset.x = -lastUnitTangent.x; lineData.StartCapOffset.y = -lastUnitTangent.y; } else { lastUnitTangent.x = lineData.Positions[0].x - lineData.Positions[numPositionsMinusOne].x; lastUnitTangent.y = lineData.Positions[0].y - lineData.Positions[numPositionsMinusOne].y; distance = Mathf.Sqrt( lastUnitTangent.x * lastUnitTangent.x + lastUnitTangent.y * lastUnitTangent.y ); lastUnitTangent.x /= distance; lastUnitTangent.y /= distance; SetPointData( lineData.Positions[0], lineData.Positions[1], ref currentUnitTangent, ref lineData.PositionTangents[0], ref lineData.PositionNormals[0], ref lastUnitTangent, ref lineData.PositionDistances[0] ); lineData.TotalLength += lineData.PositionDistances[0]; } for (int i = 1; i < numPositionsMinusOne; i++) { SetPointData( lineData.Positions[i], lineData.Positions[i + 1], ref currentUnitTangent, ref lineData.PositionTangents[i], ref lineData.PositionNormals[i], ref lastUnitTangent, ref lineData.PositionDistances[i] ); lineData.TotalLength += lineData.PositionDistances[i]; } // set data for last point if (!lineData.IsClosed) { lineData.PositionTangents[numPositionsMinusOne].x = lineData.Positions[numPositionsMinusOne].x - lineData.Positions[numPositionsMinusOne - 1].x; lineData.PositionTangents[numPositionsMinusOne].y = lineData.Positions[numPositionsMinusOne].y - lineData.Positions[numPositionsMinusOne - 1].y; distance = Mathf.Sqrt( lineData.PositionTangents[numPositionsMinusOne].x * lineData.PositionTangents[numPositionsMinusOne].x + lineData.PositionTangents[numPositionsMinusOne].y * lineData.PositionTangents[numPositionsMinusOne].y ); lineData.EndCapOffset.x = lineData.PositionTangents[numPositionsMinusOne].x / distance; lineData.EndCapOffset.y = lineData.PositionTangents[numPositionsMinusOne].y / distance; lineData.PositionNormals[numPositionsMinusOne].x = -lineData.PositionTangents[numPositionsMinusOne].y / distance; lineData.PositionNormals[numPositionsMinusOne].y = lineData.PositionTangents[numPositionsMinusOne].x / distance; } else { SetPointData( lineData.Positions[numPositionsMinusOne], lineData.Positions[0], ref currentUnitTangent, ref lineData.PositionTangents[numPositionsMinusOne], ref lineData.PositionNormals[numPositionsMinusOne], ref lastUnitTangent, ref lineData.PositionDistances[numPositionsMinusOne] ); lineData.TotalLength += lineData.PositionDistances[numPositionsMinusOne]; } if (lineData.GenerateRoundedCaps) { SetRoundedCapPointData( Mathf.Atan2(-lineData.PositionNormals[0].x, -lineData.PositionNormals[0].y), ref lineData.StartCapOffsets, ref lineData.StartCapUVs, lineData.RoundedCapResolution, true ); SetRoundedCapPointData( Mathf.Atan2(lineData.PositionNormals[numPositionsMinusOne].x, lineData.PositionNormals[numPositionsMinusOne].y), ref lineData.EndCapOffsets, ref lineData.EndCapUVs, lineData.RoundedCapResolution, false ); } float accumulatedLength = 0.0f; for (int i = 0; i < lineData.PositionDistances.Length; i++) { lineData.NormalizedPositionDistances[i] = accumulatedLength / lineData.TotalLength; accumulatedLength += lineData.PositionDistances[i]; } } lineData.NeedsUpdate = false; return(true); }
public static void SetPositions( PointListProperties pointListProperties, ref PointsList.PointsData lineData ) { if (lineData.Positions == null) { lineData.Positions = new List <Vector2>(pointListProperties.Positions.Length); } CheckMinPointDistances( ref pointListProperties.Positions, ref tmpCachedPositions, lineData.LineWeight * 0.5f, lineData.IsClosed ); lineData.Positions.Clear(); int inputNumPositions = tmpCachedPositions.Count; if (lineData.Positions.Capacity < inputNumPositions) { lineData.Positions.Capacity = lineData.Positions.Capacity + inputNumPositions + 1; } // add first position if (lineData.IsClosed) { InterpolatePoints( ref lineData, tmpCachedPositions[inputNumPositions - 1], tmpCachedPositions[0], tmpCachedPositions[1], pointListProperties, 0 ); } else { lineData.Positions.Add(tmpCachedPositions[0]); } for (int i = 1; i < inputNumPositions - 1; i++) { InterpolatePoints( ref lineData, tmpCachedPositions[i - 1], tmpCachedPositions[i], tmpCachedPositions[i + 1], pointListProperties, i ); } // add end point if (lineData.IsClosed) { InterpolatePoints( ref lineData, tmpCachedPositions[inputNumPositions - 2], tmpCachedPositions[inputNumPositions - 1], tmpCachedPositions[0], pointListProperties, inputNumPositions - 1 ); } else { lineData.Positions.Add(tmpCachedPositions[inputNumPositions - 1]); } lineData.NumPositions = lineData.Positions.Count; }