コード例 #1
0
        internal static Vector2[] TraceRectangle(Rectangle rect, Stroke stroke, TessellationOptions tessellationOptions)
        {
            var width  = rect.Size.x;
            var height = rect.Size.y;

            if (width <= ShapeUtils.Epsilon || height <= ShapeUtils.Epsilon)
            {
                return(null);
            }

            if (IsSimpleRectangle(rect))
            {
                // Fast path, square corners, no patterns
                var r = new Rect(rect.Position, rect.Size);
                return(new Vector2[] {
                    new Vector2(r.xMin, r.yMin),
                    new Vector2(r.xMax, r.yMin),
                    new Vector2(r.xMax, r.yMax),
                    new Vector2(r.xMin, r.yMax)
                });
            }
            else
            {
                var contour = BuildRectangleContour(rect);
                return(ShapeUtils.TraceShape(contour, stroke, tessellationOptions));
            }
        }
コード例 #2
0
        private static void TessellateShapeLibTess(Shape vectorShape, Color color, List <Geometry> geoms, TessellationOptions tessellationOptions)
        {
            UnityEngine.Profiling.Profiler.BeginSample("LibTess");

            var tess = new Tess();

            var angle  = 45.0f * Mathf.Deg2Rad;
            var mat    = Matrix2D.RotateLH(angle);
            var invMat = Matrix2D.RotateLH(-angle);

            var pats = new List <Vector2[]>();

            foreach (var c in vectorShape.Contours)
            {
                var contour     = new List <Vector2>(100);
                var tracedshape = ShapeUtils.TraceShape(c, vectorShape.PathProps.Stroke, tessellationOptions);
                foreach (var v in tracedshape)
                {
                    contour.Add(mat.MultiplyPoint(v));
                }
                pats.Add(tracedshape);

                tess.AddContour(contour.Select(v => new ContourVertex()
                {
                    Position = new Vec3()
                    {
                        X = v.x, Y = v.y
                    }
                }).ToArray(), ContourOrientation.Original);
            }

            var windingRule = (vectorShape.Fill.Mode == FillMode.OddEven) ? WindingRule.EvenOdd : WindingRule.NonZero;

            try
            {
                tess.Tessellate(windingRule, ElementType.Polygons, 3);
            }
            catch (System.Exception)
            {
                Debug.LogWarning("Shape tessellation failed, skipping...");
                UnityEngine.Profiling.Profiler.EndSample();
                return;
            }

            var indices  = tess.Elements.Select(i => (UInt16)i);
            var vertices = tess.Vertices.Select(v => invMat.MultiplyPoint(new Vector2(v.Position.X, v.Position.Y)));
            var paths    = pats.ToArray();

            if (indices.Count() > 0)
            {
                geoms.Add(new Geometry()
                {
                    Vertices = vertices.ToArray(), Indices = indices.ToArray(), Paths = paths, Color = color, Fill = vectorShape.Fill, FillTransform = vectorShape.FillTransform
                });
            }

            UnityEngine.Profiling.Profiler.EndSample();
        }
コード例 #3
0
        private static void TessellateConvexContour(Shape shape, Stroke stroke, Color color, List <Geometry> geoms, TessellationOptions tessellationOptions)
        {
            if (shape.Contours.Length != 1 || shape.Contours[0].Segments.Length == 0)
            {
                return;
            }

            UnityEngine.Profiling.Profiler.BeginSample("TessellateConvexContour");

            // Compute geometric mean
            var contour = shape.Contours[0];
            var mean    = Vector2.zero;

            foreach (var seg in contour.Segments)
            {
                mean += seg.P0;
            }
            mean /= contour.Segments.Length;

            var tracedShape = ShapeUtils.TraceShape(contour, stroke, tessellationOptions);
            var vertices    = new Vector2[tracedShape.Length + 1];
            var indices     = new UInt16[tracedShape.Length * 3];
            var paths       = new Vector2[tracedShape.Length];

            vertices[0] = mean;
            for (int i = 0; i < tracedShape.Length; ++i)
            {
                vertices[i + 1]    = paths[i] = tracedShape[i];
                indices[i * 3]     = 0;
                indices[i * 3 + 1] = (UInt16)(i + 1);
                indices[i * 3 + 2] = ((i + 2) >= vertices.Length) ? (UInt16)1 : (UInt16)(i + 2);
            }

            geoms.Add(new Geometry()
            {
                Vertices = vertices, Indices = indices, Paths = new Vector2[][] { paths }, Color = color, Fill = shape.Fill, FillTransform = shape.FillTransform
            });

            UnityEngine.Profiling.Profiler.EndSample();
        }
コード例 #4
0
        internal static List <Vector2[]> TraceNodeHierarchyShapes(SceneNode root, TessellationOptions tessellationOptions)
        {
            var shapes = new List <Vector2[]>();

            foreach (var nodeInfo in WorldTransformedSceneNodes(root, null))
            {
                var node = nodeInfo.Node;

                // We process the drawables even though they are obsolete, until we remove the IDrawable interface entirely
                if (node.Drawables != null)
                {
                    foreach (var drawable in node.Drawables)
                    {
                        var vectorShape = drawable as Shape;
                        if (vectorShape != null)
                        {
                            foreach (var c in vectorShape.Contours)
                            {
                                var shape = ShapeUtils.TraceShape(c, vectorShape.PathProps.Stroke, tessellationOptions);
                                if (shape.Length > 0)
                                {
                                    shapes.Add(shape.Select(v => nodeInfo.WorldTransform * v).ToArray());
                                }
                            }
                            continue;
                        }

                        var vectorPath = drawable as Path;
                        if (vectorPath != null)
                        {
                            var shape = ShapeUtils.TraceShape(vectorPath.Contour, vectorPath.PathProps.Stroke, tessellationOptions);
                            if (shape.Length > 0)
                            {
                                shapes.Add(shape.Select(v => nodeInfo.WorldTransform * v).ToArray());
                            }
                            continue;
                        }

                        var vectorRect = drawable as Rectangle;
                        if (vectorRect != null)
                        {
                            var shape = ShapeUtils.TraceRectangle(vectorRect, vectorRect.PathProps.Stroke, tessellationOptions);
                            if (shape.Length > 0)
                            {
                                shapes.Add(shape.Select(v => nodeInfo.WorldTransform * v).ToArray());
                            }
                            continue;
                        }
                    }
                }

                if (node.Shapes != null)
                {
                    foreach (var shape in node.Shapes)
                    {
                        foreach (var c in shape.Contours)
                        {
                            var tracedShape = ShapeUtils.TraceShape(c, shape.PathProps.Stroke, tessellationOptions);
                            if (tracedShape.Length > 0)
                            {
                                shapes.Add(tracedShape.Select(v => nodeInfo.WorldTransform * v).ToArray());
                            }
                        }
                    }
                }
            }

            return(shapes);
        }