From c991043c95c4af1ea7da555b2bf2ca0d0ff907ae Mon Sep 17 00:00:00 2001 From: Relintai Date: Sat, 13 Aug 2022 18:21:54 +0200 Subject: [PATCH] Backported improvements to AABB from Godot 4. Also made sure all eligible methods are bound. --- core/math/aabb.cpp | 19 ++++++++++- core/math/aabb.h | 49 +++++++++++++++++++++++++-- core/math/bsp_tree.cpp | 2 +- core/variant_call.cpp | 69 ++++++++++++++++++++++++++------------ doc/classes/AABB.xml | 4 +-- servers/physics/shape_sw.h | 2 +- 6 files changed, 116 insertions(+), 29 deletions(-) diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp index d5282e483..18693bc12 100644 --- a/core/math/aabb.cpp +++ b/core/math/aabb.cpp @@ -30,9 +30,10 @@ #include "aabb.h" +#include "core/variant.h" #include "core/print_string.h" -real_t AABB::get_area() const { +real_t AABB::get_volume() const { return size.x * size.y * size.z; } @@ -408,6 +409,22 @@ void AABB::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const { } } +Variant AABB::intersects_segmentv(const Vector3 &p_from, const Vector3 &p_to) const { + Vector3 inters; + if (intersects_segment(p_from, p_to, &inters)) { + return inters; + } + return Variant(); +} + +Variant AABB::intersects_rayv(const Vector3 &p_from, const Vector3 &p_dir) const { + Vector3 inters; + if (intersects_ray(p_from, p_dir, &inters)) { + return inters; + } + return Variant(); +} + AABB::operator String() const { return String() + position + " - " + size; } diff --git a/core/math/aabb.h b/core/math/aabb.h index 777b691ad..51ed632d1 100644 --- a/core/math/aabb.h +++ b/core/math/aabb.h @@ -39,13 +39,15 @@ * This is implemented by a point (position) and the box size */ +class Variant; + class _NO_DISCARD_CLASS_ AABB { public: Vector3 position; Vector3 size; - real_t get_area() const; /// get area - _FORCE_INLINE_ bool has_no_area() const { + real_t get_volume() const; /// get area + _FORCE_INLINE_ bool has_no_volume() const { return (size.x <= 0 || size.y <= 0 || size.z <= 0); } @@ -57,7 +59,6 @@ public: void set_position(const Vector3 &p_pos) { position = p_pos; } const Vector3 &get_size() const { return size; } void set_size(const Vector3 &p_size) { size = p_size; } - Vector3 get_center() const { return position + (size * 0.5f); } bool operator==(const AABB &p_rval) const; bool operator!=(const AABB &p_rval) const; @@ -104,6 +105,24 @@ public: return AABB(Vector3(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0), position.z + MIN(size.z, 0)), size.abs()); } + Variant intersects_segmentv(const Vector3 &p_from, const Vector3 &p_to) const; + Variant intersects_rayv(const Vector3 &p_from, const Vector3 &p_dir) const; + + _FORCE_INLINE_ void quantize(real_t p_unit); + _FORCE_INLINE_ AABB quantized(real_t p_unit) const; + + _FORCE_INLINE_ void set_end(const Vector3 &p_end) { + size = p_end - position; + } + + _FORCE_INLINE_ Vector3 get_end() const { + return position + size; + } + + _FORCE_INLINE_ Vector3 get_center() const { + return position + (size * 0.5f); + } + operator String() const; _FORCE_INLINE_ AABB() {} @@ -416,4 +435,28 @@ void AABB::grow_by(real_t p_amount) { size.z += 2 * p_amount; } +void AABB::quantize(real_t p_unit) { + size += position; + + position.x -= Math::fposmodp(position.x, p_unit); + position.y -= Math::fposmodp(position.y, p_unit); + position.z -= Math::fposmodp(position.z, p_unit); + + size.x -= Math::fposmodp(size.x, p_unit); + size.y -= Math::fposmodp(size.y, p_unit); + size.z -= Math::fposmodp(size.z, p_unit); + + size.x += p_unit; + size.y += p_unit; + size.z += p_unit; + + size -= position; +} + +AABB AABB::quantized(real_t p_unit) const { + AABB ret = *this; + ret.quantize(p_unit); + return ret; +} + #endif // AABB_H diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp index fd42310d9..a96cdd8d5 100644 --- a/core/math/bsp_tree.cpp +++ b/core/math/bsp_tree.cpp @@ -528,7 +528,7 @@ BSP_Tree::BSP_Tree(const PoolVector &p_faces, real_t p_error_radius) { indices.push_back(i); } - ERR_FAIL_COND(aabb.has_no_area()); + ERR_FAIL_COND(aabb.has_no_volume()); int top = _bsp_create_node(faces_r.ptr(), indices, planes, nodes, aabb.get_longest_axis_size() * 0.0001f); diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 351373148..39d45bfff 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -983,21 +983,21 @@ struct _VariantCall { r_ret = reinterpret_cast(p_self._data._ptr)->m_method(*p_args[0], *p_args[1], *p_args[2], *p_args[3], *p_args[4]); \ } - VCALL_PTR0R(AABB, abs); - VCALL_PTR0R(AABB, get_area); - VCALL_PTR0R(AABB, get_center); - VCALL_PTR0R(AABB, has_no_area); + VCALL_PTR0R(AABB, get_volume); + VCALL_PTR0R(AABB, has_no_volume); VCALL_PTR0R(AABB, has_no_surface); - VCALL_PTR1R(AABB, has_point); VCALL_PTR1R(AABB, is_equal_approx); VCALL_PTR1R(AABB, intersects); + VCALL_PTR1R(AABB, intersects_inclusive); VCALL_PTR1R(AABB, encloses); - VCALL_PTR1R(AABB, intersects_plane); - VCALL_PTR2R(AABB, intersects_segment); - VCALL_PTR1R(AABB, intersection); VCALL_PTR1R(AABB, merge); - VCALL_PTR1R(AABB, expand); - VCALL_PTR1R(AABB, grow); + VCALL_PTR1(AABB, merge_with); + VCALL_PTR1R(AABB, intersection); + VCALL_PTR2R(AABB, intersects_segment); + VCALL_PTR2R(AABB, intersects_ray); + VCALL_PTR4R(AABB, smits_intersect_ray); + VCALL_PTR1R(AABB, intersects_plane); + VCALL_PTR1R(AABB, has_point); VCALL_PTR1R(AABB, get_support); VCALL_PTR0R(AABB, get_longest_axis); VCALL_PTR0R(AABB, get_longest_axis_index); @@ -1005,7 +1005,21 @@ struct _VariantCall { VCALL_PTR0R(AABB, get_shortest_axis); VCALL_PTR0R(AABB, get_shortest_axis_index); VCALL_PTR0R(AABB, get_shortest_axis_size); + VCALL_PTR1R(AABB, grow); + VCALL_PTR1(AABB, grow_by); VCALL_PTR1R(AABB, get_endpoint); + VCALL_PTR1R(AABB, expand); + VCALL_PTR1(AABB, expand_to); + VCALL_PTR1(AABB, create_from_points); + VCALL_PTR0R(AABB, abs); + VCALL_PTR2R(AABB, intersects_segmentv); + VCALL_PTR2R(AABB, intersects_rayv); + VCALL_PTR1(AABB, quantize); + VCALL_PTR1R(AABB, quantized); + //Property + //VCALL_PTR1(AABB, set_end); + //VCALL_PTR0R(AABB, get_end); + VCALL_PTR0R(AABB, get_center); VCALL_PTR0R(Transform2D, inverse); VCALL_PTR0R(Transform2D, affine_inverse); @@ -2475,22 +2489,21 @@ void register_variant_methods() { ADDFUNC0(POOL_COLOR_ARRAY, NIL, PoolColorArray, sort, varray()); //pointerbased - - ADDFUNC0R(AABB, AABB, AABB, abs, varray()); - ADDFUNC0R(AABB, REAL, AABB, get_area, varray()); - ADDFUNC0R(AABB, VECTOR3, AABB, get_center, varray()); - ADDFUNC0R(AABB, BOOL, AABB, has_no_area, varray()); + ADDFUNC0R(AABB, REAL, AABB, get_volume, varray()); + ADDFUNC0R(AABB, BOOL, AABB, has_no_volume, varray()); ADDFUNC0R(AABB, BOOL, AABB, has_no_surface, varray()); - ADDFUNC1R(AABB, BOOL, AABB, has_point, VECTOR3, "point", varray()); ADDFUNC1R(AABB, BOOL, AABB, is_equal_approx, AABB, "aabb", varray()); ADDFUNC1R(AABB, BOOL, AABB, intersects, AABB, "with", varray()); + ADDFUNC1R(AABB, BOOL, AABB, intersects_inclusive, AABB, "aabb", varray()); ADDFUNC1R(AABB, BOOL, AABB, encloses, AABB, "with", varray()); - ADDFUNC1R(AABB, BOOL, AABB, intersects_plane, PLANE, "plane", varray()); - ADDFUNC2R(AABB, BOOL, AABB, intersects_segment, VECTOR3, "from", VECTOR3, "to", varray()); - ADDFUNC1R(AABB, AABB, AABB, intersection, AABB, "with", varray()); ADDFUNC1R(AABB, AABB, AABB, merge, AABB, "with", varray()); - ADDFUNC1R(AABB, AABB, AABB, expand, VECTOR3, "to_point", varray()); - ADDFUNC1R(AABB, AABB, AABB, grow, REAL, "by", varray()); + ADDFUNC1(AABB, NIL, AABB, merge_with, AABB, "with", varray()); + ADDFUNC1R(AABB, AABB, AABB, intersection, AABB, "with", varray()); + ADDFUNC2R(AABB, BOOL, AABB, intersects_segment, VECTOR3, "from", VECTOR3, "to", varray()); + ADDFUNC2R(AABB, BOOL, AABB, intersects_ray, VECTOR3, "from", VECTOR3, "dir", varray()); + ADDFUNC4R(AABB, BOOL, AABB, smits_intersect_ray, VECTOR3, "from", VECTOR3, "dir", REAL, "t0", REAL, "t1", varray()); + ADDFUNC1R(AABB, BOOL, AABB, intersects_plane, PLANE, "plane", varray()); + ADDFUNC1R(AABB, BOOL, AABB, has_point, VECTOR3, "point", varray()); ADDFUNC1R(AABB, VECTOR3, AABB, get_support, VECTOR3, "dir", varray()); ADDFUNC0R(AABB, VECTOR3, AABB, get_longest_axis, varray()); ADDFUNC0R(AABB, INT, AABB, get_longest_axis_index, varray()); @@ -2498,7 +2511,21 @@ void register_variant_methods() { ADDFUNC0R(AABB, VECTOR3, AABB, get_shortest_axis, varray()); ADDFUNC0R(AABB, INT, AABB, get_shortest_axis_index, varray()); ADDFUNC0R(AABB, REAL, AABB, get_shortest_axis_size, varray()); + ADDFUNC1R(AABB, AABB, AABB, grow, REAL, "by", varray()); + ADDFUNC1(AABB, NIL, AABB, grow_by, REAL, "amount", varray()); ADDFUNC1R(AABB, VECTOR3, AABB, get_endpoint, INT, "idx", varray()); + ADDFUNC1R(AABB, AABB, AABB, expand, VECTOR3, "to_point", varray()); + ADDFUNC1(AABB, NIL, AABB, expand_to, VECTOR3, "vector", varray()); + ADDFUNC1R(AABB, BOOL, AABB, create_from_points, POOL_VECTOR3_ARRAY, "points", varray()); + ADDFUNC0R(AABB, AABB, AABB, abs, varray()); + ADDFUNC2R(AABB, VECTOR3, AABB, intersects_segmentv, VECTOR3, "from", VECTOR3, "to", varray()); + ADDFUNC2R(AABB, VECTOR3, AABB, intersects_rayv, VECTOR3, "from", VECTOR3, "dir", varray()); + ADDFUNC1(AABB, NIL, AABB, quantize, REAL, "unit", varray()); + ADDFUNC1R(AABB, AABB, AABB, quantized, REAL, "unit", varray()); + //Property + //ADDFUNC1(AABB, NIL, AABB, set_end, VECTOR3, "vector", varray()); + //ADDFUNC0R(AABB, VECTOR3, AABB, get_end, varray()); + ADDFUNC0R(AABB, VECTOR3, AABB, get_center, varray()); ADDFUNC0R(TRANSFORM2D, TRANSFORM2D, Transform2D, inverse, varray()); ADDFUNC0R(TRANSFORM2D, TRANSFORM2D, Transform2D, affine_inverse, varray()); diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml index 502e7b59a..ca1b74781 100644 --- a/doc/classes/AABB.xml +++ b/doc/classes/AABB.xml @@ -49,7 +49,7 @@ [/codeblock] - + Returns the volume of the [AABB]. @@ -118,7 +118,7 @@ Returns a copy of the [AABB] grown a given amount of units towards all the sides. - + Returns [code]true[/code] if the [AABB] is flat or empty. diff --git a/servers/physics/shape_sw.h b/servers/physics/shape_sw.h index a936fbc15..c48f65a43 100644 --- a/servers/physics/shape_sw.h +++ b/servers/physics/shape_sw.h @@ -75,7 +75,7 @@ public: FEATURE_CIRCLE, }; - virtual real_t get_area() const { return aabb.get_area(); } + virtual real_t get_area() const { return aabb.get_volume(); } _FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; } _FORCE_INLINE_ RID get_self() const { return self; }