Пример #1
0
        /// <summary>
        /// Average extruded points of a segment to an intersection point based on fraction of how far along the segment the intersection happened.
        /// Averages UVs directly.
        /// </summary>
        /// <param name="first">First point</param>
        /// <param name="second">Second point</param>
        /// <param name="fractionOfSecond">From of the section point to be used in the average</param>
        /// <param name="otherOriginalLineIndex1">Additional original line index to be referred to by the intersection point.</param>
        /// <param name="otherOriginalLineIndex2">Additional original line index to be referred to by the intersection point.</param>
        private static IntersectionPoint AverageExtrudedPointsToIntersection(ExtrudedPointUV first, ExtrudedPointUV second, float fractionOfSecond, int otherOriginalLineIndex1, int otherOriginalLineIndex2)
        {
            var averagedLinePoint         = new LinePointUV(first).AverageWith(new LinePointUV(second), fractionOfSecond);
            var extrudedPoint             = new ExtrudedPointUV(averagedLinePoint, first.LinePointSegmentIndex, second.LinePointSegmentIndex2);
            var extrudedPointOtherIndices = extrudedPoint;

            extrudedPointOtherIndices.LinePointSegmentIndex  = otherOriginalLineIndex1;
            extrudedPointOtherIndices.LinePointSegmentIndex2 = otherOriginalLineIndex2;
            return(new IntersectionPoint(extrudedPoint, extrudedPoint, extrudedPointOtherIndices));
        }
        /// <summary>
        /// Gets the extruded subspace of points with v parameter set appropriately to direction of hte line compared to extrusion.
        /// </summary>
        /// <param name="originalLineSegments">List of line points with segments connecting to the next point in the line.</param>
        /// <param name="lastLinePoint">The final line point.</param>
        /// <param name="extrusionAmount">The extrusion amount.</param>
        /// <param name="parameterShift">The amount to shift the original line point parameters by when constructing the extruded points.</param>
        /// <param name="isReversed">Whether line point indices associated with extruded points should be reversed.</param>
        private static List <ExtrudedPointUV> GetExtrudedSubspaceAndUvFromSegmentIntersections(List <LinePointUVAndSegment> originalLineSegments, LinePointUV lastLinePoint, float extrusionAmount, float parameterShift, bool isReversed)
        {
            var   extrudedSubspace = GetExtrudedSubspace_Points_SegmentIntersections(originalLineSegments, lastLinePoint, extrusionAmount, parameterShift, isReversed, includeLast: true);
            float uv_vparameter    = isReversed ? 0f : 1f;

            for (int i = 0; i < extrudedSubspace.Count; i++)
            {
                ExtrudedPointUV extrudedPointUV = extrudedSubspace[i];
                extrudedPointUV.UV  = new Vector2(extrudedSubspace[i].UV.x, uv_vparameter);
                extrudedSubspace[i] = extrudedPointUV;
            }
            return(extrudedSubspace);
        }
        /// <summary>
        /// Gets the smallest difference between parameter value of the given extruded point and the parameters of intersection points.
        /// </summary>
        /// <param name="point">The extruded point</param>
        /// <param name="intersectionPoints">The intersection points</param>
        private static float SmallestParameterDifference(ExtrudedPointUV point, IList <IntersectionPoint> intersectionPoints)
        {
            float minDist   = float.PositiveInfinity;
            var   parameter = point.Parameter;

            for (int i = 0; i < intersectionPoints.Count; i++)
            {
                var intersectionParameter = intersectionPoints[i].Parameter;
                var dist = Mathf.Abs(parameter - intersectionParameter);
                if (dist < minDist)
                {
                    minDist = dist;
                }
            }
            return(minDist);
        }
        /// <summary>
        /// Returns the extruded point which has the largest distance parameter-wise to the parameters of a set of intersection points.
        /// </summary>
        /// <param name="extrudedPoints">Extruded points</param>
        /// <param name="intersectionPoints">Intersection points</param>
        private static ExtrudedPointUV PointOfLargestParameterDifference(IList <ExtrudedPointUV> extrudedPoints, IList <IntersectionPoint> intersectionPoints)
        {
            float           maxDist = float.NegativeInfinity;
            ExtrudedPointUV point   = new ExtrudedPointUV();

            for (int i = 0; i < extrudedPoints.Count; i++)
            {
                var currentChunkPoint = extrudedPoints[i];
                var dist = SmallestParameterDifference(currentChunkPoint, intersectionPoints);
                if (dist > maxDist)
                {
                    maxDist = dist;
                    point   = currentChunkPoint;
                }
            }
            return(point);
        }
        /// <summary>
        /// Atempt to add naively-extruded points when the extrusion from two neighbouring segments would intersect outside of those extruded segments.
        /// </summary>
        /// <param name="linePointAndForwardSegment">First segment.</param>
        /// <param name="previousLinePointAndForwardSegment">Previous segment.</param>
        /// <param name="lineSegmentIndexToAssign">Line segment index to assign the extruded point coming from.</param>
        /// <param name="extrusionAmount">The extrusion amount.</param>
        /// <param name="extrudedLinePoints">The list of all extruded line points.</param>
        /// <param name="findParameter">Delegate for determining altered point parameter.</param>
        /// <param name="extrusionIntersectionDistanceAlongTangents">The extrusion intersection distance along segment tangent directions.</param>
        private static void AttemptAddNaiveExtrudedPointsWhenTheirExtrudedSegmentsDoNotIntersect(LinePointUVAndSegment linePointAndForwardSegment, LinePointUVAndSegment previousLinePointAndForwardSegment, int lineSegmentIndexToAssign, float extrusionAmount, List <ExtrudedPointUV> extrudedLinePoints, GetShiftedScaledParameter findParameter, float extrusionIntersectionDistanceAlongTangents)
        {
            bool intersectionOccursOutOfBothSegments = extrusionIntersectionDistanceAlongTangents >= Mathf.Max(previousLinePointAndForwardSegment.SegmentLength, linePointAndForwardSegment.SegmentLength);

            if (intersectionOccursOutOfBothSegments)
            {
                //Nothing to do here, since any additional points will not contribute to any chunks that are not too close to the original line.
            }
            else
            {
                var extrudedFromCenterPointPreviousSegmentNormal = new ExtrudedPointUV(linePointAndForwardSegment.LinePoint, findParameter(linePointAndForwardSegment.Parameter), previousLinePointAndForwardSegment.SegmentNormal, extrusionAmount, lineSegmentIndexToAssign - 1);//Previous segment's index
                extrudedLinePoints.Add(extrudedFromCenterPointPreviousSegmentNormal);

                var extrudedFromCenterPointCurrentSegmentNormal = new ExtrudedPointUV(linePointAndForwardSegment.LinePoint, findParameter(linePointAndForwardSegment.Parameter), linePointAndForwardSegment.SegmentNormal, extrusionAmount, lineSegmentIndexToAssign);//Current segment's index
                extrudedLinePoints.Add(extrudedFromCenterPointCurrentSegmentNormal);
                //NB Here we are just adding the 'naive' points without computing the intersection, and relying on the overall intersection algorithm to take care of the rest.
            }
        }
        /// <summary>
        /// Gets the points corresponding to the extruded subspace due to extruded segment-by-segment intersection.
        /// </summary>
        /// <param name="linePointsAndForwardSegments">List of line points with segments connecting to the next point in the line.</param>
        /// <param name="lastLinePoint">The final line point.</param>
        /// <param name="extrusionAmount">The extrusion amount.</param>
        /// <param name="parameterShift">The amount to shift the original line point parameters by when constructing the extruded points.</param>
        /// <param name="reverseIndices">Whether line point indices associated with extruded points should be reversed.</param>
        /// <param name="includeLast">If final segment should be included in the extrusion.</param>
        private static List <ExtrudedPointUV> GetExtrudedSubspace_Points_SegmentIntersections(List <LinePointUVAndSegment> linePointsAndForwardSegments, LinePointUV lastLinePoint, float extrusionAmount, float parameterShift, bool reverseIndices, bool includeLast)
        {
            var extrudedLinePoints = new List <ExtrudedPointUV>();

            GetShiftedScaledParameter findParameter = (originalPointParameter) => parameterShift + originalPointParameter;

            var numSegments = linePointsAndForwardSegments.Count;

            if (numSegments >= 2)
            {
                int endCount = includeLast ? numSegments : numSegments - 1;
                for (int i = 0; i <= endCount; i++)
                {
                    if (i == 0)
                    {
                        int lineSegmentIndex    = 0;
                        var linePointAndSegment = linePointsAndForwardSegments[lineSegmentIndex];
                        int extrudedPointIndexOnOriginalLine = reverseIndices ? numSegments : 0;

                        var extrudedStartPoint = new ExtrudedPointUV(linePointAndSegment.LinePoint, findParameter(linePointAndSegment.Parameter), linePointAndSegment.SegmentNormal, extrusionAmount, extrudedPointIndexOnOriginalLine);
                        extrudedLinePoints.Add(extrudedStartPoint);
                    }
                    else if (i == numSegments)
                    {
                        int lineSegmentIndex                 = numSegments - 1;
                        var lastLinePointAndSegment          = linePointsAndForwardSegments[lineSegmentIndex];
                        int extrudedPointIndexOnOriginalLine = reverseIndices ? 0 : numSegments;

                        var extrudedEndPoint = new ExtrudedPointUV(lastLinePoint, findParameter(lastLinePoint.Parameter), lastLinePointAndSegment.SegmentNormal, extrusionAmount, extrudedPointIndexOnOriginalLine);
                        extrudedLinePoints.Add(extrudedEndPoint);
                    }
                    else
                    {
                        var indexToAssign       = reverseIndices ? numSegments - i : i;
                        var linePointAndSegment = linePointsAndForwardSegments[i];
                        var nextLinePoint       = i + 1 < numSegments ? linePointsAndForwardSegments[i + 1].LinePoint : lastLinePoint;
                        AddPointExtrusionFromPreviousNextSegments(linePointAndSegment, linePointsAndForwardSegments[i - 1], nextLinePoint, indexToAssign, extrusionAmount, extrudedLinePoints, findParameter);
                    }
                }
            }
            return(extrudedLinePoints);
        }