Exemplo n.º 1
0
        static Vector2[] LineBezierThicknessIntersect(BezierSegment seg, float thickness, Vector2 lineFrom, Vector2 lineTo, out float distanceToIntersection, out Vector2 intersection)
        {
            Vector2 tan       = ShapeUtils.EvalTangent(seg, 0.0f);
            Vector2 nrm       = Vector2.Perpendicular(tan);
            Vector2 lastPoint = seg.P0 + nrm * thickness;

            distanceToIntersection = 0.0f;
            intersection           = new Vector2(float.PositiveInfinity, float.PositiveInfinity);
            float stepT = 0.01f;
            float t     = 0;

            while (t < 1.0f)
            {
                t += stepT;
                var point = ShapeUtils.EvalFull(seg, t, out tan, out nrm) + nrm * thickness;
                intersection = ShapeUtils.IntersectLines(lineFrom, lineTo, lastPoint, point);
                if (PointOnLineIsWithinSegment(lastPoint, point, intersection))
                {
                    distanceToIntersection += (lastPoint - intersection).magnitude;
                    return(new Vector2[] { lastPoint, point });
                }
                distanceToIntersection += (lastPoint - point).magnitude;
                lastPoint = point;
            }
            return(null);
        }
Exemplo n.º 2
0
        static void AddSegment(BezierSegment segment, float toT, float halfThickness, JoiningInfo[] joinInfo, float segmentLengthSoFar, List <Vector2> verts, List <UInt16> inds)
        {
            Vector2 tanTo, normTo;
            Vector2 posTo = ShapeUtils.EvalFull(segment, toT, out tanTo, out normTo);

            Vector2 posThickness = posTo + normTo * halfThickness;
            Vector2 negThickness = posTo + normTo * -halfThickness;

            if (joinInfo != null)
            {
                if ((joinInfo[0] != null) && (segmentLengthSoFar < joinInfo[0].InnerCornerDistFromStart))
                {
                    if (joinInfo[0].RoundPosThickness)
                    {
                        negThickness = joinInfo[0].InnerCornerVertex;
                    }
                    else
                    {
                        posThickness = joinInfo[0].InnerCornerVertex;
                    }
                }

                if ((joinInfo[1] != null) && (segmentLengthSoFar > joinInfo[1].InnerCornerDistToEnd))
                {
                    if (joinInfo[1].RoundPosThickness)
                    {
                        negThickness = joinInfo[1].InnerCornerVertex;
                    }
                    else
                    {
                        posThickness = joinInfo[1].InnerCornerVertex;
                    }
                }
            }

            System.Diagnostics.Debug.Assert(verts.Count >= 2);
            int indexStart = verts.Count - 2;

            verts.Add(posThickness);
            verts.Add(negThickness);
            inds.Add((UInt16)(indexStart + 0));
            inds.Add((UInt16)(indexStart + 3));
            inds.Add((UInt16)(indexStart + 1));
            inds.Add((UInt16)(indexStart + 0));
            inds.Add((UInt16)(indexStart + 2));
            inds.Add((UInt16)(indexStart + 3));
        }
Exemplo n.º 3
0
        static void GenerateTip(BezierSegment segment, bool atStart, float t, PathEnding ending, float halfThickness, TessellationOptions tessellateOptions, List <Vector2> verts, List <UInt16> inds)
        {
            // The tip includes the vertices at the end itself
            Vector2 tan, nrm;
            var     pos        = ShapeUtils.EvalFull(segment, t, out tan, out nrm);
            int     indexStart = verts.Count;

            switch (ending)
            {
            case PathEnding.Chop:
                if (atStart)
                {
                    verts.Add(pos + nrm * halfThickness);
                    verts.Add(pos - nrm * halfThickness);
                }
                else
                {
                    // Not much, path segments are always expected to be generated perpendicular to the path
                    // at the segment point location, so we don't have to do anything for the ending
                }
                break;

            case PathEnding.Square:
                if (atStart)
                {
                    verts.Add(pos + nrm * halfThickness - tan * halfThickness);
                    verts.Add(pos - nrm * halfThickness - tan * halfThickness);
                    verts.Add(pos + nrm * halfThickness);
                    verts.Add(pos - nrm * halfThickness);

                    inds.Add((UInt16)(indexStart + 0));
                    inds.Add((UInt16)(indexStart + 3));
                    inds.Add((UInt16)(indexStart + 1));
                    inds.Add((UInt16)(indexStart + 0));
                    inds.Add((UInt16)(indexStart + 2));
                    inds.Add((UInt16)(indexStart + 3));
                }
                else
                {
                    // Relying on the last two vertices, and just adding two of our own here
                    verts.Add(pos + nrm * halfThickness + tan * halfThickness);
                    verts.Add(pos - nrm * halfThickness + tan * halfThickness);

                    inds.Add((UInt16)(indexStart + 0 - 2));
                    inds.Add((UInt16)(indexStart + 3 - 2));
                    inds.Add((UInt16)(indexStart + 1 - 2));
                    inds.Add((UInt16)(indexStart + 0 - 2));
                    inds.Add((UInt16)(indexStart + 2 - 2));
                    inds.Add((UInt16)(indexStart + 3 - 2));
                }
                break;

            case PathEnding.Round:
                float arcSign     = atStart ? -1 : 1;
                int   arcSegments = CalculateArcSteps(halfThickness, 0, Mathf.PI, tessellateOptions);
                for (int i = 1; i < arcSegments; i++)
                {
                    float angle = Mathf.PI * (i / (float)arcSegments);
                    verts.Add(pos + Matrix2D.RotateLH(angle) * nrm * halfThickness * arcSign);
                }

                if (atStart)
                {
                    // Note how we maintain the last two vertices being setup for connection by the rest of the path vertices
                    int indexTipStart = verts.Count;
                    verts.Add(pos + nrm * halfThickness);
                    verts.Add(pos - nrm * halfThickness);

                    for (int i = 1; i < arcSegments; i++)
                    {
                        inds.Add((UInt16)(indexTipStart + 1));
                        inds.Add((UInt16)(indexStart + i - 1));
                        inds.Add((UInt16)(indexStart + i));
                    }
                }
                else
                {
                    inds.Add((UInt16)(indexStart - 1));
                    inds.Add((UInt16)(indexStart - 2));
                    inds.Add((UInt16)(indexStart + 0));
                    for (int i = 1; i < arcSegments - 1; i++)
                    {
                        inds.Add((UInt16)(indexStart - 1));
                        inds.Add((UInt16)(indexStart + i - 1));
                        inds.Add((UInt16)(indexStart + i));
                    }
                }
                break;

            default:
                System.Diagnostics.Debug.Assert(false);     // Joining has its own function
                break;
            }
        }