Merge pull request #95790 from aaronfranke/rect-aabb-support
Simplify Rect2/AABB `get_support` function
This commit is contained in:
commit
39b77ea04e
|
@ -85,7 +85,7 @@ struct [[nodiscard]] AABB {
|
||||||
bool intersects_plane(const Plane &p_plane) const;
|
bool intersects_plane(const Plane &p_plane) const;
|
||||||
|
|
||||||
_FORCE_INLINE_ bool has_point(const Vector3 &p_point) 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;
|
Vector3 get_longest_axis() const;
|
||||||
int get_longest_axis_index() 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));
|
(src_max.z >= dst_max.z));
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 AABB::get_support(const Vector3 &p_normal) const {
|
Vector3 AABB::get_support(const Vector3 &p_direction) const {
|
||||||
Vector3 half_extents = size * 0.5f;
|
Vector3 support = position;
|
||||||
Vector3 ofs = position + half_extents;
|
if (p_direction.x > 0.0f) {
|
||||||
|
support.x += size.x;
|
||||||
return Vector3(
|
}
|
||||||
(p_normal.x > 0) ? half_extents.x : -half_extents.x,
|
if (p_direction.y > 0.0f) {
|
||||||
(p_normal.y > 0) ? half_extents.y : -half_extents.y,
|
support.y += size.y;
|
||||||
(p_normal.z > 0) ? half_extents.z : -half_extents.z) +
|
}
|
||||||
ofs;
|
if (p_direction.z > 0.0f) {
|
||||||
|
support.z += size.z;
|
||||||
|
}
|
||||||
|
return support;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 AABB::get_endpoint(int p_point) const {
|
Vector3 AABB::get_endpoint(int p_point) const {
|
||||||
|
|
|
@ -285,13 +285,15 @@ struct [[nodiscard]] Rect2 {
|
||||||
return Rect2(position.round(), size.round());
|
return Rect2(position.round(), size.round());
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 get_support(const Vector2 &p_normal) const {
|
Vector2 get_support(const Vector2 &p_direction) const {
|
||||||
Vector2 half_extents = size * 0.5f;
|
Vector2 support = position;
|
||||||
Vector2 ofs = position + half_extents;
|
if (p_direction.x > 0.0f) {
|
||||||
return Vector2(
|
support.x += size.x;
|
||||||
(p_normal.x > 0) ? -half_extents.x : half_extents.x,
|
}
|
||||||
(p_normal.y > 0) ? -half_extents.y : half_extents.y) +
|
if (p_direction.y > 0.0f) {
|
||||||
ofs;
|
support.y += size.y;
|
||||||
|
}
|
||||||
|
return support;
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ bool intersects_filled_polygon(const Vector2 *p_points, int p_point_count) const {
|
_FORCE_INLINE_ bool intersects_filled_polygon(const Vector2 *p_points, int p_point_count) const {
|
||||||
|
|
|
@ -1849,6 +1849,7 @@ static void _register_variant_builtin_methods_math() {
|
||||||
bind_method(Rect2, intersection, sarray("b"), varray());
|
bind_method(Rect2, intersection, sarray("b"), varray());
|
||||||
bind_method(Rect2, merge, sarray("b"), varray());
|
bind_method(Rect2, merge, sarray("b"), varray());
|
||||||
bind_method(Rect2, expand, sarray("to"), varray());
|
bind_method(Rect2, expand, sarray("to"), varray());
|
||||||
|
bind_method(Rect2, get_support, sarray("direction"), varray());
|
||||||
bind_method(Rect2, grow, sarray("amount"), varray());
|
bind_method(Rect2, grow, sarray("amount"), varray());
|
||||||
bind_methodv(Rect2, grow_side, &Rect2::grow_side_bind, sarray("side", "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());
|
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, merge, sarray("with"), varray());
|
||||||
bind_method(AABB, expand, sarray("to_point"), varray());
|
bind_method(AABB, expand, sarray("to_point"), varray());
|
||||||
bind_method(AABB, grow, sarray("by"), 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, sarray(), varray());
|
||||||
bind_method(AABB, get_longest_axis_index, sarray(), varray());
|
bind_method(AABB, get_longest_axis_index, sarray(), varray());
|
||||||
bind_method(AABB, get_longest_axis_size, sarray(), varray());
|
bind_method(AABB, get_longest_axis_size, sarray(), varray());
|
||||||
|
|
|
@ -206,7 +206,7 @@
|
||||||
</method>
|
</method>
|
||||||
<method name="get_support" qualifiers="const">
|
<method name="get_support" qualifiers="const">
|
||||||
<return type="Vector3" />
|
<return type="Vector3" />
|
||||||
<param index="0" name="dir" type="Vector3" />
|
<param index="0" name="direction" type="Vector3" />
|
||||||
<description>
|
<description>
|
||||||
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.
|
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.
|
||||||
</description>
|
</description>
|
||||||
|
|
|
@ -112,6 +112,13 @@
|
||||||
Returns the center point of the rectangle. This is the same as [code]position + (size / 2.0)[/code].
|
Returns the center point of the rectangle. This is the same as [code]position + (size / 2.0)[/code].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="get_support" qualifiers="const">
|
||||||
|
<return type="Vector2" />
|
||||||
|
<param index="0" name="direction" type="Vector2" />
|
||||||
|
<description>
|
||||||
|
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.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="grow" qualifiers="const">
|
<method name="grow" qualifiers="const">
|
||||||
<return type="Rect2" />
|
<return type="Rect2" />
|
||||||
<param index="0" name="amount" type="float" />
|
<param index="0" name="amount" type="float" />
|
||||||
|
|
|
@ -1734,7 +1734,7 @@ void RasterizerCanvasGLES3::light_update_directional_shadow(RID p_rid, int p_sha
|
||||||
|
|
||||||
Vector2 center = p_clip_rect.get_center();
|
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);
|
Vector2 from_pos = center - light_dir * (to_edge_distance + p_cull_distance);
|
||||||
float distance = to_edge_distance * 2.0 + p_cull_distance;
|
float distance = to_edge_distance * 2.0 + p_cull_distance;
|
||||||
|
|
|
@ -314,13 +314,20 @@ namespace Godot
|
||||||
/// <returns>A vector representing the support.</returns>
|
/// <returns>A vector representing the support.</returns>
|
||||||
public readonly Vector3 GetSupport(Vector3 dir)
|
public readonly Vector3 GetSupport(Vector3 dir)
|
||||||
{
|
{
|
||||||
Vector3 halfExtents = _size * 0.5f;
|
Vector3 support = _position;
|
||||||
Vector3 ofs = _position + halfExtents;
|
if (dir.X > 0.0f)
|
||||||
|
{
|
||||||
return ofs + new Vector3(
|
support.X += _size.X;
|
||||||
dir.X > 0f ? halfExtents.X : -halfExtents.X,
|
}
|
||||||
dir.Y > 0f ? halfExtents.Y : -halfExtents.Y,
|
if (dir.Y > 0.0f)
|
||||||
dir.Z > 0f ? halfExtents.Z : -halfExtents.Z);
|
{
|
||||||
|
support.Y += _size.Y;
|
||||||
|
}
|
||||||
|
if (dir.Z > 0.0f)
|
||||||
|
{
|
||||||
|
support.Z += _size.Z;
|
||||||
|
}
|
||||||
|
return support;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -171,6 +171,26 @@ namespace Godot
|
||||||
return _position + (_size * 0.5f);
|
return _position + (_size * 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the support point in a given direction.
|
||||||
|
/// This is useful for collision detection algorithms.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="direction">The direction to find support for.</param>
|
||||||
|
/// <returns>A vector representing the support.</returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a copy of the <see cref="Rect2"/> grown by the specified amount
|
/// Returns a copy of the <see cref="Rect2"/> grown by the specified amount
|
||||||
/// on all sides.
|
/// on all sides.
|
||||||
|
|
|
@ -1823,7 +1823,7 @@ void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_sh
|
||||||
|
|
||||||
Vector2 center = p_clip_rect.get_center();
|
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);
|
Vector2 from_pos = center - light_dir * (to_edge_distance + p_cull_distance);
|
||||||
float distance = to_edge_distance * 2.0 + p_cull_distance;
|
float distance = to_edge_distance * 2.0 + p_cull_distance;
|
||||||
|
|
|
@ -377,23 +377,23 @@ TEST_CASE("[AABB] Get longest/shortest axis") {
|
||||||
TEST_CASE("[AABB] Get support") {
|
TEST_CASE("[AABB] Get support") {
|
||||||
const AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
const AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||||
CHECK_MESSAGE(
|
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.");
|
"get_support() should return the expected value.");
|
||||||
CHECK_MESSAGE(
|
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.");
|
"get_support() should return the expected value.");
|
||||||
CHECK_MESSAGE(
|
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.");
|
"get_support() should return the expected value.");
|
||||||
CHECK_MESSAGE(
|
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.");
|
"get_support() should return the expected value.");
|
||||||
CHECK_MESSAGE(
|
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.");
|
"get_support() should return the expected value.");
|
||||||
CHECK_MESSAGE(
|
CHECK_MESSAGE(
|
||||||
aabb.get_support(Vector3()).is_equal_approx(Vector3(-1.5, 2, -2.5)),
|
aabb.get_support(Vector3()) == Vector3(-1.5, 2, -2.5),
|
||||||
"get_support() should return the expected value with a null vector.");
|
"get_support() should return the AABB position when given a zero vector.");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[AABB] Grow") {
|
TEST_CASE("[AABB] Grow") {
|
||||||
|
|
|
@ -180,6 +180,28 @@ TEST_CASE("[Rect2] Expanding") {
|
||||||
"expand() with non-contained Vector2 should return the expected result.");
|
"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") {
|
TEST_CASE("[Rect2] Growing") {
|
||||||
CHECK_MESSAGE(
|
CHECK_MESSAGE(
|
||||||
Rect2(0, 100, 1280, 720).grow(100).is_equal_approx(Rect2(-100, 0, 1480, 920)),
|
Rect2(0, 100, 1280, 720).grow(100).is_equal_approx(Rect2(-100, 0, 1480, 920)),
|
||||||
|
|
Loading…
Reference in New Issue