Beispiel #1
0
        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);
                }
            }
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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;
        }