mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-11-22 00:48:09 +01:00
Backported some improvements to Rect2 from Godot4. Also bound all eligible methods.
This commit is contained in:
parent
7650103ce7
commit
899ac5cbd8
@ -118,6 +118,11 @@ void register_global_constants() {
|
||||
BIND_GLOBAL_ENUM_CONSTANT(MARGIN_RIGHT);
|
||||
BIND_GLOBAL_ENUM_CONSTANT(MARGIN_BOTTOM);
|
||||
|
||||
BIND_GLOBAL_ENUM_CONSTANT(SIDE_LEFT);
|
||||
BIND_GLOBAL_ENUM_CONSTANT(SIDE_TOP);
|
||||
BIND_GLOBAL_ENUM_CONSTANT(SIDE_RIGHT);
|
||||
BIND_GLOBAL_ENUM_CONSTANT(SIDE_BOTTOM);
|
||||
|
||||
BIND_GLOBAL_ENUM_CONSTANT(CORNER_TOP_LEFT);
|
||||
BIND_GLOBAL_ENUM_CONSTANT(CORNER_TOP_RIGHT);
|
||||
BIND_GLOBAL_ENUM_CONSTANT(CORNER_BOTTOM_RIGHT);
|
||||
|
@ -92,6 +92,13 @@ enum Margin {
|
||||
MARGIN_BOTTOM
|
||||
};
|
||||
|
||||
enum Side {
|
||||
SIDE_LEFT,
|
||||
SIDE_TOP,
|
||||
SIDE_RIGHT,
|
||||
SIDE_BOTTOM
|
||||
};
|
||||
|
||||
enum Corner {
|
||||
|
||||
CORNER_TOP_LEFT,
|
||||
|
@ -30,6 +30,8 @@
|
||||
|
||||
#include "core/math/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D
|
||||
|
||||
#include "core/math/rect2i.h"
|
||||
|
||||
bool Rect2::is_equal_approx(const Rect2 &p_rect) const {
|
||||
return position.is_equal_approx(p_rect.position) && size.is_equal_approx(p_rect.size);
|
||||
}
|
||||
@ -263,3 +265,7 @@ next4:
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Rect2::operator String() const {
|
||||
return "[P: " + position.operator String() + ", S: " + size + "]";
|
||||
}
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "core/math/vector2i.h"
|
||||
|
||||
struct Transform2D;
|
||||
struct Rect2i;
|
||||
|
||||
struct _NO_DISCARD_CLASS_ Rect2 {
|
||||
Point2 position;
|
||||
@ -146,6 +147,25 @@ struct _NO_DISCARD_CLASS_ Rect2 {
|
||||
return new_rect;
|
||||
}
|
||||
|
||||
inline Rect2 intersection(const Rect2 &p_rect) const {
|
||||
Rect2 new_rect = p_rect;
|
||||
|
||||
if (!intersects(new_rect)) {
|
||||
return Rect2();
|
||||
}
|
||||
|
||||
new_rect.position.x = MAX(p_rect.position.x, position.x);
|
||||
new_rect.position.y = MAX(p_rect.position.y, position.y);
|
||||
|
||||
Point2 p_rect_end = p_rect.position + p_rect.size;
|
||||
Point2 end = position + size;
|
||||
|
||||
new_rect.size.x = MIN(p_rect_end.x, end.x) - new_rect.position.x;
|
||||
new_rect.size.y = MIN(p_rect_end.y, end.y) - new_rect.position.y;
|
||||
|
||||
return new_rect;
|
||||
}
|
||||
|
||||
inline Rect2 merge(const Rect2 &p_rect) const { ///< return a merged rect
|
||||
|
||||
Rect2 new_rect;
|
||||
@ -204,6 +224,15 @@ struct _NO_DISCARD_CLASS_ Rect2 {
|
||||
return g;
|
||||
}
|
||||
|
||||
inline Rect2 grow_side(Side p_side, real_t p_amount) const {
|
||||
Rect2 g = *this;
|
||||
g = g.grow_individual((SIDE_LEFT == p_side) ? p_amount : 0,
|
||||
(SIDE_TOP == p_side) ? p_amount : 0,
|
||||
(SIDE_RIGHT == p_side) ? p_amount : 0,
|
||||
(SIDE_BOTTOM == p_side) ? p_amount : 0);
|
||||
return g;
|
||||
}
|
||||
|
||||
inline Rect2 grow_individual(real_t p_left, real_t p_top, real_t p_right, real_t p_bottom) const {
|
||||
Rect2 g = *this;
|
||||
g.position.x -= p_left;
|
||||
@ -247,7 +276,78 @@ struct _NO_DISCARD_CLASS_ Rect2 {
|
||||
return Rect2(Point2(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs());
|
||||
}
|
||||
|
||||
operator String() const { return String(position) + ", " + String(size); }
|
||||
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;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool intersects_filled_polygon(const Vector2 *p_points, int p_point_count) const {
|
||||
Vector2 center = get_center();
|
||||
int side_plus = 0;
|
||||
int side_minus = 0;
|
||||
Vector2 end = position + size;
|
||||
|
||||
int i_f = p_point_count - 1;
|
||||
for (int i = 0; i < p_point_count; i++) {
|
||||
const Vector2 &a = p_points[i_f];
|
||||
const Vector2 &b = p_points[i];
|
||||
i_f = i;
|
||||
|
||||
Vector2 r = (b - a);
|
||||
float l = r.length();
|
||||
if (l == 0.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//check inside
|
||||
Vector2 tg = r.orthogonal();
|
||||
float s = tg.dot(center) - tg.dot(a);
|
||||
if (s < 0.0f) {
|
||||
side_plus++;
|
||||
} else {
|
||||
side_minus++;
|
||||
}
|
||||
|
||||
//check ray box
|
||||
r /= l;
|
||||
Vector2 ir(1.0f / r.x, 1.0f / r.y);
|
||||
|
||||
// lb is the corner of AABB with minimal coordinates - left bottom, rt is maximal corner
|
||||
// r.org is origin of ray
|
||||
Vector2 t13 = (position - a) * ir;
|
||||
Vector2 t24 = (end - a) * ir;
|
||||
|
||||
float tmin = MAX(MIN(t13.x, t24.x), MIN(t13.y, t24.y));
|
||||
float tmax = MIN(MAX(t13.x, t24.x), MAX(t13.y, t24.y));
|
||||
|
||||
// if tmax < 0, ray (line) is intersecting AABB, but the whole AABB is behind us
|
||||
if (tmax < 0 || tmin > tmax || tmin >= l) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (side_plus * side_minus == 0) {
|
||||
return true; //all inside
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void set_end(const Vector2 &p_end) {
|
||||
size = p_end - position;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Vector2 get_end() const {
|
||||
return position + size;
|
||||
}
|
||||
|
||||
operator String() const;
|
||||
|
||||
Rect2() {}
|
||||
Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height) :
|
||||
@ -260,5 +360,4 @@ struct _NO_DISCARD_CLASS_ Rect2 {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // RECT2_H
|
||||
|
@ -164,6 +164,9 @@ struct _NO_DISCARD_CLASS_ Vector2 {
|
||||
Vector2 snapped(const Vector2 &p_by) const;
|
||||
real_t aspect() const { return width / height; }
|
||||
|
||||
//TODO
|
||||
Vector2 orthogonal() { return Vector2(); }
|
||||
|
||||
operator String() const { return String::num(x) + ", " + String::num(y); }
|
||||
|
||||
_FORCE_INLINE_ Vector2(real_t p_x, real_t p_y) {
|
||||
|
@ -171,6 +171,7 @@ VARIANT_ENUM_CAST(Vector2i::Axis);
|
||||
|
||||
VARIANT_ENUM_CAST(Error);
|
||||
VARIANT_ENUM_CAST(Margin);
|
||||
VARIANT_ENUM_CAST(Side);
|
||||
VARIANT_ENUM_CAST(Corner);
|
||||
VARIANT_ENUM_CAST(Orientation);
|
||||
VARIANT_ENUM_CAST(HAlign);
|
||||
|
@ -2362,6 +2362,9 @@ Variant::operator Vector<Color>() const {
|
||||
Variant::operator Margin() const {
|
||||
return (Margin) operator int();
|
||||
}
|
||||
Variant::operator Side() const {
|
||||
return (Side) operator int();
|
||||
}
|
||||
Variant::operator Orientation() const {
|
||||
return (Orientation) operator int();
|
||||
}
|
||||
|
@ -264,6 +264,7 @@ public:
|
||||
|
||||
// some core type enums to convert to
|
||||
operator Margin() const;
|
||||
operator Side() const;
|
||||
operator Orientation() const;
|
||||
|
||||
operator IP_Address() const;
|
||||
|
@ -457,18 +457,39 @@ struct _VariantCall {
|
||||
|
||||
VCALL_LOCALMEM0R(Rect2, get_area);
|
||||
VCALL_LOCALMEM0R(Rect2, get_center);
|
||||
VCALL_LOCALMEM2R(Rect2, intersects);
|
||||
VCALL_LOCALMEM1R(Rect2, distance_to);
|
||||
VCALL_LOCALMEM2R(Rect2, intersects_transformed);
|
||||
static void _call_Rect2_intersects_segment(Variant &r_ret, Variant &p_self, const Variant **p_args) {
|
||||
Point2 pos;
|
||||
Point2 normal;
|
||||
if (reinterpret_cast<Rect2 *>(p_self._data._mem)->intersects_segment(*p_args[0], *p_args[1], &pos, &normal)) {
|
||||
Array arr;
|
||||
arr.push_back(pos);
|
||||
arr.push_back(normal);
|
||||
r_ret = arr;
|
||||
} else {
|
||||
r_ret = Variant();
|
||||
}
|
||||
}
|
||||
VCALL_LOCALMEM1R(Rect2, encloses);
|
||||
VCALL_LOCALMEM0R(Rect2, has_no_area);
|
||||
VCALL_LOCALMEM1R(Rect2, clip);
|
||||
VCALL_LOCALMEM1R(Rect2, intersection);
|
||||
VCALL_LOCALMEM1R(Rect2, merge);
|
||||
VCALL_LOCALMEM1R(Rect2, has_point);
|
||||
VCALL_LOCALMEM1R(Rect2, is_equal_approx);
|
||||
VCALL_LOCALMEM2R(Rect2, intersects);
|
||||
VCALL_LOCALMEM1R(Rect2, encloses);
|
||||
VCALL_LOCALMEM1R(Rect2, clip);
|
||||
VCALL_LOCALMEM1R(Rect2, merge);
|
||||
VCALL_LOCALMEM1R(Rect2, expand);
|
||||
VCALL_LOCALMEM1R(Rect2, grow);
|
||||
VCALL_LOCALMEM1(Rect2, grow_by);
|
||||
VCALL_LOCALMEM2R(Rect2, grow_margin);
|
||||
VCALL_LOCALMEM2R(Rect2, grow_side);
|
||||
VCALL_LOCALMEM4R(Rect2, grow_individual);
|
||||
VCALL_LOCALMEM1R(Rect2, expand);
|
||||
VCALL_LOCALMEM1(Rect2, expand_to);
|
||||
VCALL_LOCALMEM0R(Rect2, abs);
|
||||
VCALL_LOCALMEM1R(Rect2, get_support);
|
||||
VCALL_LOCALMEM1(Rect2, set_end);
|
||||
VCALL_LOCALMEM0R(Rect2, get_end);
|
||||
|
||||
VCALL_LOCALMEM0R(Rect2i, get_area);
|
||||
VCALL_LOCALMEM0R(Rect2i, get_center);
|
||||
@ -2172,18 +2193,28 @@ void register_variant_methods() {
|
||||
|
||||
ADDFUNC0R(RECT2, REAL, Rect2, get_area, varray());
|
||||
ADDFUNC0R(RECT2, VECTOR2, Rect2, get_center, varray());
|
||||
ADDFUNC2R(RECT2, BOOL, Rect2, intersects, RECT2, "b", BOOL, "include_borders", varray(false));
|
||||
ADDFUNC1R(RECT2, REAL, Rect2, distance_to, VECTOR2, "point", varray());
|
||||
ADDFUNC2R(RECT2, BOOL, Rect2, intersects_transformed, TRANSFORM2D, "xform", RECT2, "rect", varray());
|
||||
ADDFUNC2R(RECT2, NIL, Rect2, intersects_segment, VECTOR2, "from", VECTOR2, "to", varray());
|
||||
ADDFUNC1R(RECT2, BOOL, Rect2, encloses, RECT2, "b", varray());
|
||||
ADDFUNC0R(RECT2, BOOL, Rect2, has_no_area, varray());
|
||||
ADDFUNC1R(RECT2, RECT2, Rect2, clip, RECT2, "b", varray());
|
||||
ADDFUNC1R(RECT2, RECT2, Rect2, intersection, RECT2, "rect", varray());
|
||||
ADDFUNC1R(RECT2, RECT2, Rect2, merge, RECT2, "b", varray());
|
||||
ADDFUNC1R(RECT2, BOOL, Rect2, has_point, VECTOR2, "point", varray());
|
||||
ADDFUNC1R(RECT2, BOOL, Rect2, is_equal_approx, RECT2, "rect", varray());
|
||||
ADDFUNC2R(RECT2, BOOL, Rect2, intersects, RECT2, "b", BOOL, "include_borders", varray(false));
|
||||
ADDFUNC1R(RECT2, BOOL, Rect2, encloses, RECT2, "b", varray());
|
||||
ADDFUNC1R(RECT2, RECT2, Rect2, clip, RECT2, "b", varray());
|
||||
ADDFUNC1R(RECT2, RECT2, Rect2, merge, RECT2, "b", varray());
|
||||
ADDFUNC1R(RECT2, RECT2, Rect2, expand, VECTOR2, "to", varray());
|
||||
ADDFUNC1R(RECT2, RECT2, Rect2, grow, REAL, "by", varray());
|
||||
ADDFUNC1(RECT2, NIL, Rect2, grow_by, REAL, "by", varray());
|
||||
ADDFUNC2R(RECT2, RECT2, Rect2, grow_margin, INT, "margin", REAL, "by", varray());
|
||||
ADDFUNC2R(RECT2, RECT2, Rect2, grow_side, INT, "side", REAL, "by", varray());
|
||||
ADDFUNC4R(RECT2, RECT2, Rect2, grow_individual, REAL, "left", REAL, "top", REAL, "right", REAL, " bottom", varray());
|
||||
ADDFUNC1R(RECT2, RECT2, Rect2, expand, VECTOR2, "to", varray());
|
||||
ADDFUNC1R(RECT2, RECT2, Rect2, expand_to, VECTOR2, "to", varray());
|
||||
ADDFUNC0R(RECT2, RECT2, Rect2, abs, varray());
|
||||
ADDFUNC1R(RECT2, VECTOR2, Rect2, get_support, VECTOR2, "normal", varray());
|
||||
ADDFUNC1(RECT2, NIL, Rect2, set_end, VECTOR2, "end", varray());
|
||||
ADDFUNC0R(RECT2, VECTOR2, Rect2, get_end, varray());
|
||||
|
||||
ADDFUNC0R(RECT2I, INT, Rect2i, get_area, varray());
|
||||
ADDFUNC0R(RECT2I, VECTOR2I, Rect2i, get_center, varray());
|
||||
@ -2280,7 +2311,6 @@ void register_variant_methods() {
|
||||
ADDFUNC0R(COLOR, INT, Color, to_argb64, varray());
|
||||
ADDFUNC0R(COLOR, INT, Color, to_abgr64, varray());
|
||||
ADDFUNC0R(COLOR, REAL, Color, gray, varray());
|
||||
|
||||
ADDFUNC0R(COLOR, REAL, Color, get_h, varray());
|
||||
ADDFUNC0R(COLOR, REAL, Color, get_s, varray());
|
||||
ADDFUNC0R(COLOR, REAL, Color, get_v, varray());
|
||||
|
Loading…
Reference in New Issue
Block a user