diff options
Diffstat (limited to 'core/math')
-rw-r--r-- | core/math/aabb.cpp | 68 | ||||
-rw-r--r-- | core/math/aabb.h | 11 | ||||
-rw-r--r-- | core/math/delaunay_3d.h | 6 | ||||
-rw-r--r-- | core/math/quick_hull.cpp | 2 | ||||
-rw-r--r-- | core/math/rect2.h | 2 | ||||
-rw-r--r-- | core/math/rect2i.h | 2 | ||||
-rw-r--r-- | core/math/static_raycaster.h | 2 | ||||
-rw-r--r-- | core/math/triangle_mesh.cpp | 2 | ||||
-rw-r--r-- | core/math/vector2.cpp | 12 | ||||
-rw-r--r-- | core/math/vector2.h | 10 | ||||
-rw-r--r-- | core/math/vector2i.cpp | 12 | ||||
-rw-r--r-- | core/math/vector2i.h | 10 | ||||
-rw-r--r-- | core/math/vector3.cpp | 19 | ||||
-rw-r--r-- | core/math/vector3.h | 11 | ||||
-rw-r--r-- | core/math/vector3i.cpp | 14 | ||||
-rw-r--r-- | core/math/vector3i.h | 10 | ||||
-rw-r--r-- | core/math/vector4.cpp | 27 | ||||
-rw-r--r-- | core/math/vector4.h | 41 | ||||
-rw-r--r-- | core/math/vector4i.cpp | 16 | ||||
-rw-r--r-- | core/math/vector4i.h | 10 |
20 files changed, 235 insertions, 52 deletions
diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp index 76e9e74dea..7d1d7c5648 100644 --- a/core/math/aabb.cpp +++ b/core/math/aabb.cpp @@ -117,55 +117,75 @@ AABB AABB::intersection(const AABB &p_aabb) const { return AABB(min, max - min); } -bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip, Vector3 *r_normal) const { +// Note that this routine returns the BACKTRACKED (i.e. behind the ray origin) +// intersection point + normal if INSIDE the AABB. +// The caller can therefore decide when INSIDE whether to use the +// backtracked intersection, or use p_from as the intersection, and +// carry on progressing without e.g. reflecting against the normal. +bool AABB::find_intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, bool &r_inside, Vector3 *r_intersection_point, Vector3 *r_normal) const { #ifdef MATH_CHECKS if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) { ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size."); } #endif - Vector3 c1, c2; Vector3 end = position + size; - real_t depth_near = -1e20; - real_t depth_far = 1e20; + real_t tmin = -1e20; + real_t tmax = 1e20; int axis = 0; + // Make sure r_inside is always initialized, + // to prevent reading uninitialized data in the client code. + r_inside = false; + for (int i = 0; i < 3; i++) { if (p_dir[i] == 0) { if ((p_from[i] < position[i]) || (p_from[i] > end[i])) { return false; } } else { // ray not parallel to planes in this direction - c1[i] = (position[i] - p_from[i]) / p_dir[i]; - c2[i] = (end[i] - p_from[i]) / p_dir[i]; + real_t t1 = (position[i] - p_from[i]) / p_dir[i]; + real_t t2 = (end[i] - p_from[i]) / p_dir[i]; - if (c1[i] > c2[i]) { - SWAP(c1, c2); + if (t1 > t2) { + SWAP(t1, t2); } - if (c1[i] > depth_near) { - depth_near = c1[i]; + if (t1 >= tmin) { + tmin = t1; axis = i; } - if (c2[i] < depth_far) { - depth_far = c2[i]; + if (t2 < tmax) { + if (t2 < 0) { + return false; + } + tmax = t2; } - if ((depth_near > depth_far) || (depth_far < 0)) { + if (tmin > tmax) { return false; } } } - if (r_clip) { - *r_clip = c1; + // Did the ray start from inside the box? + // In which case the intersection returned is the point of entry + // (behind the ray start) or the calling routine can use the ray origin as intersection point. + r_inside = tmin < 0; + + if (r_intersection_point) { + *r_intersection_point = p_from + p_dir * tmin; + + // Prevent float error by making sure the point is exactly + // on the AABB border on the relevant axis. + r_intersection_point->coord[axis] = (p_dir[axis] >= 0) ? position.coord[axis] : end.coord[axis]; } if (r_normal) { *r_normal = Vector3(); - (*r_normal)[axis] = p_dir[axis] ? -1 : 1; + (*r_normal)[axis] = (p_dir[axis] >= 0) ? -1 : 1; } return true; } -bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip, Vector3 *r_normal) const { +bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_intersection_point, Vector3 *r_normal) const { #ifdef MATH_CHECKS if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) { ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size."); @@ -223,8 +243,8 @@ bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector *r_normal = normal; } - if (r_clip) { - *r_clip = p_from + rel * min; + if (r_intersection_point) { + *r_intersection_point = p_from + rel * min; } return true; @@ -410,7 +430,15 @@ Variant AABB::intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to Variant AABB::intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) const { Vector3 inters; - if (intersects_ray(p_from, p_dir, &inters)) { + bool inside = false; + + if (find_intersects_ray(p_from, p_dir, inside, &inters)) { + // When inside the intersection point may be BEHIND the ray, + // so for general use we return the ray origin. + if (inside) { + return p_from; + } + return inters; } return Variant(); diff --git a/core/math/aabb.h b/core/math/aabb.h index 48a883e64c..9a74266ff7 100644 --- a/core/math/aabb.h +++ b/core/math/aabb.h @@ -71,10 +71,15 @@ struct _NO_DISCARD_ AABB { AABB merge(const AABB &p_with) const; void merge_with(const AABB &p_aabb); ///merge with another AABB AABB intersection(const AABB &p_aabb) const; ///get box where two intersect, empty if no intersection occurs - bool intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip = nullptr, Vector3 *r_normal = nullptr) const; - bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip = nullptr, Vector3 *r_normal = nullptr) const; _FORCE_INLINE_ bool smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t p_t0, real_t p_t1) const; + bool intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_intersection_point = nullptr, Vector3 *r_normal = nullptr) const; + bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir) const { + bool inside; + return find_intersects_ray(p_from, p_dir, inside); + } + bool find_intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, bool &r_inside, Vector3 *r_intersection_point = nullptr, Vector3 *r_normal = nullptr) const; + _FORCE_INLINE_ bool intersects_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count) const; _FORCE_INLINE_ bool inside_convex_shape(const Plane *p_planes, int p_plane_count) const; bool intersects_plane(const Plane &p_plane) const; @@ -101,7 +106,7 @@ struct _NO_DISCARD_ AABB { _FORCE_INLINE_ void expand_to(const Vector3 &p_vector); /** expand to contain a point if necessary */ _FORCE_INLINE_ AABB abs() const { - return AABB(position + size.min(Vector3()), size.abs()); + return AABB(position + size.minf(0), size.abs()); } Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const; diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h index 25bd4e8d89..4f21a665de 100644 --- a/core/math/delaunay_3d.h +++ b/core/math/delaunay_3d.h @@ -278,7 +278,7 @@ public: } Vector3i grid_pos = Vector3i(points[i] * proportions * ACCEL_GRID_SIZE); - grid_pos = grid_pos.clamp(Vector3i(), Vector3i(ACCEL_GRID_SIZE - 1, ACCEL_GRID_SIZE - 1, ACCEL_GRID_SIZE - 1)); + grid_pos = grid_pos.clampi(0, ACCEL_GRID_SIZE - 1); for (List<Simplex *>::Element *E = acceleration_grid[grid_pos.x][grid_pos.y][grid_pos.z].front(); E;) { List<Simplex *>::Element *N = E->next(); //may be deleted @@ -335,8 +335,8 @@ public: Vector3 extents = Vector3(radius2, radius2, radius2); Vector3i from = Vector3i((center - extents) * proportions * ACCEL_GRID_SIZE); Vector3i to = Vector3i((center + extents) * proportions * ACCEL_GRID_SIZE); - from = from.clamp(Vector3i(), Vector3i(ACCEL_GRID_SIZE - 1, ACCEL_GRID_SIZE - 1, ACCEL_GRID_SIZE - 1)); - to = to.clamp(Vector3i(), Vector3i(ACCEL_GRID_SIZE - 1, ACCEL_GRID_SIZE - 1, ACCEL_GRID_SIZE - 1)); + from = from.clampi(0, ACCEL_GRID_SIZE - 1); + to = to.clampi(0, ACCEL_GRID_SIZE - 1); for (int32_t x = from.x; x <= to.x; x++) { for (int32_t y = from.y; y <= to.y; y++) { diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index 4483f61bc4..6a60a5925d 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -55,7 +55,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ HashSet<Vector3> valid_cache; for (int i = 0; i < p_points.size(); i++) { - Vector3 sp = p_points[i].snapped(Vector3(0.0001, 0.0001, 0.0001)); + Vector3 sp = p_points[i].snappedf(0.0001); if (valid_cache.has(sp)) { valid_points.write[i] = false; } else { diff --git a/core/math/rect2.h b/core/math/rect2.h index 7f410feb1c..b4069ae86a 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -278,7 +278,7 @@ struct _NO_DISCARD_ Rect2 { } _FORCE_INLINE_ Rect2 abs() const { - return Rect2(position + size.min(Point2()), size.abs()); + return Rect2(position + size.minf(0), size.abs()); } _FORCE_INLINE_ Rect2 round() const { diff --git a/core/math/rect2i.h b/core/math/rect2i.h index 64806414c7..a1338da0bb 100644 --- a/core/math/rect2i.h +++ b/core/math/rect2i.h @@ -213,7 +213,7 @@ struct _NO_DISCARD_ Rect2i { } _FORCE_INLINE_ Rect2i abs() const { - return Rect2i(position + size.min(Point2i()), size.abs()); + return Rect2i(position + size.mini(0), size.abs()); } _FORCE_INLINE_ void set_end(const Vector2i &p_end) { diff --git a/core/math/static_raycaster.h b/core/math/static_raycaster.h index c53868e12d..74e4b75163 100644 --- a/core/math/static_raycaster.h +++ b/core/math/static_raycaster.h @@ -49,7 +49,7 @@ protected: static StaticRaycaster *(*create_function)(); public: - // compatible with embree3 rays + // Compatible with embree4 rays. struct __aligned(16) Ray { const static unsigned int INVALID_GEOMETRY_ID = ((unsigned int)-1); // from rtcore_common.h diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 0da1b8c7ad..01b733183d 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -133,7 +133,7 @@ void TriangleMesh::create(const Vector<Vector3> &p_faces, const Vector<int32_t> for (int j = 0; j < 3; j++) { int vidx = -1; - Vector3 vs = v[j].snapped(Vector3(0.0001, 0.0001, 0.0001)); + Vector3 vs = v[j].snappedf(0.0001); HashMap<Vector3, int>::Iterator E = db.find(vs); if (E) { vidx = E->value; diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index 198fd85d20..e86b97d6a8 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -135,12 +135,24 @@ Vector2 Vector2::clamp(const Vector2 &p_min, const Vector2 &p_max) const { CLAMP(y, p_min.y, p_max.y)); } +Vector2 Vector2::clampf(real_t p_min, real_t p_max) const { + return Vector2( + CLAMP(x, p_min, p_max), + CLAMP(y, p_min, p_max)); +} + Vector2 Vector2::snapped(const Vector2 &p_step) const { return Vector2( Math::snapped(x, p_step.x), Math::snapped(y, p_step.y)); } +Vector2 Vector2::snappedf(real_t p_step) const { + return Vector2( + Math::snapped(x, p_step), + Math::snapped(y, p_step)); +} + Vector2 Vector2::limit_length(real_t p_len) const { const real_t l = length(); Vector2 v = *this; diff --git a/core/math/vector2.h b/core/math/vector2.h index 6ad003edd1..8851942cdd 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -89,10 +89,18 @@ struct _NO_DISCARD_ Vector2 { return Vector2(MIN(x, p_vector2.x), MIN(y, p_vector2.y)); } + Vector2 minf(real_t p_scalar) const { + return Vector2(MIN(x, p_scalar), MIN(y, p_scalar)); + } + Vector2 max(const Vector2 &p_vector2) const { return Vector2(MAX(x, p_vector2.x), MAX(y, p_vector2.y)); } + Vector2 maxf(real_t p_scalar) const { + return Vector2(MAX(x, p_scalar), MAX(y, p_scalar)); + } + real_t distance_to(const Vector2 &p_vector2) const; real_t distance_squared_to(const Vector2 &p_vector2) const; real_t angle_to(const Vector2 &p_vector2) const; @@ -168,7 +176,9 @@ struct _NO_DISCARD_ Vector2 { Vector2 ceil() const; Vector2 round() const; Vector2 snapped(const Vector2 &p_by) const; + Vector2 snappedf(real_t p_by) const; Vector2 clamp(const Vector2 &p_min, const Vector2 &p_max) const; + Vector2 clampf(real_t p_min, real_t p_max) const; real_t aspect() const { return width / height; } operator String() const; diff --git a/core/math/vector2i.cpp b/core/math/vector2i.cpp index ba79d439dd..790f564734 100644 --- a/core/math/vector2i.cpp +++ b/core/math/vector2i.cpp @@ -39,12 +39,24 @@ Vector2i Vector2i::clamp(const Vector2i &p_min, const Vector2i &p_max) const { CLAMP(y, p_min.y, p_max.y)); } +Vector2i Vector2i::clampi(int32_t p_min, int32_t p_max) const { + return Vector2i( + CLAMP(x, p_min, p_max), + CLAMP(y, p_min, p_max)); +} + Vector2i Vector2i::snapped(const Vector2i &p_step) const { return Vector2i( Math::snapped(x, p_step.x), Math::snapped(y, p_step.y)); } +Vector2i Vector2i::snappedi(int32_t p_step) const { + return Vector2i( + Math::snapped(x, p_step), + Math::snapped(y, p_step)); +} + int64_t Vector2i::length_squared() const { return x * (int64_t)x + y * (int64_t)y; } diff --git a/core/math/vector2i.h b/core/math/vector2i.h index aa29263a65..aca9ae8272 100644 --- a/core/math/vector2i.h +++ b/core/math/vector2i.h @@ -81,10 +81,18 @@ struct _NO_DISCARD_ Vector2i { return Vector2i(MIN(x, p_vector2i.x), MIN(y, p_vector2i.y)); } + Vector2i mini(int32_t p_scalar) const { + return Vector2i(MIN(x, p_scalar), MIN(y, p_scalar)); + } + Vector2i max(const Vector2i &p_vector2i) const { return Vector2i(MAX(x, p_vector2i.x), MAX(y, p_vector2i.y)); } + Vector2i maxi(int32_t p_scalar) const { + return Vector2i(MAX(x, p_scalar), MAX(y, p_scalar)); + } + double distance_to(const Vector2i &p_to) const { return (p_to - *this).length(); } @@ -127,7 +135,9 @@ struct _NO_DISCARD_ Vector2i { Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); } Vector2i abs() const { return Vector2i(Math::abs(x), Math::abs(y)); } Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const; + Vector2i clampi(int32_t p_min, int32_t p_max) const; Vector2i snapped(const Vector2i &p_step) const; + Vector2i snappedi(int32_t p_step) const; operator String() const; operator Vector2() const; diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index fad5f2c0fb..1e90002665 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -52,6 +52,13 @@ Vector3 Vector3::clamp(const Vector3 &p_min, const Vector3 &p_max) const { CLAMP(z, p_min.z, p_max.z)); } +Vector3 Vector3::clampf(real_t p_min, real_t p_max) const { + return Vector3( + CLAMP(x, p_min, p_max), + CLAMP(y, p_min, p_max), + CLAMP(z, p_min, p_max)); +} + void Vector3::snap(const Vector3 &p_step) { x = Math::snapped(x, p_step.x); y = Math::snapped(y, p_step.y); @@ -64,6 +71,18 @@ Vector3 Vector3::snapped(const Vector3 &p_step) const { return v; } +void Vector3::snapf(real_t p_step) { + x = Math::snapped(x, p_step); + y = Math::snapped(y, p_step); + z = Math::snapped(z, p_step); +} + +Vector3 Vector3::snappedf(real_t p_step) const { + Vector3 v = *this; + v.snapf(p_step); + return v; +} + Vector3 Vector3::limit_length(real_t p_len) const { const real_t l = length(); Vector3 v = *this; diff --git a/core/math/vector3.h b/core/math/vector3.h index f5d16984d9..2313eb557a 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -80,10 +80,18 @@ struct _NO_DISCARD_ Vector3 { return Vector3(MIN(x, p_vector3.x), MIN(y, p_vector3.y), MIN(z, p_vector3.z)); } + Vector3 minf(real_t p_scalar) const { + return Vector3(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar)); + } + Vector3 max(const Vector3 &p_vector3) const { return Vector3(MAX(x, p_vector3.x), MAX(y, p_vector3.y), MAX(z, p_vector3.z)); } + Vector3 maxf(real_t p_scalar) const { + return Vector3(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar)); + } + _FORCE_INLINE_ real_t length() const; _FORCE_INLINE_ real_t length_squared() const; @@ -96,7 +104,9 @@ struct _NO_DISCARD_ Vector3 { _FORCE_INLINE_ void zero(); void snap(const Vector3 &p_step); + void snapf(real_t p_step); Vector3 snapped(const Vector3 &p_step) const; + Vector3 snappedf(real_t p_step) const; void rotate(const Vector3 &p_axis, real_t p_angle); Vector3 rotated(const Vector3 &p_axis, real_t p_angle) const; @@ -127,6 +137,7 @@ struct _NO_DISCARD_ Vector3 { _FORCE_INLINE_ Vector3 ceil() const; _FORCE_INLINE_ Vector3 round() const; Vector3 clamp(const Vector3 &p_min, const Vector3 &p_max) const; + Vector3 clampf(real_t p_min, real_t p_max) const; _FORCE_INLINE_ real_t distance_to(const Vector3 &p_to) const; _FORCE_INLINE_ real_t distance_squared_to(const Vector3 &p_to) const; diff --git a/core/math/vector3i.cpp b/core/math/vector3i.cpp index f41460e623..93f9d15ac1 100644 --- a/core/math/vector3i.cpp +++ b/core/math/vector3i.cpp @@ -48,6 +48,13 @@ Vector3i Vector3i::clamp(const Vector3i &p_min, const Vector3i &p_max) const { CLAMP(z, p_min.z, p_max.z)); } +Vector3i Vector3i::clampi(int32_t p_min, int32_t p_max) const { + return Vector3i( + CLAMP(x, p_min, p_max), + CLAMP(y, p_min, p_max), + CLAMP(z, p_min, p_max)); +} + Vector3i Vector3i::snapped(const Vector3i &p_step) const { return Vector3i( Math::snapped(x, p_step.x), @@ -55,6 +62,13 @@ Vector3i Vector3i::snapped(const Vector3i &p_step) const { Math::snapped(z, p_step.z)); } +Vector3i Vector3i::snappedi(int32_t p_step) const { + return Vector3i( + Math::snapped(x, p_step), + Math::snapped(y, p_step), + Math::snapped(z, p_step)); +} + Vector3i::operator String() const { return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ")"; } diff --git a/core/math/vector3i.h b/core/math/vector3i.h index a9f298bff1..035cfcf9e2 100644 --- a/core/math/vector3i.h +++ b/core/math/vector3i.h @@ -73,10 +73,18 @@ struct _NO_DISCARD_ Vector3i { return Vector3i(MIN(x, p_vector3i.x), MIN(y, p_vector3i.y), MIN(z, p_vector3i.z)); } + Vector3i mini(int32_t p_scalar) const { + return Vector3i(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar)); + } + Vector3i max(const Vector3i &p_vector3i) const { return Vector3i(MAX(x, p_vector3i.x), MAX(y, p_vector3i.y), MAX(z, p_vector3i.z)); } + Vector3i maxi(int32_t p_scalar) const { + return Vector3i(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar)); + } + _FORCE_INLINE_ int64_t length_squared() const; _FORCE_INLINE_ double length() const; @@ -85,7 +93,9 @@ struct _NO_DISCARD_ Vector3i { _FORCE_INLINE_ Vector3i abs() const; _FORCE_INLINE_ Vector3i sign() const; Vector3i clamp(const Vector3i &p_min, const Vector3i &p_max) const; + Vector3i clampi(int32_t p_min, int32_t p_max) const; Vector3i snapped(const Vector3i &p_step) const; + Vector3i snappedi(int32_t p_step) const; _FORCE_INLINE_ double distance_to(const Vector3i &p_to) const; _FORCE_INLINE_ int64_t distance_squared_to(const Vector3i &p_to) const; diff --git a/core/math/vector4.cpp b/core/math/vector4.cpp index e6f6dee42c..b6b914f36d 100644 --- a/core/math/vector4.cpp +++ b/core/math/vector4.cpp @@ -30,6 +30,8 @@ #include "vector4.h" +#include "core/math/math_funcs.h" +#include "core/math/vector4i.h" #include "core/string/ustring.h" Vector4::Axis Vector4::min_axis_index() const { @@ -171,12 +173,25 @@ void Vector4::snap(const Vector4 &p_step) { w = Math::snapped(w, p_step.w); } +void Vector4::snapf(real_t p_step) { + x = Math::snapped(x, p_step); + y = Math::snapped(y, p_step); + z = Math::snapped(z, p_step); + w = Math::snapped(w, p_step); +} + Vector4 Vector4::snapped(const Vector4 &p_step) const { Vector4 v = *this; v.snap(p_step); return v; } +Vector4 Vector4::snappedf(real_t p_step) const { + Vector4 v = *this; + v.snapf(p_step); + return v; +} + Vector4 Vector4::inverse() const { return Vector4(1.0f / x, 1.0f / y, 1.0f / z, 1.0f / w); } @@ -189,8 +204,20 @@ Vector4 Vector4::clamp(const Vector4 &p_min, const Vector4 &p_max) const { CLAMP(w, p_min.w, p_max.w)); } +Vector4 Vector4::clampf(real_t p_min, real_t p_max) const { + return Vector4( + CLAMP(x, p_min, p_max), + CLAMP(y, p_min, p_max), + CLAMP(z, p_min, p_max), + CLAMP(w, p_min, p_max)); +} + Vector4::operator String() const { return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ", " + String::num_real(w, false) + ")"; } static_assert(sizeof(Vector4) == 4 * sizeof(real_t)); + +Vector4::operator Vector4i() const { + return Vector4i(x, y, z, w); +} diff --git a/core/math/vector4.h b/core/math/vector4.h index 4dba3126cb..f69b4752bb 100644 --- a/core/math/vector4.h +++ b/core/math/vector4.h @@ -32,9 +32,11 @@ #define VECTOR4_H #include "core/error/error_macros.h" -#include "core/math/math_funcs.h" +#include "core/math/math_defs.h" +#include "core/typedefs.h" class String; +struct Vector4i; struct _NO_DISCARD_ Vector4 { static const int AXIS_COUNT = 4; @@ -72,10 +74,18 @@ struct _NO_DISCARD_ Vector4 { return Vector4(MIN(x, p_vector4.x), MIN(y, p_vector4.y), MIN(z, p_vector4.z), MIN(w, p_vector4.w)); } + Vector4 minf(real_t p_scalar) const { + return Vector4(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar), MIN(w, p_scalar)); + } + Vector4 max(const Vector4 &p_vector4) const { return Vector4(MAX(x, p_vector4.x), MAX(y, p_vector4.y), MAX(z, p_vector4.z), MAX(w, p_vector4.w)); } + Vector4 maxf(real_t p_scalar) const { + return Vector4(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar), MAX(w, p_scalar)); + } + _FORCE_INLINE_ real_t length_squared() const; bool is_equal_approx(const Vector4 &p_vec4) const; bool is_zero_approx() const; @@ -101,8 +111,11 @@ struct _NO_DISCARD_ Vector4 { Vector4 posmod(real_t p_mod) const; Vector4 posmodv(const Vector4 &p_modv) const; void snap(const Vector4 &p_step); + void snapf(real_t p_step); Vector4 snapped(const Vector4 &p_step) const; + Vector4 snappedf(real_t p_step) const; Vector4 clamp(const Vector4 &p_min, const Vector4 &p_max) const; + Vector4 clampf(real_t p_min, real_t p_max) const; Vector4 inverse() const; _FORCE_INLINE_ real_t dot(const Vector4 &p_vec4) const; @@ -129,28 +142,14 @@ struct _NO_DISCARD_ Vector4 { _FORCE_INLINE_ bool operator<=(const Vector4 &p_vec4) const; operator String() const; + operator Vector4i() const; _FORCE_INLINE_ Vector4() {} - - _FORCE_INLINE_ Vector4(real_t p_x, real_t p_y, real_t p_z, real_t p_w) : - x(p_x), - y(p_y), - z(p_z), - w(p_w) { - } - - Vector4(const Vector4 &p_vec4) : - x(p_vec4.x), - y(p_vec4.y), - z(p_vec4.z), - w(p_vec4.w) { - } - - void operator=(const Vector4 &p_vec4) { - x = p_vec4.x; - y = p_vec4.y; - z = p_vec4.z; - w = p_vec4.w; + _FORCE_INLINE_ Vector4(real_t p_x, real_t p_y, real_t p_z, real_t p_w) { + x = p_x; + y = p_y; + z = p_z; + w = p_w; } }; diff --git a/core/math/vector4i.cpp b/core/math/vector4i.cpp index 8e36c6b534..afa77a4988 100644 --- a/core/math/vector4i.cpp +++ b/core/math/vector4i.cpp @@ -65,6 +65,14 @@ Vector4i Vector4i::clamp(const Vector4i &p_min, const Vector4i &p_max) const { CLAMP(w, p_min.w, p_max.w)); } +Vector4i Vector4i::clampi(int32_t p_min, int32_t p_max) const { + return Vector4i( + CLAMP(x, p_min, p_max), + CLAMP(y, p_min, p_max), + CLAMP(z, p_min, p_max), + CLAMP(w, p_min, p_max)); +} + Vector4i Vector4i::snapped(const Vector4i &p_step) const { return Vector4i( Math::snapped(x, p_step.x), @@ -73,6 +81,14 @@ Vector4i Vector4i::snapped(const Vector4i &p_step) const { Math::snapped(w, p_step.w)); } +Vector4i Vector4i::snappedi(int32_t p_step) const { + return Vector4i( + Math::snapped(x, p_step), + Math::snapped(y, p_step), + Math::snapped(z, p_step), + Math::snapped(w, p_step)); +} + Vector4i::operator String() const { return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ", " + itos(w) + ")"; } diff --git a/core/math/vector4i.h b/core/math/vector4i.h index 5a96d98d18..8a9c580bc1 100644 --- a/core/math/vector4i.h +++ b/core/math/vector4i.h @@ -75,10 +75,18 @@ struct _NO_DISCARD_ Vector4i { return Vector4i(MIN(x, p_vector4i.x), MIN(y, p_vector4i.y), MIN(z, p_vector4i.z), MIN(w, p_vector4i.w)); } + Vector4i mini(int32_t p_scalar) const { + return Vector4i(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar), MIN(w, p_scalar)); + } + Vector4i max(const Vector4i &p_vector4i) const { return Vector4i(MAX(x, p_vector4i.x), MAX(y, p_vector4i.y), MAX(z, p_vector4i.z), MAX(w, p_vector4i.w)); } + Vector4i maxi(int32_t p_scalar) const { + return Vector4i(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar), MAX(w, p_scalar)); + } + _FORCE_INLINE_ int64_t length_squared() const; _FORCE_INLINE_ double length() const; @@ -90,7 +98,9 @@ struct _NO_DISCARD_ Vector4i { _FORCE_INLINE_ Vector4i abs() const; _FORCE_INLINE_ Vector4i sign() const; Vector4i clamp(const Vector4i &p_min, const Vector4i &p_max) const; + Vector4i clampi(int32_t p_min, int32_t p_max) const; Vector4i snapped(const Vector4i &p_step) const; + Vector4i snappedi(int32_t p_step) const; /* Operators */ |