Exemplo n.º 1
0
            // A parent is a shape which fully contains another shape
            public bool IsParentOf(CompositeSolidShapeData otherShape)
            {
                if (otherShape.parents.Contains(this))
                {
                    return(true);
                }
                if (parents.Contains(otherShape))
                {
                    return(false);
                }

                // check if first point in otherShape is inside this shape. If not, parent test fails.
                // if yes, then continue to line seg intersection test between the two shapes

                // (this point test is important because without it, if all line seg intersection tests fail,
                // we wouldn't know if otherShape is entirely inside or entirely outside of this shape)
                bool pointInsideShape = false;

                for (int i = 0; i < triangles.Length; i += 3)
                {
                    if (Maths2D.PointInTriangle(polygon.points[triangles[i]], polygon.points[triangles[i + 1]], polygon.points[triangles[i + 2]], otherShape.points[0]))
                    {
                        pointInsideShape = true;
                        break;
                    }
                }

                if (!pointInsideShape)
                {
                    return(false);
                }

                // Check for intersections between line segs of this shape and otherShape (any intersections will fail the parent test)
                for (int i = 0; i < points.Length; i++)
                {
                    LineSegment parentSeg = new LineSegment(points[i], points[(i + 1) % points.Length]);
                    for (int j = 0; j < otherShape.points.Length; j++)
                    {
                        LineSegment childSeg = new LineSegment(otherShape.points[j], otherShape.points[(j + 1) % otherShape.points.Length]);
                        if (Maths2D.LineSegmentsIntersect(parentSeg.a, parentSeg.b, childSeg.a, childSeg.b))
                        {
                            return(false);
                        }
                    }
                }
                return(true);
            }
Exemplo n.º 2
0
 // Test if the shapes overlap partially (test will fail if one shape entirely contains other shape, i.e. one is parent of the other).
 public bool OverlapsPartially(CompositeSolidShapeData otherShape)
 {
     // Check for intersections between line segs of this shape and otherShape (any intersection will validate the overlap test)
     for (int i = 0; i < points.Length; i++)
     {
         LineSegment segA = new LineSegment(points[i], points[(i + 1) % points.Length]);
         for (int j = 0; j < otherShape.points.Length; j++)
         {
             LineSegment segB = new LineSegment(otherShape.points[j], otherShape.points[(j + 1) % otherShape.points.Length]);
             if (Maths2D.LineSegmentsIntersect(segA.a, segA.b, segB.a, segB.b))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Exemplo n.º 3
0
        public void Process()
        {
            // Generate array of valid shape data
            CompositeSolidShapeData[] eligibleShapes = shapes.Select(x => new CompositeSolidShapeData(x.points.ToArray())).Where(x => x.IsValidShape).ToArray();

            // Set parents for all shapes. A parent is a shape which completely contains another shape.
            for (int i = 0; i < eligibleShapes.Length; i++)
            {
                for (int j = 0; j < eligibleShapes.Length; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }

                    if (eligibleShapes[i].IsParentOf(eligibleShapes[j]))
                    {
                        eligibleShapes[j].parents.Add(eligibleShapes[i]);
                    }
                }
            }

            // Holes are shapes with an odd number of parents.
            CompositeSolidShapeData[] holeShapes = eligibleShapes.Where(x => x.parents.Count % 2 != 0).ToArray();
            foreach (CompositeSolidShapeData holeShape in holeShapes)
            {
                // The most immediate parent (i.e the smallest parent shape) will be the one that has the highest number of parents of its own.
                CompositeSolidShapeData immediateParent = holeShape.parents.OrderByDescending(x => x.parents.Count).First();
                immediateParent.holes.Add(holeShape);
            }

            // Solid shapes have an even number of parents
            CompositeSolidShapeData[] solidShapes = eligibleShapes.Where(x => x.parents.Count % 2 == 0).ToArray();
            foreach (CompositeSolidShapeData solidShape in solidShapes)
            {
                solidShape.ValidateHoles();
            }
            // Create polygons from the solid shapes and their associated hole shapes
            Polygon[] polygons = solidShapes.Select(x => new Polygon(x.polygon.points, x.holes.Select(h => h.polygon.points).ToArray())).ToArray();

            // Flatten the points arrays from all polygons into a single array, and convert the vector2s to vector3s.
            vertices = polygons.SelectMany(x => x.points.Select(v2 => new Vector3(v2.x, height, v2.y))).ToArray();

            // Triangulate each polygon and flatten the triangle arrays into a single array.
            List <int> allTriangles     = new List <int>();
            int        startVertexIndex = 0;

            for (int i = 0; i < polygons.Length; i++)
            {
                Triangulator triangulator     = new Triangulator(polygons[i]);
                int[]        polygonTriangles = triangulator.Triangulate();

                for (int j = 0; j < polygonTriangles.Length; j++)
                {
                    allTriangles.Add(polygonTriangles[j] + startVertexIndex);
                }
                startVertexIndex += polygons[i].numPoints;
            }

            triangles = allTriangles.ToArray();
        }