static void GenerateJoining(JoiningInfo joinInfo, PathCorner corner, float halfThickness, float tippedCornerLimit, TessellationOptions tessellateOptions, List <Vector2> verts, List <UInt16> inds)
        {
            // The joining generates the vertices at both ends as well as the joining itself
            if (verts.Count == 0)
            {
                // Starting a path with a joining (meaning a loop)
                verts.Add(joinInfo.RoundPosThickness ? joinInfo.PosThicknessEnd : joinInfo.InnerCornerVertex);
                verts.Add(joinInfo.RoundPosThickness ? joinInfo.InnerCornerVertex : joinInfo.NegThicknessEnd);
            }

            System.Diagnostics.Debug.Assert(verts.Count >= 2);
            int indexStart = verts.Count - 2; // Using the last two vertices

            // Convert a tipped corner to a beveled one if tippedCornerLimit ratio is reached
            if (corner == PathCorner.Tipped && tippedCornerLimit >= 1.0f)
            {
                var theta = Vector2.Angle(-joinInfo.TanAtEnd, joinInfo.TanAtStart) * Mathf.Deg2Rad;
                var ratio = 1.0f / Mathf.Sin(theta / 2.0f);
                if (ratio > tippedCornerLimit)
                {
                    corner = PathCorner.Beveled;
                }
            }

            if (joinInfo.SimpleJoin)
            {
                // TODO
            }
            else if (corner == PathCorner.Tipped)
            {
                verts.Add(joinInfo.PosThicknessClosingPoint);
                verts.Add(joinInfo.NegThicknessClosingPoint);
                verts.Add(joinInfo.RoundPosThickness ? joinInfo.PosThicknessStart : joinInfo.InnerCornerVertex);
                verts.Add(joinInfo.RoundPosThickness ? joinInfo.InnerCornerVertex : joinInfo.NegThicknessStart);

                // Ending to tip
                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));

                // Tip to starting
                inds.Add((UInt16)(indexStart + 4));
                inds.Add((UInt16)(indexStart + 3));
                inds.Add((UInt16)(indexStart + 2));
                inds.Add((UInt16)(indexStart + 4));
                inds.Add((UInt16)(indexStart + 5));
                inds.Add((UInt16)(indexStart + 3));

                return;
            }
            else if (corner == PathCorner.Beveled)
            {
                verts.Add(joinInfo.RoundPosThickness ? joinInfo.PosThicknessEnd : joinInfo.InnerCornerVertex);   // 2
                verts.Add(joinInfo.RoundPosThickness ? joinInfo.InnerCornerVertex : joinInfo.NegThicknessEnd);   // 3
                verts.Add(joinInfo.RoundPosThickness ? joinInfo.PosThicknessStart : joinInfo.InnerCornerVertex); // 4
                verts.Add(joinInfo.RoundPosThickness ? joinInfo.InnerCornerVertex : joinInfo.NegThicknessStart); // 5

                // Ending to tip
                inds.Add((UInt16)(indexStart + 0));
                inds.Add((UInt16)(indexStart + 2));
                inds.Add((UInt16)(indexStart + 1));
                inds.Add((UInt16)(indexStart + 1));
                inds.Add((UInt16)(indexStart + 2));
                inds.Add((UInt16)(indexStart + 3));

                // Bevel
                if (joinInfo.RoundPosThickness)
                {
                    inds.Add((UInt16)(indexStart + 2));
                    inds.Add((UInt16)(indexStart + 4));
                    inds.Add((UInt16)(indexStart + 3));
                }
                else
                {
                    inds.Add((UInt16)(indexStart + 3));
                    inds.Add((UInt16)(indexStart + 2));
                    inds.Add((UInt16)(indexStart + 5));
                }

                return;
            }

            if (corner == PathCorner.Round)
            {
                float sweepAngle = Mathf.Acos(Vector2.Dot(joinInfo.NormAtEnd, joinInfo.NormAtStart));
                bool  flipArc    = false;
                if (!PointOnTheLeftOfLine(Vector2.zero, joinInfo.NormAtEnd, joinInfo.NormAtStart))
                {
                    sweepAngle = -sweepAngle;
                    flipArc    = true;
                }

                UInt16 innerCornerVertexIndex = (UInt16)verts.Count;
                verts.Add(joinInfo.InnerCornerVertex);

                int arcSegments = CalculateArcSteps(halfThickness, 0, sweepAngle, tessellateOptions);
                for (int i = 0; i <= arcSegments; i++)
                {
                    float   angle = sweepAngle * (i / (float)arcSegments);
                    Vector2 nrm   = Matrix2D.RotateLH(angle) * joinInfo.NormAtEnd;
                    if (flipArc)
                    {
                        nrm = -nrm;
                    }
                    verts.Add(nrm * halfThickness + joinInfo.JoinPos);

                    if (i == 0)
                    {
                        inds.Add((UInt16)(indexStart + 0));
                        inds.Add((UInt16)(indexStart + 3));
                        inds.Add((UInt16)(indexStart + (joinInfo.RoundPosThickness ? 2 : 1)));

                        inds.Add((UInt16)(indexStart + 0));
                        inds.Add((UInt16)(indexStart + 2));
                        inds.Add((UInt16)(indexStart + (joinInfo.RoundPosThickness ? 1 : 3)));
                    }
                    else
                    {
                        if (joinInfo.RoundPosThickness)
                        {
                            inds.Add((UInt16)(indexStart + i + (flipArc ? 3 : 2)));
                            inds.Add((UInt16)(indexStart + i + (flipArc ? 2 : 3)));
                            inds.Add(innerCornerVertexIndex);
                        }
                        else
                        {
                            inds.Add((UInt16)(indexStart + i + (flipArc ? 3 : 2)));
                            inds.Add((UInt16)(indexStart + i + (flipArc ? 2 : 3)));
                            inds.Add(innerCornerVertexIndex);
                        }
                    }
                }

                // Manually add the last segment, maintain the expected vertex positioning
                int endingVerticesIndex = verts.Count;
                if (joinInfo.RoundPosThickness)
                {
                    verts.Add(joinInfo.PosThicknessStart);
                    verts.Add(joinInfo.InnerCornerVertex);
                }
                else
                {
                    verts.Add(joinInfo.InnerCornerVertex);
                    verts.Add(joinInfo.NegThicknessStart);
                }
                inds.Add((UInt16)(endingVerticesIndex - 1));
                inds.Add((UInt16)(endingVerticesIndex + 0));
                inds.Add(innerCornerVertexIndex);
            }
        }
Пример #2
0
    private static void BuildTestColumnWithProperties(float x, float width, PathEnding ending, PathCorner corners, VectorUtils.TessellationOptions options)
    {
        var sprites = new List <Sprite>();

        var angles = new float[] {
            -Mathf.PI + Mathf.PI / 8,
            -Mathf.PI + Mathf.PI / 4,
            Mathf.PI - Mathf.PI / 4,
            Mathf.PI - Mathf.PI / 8
        };

        foreach (var angle in angles)
        {
            var path      = LinesWithAngle(angle, width);
            var pathProps = path.PathProps;
            pathProps.Head    = ending;
            pathProps.Tail    = ending;
            pathProps.Corners = corners;
            path.PathProps    = pathProps;

            var geoms = new List <VectorUtils.Geometry>();
            TessellatePath(path.Contours[0], path.PathProps, geoms, options);
            sprites.Add(SpriteFromGeometry(geoms));
        }

        var pos = new Vector2(x, 0.0f);

        foreach (var sprite in sprites)
        {
            var go = new GameObject("Path");
            go.transform.position = pos;
            var sr = go.AddComponent <SpriteRenderer>();
            sr.sprite = sprite;
            pos.y    += 0.25f;
        }
    }