private static void MirrorVertices(Rect rect, NativeSlice <Vertex>?vertices, int vertexStart, int vertexCount, bool flipHorizontal)
        {
            if (!vertices.HasValue)
            {
                return;
            }

            var verts = vertices.GetValueOrDefault();

            if (flipHorizontal)
            {
                for (int i = 0; i < vertexCount; ++i)
                {
                    var vertex = verts[vertexStart + i];
                    vertex.position.x      = rect.xMax - (vertex.position.x - rect.xMax);
                    vertex.uv.x            = -vertex.uv.x;
                    verts[vertexStart + i] = vertex;
                }
            }
            else
            {
                for (int i = 0; i < vertexCount; ++i)
                {
                    var vertex = verts[vertexStart + i];
                    vertex.position.y      = rect.yMax - (vertex.position.y - rect.yMax);
                    vertex.uv.y            = -vertex.uv.y;
                    verts[vertexStart + i] = vertex;
                }
            }
        }
        private static void TessellateFilledFan(TessellationType tessellationType, Vector2 center, float radius, Color color, float posZ, VertexFlags vertexFlags, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 indexOffset, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly)
        {
            VertexFlags innerVertexFlags, outerVertexFlags;

            if (tessellationType == TessellationType.EdgeCorner)
            {
                innerVertexFlags = VertexFlags.IsEdge;
                outerVertexFlags = VertexFlags.IsSolid;
            }
            else
            {
                innerVertexFlags = vertexFlags;
                outerVertexFlags = vertexFlags;
            }

            if (countOnly)
            {
                vertexCount += (UInt16)(kSubdivisions + 1);
                indexCount  += (UInt16)((kSubdivisions - 1) * 3);
                return;
            }

            var p = new Vector2(center.x - radius, center.y);

            var verts = vertices.GetValueOrDefault();
            var inds  = indices.GetValueOrDefault();

            verts[vertexCount++] = new Vertex()
            {
                position = new Vector3(center.x, center.y, posZ), uv = p, tint = color, flags = (float)innerVertexFlags
            };
            verts[vertexCount++] = new Vertex()
            {
                position = new Vector3(p.x, p.y, posZ), uv = center, tint = color, flags = (float)outerVertexFlags
            };

            for (int k = 1; k < kSubdivisions; ++k)
            {
                float angle = (Mathf.PI / 2.0f) * ((float)k) / (kSubdivisions - 1);
                p = center + new Vector2(-Mathf.Cos(angle), -Mathf.Sin(angle)) * radius;
                verts[vertexCount++] = new Vertex()
                {
                    position = new Vector3(p.x, p.y, posZ), uv = center, tint = color, flags = (float)outerVertexFlags
                };

                inds[indexCount++] = (UInt16)(indexOffset + 0);
                inds[indexCount++] = (UInt16)(indexOffset + k + 1);
                inds[indexCount++] = (UInt16)(indexOffset + k);
            }

            indexOffset += (UInt16)(kSubdivisions + 1);
        }
        private static void FlipWinding(NativeSlice <UInt16>?indices, int indexStart, int indexCount)
        {
            if (!indices.HasValue)
            {
                return;
            }

            var inds = indices.GetValueOrDefault();

            for (int i = 0; i < indexCount; i += 3)
            {
                UInt16 tmp = inds[indexStart + i];
                inds[indexStart + i]     = inds[indexStart + i + 1];
                inds[indexStart + i + 1] = tmp;
            }
        }
        private static void TessellateBorderedFan(TessellationType tessellationType, Vector2 center, float radius, float leftWidth, float topWidth, Color color, float posZ, VertexFlags vertexFlags, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 indexOffset, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly)
        {
            VertexFlags innerVertexFlags, outerVertexFlags;

            if (tessellationType == TessellationType.EdgeCorner)
            {
                innerVertexFlags = VertexFlags.IsEdge;
                outerVertexFlags = VertexFlags.IsSolid;
            }
            else
            {
                innerVertexFlags = vertexFlags;
                outerVertexFlags = vertexFlags;
            }

            if (countOnly)
            {
                vertexCount += (UInt16)(kSubdivisions * 2);
                indexCount  += (UInt16)((kSubdivisions - 1) * 6);
                return;
            }

            var a = radius - leftWidth;
            var b = radius - topWidth;
            var p = new Vector2(center.x - radius, center.y);
            var q = new Vector2(center.x - a, center.y);

            var verts = vertices.GetValueOrDefault();
            var inds  = indices.GetValueOrDefault();

            verts[vertexCount++] = new Vertex {
                position = new Vector3(q.x, q.y, posZ), uv = q - p, tint = color, flags = (float)innerVertexFlags
            };
            verts[vertexCount++] = new Vertex {
                position = new Vector3(p.x, p.y, posZ), uv = p - q, tint = color, flags = (float)outerVertexFlags
            };

            for (int k = 1; k < kSubdivisions; ++k)
            {
                float percent = ((float)k) / (kSubdivisions - 1);
                float angle   = (Mathf.PI / 2.0f) * percent;
                p = center + new Vector2(-Mathf.Cos(angle), -Mathf.Sin(angle)) * radius;
                q = center + new Vector2(-a * Mathf.Cos(angle), -b * Mathf.Sin(angle));
                verts[vertexCount++] = new Vertex {
                    position = new Vector3(q.x, q.y, posZ), uv = q - p, tint = color, flags = (float)innerVertexFlags
                };
                verts[vertexCount++] = new Vertex {
                    position = new Vector3(p.x, p.y, posZ), uv = p - q, tint = color, flags = (float)outerVertexFlags
                };

                int i = k * 2;
                inds[indexCount++] = (UInt16)(indexOffset + (i - 2));
                inds[indexCount++] = (UInt16)(indexOffset + (i));
                inds[indexCount++] = (UInt16)(indexOffset + (i - 1));
                inds[indexCount++] = (UInt16)(indexOffset + (i - 1));
                inds[indexCount++] = (UInt16)(indexOffset + (i));
                inds[indexCount++] = (UInt16)(indexOffset + (i + 1));
            }

            indexOffset += (UInt16)(kSubdivisions * 2);
        }
        private static void TessellateQuad(Rect rect, TessellationType tessellationType, Color color, float posZ, VertexFlags vertexFlags, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 indexOffset, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly)
        {
            if (rect.width < kEpsilon || rect.height < kEpsilon)
            {
                return;
            }

            if (countOnly)
            {
                vertexCount += 4;
                indexCount  += 6;
                return;
            }

            float x0 = rect.x;
            float x3 = rect.xMax;
            float y0 = rect.y;
            float y3 = rect.yMax;

            Vector2 uv0, uv1, uv2, uv3;
            float   flags0, flags1, flags2, flags3;

            switch (tessellationType)
            {
            case TessellationType.EdgeHorizontal:
                // The uvs contain the displacement from the vertically opposed corner.
                uv0    = new Vector2(0, y0 - y3);
                uv1    = new Vector2(0, y0 - y3);
                uv2    = new Vector2(0, y3 - y0);
                uv3    = new Vector2(0, y3 - y0);
                flags0 = flags1 = (float)VertexFlags.IsSolid;
                flags2 = flags3 = (float)VertexFlags.IsEdge;
                break;

            case TessellationType.EdgeVertical:
                // The uvs contain the displacement from the horizontally opposed corner.
                uv0    = new Vector2(x0 - x3, 0);
                uv1    = new Vector2(x3 - x0, 0);
                uv2    = new Vector2(x0 - x3, 0);
                uv3    = new Vector2(x3 - x0, 0);
                flags0 = flags2 = (float)VertexFlags.IsSolid;
                flags1 = flags3 = (float)VertexFlags.IsEdge;
                break;

            case TessellationType.EdgeCorner:
                uv0    = uv1 = uv2 = uv3 = Vector2.zero;
                flags0 = flags1 = flags2 = flags3 = (float)VertexFlags.IsSolid;
                break;

            case TessellationType.Content:
                uv0    = uv1 = uv2 = uv3 = Vector2.zero;  // UVs are computed later for content
                flags0 = flags1 = flags2 = flags3 = (float)vertexFlags;
                break;

            default:
                throw new NotImplementedException();
            }

            var verts = vertices.GetValueOrDefault();

            verts[vertexCount++] = new Vertex {
                position = new Vector3(x0, y0, posZ), uv = uv0, tint = color, flags = flags0
            };
            verts[vertexCount++] = new Vertex {
                position = new Vector3(x3, y0, posZ), uv = uv1, tint = color, flags = flags1
            };
            verts[vertexCount++] = new Vertex {
                position = new Vector3(x0, y3, posZ), uv = uv2, tint = color, flags = flags2
            };
            verts[vertexCount++] = new Vertex {
                position = new Vector3(x3, y3, posZ), uv = uv3, tint = color, flags = flags3
            };

            var inds = indices.GetValueOrDefault();

            inds[indexCount++] = (UInt16)(indexOffset + 0);
            inds[indexCount++] = (UInt16)(indexOffset + 2);
            inds[indexCount++] = (UInt16)(indexOffset + 1);
            inds[indexCount++] = (UInt16)(indexOffset + 3);
            inds[indexCount++] = (UInt16)(indexOffset + 1);
            inds[indexCount++] = (UInt16)(indexOffset + 2);

            indexOffset += 4;
        }