summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZiya Erkoc <ziya.erkoc@bilkent.edu.tr>2023-04-07 17:44:40 +0200
committerYuri Sizov <yuris@humnom.net>2023-04-07 17:44:40 +0200
commit210879d28451be465af9c19b008f6f5258c8fb7d (patch)
treeb9b3ce6aa10b69ba4375c4f0095c60a7f562e8d9
parent66a8ddf61c401ac91040c7d745499eb853f99dc6 (diff)
Warn if a concave shape is assigned to ConvexPolygonShape2D
(cherry picked from commit 6fb113f59f0fca1415a7a92e629f6f8611dc3c0a)
-rw-r--r--scene/resources/convex_polygon_shape_2d.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp
index 7f19dd63e6..0d9e570149 100644
--- a/scene/resources/convex_polygon_shape_2d.cpp
+++ b/scene/resources/convex_polygon_shape_2d.cpp
@@ -38,11 +38,41 @@ bool ConvexPolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, dou
return Geometry2D::is_point_in_polygon(p_point, points);
}
+#ifdef DEBUG_ENABLED
+// Check if point p3 is to the left of [p1, p2] segment or on it.
+bool left_test(const Vector2 &p1, const Vector2 &p2, const Vector2 &p3) {
+ Vector2 p12 = p2 - p1;
+ Vector2 p13 = p3 - p1;
+ // If the value of the cross product is positive or zero; p3 is to the left or on the segment, respectively.
+ return p12.cross(p13) >= 0;
+}
+
+bool is_convex(const Vector<Vector2> &p_points) {
+ // Pre-condition: Polygon is in counter-clockwise order.
+ int polygon_size = p_points.size();
+ for (int i = 0; i < polygon_size && polygon_size > 3; i++) {
+ int j = (i + 1) % polygon_size;
+ int k = (j + 1) % polygon_size;
+ // If any consecutive three points fail left-test, then there is a concavity.
+ if (!left_test(p_points[i], p_points[j], p_points[k])) {
+ return false;
+ }
+ }
+
+ return true;
+}
+#endif
+
void ConvexPolygonShape2D::_update_shape() {
Vector<Vector2> final_points = points;
if (Geometry2D::is_polygon_clockwise(final_points)) { //needs to be counter clockwise
final_points.reverse();
}
+#ifdef DEBUG_ENABLED
+ if (!is_convex(final_points)) {
+ WARN_PRINT("Concave polygon is assigned to ConvexPolygonShape2D.");
+ }
+#endif
PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), final_points);
emit_changed();
}