/// <summary>Called when we're emitting a line segment.</summary>
        protected override void EmitLine(StrokePoint inner, StrokePoint outer)
        {
            // Emit two verts and UVs:
            Vertices[VertexIndex] = new Vector3(inner.X, inner.Y, 0f);
            UV1[VertexIndex]      = new Vector2(inner.C * UvMultiplier.x, 0f);
            VertexIndex++;

            Vertices[VertexIndex] = new Vector3(outer.X, outer.Y, 0f);
            UV1[VertexIndex]      = new Vector2(outer.C * UvMultiplier.x, UvMultiplier.y);
            VertexIndex++;

            // Emit the triangles next (if we can):
            if (FirstLine)
            {
                FirstLine = false;
                return;
            }

            // 4 important verts are..
            // [VertexIndex-1, VertexIndex-2], [VertexIndex-3, VertexIndex-4]
            Triangles[TriangleIndex++] = VertexIndex - 1;
            Triangles[TriangleIndex++] = VertexIndex - 3;
            Triangles[TriangleIndex++] = VertexIndex - 2;

            Triangles[TriangleIndex++] = VertexIndex - 2;
            Triangles[TriangleIndex++] = VertexIndex - 3;
            Triangles[TriangleIndex++] = VertexIndex - 4;
        }
Exemple #2
0
        /// <summary>Adds points to the given set for a circle of the given angle, starting at a point about a center.</summary>
        private void DrawCircle(List <StrokePoint> set, ref int count, float angle, float pX, float pY, float c, Vector2 center)
        {
            // The length of the arc:
            float arc = (Width / 2f) * angle;

            if (arc < 0f)
            {
                arc = -arc;
            }

            // Divide it by accuracy to get the # of points to add:
            int segmentsToAdd = (int)(arc / Accuracy) - 1;

            if (segmentsToAdd <= 0)
            {
                return;
            }

            // Delta angle:
            float deltaAngle = -angle / (float)(segmentsToAdd + 1);

            // The point to rotate:
            float rotateX = pX - center.x;
            float rotateY = pY - center.y;

            arc = deltaAngle;

            for (int i = 0; i < segmentsToAdd; i++)
            {
                // Rotate the previous point about center
                // by 'arc'

                // Get cos/sin:
                float cs = (float)System.Math.Cos(arc);
                float sn = (float)System.Math.Sin(arc);

                // Compute the point:
                float rotatedX = (rotateX * cs - rotateY * sn) + center.x;
                float rotatedY = (rotateX * sn + rotateY * cs) + center.y;

                if (count == set.Count)
                {
                    set.Add(new StrokePoint(rotatedX, rotatedY, c));
                }
                else
                {
                    set[count] = new StrokePoint(rotatedX, rotatedY, c);
                }

                count++;
                arc += deltaAngle;
            }
        }
Exemple #3
0
        public void AddPoint(float x, float y, float c)
        {
            // Note that we don't know the total line length yet because of how extrude works.
            List <StrokePoint> set;
            int count;

            if (Outer)
            {
                set   = OuterSet;
                count = OuterCount;

                // Make c relative to the whole line (in terms of its length):
                c = OuterLength + c * CurrentLine.Length;
            }
            else
            {
                set   = InnerSet;
                count = InnerCount;

                // Make c relative to the whole line (in terms of its length):
                c = InnerLength + c * CurrentLine.Length;
            }

            if (ApplyLineJoinNow)
            {
                // Clear:
                ApplyLineJoinNow = false;

                if (count > 0)
                {
                    // Get the previous point:
                    StrokePoint previous = set[count - 1];

                    // Apply join now! Compare set[count-1] to our incoming point.
                    if (LineJoinMode == StrokeLineMode.Miter)
                    {
                        // Add a single point which occurs at the miter distance from the original line point
                        // along the average of StartNormal and EndNormal.

                        // Note that we've already made sure miter length is a suitable distance away.

                        // So, first, average that normal:
                        Vector2 avg = new Vector2(
                            (StartNormal.x + EndNormal.x) / 2f,
                            (StartNormal.y + EndNormal.y) / 2f
                            );

                        float length = MiterLength / avg.magnitude;

                        // The point to add is therefore..
                        float miterX = OriginalLinePoint.x + (avg.x * length);
                        float miterY = OriginalLinePoint.y + (avg.y * length);
                        float miterC = previous.C + ((c - previous.C) * 0.5f);

                        if (count == set.Count)
                        {
                            set.Add(new StrokePoint(miterX, miterY, miterC));
                        }
                        else
                        {
                            set[count] = new StrokePoint(miterX, miterY, miterC);
                        }

                        count++;
                    }
                    else if (LineJoinMode == StrokeLineMode.Round)
                    {
                        // Make a circle of radius halfWidth about the original line point.
                        DrawCircle(
                            set,
                            ref count,
                            LineAngle,
                            previous.X, previous.Y, c,
                            OriginalLinePoint
                            );
                    }
                }
            }

            if (count == set.Count)
            {
                set.Add(new StrokePoint(x, y, c));
            }
            else
            {
                set[count] = new StrokePoint(x, y, c);
            }

            if (Outer)
            {
                OuterCount = count + 1;
            }
            else
            {
                InnerCount = count + 1;
            }
        }
Exemple #4
0
        /// <summary>Called when a contour is completed.</summary>
        private void CompleteContour(bool closed)
        {
            AtLeastOneLine = false;

            if (InnerCount == 0 || OuterCount == 0)
            {
                return;
            }

            // We have a computed line to deal with!

            // First, make those C values relative to the total length of their lines.
            for (int i = 0; i < OuterCount; i++)
            {
                StrokePoint sp = OuterSet[i];
                sp.C       /= OuterLength;
                OuterSet[i] = sp;
            }

            for (int i = 0; i < InnerCount; i++)
            {
                StrokePoint sp = InnerSet[i];
                sp.C       /= InnerLength;
                InnerSet[i] = sp;
            }

            // Next, we'll step along the edges, pairing nodes together and emitting them.

            // Index in the other edge:
            int otherIndex = 0;

            int innerMax = InnerCount - 1;
            int outerMax = OuterCount - 1;

            // Biggest number of verts:
            if (InnerCount > OuterCount)
            {
                // We'll be emitting InnerCount lines:
                StartMesh(closed, InnerCount);

                // The inner edge is longer. It will set the pace.
                for (int i = 0; i < InnerCount; i++)
                {
                    // Compare inner.C with the two nearest verts in OuterSet.

                    // If this is the last index, we always emit both maxes:
                    if (i == innerMax)
                    {
                        otherIndex = outerMax;
                    }
                    else if (otherIndex != outerMax)
                    {
                        // Get the two C values to compare with:
                        float currentC = InnerSet[i].C;
                        float firstC   = currentC - OuterSet[otherIndex].C;
                        float secondC  = OuterSet[otherIndex + 1].C - currentC;

                        // If firstC is -ve, then use otherIndex.
                        // If secondC is -ve then use otherIndex+1.
                        // Otherwise, the smallest +ve number wins.

                        if (firstC > 0f && (secondC <= 0f || secondC < firstC))
                        {
                            // Pair with otherIndex+1.
                            otherIndex++;
                        }
                    }

                    // Pair now:
                    EmitLine(InnerSet[i], OuterSet[otherIndex]);
                }
            }
            else
            {
                // We'll be emitting OuterCount lines:
                StartMesh(closed, OuterCount);

                // The outer edge is longer. It will set the pace.
                for (int i = 0; i < OuterCount; i++)
                {
                    // Compare outer.C with the two nearest verts in InnerSet.

                    // If this is the last index, we always emit both maxes:
                    if (i == outerMax)
                    {
                        otherIndex = innerMax;
                    }
                    else if (otherIndex != innerMax)
                    {
                        // Get the two C values to compare with:
                        float currentC = OuterSet[i].C;
                        float firstC   = currentC - InnerSet[otherIndex].C;
                        float secondC  = InnerSet[otherIndex + 1].C - currentC;

                        // If firstC is -ve, then use otherIndex.
                        // If secondC is -ve then use otherIndex+1.
                        // Otherwise, the smallest +ve number wins.

                        if (firstC > 0f && (secondC <= 0f || secondC < firstC))
                        {
                            // Pair with otherIndex+1.
                            otherIndex++;
                        }
                    }

                    // Pair now:
                    EmitLine(InnerSet[otherIndex], OuterSet[i]);
                }
            }

            // Done!
            EndMesh();

            // Clear the values:
            InnerCount  = 0;
            OuterCount  = 0;
            InnerLength = 0f;
            OuterLength = 0f;
        }
Exemple #5
0
 /// <summary>Called when we're emitting a line segment.</summary>
 protected virtual void EmitLine(StrokePoint inner, StrokePoint outer)
 {
 }