Esempio n. 1
0
        //#endfor instanced to 'Vector2d'

        //#foreach instanced to 'Vector2f'


        /// <summary>
        /// Tesselates an outline using options to array of triangles.
        /// </summary>
        /// <param name="data">The input data. If options has OutlineEnd.NoEnd options, last and first element
        /// will be linked automatically (as with polygons). Otherwise, all points will be used.</param>
        /// <param name="options">The options of tesselation.</param>
        /// <param name="builder">The buolder that is used to build the mesh.</param>
        public static void Tesselate([NotNull] Vector2f[] data, [NotNull] TesselationOptionsf options,
                                     [NotNull] Storage.Builders.ITriangleBuilder2f builder)
        {
            if (data.Length < 2)
            {
                throw new ArgumentException("The data length must be at least 2, otherwise cannot tesselate.");
            }

            if (options.OutlineType == OutlineType.Line)
            {
                TesselateLine(data, options, builder);
            }
            else
            {
                throw new NotImplementedException("The feature not yet implemented.");
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Tesselates outline as line (most common).
        /// </summary>
        /// <param name="points"></param>
        /// <param name="options"></param>
        /// <param name="mesh"></param>
        static void TesselateLine(Vector2f[] points, TesselationOptionsf options,
                                  Storage.Builders.ITriangleBuilder2f mesh)
        {
            // This is actually half width, because we go both ways.
            float width = options.LineThickness * (float)0.5;

            // Previous lower and upper coordinates, usually pen dependant.
            Vector2f grad = points[1] - points[0];

            grad = new Vector2f(-grad.Y, grad.X).Normal;
            Vector2f prevLower = points[0] - grad * width,
                     prevUpper = points[0] + grad * width;

            // We check if it is closed.
            bool isClosed = false;

            if (Vector2f.NearEqual(points[0], points[points.Length - 1]))
            {
                isClosed = true;

                // We correct prevLower and prevUpper.
                Vector2f p0, p1, p2;
                if (CalcPathIntersection(points[points.Length - 2], points[0], points[1],
                                         width, out p0, out p1, out p2))
                {
                    prevUpper = p0;
                    prevLower = p2;
                }
                else
                {
                    prevUpper = p2;
                    prevLower = p0;
                }
            }
            else
            {
                if (options.OutlineEnd == OutlineEnd.NoEnd)
                {
                    throw new ArgumentException("The outline must be 'linked' in order to have no end.");
                }
            }

            // We insert prevUpper and predLower.
            uint prevUpperId = mesh.AddControlPoints(prevUpper, prevLower);
            uint prevLowerId = prevUpperId + 1;


            // We go through all points.
            for (int i = 1; i < points.Length - 1; i++)
            {
                Vector2f p0, p1, p2;
                if (CalcPathIntersection(points[i - 1], points[i], points[i + 1],
                                         width, out p0, out p1, out p2))
                {
                    // We now add new values.
                    uint p0Id = mesh.AddControlPoints(p0, p1, p2);
                    uint p1Id = p0Id + 1;
                    uint p2Id = p0Id + 2;

                    // We now add triangles.
                    mesh.AddIndexedTriangles(prevLowerId, p0Id, prevUpperId,
                                             prevLowerId, p1Id, p0Id,
                                             p0Id, p1Id, p2Id);

                    prevLowerId = p2Id;
                    prevUpperId = p0Id;
                }
                else
                {
                    // We now add new values.
                    uint p0Id = mesh.AddControlPoints(p0, p1, p2);
                    uint p1Id = p0Id + 1;
                    uint p2Id = p0Id + 2;

                    mesh.AddIndexedTriangles(prevLowerId, p1Id, prevUpperId,
                                             prevLowerId, p0Id, p1Id,
                                             p0Id, p1Id, p2Id);

                    prevLowerId = p0Id;
                    prevUpperId = p2Id;
                }
            }

            if (isClosed)
            {
                // If it is closed, we must close it correctly.
                Vector2f p0, p1, p2;
                if (CalcPathIntersection(points[points.Length - 2], points[0], points[1],
                                         width, out p0, out p1, out p2))
                {
                    // We now add new values.
                    uint p0Id = mesh.AddControlPoints(p0, p1, p2);
                    uint p1Id = p0Id + 1;
                    uint p2Id = p0Id + 2;

                    // We now add triangles.
                    mesh.AddIndexedTriangles(prevLowerId, p0Id, prevUpperId,
                                             prevLowerId, p1Id, p0Id,
                                             p0Id, p1Id, p2Id);
                }
                else
                {
                    // We now add new values.
                    uint p0Id = mesh.AddControlPoints(p0, p1, p2);
                    uint p1Id = p0Id + 1;
                    uint p2Id = p0Id + 2;

                    mesh.AddIndexedTriangles(prevLowerId, p1Id, prevUpperId,
                                             prevLowerId, p0Id, p1Id,
                                             p0Id, p1Id, p2Id);
                }
            }
            else
            {
                // TODO: may need to implement other endings.
                if (options.OutlineEnd != OutlineEnd.Square)
                {
                    throw new NotImplementedException("No other endings but 'Square' implemented.");
                }

                // Last point special again.
                Vector2f last = points[points.Length - 1];
                grad = last - points[points.Length - 2];
                grad = new Vector2f(-grad.Y, grad.X).Normal;

                Vector2f lower = last - grad * width;
                Vector2f upper = last + grad * width;

                // The lower id.
                uint lowerId = mesh.AddControlPoints(lower, upper);
                uint upperId = lowerId + 1;

                mesh.AddIndexedTriangles(prevLowerId, lowerId, upperId,
                                         prevLowerId, upperId, prevUpperId);
            }
        }