summaryrefslogtreecommitdiffstats
path: root/core/math
diff options
context:
space:
mode:
Diffstat (limited to 'core/math')
-rw-r--r--core/math/aabb.cpp68
-rw-r--r--core/math/aabb.h11
-rw-r--r--core/math/delaunay_3d.h6
-rw-r--r--core/math/quick_hull.cpp2
-rw-r--r--core/math/rect2.h2
-rw-r--r--core/math/rect2i.h2
-rw-r--r--core/math/static_raycaster.h2
-rw-r--r--core/math/triangle_mesh.cpp2
-rw-r--r--core/math/vector2.cpp12
-rw-r--r--core/math/vector2.h10
-rw-r--r--core/math/vector2i.cpp12
-rw-r--r--core/math/vector2i.h10
-rw-r--r--core/math/vector3.cpp19
-rw-r--r--core/math/vector3.h11
-rw-r--r--core/math/vector3i.cpp14
-rw-r--r--core/math/vector3i.h10
-rw-r--r--core/math/vector4.cpp27
-rw-r--r--core/math/vector4.h41
-rw-r--r--core/math/vector4i.cpp16
-rw-r--r--core/math/vector4i.h10
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 */