Jelajahi Sumber

Ensure that array passed to physics is always counter clockwise, fixes #15361.

Juan Linietsky 6 tahun lalu
induk
melakukan
16022da187
2 mengubah file dengan 21 tambahan dan 1 penghapusan
  1. 15 0
      core/math/geometry.h
  2. 6 1
      scene/resources/convex_polygon_shape_2d.cpp

+ 15 - 0
core/math/geometry.h

@@ -800,6 +800,21 @@ public:
 		return Vector<Vector<Vector2> >();
 	}
 
+	static bool is_polygon_clockwise(const Vector<Vector2> &p_polygon) {
+		int c = p_polygon.size();
+		if (c < 3)
+			return false;
+		const Vector2 *p = p_polygon.ptr();
+		real_t sum = 0;
+		for (int i = 0; i < c; i++) {
+			const Vector2 &v1 = p[i];
+			const Vector2 &v2 = p[(i + 1) % c];
+			sum += (v2.x - v1.x) * (v2.y + v1.y);
+		}
+
+		return sum > 0.0f;
+	}
+
 	static PoolVector<PoolVector<Face3> > separate_objects(PoolVector<Face3> p_array);
 
 	static PoolVector<Face3> wrap_geometry(PoolVector<Face3> p_array, real_t *p_error = NULL); ///< create a "wrap" that encloses the given geometry

+ 6 - 1
scene/resources/convex_polygon_shape_2d.cpp

@@ -41,7 +41,11 @@ bool ConvexPolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, dou
 
 void ConvexPolygonShape2D::_update_shape() {
 
-	Physics2DServer::get_singleton()->shape_set_data(get_rid(), points);
+	Vector<Vector2> final_points = points;
+	if (Geometry::is_polygon_clockwise(final_points)) { //needs to be counter clockwise
+		final_points.invert();
+	}
+	Physics2DServer::get_singleton()->shape_set_data(get_rid(), final_points);
 	emit_changed();
 }
 
@@ -55,6 +59,7 @@ void ConvexPolygonShape2D::set_point_cloud(const Vector<Vector2> &p_points) {
 void ConvexPolygonShape2D::set_points(const Vector<Vector2> &p_points) {
 
 	points = p_points;
+
 	_update_shape();
 }