Backported improvements to AABB from Godot 4. Also made sure all eligible methods are bound.

This commit is contained in:
Relintai 2022-08-13 18:21:54 +02:00
parent 6523457c0f
commit c991043c95
6 changed files with 116 additions and 29 deletions

View File

@ -30,9 +30,10 @@
#include "aabb.h" #include "aabb.h"
#include "core/variant.h"
#include "core/print_string.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; 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 { AABB::operator String() const {
return String() + position + " - " + size; return String() + position + " - " + size;
} }

View File

@ -39,13 +39,15 @@
* This is implemented by a point (position) and the box size * This is implemented by a point (position) and the box size
*/ */
class Variant;
class _NO_DISCARD_CLASS_ AABB { class _NO_DISCARD_CLASS_ AABB {
public: public:
Vector3 position; Vector3 position;
Vector3 size; Vector3 size;
real_t get_area() const; /// get area real_t get_volume() const; /// get area
_FORCE_INLINE_ bool has_no_area() const { _FORCE_INLINE_ bool has_no_volume() const {
return (size.x <= 0 || size.y <= 0 || size.z <= 0); 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; } void set_position(const Vector3 &p_pos) { position = p_pos; }
const Vector3 &get_size() const { return size; } const Vector3 &get_size() const { return size; }
void set_size(const Vector3 &p_size) { size = p_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;
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()); 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; operator String() const;
_FORCE_INLINE_ AABB() {} _FORCE_INLINE_ AABB() {}
@ -416,4 +435,28 @@ void AABB::grow_by(real_t p_amount) {
size.z += 2 * 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 #endif // AABB_H

View File

@ -528,7 +528,7 @@ BSP_Tree::BSP_Tree(const PoolVector<Face3> &p_faces, real_t p_error_radius) {
indices.push_back(i); 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); int top = _bsp_create_node(faces_r.ptr(), indices, planes, nodes, aabb.get_longest_axis_size() * 0.0001f);

View File

@ -983,21 +983,21 @@ struct _VariantCall {
r_ret = reinterpret_cast<m_type *>(p_self._data._ptr)->m_method(*p_args[0], *p_args[1], *p_args[2], *p_args[3], *p_args[4]); \ r_ret = reinterpret_cast<m_type *>(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_volume);
VCALL_PTR0R(AABB, get_area); VCALL_PTR0R(AABB, has_no_volume);
VCALL_PTR0R(AABB, get_center);
VCALL_PTR0R(AABB, has_no_area);
VCALL_PTR0R(AABB, has_no_surface); VCALL_PTR0R(AABB, has_no_surface);
VCALL_PTR1R(AABB, has_point);
VCALL_PTR1R(AABB, is_equal_approx); VCALL_PTR1R(AABB, is_equal_approx);
VCALL_PTR1R(AABB, intersects); VCALL_PTR1R(AABB, intersects);
VCALL_PTR1R(AABB, intersects_inclusive);
VCALL_PTR1R(AABB, encloses); 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, merge);
VCALL_PTR1R(AABB, expand); VCALL_PTR1(AABB, merge_with);
VCALL_PTR1R(AABB, grow); 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_PTR1R(AABB, get_support);
VCALL_PTR0R(AABB, get_longest_axis); VCALL_PTR0R(AABB, get_longest_axis);
VCALL_PTR0R(AABB, get_longest_axis_index); 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);
VCALL_PTR0R(AABB, get_shortest_axis_index); VCALL_PTR0R(AABB, get_shortest_axis_index);
VCALL_PTR0R(AABB, get_shortest_axis_size); VCALL_PTR0R(AABB, get_shortest_axis_size);
VCALL_PTR1R(AABB, grow);
VCALL_PTR1(AABB, grow_by);
VCALL_PTR1R(AABB, get_endpoint); 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, inverse);
VCALL_PTR0R(Transform2D, affine_inverse); VCALL_PTR0R(Transform2D, affine_inverse);
@ -2475,22 +2489,21 @@ void register_variant_methods() {
ADDFUNC0(POOL_COLOR_ARRAY, NIL, PoolColorArray, sort, varray()); ADDFUNC0(POOL_COLOR_ARRAY, NIL, PoolColorArray, sort, varray());
//pointerbased //pointerbased
ADDFUNC0R(AABB, REAL, AABB, get_volume, varray());
ADDFUNC0R(AABB, AABB, AABB, abs, varray()); ADDFUNC0R(AABB, BOOL, AABB, has_no_volume, 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, BOOL, AABB, has_no_surface, 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, is_equal_approx, AABB, "aabb", varray());
ADDFUNC1R(AABB, BOOL, AABB, intersects, AABB, "with", 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, 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, merge, AABB, "with", varray());
ADDFUNC1R(AABB, AABB, AABB, expand, VECTOR3, "to_point", varray()); ADDFUNC1(AABB, NIL, AABB, merge_with, AABB, "with", varray());
ADDFUNC1R(AABB, AABB, AABB, grow, REAL, "by", 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()); ADDFUNC1R(AABB, VECTOR3, AABB, get_support, VECTOR3, "dir", varray());
ADDFUNC0R(AABB, VECTOR3, AABB, get_longest_axis, varray()); ADDFUNC0R(AABB, VECTOR3, AABB, get_longest_axis, varray());
ADDFUNC0R(AABB, INT, AABB, get_longest_axis_index, 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, VECTOR3, AABB, get_shortest_axis, varray());
ADDFUNC0R(AABB, INT, AABB, get_shortest_axis_index, varray()); ADDFUNC0R(AABB, INT, AABB, get_shortest_axis_index, varray());
ADDFUNC0R(AABB, REAL, AABB, get_shortest_axis_size, 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, 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, inverse, varray());
ADDFUNC0R(TRANSFORM2D, TRANSFORM2D, Transform2D, affine_inverse, varray()); ADDFUNC0R(TRANSFORM2D, TRANSFORM2D, Transform2D, affine_inverse, varray());

View File

@ -49,7 +49,7 @@
[/codeblock] [/codeblock]
</description> </description>
</method> </method>
<method name="get_area"> <method name="get_volume">
<return type="float" /> <return type="float" />
<description> <description>
Returns the volume of the [AABB]. 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 a copy of the [AABB] grown a given amount of units towards all the sides.
</description> </description>
</method> </method>
<method name="has_no_area"> <method name="has_no_volume">
<return type="bool" /> <return type="bool" />
<description> <description>
Returns [code]true[/code] if the [AABB] is flat or empty. Returns [code]true[/code] if the [AABB] is flat or empty.

View File

@ -75,7 +75,7 @@ public:
FEATURE_CIRCLE, 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_ void set_self(const RID &p_self) { self = p_self; }
_FORCE_INLINE_ RID get_self() const { return self; } _FORCE_INLINE_ RID get_self() const { return self; }