diff --git a/core/math/aabb.h b/core/math/aabb.h
index cb358ca7efc..7a5581b5d45 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -85,7 +85,7 @@ struct [[nodiscard]] AABB {
bool intersects_plane(const Plane &p_plane) const;
_FORCE_INLINE_ bool has_point(const Vector3 &p_point) const;
- _FORCE_INLINE_ Vector3 get_support(const Vector3 &p_normal) const;
+ _FORCE_INLINE_ Vector3 get_support(const Vector3 &p_direction) const;
Vector3 get_longest_axis() const;
int get_longest_axis_index() const;
@@ -212,15 +212,18 @@ inline bool AABB::encloses(const AABB &p_aabb) const {
(src_max.z >= dst_max.z));
}
-Vector3 AABB::get_support(const Vector3 &p_normal) const {
- Vector3 half_extents = size * 0.5f;
- Vector3 ofs = position + half_extents;
-
- return Vector3(
- (p_normal.x > 0) ? half_extents.x : -half_extents.x,
- (p_normal.y > 0) ? half_extents.y : -half_extents.y,
- (p_normal.z > 0) ? half_extents.z : -half_extents.z) +
- ofs;
+Vector3 AABB::get_support(const Vector3 &p_direction) const {
+ Vector3 support = position;
+ if (p_direction.x > 0.0f) {
+ support.x += size.x;
+ }
+ if (p_direction.y > 0.0f) {
+ support.y += size.y;
+ }
+ if (p_direction.z > 0.0f) {
+ support.z += size.z;
+ }
+ return support;
}
Vector3 AABB::get_endpoint(int p_point) const {
diff --git a/core/math/rect2.h b/core/math/rect2.h
index 9cb341b6894..817923c1348 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -285,13 +285,15 @@ struct [[nodiscard]] Rect2 {
return Rect2(position.round(), size.round());
}
- Vector2 get_support(const Vector2 &p_normal) const {
- Vector2 half_extents = size * 0.5f;
- Vector2 ofs = position + half_extents;
- return Vector2(
- (p_normal.x > 0) ? -half_extents.x : half_extents.x,
- (p_normal.y > 0) ? -half_extents.y : half_extents.y) +
- ofs;
+ Vector2 get_support(const Vector2 &p_direction) const {
+ Vector2 support = position;
+ if (p_direction.x > 0.0f) {
+ support.x += size.x;
+ }
+ if (p_direction.y > 0.0f) {
+ support.y += size.y;
+ }
+ return support;
}
_FORCE_INLINE_ bool intersects_filled_polygon(const Vector2 *p_points, int p_point_count) const {
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 5e402937cf9..695ad23bf5c 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1849,6 +1849,7 @@ static void _register_variant_builtin_methods_math() {
bind_method(Rect2, intersection, sarray("b"), varray());
bind_method(Rect2, merge, sarray("b"), varray());
bind_method(Rect2, expand, sarray("to"), varray());
+ bind_method(Rect2, get_support, sarray("direction"), varray());
bind_method(Rect2, grow, sarray("amount"), varray());
bind_methodv(Rect2, grow_side, &Rect2::grow_side_bind, sarray("side", "amount"), varray());
bind_method(Rect2, grow_individual, sarray("left", "top", "right", "bottom"), varray());
@@ -2185,7 +2186,7 @@ static void _register_variant_builtin_methods_misc() {
bind_method(AABB, merge, sarray("with"), varray());
bind_method(AABB, expand, sarray("to_point"), varray());
bind_method(AABB, grow, sarray("by"), varray());
- bind_method(AABB, get_support, sarray("dir"), varray());
+ bind_method(AABB, get_support, sarray("direction"), varray());
bind_method(AABB, get_longest_axis, sarray(), varray());
bind_method(AABB, get_longest_axis_index, sarray(), varray());
bind_method(AABB, get_longest_axis_size, sarray(), varray());
diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml
index 77c74e17da7..188d9652a8c 100644
--- a/doc/classes/AABB.xml
+++ b/doc/classes/AABB.xml
@@ -206,7 +206,7 @@
-
+
Returns the vertex's position of this bounding box that's the farthest in the given direction. This point is commonly known as the support point in collision detection algorithms.
diff --git a/doc/classes/Rect2.xml b/doc/classes/Rect2.xml
index ba7dcab2d76..f2c0b017bce 100644
--- a/doc/classes/Rect2.xml
+++ b/doc/classes/Rect2.xml
@@ -112,6 +112,13 @@
Returns the center point of the rectangle. This is the same as [code]position + (size / 2.0)[/code].
+
+
+
+
+ Returns the vertex's position of this rect that's the farthest in the given direction. This point is commonly known as the support point in collision detection algorithms.
+
+
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 7a6df3d2a43..b9206f310e8 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -1734,7 +1734,7 @@ void RasterizerCanvasGLES3::light_update_directional_shadow(RID p_rid, int p_sha
Vector2 center = p_clip_rect.get_center();
- float to_edge_distance = ABS(light_dir.dot(p_clip_rect.get_support(light_dir)) - light_dir.dot(center));
+ float to_edge_distance = ABS(light_dir.dot(p_clip_rect.get_support(-light_dir)) - light_dir.dot(center));
Vector2 from_pos = center - light_dir * (to_edge_distance + p_cull_distance);
float distance = to_edge_distance * 2.0 + p_cull_distance;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Aabb.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Aabb.cs
index 33f0850a8d5..ef550eab0d4 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Aabb.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Aabb.cs
@@ -314,13 +314,20 @@ namespace Godot
/// A vector representing the support.
public readonly Vector3 GetSupport(Vector3 dir)
{
- Vector3 halfExtents = _size * 0.5f;
- Vector3 ofs = _position + halfExtents;
-
- return ofs + new Vector3(
- dir.X > 0f ? halfExtents.X : -halfExtents.X,
- dir.Y > 0f ? halfExtents.Y : -halfExtents.Y,
- dir.Z > 0f ? halfExtents.Z : -halfExtents.Z);
+ Vector3 support = _position;
+ if (dir.X > 0.0f)
+ {
+ support.X += _size.X;
+ }
+ if (dir.Y > 0.0f)
+ {
+ support.Y += _size.Y;
+ }
+ if (dir.Z > 0.0f)
+ {
+ support.Z += _size.Z;
+ }
+ return support;
}
///
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
index 19721b6ccaf..4f606cc6b3b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
@@ -171,6 +171,26 @@ namespace Godot
return _position + (_size * 0.5f);
}
+ ///
+ /// Returns the support point in a given direction.
+ /// This is useful for collision detection algorithms.
+ ///
+ /// The direction to find support for.
+ /// A vector representing the support.
+ public readonly Vector2 GetSupport(Vector2 direction)
+ {
+ Vector2 support = _position;
+ if (direction.X > 0.0f)
+ {
+ support.X += _size.X;
+ }
+ if (direction.Y > 0.0f)
+ {
+ support.Y += _size.Y;
+ }
+ return support;
+ }
+
///
/// Returns a copy of the grown by the specified amount
/// on all sides.
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 5e4721dfb51..51fec8c206a 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -1823,7 +1823,7 @@ void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_sh
Vector2 center = p_clip_rect.get_center();
- float to_edge_distance = ABS(light_dir.dot(p_clip_rect.get_support(light_dir)) - light_dir.dot(center));
+ float to_edge_distance = ABS(light_dir.dot(p_clip_rect.get_support(-light_dir)) - light_dir.dot(center));
Vector2 from_pos = center - light_dir * (to_edge_distance + p_cull_distance);
float distance = to_edge_distance * 2.0 + p_cull_distance;
diff --git a/tests/core/math/test_aabb.h b/tests/core/math/test_aabb.h
index dbc62bc2486..741e6af5d47 100644
--- a/tests/core/math/test_aabb.h
+++ b/tests/core/math/test_aabb.h
@@ -377,23 +377,23 @@ TEST_CASE("[AABB] Get longest/shortest axis") {
TEST_CASE("[AABB] Get support") {
const AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
CHECK_MESSAGE(
- aabb.get_support(Vector3(1, 0, 0)).is_equal_approx(Vector3(2.5, 2, -2.5)),
+ aabb.get_support(Vector3(1, 0, 0)) == Vector3(2.5, 2, -2.5),
"get_support() should return the expected value.");
CHECK_MESSAGE(
- aabb.get_support(Vector3(0.5, 1, 0)).is_equal_approx(Vector3(2.5, 7, -2.5)),
+ aabb.get_support(Vector3(0.5, 1, 1)) == Vector3(2.5, 7, 3.5),
"get_support() should return the expected value.");
CHECK_MESSAGE(
- aabb.get_support(Vector3(0.5, 1, -400)).is_equal_approx(Vector3(2.5, 7, -2.5)),
+ aabb.get_support(Vector3(0.5, 1, -400)) == Vector3(2.5, 7, -2.5),
"get_support() should return the expected value.");
CHECK_MESSAGE(
- aabb.get_support(Vector3(0, -1, 0)).is_equal_approx(Vector3(-1.5, 2, -2.5)),
+ aabb.get_support(Vector3(0, -1, 0)) == Vector3(-1.5, 2, -2.5),
"get_support() should return the expected value.");
CHECK_MESSAGE(
- aabb.get_support(Vector3(0, -0.1, 0)).is_equal_approx(Vector3(-1.5, 2, -2.5)),
+ aabb.get_support(Vector3(0, -0.1, 0)) == Vector3(-1.5, 2, -2.5),
"get_support() should return the expected value.");
CHECK_MESSAGE(
- aabb.get_support(Vector3()).is_equal_approx(Vector3(-1.5, 2, -2.5)),
- "get_support() should return the expected value with a null vector.");
+ aabb.get_support(Vector3()) == Vector3(-1.5, 2, -2.5),
+ "get_support() should return the AABB position when given a zero vector.");
}
TEST_CASE("[AABB] Grow") {
diff --git a/tests/core/math/test_rect2.h b/tests/core/math/test_rect2.h
index 26ab185aa2f..c4368808a6b 100644
--- a/tests/core/math/test_rect2.h
+++ b/tests/core/math/test_rect2.h
@@ -180,6 +180,28 @@ TEST_CASE("[Rect2] Expanding") {
"expand() with non-contained Vector2 should return the expected result.");
}
+TEST_CASE("[Rect2] Get support") {
+ const Rect2 rect = Rect2(Vector2(-1.5, 2), Vector2(4, 5));
+ CHECK_MESSAGE(
+ rect.get_support(Vector2(1, 0)) == Vector2(2.5, 2),
+ "get_support() should return the expected value.");
+ CHECK_MESSAGE(
+ rect.get_support(Vector2(0.5, 1)) == Vector2(2.5, 7),
+ "get_support() should return the expected value.");
+ CHECK_MESSAGE(
+ rect.get_support(Vector2(0.5, 1)) == Vector2(2.5, 7),
+ "get_support() should return the expected value.");
+ CHECK_MESSAGE(
+ rect.get_support(Vector2(0, -1)) == Vector2(-1.5, 2),
+ "get_support() should return the expected value.");
+ CHECK_MESSAGE(
+ rect.get_support(Vector2(0, -0.1)) == Vector2(-1.5, 2),
+ "get_support() should return the expected value.");
+ CHECK_MESSAGE(
+ rect.get_support(Vector2()) == Vector2(-1.5, 2),
+ "get_support() should return the Rect2 position when given a zero vector.");
+}
+
TEST_CASE("[Rect2] Growing") {
CHECK_MESSAGE(
Rect2(0, 100, 1280, 720).grow(100).is_equal_approx(Rect2(-100, 0, 1480, 920)),