public CubeBlueprint(ShapeDataFactory dataFactory) : base(dataFactory) { for (int i = 0; i < m_Points.Length; i++) { m_Points[i] = dataFactory.CreatePointData(); m_Points[i].NameUpdated.Subscribe(NameUpdated); } for (int i = 0; i < m_Lines.Length; i++) { m_Lines[i] = dataFactory.CreateLineData(); } for (int i = 0; i < m_Polygons.Length; i++) { m_Polygons[i] = dataFactory.CreatePolygonData(); m_Polygons[i].SetPointsCount(4); // By default polygon has 3 points, we need 4 } ConstructLines(); ConstructPolygons(); m_CompositeShapeData = dataFactory.CreateCompositeShapeData(); m_CompositeShapeData.SetPoints(m_Points); m_CompositeShapeData.SetLines(m_Lines); m_CompositeShapeData.SetPolygons(m_Polygons); OnDeserialized(); }
public TetrahedronBlueprint(ShapeDataFactory dataFactory) : base(dataFactory) { for (int i = 0; i < m_Points.Length; i++) { m_Points[i] = dataFactory.CreatePointData(); m_Points[i].NameUpdated.Subscribe(NameUpdated); } for (int i = 0; i < m_Lines.Length; i++) { m_Lines[i] = dataFactory.CreateLineData(); } for (int i = 0; i < m_Polygons.Length; i++) { m_Polygons[i] = dataFactory.CreatePolygonData(); } ConstructLines(); ConstructPolygons(); m_CompositeShapeData = dataFactory.CreateCompositeShapeData(); m_CompositeShapeData.SetPoints(m_Points); m_CompositeShapeData.SetLines(m_Lines); m_CompositeShapeData.SetPolygons(m_Polygons); OnDeserialized(); }
// A parent is a shape which fully contains another shape public bool IsParentOf(CompositeShapeData 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); }
// 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(CompositeShapeData 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); }
public CompositeShapeView(CompositeShapeData compositeShapeData) { m_CompositeShapeData = compositeShapeData; }
private CompositeShapeView CreateCompositeShapeView(CompositeShapeData data) { return(new CompositeShapeView(data)); }
public PrismBlueprint(ShapeDataFactory dataFactory) : base(dataFactory) { m_CompositeShapeData = dataFactory.CreateCompositeShapeData(); ConstructPrism(); OnDeserialized(); }
public void Process() { // Generate array of valid shape data CompositeShapeData[] eligibleShapes = shapes.Select(x => new CompositeShapeData(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. CompositeShapeData[] holeShapes = eligibleShapes.Where(x => x.parents.Count % 2 != 0).ToArray(); foreach (CompositeShapeData 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. CompositeShapeData immediateParent = holeShape.parents.OrderByDescending(x => x.parents.Count).First(); immediateParent.holes.Add(holeShape); } // Solid shapes have an even number of parents CompositeShapeData[] solidShapes = eligibleShapes.Where(x => x.parents.Count % 2 == 0).ToArray(); foreach (CompositeShapeData 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(); }
public RegularPyramidBlueprint(ShapeDataFactory dataFactory) : base(dataFactory) { m_CompositeShapeData = dataFactory.CreateCompositeShapeData(); ConstructPyramid(); OnDeserialized(); }