Esempio n. 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);
                }
            }
        }
Esempio n. 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);
            }
        }
Esempio n. 3
0
        public static void AddRoundedCap(
            ref VertexHelper vh,
            bool isStart,
            int firstVertIndex,
            Vector2 position,
            Vector2 normal,
            Vector2 capOffset,
            int invertIndices,
            LineProperties lineProperties,
            GeoUtils.OutlineProperties outlineProperties,
            Color32 color,
            Vector2 uv,
            PointsList.PointsData pointsData,
            GeoUtils.EdgeGradientData edgeGradientData,
            Vector2[] capOffsets,
            Vector2[] uvOffsets,
            float uvXMin,
            float uvXLength,
            int currentVertCount
            )
        {
            int baseIndex = currentVertCount;

            float innerOffset     = outlineProperties.GetCenterDistace();
            float capOffsetAmount = (edgeGradientData.ShadowOffset + outlineProperties.HalfLineWeight) * edgeGradientData.InnerScale;

            if (isStart)
            {
                uv.x = uvXMin;
            }
            else
            {
                uv.x = uvXMin + uvXLength;
            }

#if CENTER_ROUNDED_CAPS
            // add center vert
            tmpPos.x = position.x;
            tmpPos.y = position.y;
            uv.y     = 0.5f;

            vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);
#endif

            for (int i = 0; i < capOffsets.Length; i++)
            {
                {
                    tmpPos.x = position.x + normal.x * innerOffset + capOffsets[i].x * capOffsetAmount;
                    tmpPos.y = position.y + normal.y * innerOffset + capOffsets[i].y * capOffsetAmount;
                }

                if (isStart)
                {
                    uv.x = Mathf.LerpUnclamped(uvXMin, 0.0f, uvOffsets[i].x);
                }
                else
                {
                    uv.x = Mathf.LerpUnclamped(uvXMin + uvXLength, 1.0f, uvOffsets[i].x);
                }
                uv.y = uvOffsets[i].y;

                vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

                if (i > 0)
                {
#if CENTER_ROUNDED_CAPS
                    vh.AddTriangle(baseIndex, baseIndex + i - 1, baseIndex + i);
#else
                    vh.AddTriangle(firstVertIndex, baseIndex + i - 1, baseIndex + i);
#endif
                }
            }

            // last fans
            if (isStart)
            {
#if CENTER_ROUNDED_CAPS
                // starting triangle
                vh.AddTriangle(baseIndex + 1, baseIndex, firstVertIndex);

                // end triangles
                vh.AddTriangle(baseIndex, baseIndex + capOffsets.Length - 1, baseIndex + capOffsets.Length);
                vh.AddTriangle(baseIndex, baseIndex + capOffsets.Length, firstVertIndex + 1);
#else
                vh.AddTriangle(baseIndex + capOffsets.Length - 1, firstVertIndex + 1, firstVertIndex);
#endif
            }
            else
            {
#if CENTER_ROUNDED_CAPS
                // starting triangle
                vh.AddTriangle(baseIndex + 1, baseIndex, firstVertIndex + 1);

                // end triangles
                vh.AddTriangle(baseIndex, baseIndex + capOffsets.Length - 1, baseIndex + capOffsets.Length);
                vh.AddTriangle(baseIndex, baseIndex + capOffsets.Length, firstVertIndex);
#else
                vh.AddTriangle(baseIndex, firstVertIndex, firstVertIndex + 1);
#endif
            }

            if (edgeGradientData.IsActive)
            {
                color.a = 0;

                innerOffset = outlineProperties.GetCenterDistace();

                capOffsetAmount = outlineProperties.HalfLineWeight + edgeGradientData.SizeAdd + edgeGradientData.ShadowOffset;

                int antiAliasedIndex = firstVertIndex + pointsData.NumPositions * 2;

                for (int i = 0; i < capOffsets.Length; i++)
                {
                    {
                        tmpPos.x = position.x + normal.x * innerOffset + capOffsets[i].x * capOffsetAmount;
                        tmpPos.y = position.y + normal.y * innerOffset + capOffsets[i].y * capOffsetAmount;
                    }

                    if (isStart)
                    {
                        uv.x = Mathf.LerpUnclamped(uvXMin, 0.0f, uvOffsets[i].x);
                    }
                    else
                    {
                        uv.x = Mathf.LerpUnclamped(uvXMin + uvXLength, 1.0f, uvOffsets[i].x);
                    }
                    uv.y = uvOffsets[i].y;

                    vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

                    if (i > 0)
                    {
                        vh.AddTriangle(baseIndex + i - 1, baseIndex + capOffsets.Length + i - 1, baseIndex + i);
                        vh.AddTriangle(baseIndex + capOffsets.Length + i, baseIndex + i, baseIndex + capOffsets.Length + i - 1);
                    }
                }

                if (!isStart)
                {
                    vh.AddTriangle(baseIndex, firstVertIndex + 1, antiAliasedIndex + 1);
                    vh.AddTriangle(antiAliasedIndex + 1, baseIndex + capOffsets.Length, baseIndex);

                    vh.AddTriangle(baseIndex + capOffsets.Length * 2 - 1, antiAliasedIndex, firstVertIndex);
                    vh.AddTriangle(baseIndex + capOffsets.Length - 1, baseIndex + capOffsets.Length * 2 - 1, firstVertIndex);
                }
                else
                {
                    vh.AddTriangle(firstVertIndex + 1, baseIndex + capOffsets.Length - 1, baseIndex + capOffsets.Length * 2 - 1);
                    vh.AddTriangle(antiAliasedIndex + 1, firstVertIndex + 1, baseIndex + capOffsets.Length * 2 - 1);

                    vh.AddTriangle(antiAliasedIndex, baseIndex, firstVertIndex);
                    vh.AddTriangle(baseIndex + capOffsets.Length, baseIndex, antiAliasedIndex);
                }
            }
        }
Esempio n. 4
0
        public static void AddProjectedCap(
            ref VertexHelper vh,
            bool isStart,
            int firstVertIndex,
            Vector2 position,
            Vector2 normal,
            Vector2 capOffset,
            int invertIndices,
            LineProperties lineProperties,
            GeoUtils.OutlineProperties outlineProperties,
            Color32 color,
            Vector2 uv,
            PointsList.PointsData pointsData,
            GeoUtils.EdgeGradientData edgeGradientData,
            int currentVertCount
            )
        {
            int baseIndex = currentVertCount;

            if (isStart)
            {
                uv.x = 0.0f;
            }
            else
            {
                uv.x = 1.0f;
            }

            float innerOffset = outlineProperties.GetCenterDistace() - (outlineProperties.HalfLineWeight + edgeGradientData.ShadowOffset) * edgeGradientData.InnerScale;
            float outerOffset = outlineProperties.GetCenterDistace() + (outlineProperties.HalfLineWeight + edgeGradientData.ShadowOffset) * edgeGradientData.InnerScale;

            float capOffsetAmount = edgeGradientData.ShadowOffset + outlineProperties.LineWeight * 0.5f;

            capOffsetAmount *= edgeGradientData.InnerScale;

            // add lineWeight to position
            {
                tmpPos.x = position.x + normal.x * innerOffset + capOffset.x * capOffsetAmount;
                tmpPos.y = position.y + normal.y * innerOffset + capOffset.y * capOffsetAmount;
            }

            uv.y = 0.0f;
            vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

            {
                tmpPos.x = position.x + normal.x * outerOffset + capOffset.x * capOffsetAmount;
                tmpPos.y = position.y + normal.y * outerOffset + capOffset.y * capOffsetAmount;
            }

            uv.y = 1.0f;
            vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

            vh.AddTriangle(firstVertIndex, baseIndex + invertIndices, baseIndex + 1 - invertIndices);
            vh.AddTriangle(firstVertIndex + invertIndices, baseIndex + 1, firstVertIndex + 1 - invertIndices);

            if (edgeGradientData.IsActive)
            {
                innerOffset = outlineProperties.GetCenterDistace() - (outlineProperties.HalfLineWeight + edgeGradientData.ShadowOffset) - edgeGradientData.SizeAdd;
                outerOffset = outlineProperties.GetCenterDistace() + (outlineProperties.HalfLineWeight + edgeGradientData.ShadowOffset) + edgeGradientData.SizeAdd;

                capOffsetAmount = outlineProperties.HalfLineWeight + edgeGradientData.SizeAdd + edgeGradientData.ShadowOffset;

                color.a = 0;

                {
                    tmpPos.x = position.x + normal.x * innerOffset + capOffset.x * capOffsetAmount;
                    tmpPos.y = position.y + normal.y * innerOffset + capOffset.y * capOffsetAmount;
                }

                uv.y = 0.0f;
                vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);


                {
                    tmpPos.x = position.x + normal.x * outerOffset + capOffset.x * capOffsetAmount;
                    tmpPos.y = position.y + normal.y * outerOffset + capOffset.y * capOffsetAmount;
                }

                uv.y = 1.0f;
                vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

                int antiAliasedIndex = firstVertIndex + pointsData.NumPositions * 2;
                baseIndex += 2;

                if (invertIndices != 0)
                {
                    vh.AddTriangle(firstVertIndex, baseIndex, antiAliasedIndex);
                    vh.AddTriangle(firstVertIndex + 1, antiAliasedIndex + 1, baseIndex + 1);

                    vh.AddTriangle(baseIndex - 2, baseIndex - 1, baseIndex);
                    vh.AddTriangle(baseIndex + 1, baseIndex, baseIndex - 1);

                    vh.AddTriangle(firstVertIndex, baseIndex - 2, baseIndex);
                    vh.AddTriangle(firstVertIndex + 1, baseIndex + 1, baseIndex - 1);
                }
                else
                {
                    vh.AddTriangle(firstVertIndex, antiAliasedIndex, baseIndex);
                    vh.AddTriangle(firstVertIndex + 1, baseIndex + 1, antiAliasedIndex + 1);

                    vh.AddTriangle(baseIndex - 2, baseIndex, baseIndex - 1);
                    vh.AddTriangle(baseIndex + 1, baseIndex - 1, baseIndex);

                    vh.AddTriangle(firstVertIndex, baseIndex, baseIndex - 2);
                    vh.AddTriangle(firstVertIndex + 1, baseIndex - 1, baseIndex + 1);
                }
            }
        }
Esempio n. 5
0
        public static void AddEndCap(
            ref VertexHelper vh,
            LineProperties lineProperties,
            Vector2 positionOffset,
            GeoUtils.OutlineProperties outlineProperties,
            Color32 color,
            Vector2 uv,
            float uvXMin,
            float uvXLength,
            PointsList.PointsData pointsData,
            GeoUtils.EdgeGradientData edgeGradientData
            )
        {
            int currentVertCount = vh.currentVertCount;
            int startIndex       = currentVertCount;

            if (edgeGradientData.IsActive)
            {
                startIndex -= pointsData.NumPositions * 2;
            }

            int lastPositionIndex = pointsData.NumPositions - 1;

            tmpPos2.x = positionOffset.x + pointsData.Positions[lastPositionIndex].x;
            tmpPos2.y = positionOffset.y + pointsData.Positions[lastPositionIndex].y;

            switch (lineProperties.LineCap)
            {
            case LineProperties.LineCapTypes.Close:

                startIndex -= 4;

                AddCloseCap(
                    ref vh,
                    false,
                    startIndex,
                    tmpPos2,
                    pointsData.PositionNormals[lastPositionIndex],
                    pointsData.EndCapOffset,
                    1,
                    lineProperties,
                    outlineProperties,
                    color,
                    uv,
                    pointsData,
                    edgeGradientData,
                    currentVertCount
                    );

                break;

            case LineProperties.LineCapTypes.Projected:

                startIndex -= 6;

                AddProjectedCap(
                    ref vh,
                    false,
                    startIndex,
                    tmpPos2,
                    pointsData.PositionNormals[lastPositionIndex],
                    pointsData.EndCapOffset,
                    1,
                    lineProperties,
                    outlineProperties,
                    color,
                    uv,
                    pointsData,
                    edgeGradientData,
                    currentVertCount
                    );

                break;

            case LineProperties.LineCapTypes.Round:
#if CENTER_ROUNDED_CAPS
                startIndex -= pointsData.RoundedCapResolution + 3;
#else
                startIndex -= pointsData.RoundedCapResolution + 2;
#endif

                if (edgeGradientData.IsActive)
                {
                    startIndex -= pointsData.RoundedCapResolution;
                }

                AddRoundedCap(
                    ref vh,
                    false,
                    startIndex,
                    tmpPos2,
                    pointsData.PositionNormals[lastPositionIndex],
                    pointsData.EndCapOffset,
                    1,
                    lineProperties,
                    outlineProperties,
                    color,
                    uv,
                    pointsData,
                    edgeGradientData,
                    pointsData.EndCapOffsets,
                    pointsData.EndCapUVs,
                    uvXMin,
                    uvXLength,
                    currentVertCount
                    );

                break;
            }
        }
Esempio n. 6
0
        public static void AddLine(
            ref VertexHelper vh,
            LineProperties lineProperties,
            PointsList.PointListProperties pointListProperties,
            Vector2 positionOffset,
            GeoUtils.OutlineProperties outlineProperties,
            Color32 color,
            Vector2 uv,
            ref PointsList.PointsData pointsData,
            GeoUtils.EdgeGradientData edgeGradientData
            )
        {
            pointListProperties.SetPoints();
            pointsData.IsClosed = lineProperties.Closed && pointListProperties.Positions.Length > 2;

            pointsData.GenerateRoundedCaps = lineProperties.LineCap == LineProperties.LineCapTypes.Round;

            pointsData.LineWeight = outlineProperties.LineWeight;

            if (pointsData.GenerateRoundedCaps)
            {
                lineProperties.RoundedCapResolution.UpdateAdjusted(outlineProperties.HalfLineWeight, 0.0f, 2.0f);
                pointsData.RoundedCapResolution = lineProperties.RoundedCapResolution.AdjustedResolution;
            }

            if (!PointsList.SetLineData(pointListProperties, ref pointsData))
            {
                return;
            }


            // scale uv x for caps
            float uvXMin    = 0.0f;
            float uvXLength = 1.0f;

            if (
                !lineProperties.Closed &&
                lineProperties.LineCap != LineProperties.LineCapTypes.Close
                )
            {
                float uvStartOffset = outlineProperties.LineWeight / pointsData.TotalLength;

                uvXMin    = uvStartOffset * 0.5f;
                uvXLength = 1.0f - uvXMin * 2.0f;
            }

            float innerOffset = outlineProperties.GetCenterDistace() - (outlineProperties.HalfLineWeight + edgeGradientData.ShadowOffset) * edgeGradientData.InnerScale;
            float outerOffset = outlineProperties.GetCenterDistace() + (outlineProperties.HalfLineWeight + edgeGradientData.ShadowOffset) * edgeGradientData.InnerScale;

            float capOffsetAmount = 0.0f;

            if (!lineProperties.Closed && lineProperties.LineCap == LineProperties.LineCapTypes.Close)
            {
                capOffsetAmount = edgeGradientData.ShadowOffset * (edgeGradientData.InnerScale * 2.0f - 1.0f);
            }


            int numVertices = vh.currentVertCount;
            int startVertex = numVertices - 1;
            int baseIndex;

            uv.x = uvXMin + pointsData.NormalizedPositionDistances[0] * uvXLength;
            uv.y = 0.0f;

            {
                tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * innerOffset + pointsData.StartCapOffset.x * capOffsetAmount;
                tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * innerOffset + pointsData.StartCapOffset.y * capOffsetAmount;
            }

            vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

            uv.y = 1.0f;

            {
                tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * outerOffset + pointsData.StartCapOffset.x * capOffsetAmount;
                tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * outerOffset + pointsData.StartCapOffset.y * capOffsetAmount;
            }

            vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

            for (int i = 1; i < pointsData.NumPositions - 1; i++)
            {
                uv.x = uvXMin + pointsData.NormalizedPositionDistances[i] * uvXLength;
                uv.y = 0.0f;

                {
                    tmpPos.x = positionOffset.x + pointsData.Positions[i].x + pointsData.PositionNormals[i].x * innerOffset;
                    tmpPos.y = positionOffset.y + pointsData.Positions[i].y + pointsData.PositionNormals[i].y * innerOffset;
                }

                vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

                uv.y = 1.0f;

                {
                    tmpPos.x = positionOffset.x + pointsData.Positions[i].x + pointsData.PositionNormals[i].x * outerOffset;
                    tmpPos.y = positionOffset.y + pointsData.Positions[i].y + pointsData.PositionNormals[i].y * outerOffset;
                }

                vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

                baseIndex = startVertex + i * 2;
                vh.AddTriangle(baseIndex - 1, baseIndex, baseIndex + 1);
                vh.AddTriangle(baseIndex, baseIndex + 2, baseIndex + 1);
            }

            // add end vertices
            int endIndex = pointsData.NumPositions - 1;

            uv.x = uvXMin + pointsData.NormalizedPositionDistances[endIndex] * uvXLength;
            uv.y = 0.0f;

            {
                tmpPos.x = positionOffset.x + pointsData.Positions[endIndex].x + pointsData.PositionNormals[endIndex].x * innerOffset + pointsData.EndCapOffset.x * capOffsetAmount;
                tmpPos.y = positionOffset.y + pointsData.Positions[endIndex].y + pointsData.PositionNormals[endIndex].y * innerOffset + pointsData.EndCapOffset.y * capOffsetAmount;
            }

            vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

            uv.y = 1.0f;

            {
                tmpPos.x = positionOffset.x + pointsData.Positions[endIndex].x + pointsData.PositionNormals[endIndex].x * outerOffset + pointsData.EndCapOffset.x * capOffsetAmount;
                tmpPos.y = positionOffset.y + pointsData.Positions[endIndex].y + pointsData.PositionNormals[endIndex].y * outerOffset + pointsData.EndCapOffset.y * capOffsetAmount;
            }

            vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

            baseIndex = startVertex + endIndex * 2;
            vh.AddTriangle(baseIndex - 1, baseIndex, baseIndex + 1);
            vh.AddTriangle(baseIndex, baseIndex + 2, baseIndex + 1);

            if (lineProperties.Closed)
            {
                uv.x = 1.0f;
                uv.y = 0.0f;

                {
                    tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * innerOffset + pointsData.StartCapOffset.x * capOffsetAmount;
                    tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * innerOffset + pointsData.StartCapOffset.y * capOffsetAmount;
                }

                vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

                uv.y = 1.0f;

                {
                    tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * outerOffset + pointsData.StartCapOffset.x * capOffsetAmount;
                    tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * outerOffset + pointsData.StartCapOffset.y * capOffsetAmount;
                }

                vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

                baseIndex = startVertex + endIndex * 2 + 2;
                vh.AddTriangle(baseIndex - 1, baseIndex, baseIndex + 1);
                vh.AddTriangle(baseIndex, baseIndex + 2, baseIndex + 1);
            }

            if (edgeGradientData.IsActive)
            {
                byte colorAlpha = color.a;

                innerOffset = outlineProperties.GetCenterDistace() - (outlineProperties.HalfLineWeight + edgeGradientData.ShadowOffset);
                outerOffset = outlineProperties.GetCenterDistace() + (outlineProperties.HalfLineWeight + edgeGradientData.ShadowOffset);

                innerOffset -= edgeGradientData.SizeAdd;
                outerOffset += edgeGradientData.SizeAdd;

                color.a = 0;

                int outerBaseIndex = numVertices + pointsData.NumPositions * 2;

                if (lineProperties.Closed)
                {
                    outerBaseIndex += 2;
                }

                uv.x = uvXMin + pointsData.NormalizedPositionDistances[0] * uvXLength;
                uv.y = 0.0f;

                {
                    tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * innerOffset;
                    tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * innerOffset;
                }

                vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

                uv.y = 1.0f;

                {
                    tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * outerOffset;
                    tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * outerOffset;
                }

                vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

                for (int i = 1; i < pointsData.NumPositions; i++)
                {
                    uv.x = uvXMin + pointsData.NormalizedPositionDistances[i] * uvXLength;
                    uv.y = 0.0f;

                    {
                        tmpPos.x = positionOffset.x + pointsData.Positions[i].x + pointsData.PositionNormals[i].x * innerOffset;
                        tmpPos.y = positionOffset.y + pointsData.Positions[i].y + pointsData.PositionNormals[i].y * innerOffset;
                    }

                    vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

                    uv.y = 1.0f;

                    {
                        tmpPos.x = positionOffset.x + pointsData.Positions[i].x + pointsData.PositionNormals[i].x * outerOffset;
                        tmpPos.y = positionOffset.y + pointsData.Positions[i].y + pointsData.PositionNormals[i].y * outerOffset;
                    }

                    vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

                    // inner quad
                    vh.AddTriangle(startVertex + i * 2 - 1, startVertex + i * 2 + 1, outerBaseIndex + i * 2);
                    vh.AddTriangle(startVertex + i * 2 - 1, outerBaseIndex + i * 2, outerBaseIndex + i * 2 - 2);

                    // outer quad
                    vh.AddTriangle(startVertex + i * 2, outerBaseIndex + i * 2 - 1, startVertex + i * 2 + 2);
                    vh.AddTriangle(startVertex + i * 2 + 2, outerBaseIndex + i * 2 - 1, outerBaseIndex + i * 2 + 1);
                }

                if (lineProperties.Closed)
                {
                    int lastIndex = pointsData.NumPositions;

                    uv.x = 1.0f;
                    uv.y = 0.0f;

                    {
                        tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * innerOffset;
                        tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * innerOffset;
                    }

                    vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

                    uv.y = 1.0f;

                    {
                        tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * outerOffset;
                        tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * outerOffset;
                    }

                    vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

                    // inner quad
                    vh.AddTriangle(startVertex + lastIndex * 2 - 1, startVertex + lastIndex * 2 + 1, outerBaseIndex + lastIndex * 2);
                    vh.AddTriangle(startVertex + lastIndex * 2 - 1, outerBaseIndex + lastIndex * 2, outerBaseIndex + lastIndex * 2 - 2);

                    // outer quad
                    vh.AddTriangle(startVertex + lastIndex * 2, outerBaseIndex + lastIndex * 2 - 1, startVertex + lastIndex * 2 + 2);
                    vh.AddTriangle(startVertex + lastIndex * 2 + 2, outerBaseIndex + lastIndex * 2 - 1, outerBaseIndex + lastIndex * 2 + 1);
                }

                color.a = colorAlpha;
            }

            // close line or add caps
            if (!lineProperties.Closed)
            {
                AddStartCap(
                    ref vh,
                    lineProperties,
                    positionOffset,
                    outlineProperties,
                    color,
                    uv,
                    uvXMin,
                    uvXLength,
                    pointsData,
                    edgeGradientData
                    );

                AddEndCap(
                    ref vh,
                    lineProperties,
                    positionOffset,
                    outlineProperties,
                    color,
                    uv,
                    uvXMin,
                    uvXLength,
                    pointsData,
                    edgeGradientData
                    );
            }
        }
Esempio n. 7
0
        public static void AddStartCap(
            ref VertexHelper vh,
            LineProperties lineProperties,
            Vector2 positionOffset,
            GeoUtils.OutlineProperties outlineProperties,
            Color32 color,
            Vector2 uv,
            float uvXMin,
            float uvXLength,
            PointsList.PointsData pointsData,
            GeoUtils.EdgeGradientData edgeGradientData
            )
        {
            int currentVertCount = vh.currentVertCount;
            int startIndex       = currentVertCount - pointsData.NumPositions * 2;

            if (edgeGradientData.IsActive)
            {
                startIndex -= pointsData.NumPositions * 2;
            }

            tmpPos2.x = positionOffset.x + pointsData.Positions[0].x;
            tmpPos2.y = positionOffset.y + pointsData.Positions[0].y;

            switch (lineProperties.LineCap)
            {
            case LineProperties.LineCapTypes.Close:
                AddCloseCap(
                    ref vh,
                    true,
                    startIndex,
                    tmpPos2,
                    pointsData.PositionNormals[0],
                    pointsData.StartCapOffset,
                    0,
                    lineProperties,
                    outlineProperties,
                    color,
                    uv,
                    pointsData,
                    edgeGradientData,
                    currentVertCount
                    );

                break;

            case LineProperties.LineCapTypes.Projected:
                AddProjectedCap(
                    ref vh,
                    true,
                    startIndex,
                    tmpPos2,
                    pointsData.PositionNormals[0],
                    pointsData.StartCapOffset,
                    0,
                    lineProperties,
                    outlineProperties,
                    color,
                    uv,
                    pointsData,
                    edgeGradientData,
                    currentVertCount
                    );

                break;

            case LineProperties.LineCapTypes.Round:
                AddRoundedCap(
                    ref vh,
                    true,
                    startIndex,
                    tmpPos2,
                    pointsData.PositionNormals[0],
                    pointsData.StartCapOffset,
                    0,
                    lineProperties,
                    outlineProperties,
                    color,
                    uv,
                    pointsData,
                    edgeGradientData,
                    pointsData.StartCapOffsets,
                    pointsData.StartCapUVs,
                    uvXMin,
                    uvXLength,
                    currentVertCount
                    );
                break;
            }
        }
Esempio n. 8
0
        public static void AddPolygon(
            ref VertexHelper vh,
            PolygonProperties polygonProperties,
            PointsList.PointListProperties pointListProperties,
            Vector2 positionOffset,
            Color32 color,
            Vector2 uv,
            ref PointsList.PointsData pointsData,
            GeoUtils.EdgeGradientData edgeGradientData
            )
        {
            pointListProperties.SetPoints();
            PointsList.SetLineData(pointListProperties, ref pointsData);

            int numVertices      = vh.currentVertCount;
            int firstOuterVertex = vh.currentVertCount + polygonProperties.CutoutProperties.Resolution - 1;

            bool usesCutout = polygonProperties.CenterType == PolygonProperties.CenterTypes.Cutout;

            if (usesCutout)
            {
                float cutoutOffsetDistance = polygonProperties.CutoutProperties.Radius - edgeGradientData.ShadowOffset;
                cutoutOffsetDistance += Mathf.LerpUnclamped(
                    pointsData.PositionNormals[0].magnitude * edgeGradientData.ShadowOffset * 3.0f,
                    0.0f,
                    edgeGradientData.InnerScale
                    );

                for (int i = 0; i < polygonProperties.CutoutProperties.Resolution; i++)
                {
                    tmpPos.x =
                        polygonProperties.AdjustedCenter.x +
                        positionOffset.x +
                        polygonProperties.CutoutProperties.UnitPositionData.UnitPositions[i].x * cutoutOffsetDistance;
                    tmpPos.y =
                        polygonProperties.AdjustedCenter.y +
                        positionOffset.y +
                        polygonProperties.CutoutProperties.UnitPositionData.UnitPositions[i].y * cutoutOffsetDistance;
                    tmpPos.z = 0.0f;

                    vh.AddVert(
                        tmpPos,
                        color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent
                        );
                }
            }
            else
            {
                // add center
                tmpPos.x = polygonProperties.AdjustedCenter.x + positionOffset.x;
                tmpPos.y = polygonProperties.AdjustedCenter.y + positionOffset.y;
                tmpPos.z = 0.0f;

                vh.AddVert(
                    tmpPos,
                    color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent
                    );
            }

            // add first position
            tmpPos.x = positionOffset.x + Mathf.LerpUnclamped(
                polygonProperties.AdjustedCenter.x,
                pointsData.Positions[0].x + pointsData.PositionNormals[0].x * edgeGradientData.ShadowOffset,
                edgeGradientData.InnerScale
                );
            tmpPos.y = positionOffset.y + Mathf.LerpUnclamped(
                polygonProperties.AdjustedCenter.y,
                pointsData.Positions[0].y + pointsData.PositionNormals[0].y * edgeGradientData.ShadowOffset,
                edgeGradientData.InnerScale
                );
            tmpPos.z = 0.0f;

            vh.AddVert(
                tmpPos,
                color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent
                );

            for (int i = 1; i < pointsData.NumPositions; i++)
            {
                tmpPos.x = positionOffset.x + Mathf.LerpUnclamped(
                    polygonProperties.AdjustedCenter.x,
                    pointsData.Positions[i].x + pointsData.PositionNormals[i].x * edgeGradientData.ShadowOffset,
                    edgeGradientData.InnerScale
                    );
                tmpPos.y = positionOffset.y + Mathf.LerpUnclamped(
                    polygonProperties.AdjustedCenter.y,
                    pointsData.Positions[i].y + pointsData.PositionNormals[i].y * edgeGradientData.ShadowOffset,
                    edgeGradientData.InnerScale
                    );

                vh.AddVert(
                    tmpPos,
                    color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent
                    );

                if (!usesCutout)
                {
                    vh.AddTriangle(numVertices, numVertices + i, numVertices + i + 1);
                }
            }

            // add cutout indices
            if (usesCutout)
            {
                for (int i = 1; i < pointsData.NumPositions; i++)
                {
                    vh.AddTriangle(
                        numVertices + GeoUtils.SimpleMap(i, pointsData.NumPositions, polygonProperties.CutoutProperties.Resolution),
                        firstOuterVertex + i,
                        firstOuterVertex + i + 1
                        );
                }

                for (int i = 1; i < polygonProperties.CutoutProperties.Resolution; i++)
                {
                    vh.AddTriangle(
                        numVertices + i,
                        numVertices + i - 1,
                        firstOuterVertex + Mathf.CeilToInt(GeoUtils.SimpleMap((float)i, (float)polygonProperties.CutoutProperties.Resolution, (float)pointsData.NumPositions))
                        );
                }
            }

            // add last triangle
            if (usesCutout)
            {
                vh.AddTriangle(
                    numVertices,
                    firstOuterVertex + pointsData.NumPositions,
                    firstOuterVertex + 1
                    );

                vh.AddTriangle(
                    numVertices,
                    firstOuterVertex,
                    firstOuterVertex + pointsData.NumPositions
                    );
            }
            else
            {
                vh.AddTriangle(numVertices, numVertices + pointsData.NumPositions, numVertices + 1);
            }

            if (edgeGradientData.IsActive)
            {
                color.a = 0;

                int outerFirstIndex = numVertices + pointsData.NumPositions;

                if (usesCutout)
                {
                    outerFirstIndex = firstOuterVertex + pointsData.NumPositions;
                }
                else
                {
                    firstOuterVertex = numVertices;
                }

                float offset = edgeGradientData.SizeAdd + edgeGradientData.ShadowOffset;

                vh.AddVert(positionOffset + pointsData.Positions[0] + pointsData.PositionNormals[0] * offset,
                           color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

                for (int i = 1; i < pointsData.NumPositions; i++)
                {
                    vh.AddVert(positionOffset + pointsData.Positions[i] + pointsData.PositionNormals[i] * offset,
                               color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent);

                    vh.AddTriangle(firstOuterVertex + i + 1, outerFirstIndex + i, outerFirstIndex + i + 1);
                    vh.AddTriangle(firstOuterVertex + i + 1, outerFirstIndex + i + 1, firstOuterVertex + i + 2);
                }

                // fill last outer quad
                vh.AddTriangle(firstOuterVertex + 1, outerFirstIndex, outerFirstIndex + 1);
                vh.AddTriangle(firstOuterVertex + 2, firstOuterVertex + 1, outerFirstIndex + 1);


                if (usesCutout)
                {
                    float radius = (polygonProperties.CutoutProperties.Radius - offset);
                    for (int i = 0; i < polygonProperties.CutoutProperties.Resolution; i++)
                    {
                        tmpPos.x =
                            polygonProperties.AdjustedCenter.x +
                            positionOffset.x +
                            polygonProperties.CutoutProperties.UnitPositionData.UnitPositions[i].x * radius;
                        tmpPos.y =
                            polygonProperties.AdjustedCenter.y +
                            positionOffset.y +
                            polygonProperties.CutoutProperties.UnitPositionData.UnitPositions[i].y * radius;
                        tmpPos.z = 0.0f;

                        vh.AddVert(
                            tmpPos,
                            color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent
                            );
                    }

                    for (int i = 1; i < polygonProperties.CutoutProperties.Resolution; i++)
                    {
                        vh.AddTriangle(
                            numVertices + i - 1,
                            numVertices + i,
                            outerFirstIndex + pointsData.NumPositions + i
                            );

                        vh.AddTriangle(
                            numVertices + i,
                            outerFirstIndex + pointsData.NumPositions + i + 1,
                            outerFirstIndex + pointsData.NumPositions + i
                            );
                    }

                    vh.AddTriangle(
                        firstOuterVertex,
                        numVertices,
                        outerFirstIndex + pointsData.NumPositions + polygonProperties.CutoutProperties.Resolution
                        );

                    vh.AddTriangle(
                        numVertices,
                        outerFirstIndex + pointsData.NumPositions + 1,
                        outerFirstIndex + pointsData.NumPositions + polygonProperties.CutoutProperties.Resolution
                        );
                }
            }
        }
Esempio n. 9
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]  = GeoUtils.ZeroV2;
                    lineData.PositionTangents[i] = GeoUtils.ZeroV2;
                }

                needsUpdate = true;
            }

            if (needsUpdate)
            {
                int numPositionsMinusOne = numPositions - 1;

                lineData.TotalLength = 0.0f;

                float   distance;
                Vector2 lastUnitTangent    = GeoUtils.ZeroV2;
                Vector2 currentUnitTangent = 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);
        }
Esempio n. 10
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;
        }