feat: modules moved and engine moved to submodule

This commit is contained in:
Jan van der Weide 2025-04-12 18:40:44 +02:00
parent dfb5e645cd
commit c33d2130cc
5136 changed files with 225275 additions and 64485 deletions

View file

@ -302,12 +302,7 @@ Vector3 AStar3D::get_closest_position_in_segment(const Vector3 &p_point) const {
continue;
}
Vector3 segment[2] = {
from_point->pos,
to_point->pos,
};
Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, segment);
Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, from_point->pos, to_point->pos);
real_t d = p_point.distance_squared_to(p);
if (d < closest_dist) {
closest_point = p;

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef A_STAR_H
#define A_STAR_H
#pragma once
#include "core/object/gdvirtual.gen.inc"
#include "core/object/ref_counted.h"
@ -222,5 +221,3 @@ public:
AStar2D() {}
~AStar2D() {}
};
#endif // A_STAR_H

View file

@ -34,27 +34,27 @@
#include "core/variant/typed_array.h"
static real_t heuristic_euclidean(const Vector2i &p_from, const Vector2i &p_to) {
real_t dx = (real_t)ABS(p_to.x - p_from.x);
real_t dy = (real_t)ABS(p_to.y - p_from.y);
real_t dx = (real_t)Math::abs(p_to.x - p_from.x);
real_t dy = (real_t)Math::abs(p_to.y - p_from.y);
return (real_t)Math::sqrt(dx * dx + dy * dy);
}
static real_t heuristic_manhattan(const Vector2i &p_from, const Vector2i &p_to) {
real_t dx = (real_t)ABS(p_to.x - p_from.x);
real_t dy = (real_t)ABS(p_to.y - p_from.y);
real_t dx = (real_t)Math::abs(p_to.x - p_from.x);
real_t dy = (real_t)Math::abs(p_to.y - p_from.y);
return dx + dy;
}
static real_t heuristic_octile(const Vector2i &p_from, const Vector2i &p_to) {
real_t dx = (real_t)ABS(p_to.x - p_from.x);
real_t dy = (real_t)ABS(p_to.y - p_from.y);
real_t F = Math_SQRT2 - 1;
real_t dx = (real_t)Math::abs(p_to.x - p_from.x);
real_t dy = (real_t)Math::abs(p_to.y - p_from.y);
real_t F = Math::SQRT2 - 1;
return (dx < dy) ? F * dx + dy : F * dy + dx;
}
static real_t heuristic_chebyshev(const Vector2i &p_from, const Vector2i &p_to) {
real_t dx = (real_t)ABS(p_to.x - p_from.x);
real_t dy = (real_t)ABS(p_to.y - p_from.y);
real_t dx = (real_t)Math::abs(p_to.x - p_from.x);
real_t dy = (real_t)Math::abs(p_to.y - p_from.y);
return MAX(dx, dy);
}
@ -503,6 +503,7 @@ bool AStarGrid2D::_solve(Point *p_begin_point, Point *p_end_point, bool p_allow_
LocalVector<Point *> open_list;
SortArray<Point *, SortPoints> sorter;
LocalVector<Point *> nbors;
p_begin_point->g_score = 0;
p_begin_point->f_score = _estimate_cost(p_begin_point->id, p_end_point->id);
@ -528,7 +529,7 @@ bool AStarGrid2D::_solve(Point *p_begin_point, Point *p_end_point, bool p_allow_
open_list.remove_at(open_list.size() - 1);
p->closed_pass = pass; // Mark the point as closed.
LocalVector<Point *> nbors;
nbors.clear();
_get_nbors(p, nbors);
for (Point *e : nbors) {

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef A_STAR_GRID_2D_H
#define A_STAR_GRID_2D_H
#pragma once
#include "core/object/gdvirtual.gen.inc"
#include "core/object/ref_counted.h"
@ -230,5 +229,3 @@ public:
VARIANT_ENUM_CAST(AStarGrid2D::DiagonalMode);
VARIANT_ENUM_CAST(AStarGrid2D::Heuristic);
VARIANT_ENUM_CAST(AStarGrid2D::CellShape)
#endif // A_STAR_GRID_2D_H

View file

@ -37,14 +37,6 @@ real_t AABB::get_volume() const {
return size.x * size.y * size.z;
}
bool AABB::operator==(const AABB &p_rval) const {
return ((position == p_rval.position) && (size == p_rval.size));
}
bool AABB::operator!=(const AABB &p_rval) const {
return ((position != p_rval.position) || (size != p_rval.size));
}
void AABB::merge_with(const AABB &p_aabb) {
#ifdef MATH_CHECKS
if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
@ -76,6 +68,10 @@ bool AABB::is_equal_approx(const AABB &p_aabb) const {
return position.is_equal_approx(p_aabb.position) && size.is_equal_approx(p_aabb.size);
}
bool AABB::is_same(const AABB &p_aabb) const {
return position.is_same(p_aabb.position) && size.is_same(p_aabb.size);
}
bool AABB::is_finite() const {
return position.is_finite() && size.is_finite();
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef AABB_H
#define AABB_H
#pragma once
#include "core/math/plane.h"
#include "core/math/vector3.h"
@ -59,10 +58,15 @@ struct [[nodiscard]] AABB {
const Vector3 &get_size() const { return size; }
void set_size(const Vector3 &p_size) { size = p_size; }
bool operator==(const AABB &p_rval) const;
bool operator!=(const AABB &p_rval) const;
constexpr bool operator==(const AABB &p_rval) const {
return position == p_rval.position && size == p_rval.size;
}
constexpr bool operator!=(const AABB &p_rval) const {
return position != p_rval.position || size != p_rval.size;
}
bool is_equal_approx(const AABB &p_aabb) const;
bool is_same(const AABB &p_aabb) const;
bool is_finite() const;
_FORCE_INLINE_ bool intersects(const AABB &p_aabb) const; /// Both AABBs overlap
_FORCE_INLINE_ bool intersects_inclusive(const AABB &p_aabb) const; /// Both AABBs (or their faces) overlap
@ -129,8 +133,8 @@ struct [[nodiscard]] AABB {
operator String() const;
_FORCE_INLINE_ AABB() {}
inline AABB(const Vector3 &p_pos, const Vector3 &p_size) :
AABB() = default;
constexpr AABB(const Vector3 &p_pos, const Vector3 &p_size) :
position(p_pos),
size(p_size) {
}
@ -496,4 +500,5 @@ AABB AABB::quantized(real_t p_unit) const {
return ret;
}
#endif // AABB_H
template <>
struct is_zero_constructible<AABB> : std::true_type {};

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef AUDIO_FRAME_H
#define AUDIO_FRAME_H
#pragma once
#include "core/math/vector2.h"
#include "core/typedefs.h"
@ -53,6 +52,7 @@ static const float AUDIO_MIN_PEAK_DB = -200.0f; // linear_to_db(AUDIO_PEAK_OFFSE
struct AudioFrame {
// Left and right samples.
union {
// NOLINTBEGIN(modernize-use-default-member-init)
struct {
float left;
float right;
@ -64,6 +64,7 @@ struct AudioFrame {
};
#endif
float levels[2] = { 0.0 };
// NOLINTEND(modernize-use-default-member-init)
};
_ALWAYS_INLINE_ const float &operator[](int p_idx) const {
@ -75,46 +76,46 @@ struct AudioFrame {
return levels[p_idx];
}
_ALWAYS_INLINE_ AudioFrame operator+(const AudioFrame &p_frame) const { return AudioFrame(left + p_frame.left, right + p_frame.right); }
_ALWAYS_INLINE_ AudioFrame operator-(const AudioFrame &p_frame) const { return AudioFrame(left - p_frame.left, right - p_frame.right); }
_ALWAYS_INLINE_ AudioFrame operator*(const AudioFrame &p_frame) const { return AudioFrame(left * p_frame.left, right * p_frame.right); }
_ALWAYS_INLINE_ AudioFrame operator/(const AudioFrame &p_frame) const { return AudioFrame(left / p_frame.left, right / p_frame.right); }
constexpr AudioFrame operator+(const AudioFrame &p_frame) const { return AudioFrame(left + p_frame.left, right + p_frame.right); }
constexpr AudioFrame operator-(const AudioFrame &p_frame) const { return AudioFrame(left - p_frame.left, right - p_frame.right); }
constexpr AudioFrame operator*(const AudioFrame &p_frame) const { return AudioFrame(left * p_frame.left, right * p_frame.right); }
constexpr AudioFrame operator/(const AudioFrame &p_frame) const { return AudioFrame(left / p_frame.left, right / p_frame.right); }
_ALWAYS_INLINE_ AudioFrame operator+(float p_sample) const { return AudioFrame(left + p_sample, right + p_sample); }
_ALWAYS_INLINE_ AudioFrame operator-(float p_sample) const { return AudioFrame(left - p_sample, right - p_sample); }
_ALWAYS_INLINE_ AudioFrame operator*(float p_sample) const { return AudioFrame(left * p_sample, right * p_sample); }
_ALWAYS_INLINE_ AudioFrame operator/(float p_sample) const { return AudioFrame(left / p_sample, right / p_sample); }
constexpr AudioFrame operator+(float p_sample) const { return AudioFrame(left + p_sample, right + p_sample); }
constexpr AudioFrame operator-(float p_sample) const { return AudioFrame(left - p_sample, right - p_sample); }
constexpr AudioFrame operator*(float p_sample) const { return AudioFrame(left * p_sample, right * p_sample); }
constexpr AudioFrame operator/(float p_sample) const { return AudioFrame(left / p_sample, right / p_sample); }
_ALWAYS_INLINE_ void operator+=(const AudioFrame &p_frame) {
constexpr void operator+=(const AudioFrame &p_frame) {
left += p_frame.left;
right += p_frame.right;
}
_ALWAYS_INLINE_ void operator-=(const AudioFrame &p_frame) {
constexpr void operator-=(const AudioFrame &p_frame) {
left -= p_frame.left;
right -= p_frame.right;
}
_ALWAYS_INLINE_ void operator*=(const AudioFrame &p_frame) {
constexpr void operator*=(const AudioFrame &p_frame) {
left *= p_frame.left;
right *= p_frame.right;
}
_ALWAYS_INLINE_ void operator/=(const AudioFrame &p_frame) {
constexpr void operator/=(const AudioFrame &p_frame) {
left /= p_frame.left;
right /= p_frame.right;
}
_ALWAYS_INLINE_ void operator+=(float p_sample) {
constexpr void operator+=(float p_sample) {
left += p_sample;
right += p_sample;
}
_ALWAYS_INLINE_ void operator-=(float p_sample) {
constexpr void operator-=(float p_sample) {
left -= p_sample;
right -= p_sample;
}
_ALWAYS_INLINE_ void operator*=(float p_sample) {
constexpr void operator*=(float p_sample) {
left *= p_sample;
right *= p_sample;
}
_ALWAYS_INLINE_ void operator/=(float p_sample) {
constexpr void operator/=(float p_sample) {
left /= p_sample;
right /= p_sample;
}
@ -133,41 +134,41 @@ struct AudioFrame {
return res;
}
_ALWAYS_INLINE_ AudioFrame(float p_left, float p_right) {
left = p_left;
right = p_right;
}
_ALWAYS_INLINE_ AudioFrame(const AudioFrame &p_frame) {
// NOLINTBEGIN(cppcoreguidelines-pro-type-member-init)
constexpr AudioFrame(float p_left, float p_right) :
left(p_left), right(p_right) {}
constexpr AudioFrame(const AudioFrame &p_frame) :
left(p_frame.left), right(p_frame.right) {}
// NOLINTEND(cppcoreguidelines-pro-type-member-init)
constexpr void operator=(const AudioFrame &p_frame) {
left = p_frame.left;
right = p_frame.right;
}
_ALWAYS_INLINE_ void operator=(const AudioFrame &p_frame) {
left = p_frame.left;
right = p_frame.right;
}
_ALWAYS_INLINE_ operator Vector2() const {
constexpr operator Vector2() const {
return Vector2(left, right);
}
_ALWAYS_INLINE_ AudioFrame(const Vector2 &p_v2) {
left = p_v2.x;
right = p_v2.y;
}
_ALWAYS_INLINE_ AudioFrame() {}
// NOLINTBEGIN(cppcoreguidelines-pro-type-member-init)
constexpr AudioFrame(const Vector2 &p_v2) :
left(p_v2.x), right(p_v2.y) {}
constexpr AudioFrame() :
left(0), right(0) {}
// NOLINTEND(cppcoreguidelines-pro-type-member-init)
};
_ALWAYS_INLINE_ AudioFrame operator*(float p_scalar, const AudioFrame &p_frame) {
constexpr AudioFrame operator*(float p_scalar, const AudioFrame &p_frame) {
return AudioFrame(p_frame.left * p_scalar, p_frame.right * p_scalar);
}
_ALWAYS_INLINE_ AudioFrame operator*(int32_t p_scalar, const AudioFrame &p_frame) {
constexpr AudioFrame operator*(int32_t p_scalar, const AudioFrame &p_frame) {
return AudioFrame(p_frame.left * p_scalar, p_frame.right * p_scalar);
}
_ALWAYS_INLINE_ AudioFrame operator*(int64_t p_scalar, const AudioFrame &p_frame) {
constexpr AudioFrame operator*(int64_t p_scalar, const AudioFrame &p_frame) {
return AudioFrame(p_frame.left * p_scalar, p_frame.right * p_scalar);
}
#endif // AUDIO_FRAME_H
template <>
struct is_zero_constructible<AudioFrame> : std::true_type {};

View file

@ -186,7 +186,7 @@ Basis Basis::diagonalize() {
// Compute the rotation angle
real_t angle;
if (Math::is_equal_approx(rows[j][j], rows[i][i])) {
angle = Math_PI / 4;
angle = Math::PI / 4;
} else {
angle = 0.5f * Math::atan(2 * rows[i][j] / (rows[j][j] - rows[i][i]));
}
@ -486,12 +486,12 @@ Vector3 Basis::get_euler(EulerOrder p_order) const {
}
} else {
euler.x = Math::atan2(rows[2][1], rows[1][1]);
euler.y = -Math_PI / 2.0f;
euler.y = -Math::PI / 2.0f;
euler.z = 0.0f;
}
} else {
euler.x = Math::atan2(rows[2][1], rows[1][1]);
euler.y = Math_PI / 2.0f;
euler.y = Math::PI / 2.0f;
euler.z = 0.0f;
}
return euler;
@ -515,13 +515,13 @@ Vector3 Basis::get_euler(EulerOrder p_order) const {
// It's -1
euler.x = -Math::atan2(rows[1][2], rows[2][2]);
euler.y = 0.0f;
euler.z = Math_PI / 2.0f;
euler.z = Math::PI / 2.0f;
}
} else {
// It's 1
euler.x = -Math::atan2(rows[1][2], rows[2][2]);
euler.y = 0.0f;
euler.z = -Math_PI / 2.0f;
euler.z = -Math::PI / 2.0f;
}
return euler;
}
@ -551,12 +551,12 @@ Vector3 Basis::get_euler(EulerOrder p_order) const {
euler.z = atan2(rows[1][0], rows[1][1]);
}
} else { // m12 == -1
euler.x = Math_PI * 0.5f;
euler.x = Math::PI * 0.5f;
euler.y = atan2(rows[0][1], rows[0][0]);
euler.z = 0;
}
} else { // m12 == 1
euler.x = -Math_PI * 0.5f;
euler.x = -Math::PI * 0.5f;
euler.y = -atan2(rows[0][1], rows[0][0]);
euler.z = 0;
}
@ -582,13 +582,13 @@ Vector3 Basis::get_euler(EulerOrder p_order) const {
// It's -1
euler.x = Math::atan2(rows[2][1], rows[2][2]);
euler.y = 0.0f;
euler.z = -Math_PI / 2.0f;
euler.z = -Math::PI / 2.0f;
}
} else {
// It's 1
euler.x = Math::atan2(rows[2][1], rows[2][2]);
euler.y = 0.0f;
euler.z = Math_PI / 2.0f;
euler.z = Math::PI / 2.0f;
}
return euler;
} break;
@ -608,13 +608,13 @@ Vector3 Basis::get_euler(EulerOrder p_order) const {
euler.z = Math::atan2(-rows[0][1], rows[1][1]);
} else {
// It's -1
euler.x = -Math_PI / 2.0f;
euler.x = -Math::PI / 2.0f;
euler.y = Math::atan2(rows[0][2], rows[0][0]);
euler.z = 0;
}
} else {
// It's 1
euler.x = Math_PI / 2.0f;
euler.x = Math::PI / 2.0f;
euler.y = Math::atan2(rows[0][2], rows[0][0]);
euler.z = 0;
}
@ -637,13 +637,13 @@ Vector3 Basis::get_euler(EulerOrder p_order) const {
} else {
// It's -1
euler.x = 0;
euler.y = Math_PI / 2.0f;
euler.y = Math::PI / 2.0f;
euler.z = -Math::atan2(rows[0][1], rows[1][1]);
}
} else {
// It's 1
euler.x = 0;
euler.y = -Math_PI / 2.0f;
euler.y = -Math::PI / 2.0f;
euler.z = -Math::atan2(rows[0][1], rows[1][1]);
}
return euler;
@ -699,26 +699,14 @@ bool Basis::is_equal_approx(const Basis &p_basis) const {
return rows[0].is_equal_approx(p_basis.rows[0]) && rows[1].is_equal_approx(p_basis.rows[1]) && rows[2].is_equal_approx(p_basis.rows[2]);
}
bool Basis::is_same(const Basis &p_basis) const {
return rows[0].is_same(p_basis.rows[0]) && rows[1].is_same(p_basis.rows[1]) && rows[2].is_same(p_basis.rows[2]);
}
bool Basis::is_finite() const {
return rows[0].is_finite() && rows[1].is_finite() && rows[2].is_finite();
}
bool Basis::operator==(const Basis &p_matrix) const {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (rows[i][j] != p_matrix.rows[i][j]) {
return false;
}
}
}
return true;
}
bool Basis::operator!=(const Basis &p_matrix) const {
return (!(*this == p_matrix));
}
Basis::operator String() const {
return "[X: " + get_column(0).operator String() +
", Y: " + get_column(1).operator String() +
@ -790,8 +778,8 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
if ((xx > yy) && (xx > zz)) { // rows[0][0] is the largest diagonal term.
if (xx < CMP_EPSILON) {
x = 0;
y = Math_SQRT12;
z = Math_SQRT12;
y = Math::SQRT12;
z = Math::SQRT12;
} else {
x = Math::sqrt(xx);
y = xy / x;
@ -799,9 +787,9 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
}
} else if (yy > zz) { // rows[1][1] is the largest diagonal term.
if (yy < CMP_EPSILON) {
x = Math_SQRT12;
x = Math::SQRT12;
y = 0;
z = Math_SQRT12;
z = Math::SQRT12;
} else {
y = Math::sqrt(yy);
x = xy / y;
@ -809,8 +797,8 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
}
} else { // rows[2][2] is the largest diagonal term so base result on this.
if (zz < CMP_EPSILON) {
x = Math_SQRT12;
y = Math_SQRT12;
x = Math::SQRT12;
y = Math::SQRT12;
z = 0;
} else {
z = Math::sqrt(zz);
@ -819,7 +807,7 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
}
}
r_axis = Vector3(x, y, z);
r_angle = Math_PI;
r_angle = Math::PI;
return;
}
// As we have reached here there are no singularities so we can handle normally.

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef BASIS_H
#define BASIS_H
#pragma once
#include "core/math/quaternion.h"
#include "core/math/vector3.h"
@ -41,10 +40,10 @@ struct [[nodiscard]] Basis {
Vector3(0, 0, 1)
};
_FORCE_INLINE_ const Vector3 &operator[](int p_row) const {
constexpr const Vector3 &operator[](int p_row) const {
return rows[p_row];
}
_FORCE_INLINE_ Vector3 &operator[](int p_row) {
constexpr Vector3 &operator[](int p_row) {
return rows[p_row];
}
@ -121,23 +120,24 @@ struct [[nodiscard]] Basis {
}
bool is_equal_approx(const Basis &p_basis) const;
bool is_same(const Basis &p_basis) const;
bool is_finite() const;
bool operator==(const Basis &p_matrix) const;
bool operator!=(const Basis &p_matrix) const;
constexpr bool operator==(const Basis &p_matrix) const;
constexpr bool operator!=(const Basis &p_matrix) const;
_FORCE_INLINE_ Vector3 xform(const Vector3 &p_vector) const;
_FORCE_INLINE_ Vector3 xform_inv(const Vector3 &p_vector) const;
_FORCE_INLINE_ void operator*=(const Basis &p_matrix);
_FORCE_INLINE_ Basis operator*(const Basis &p_matrix) const;
_FORCE_INLINE_ void operator+=(const Basis &p_matrix);
_FORCE_INLINE_ Basis operator+(const Basis &p_matrix) const;
_FORCE_INLINE_ void operator-=(const Basis &p_matrix);
_FORCE_INLINE_ Basis operator-(const Basis &p_matrix) const;
_FORCE_INLINE_ void operator*=(real_t p_val);
_FORCE_INLINE_ Basis operator*(real_t p_val) const;
_FORCE_INLINE_ void operator/=(real_t p_val);
_FORCE_INLINE_ Basis operator/(real_t p_val) const;
constexpr void operator+=(const Basis &p_matrix);
constexpr Basis operator+(const Basis &p_matrix) const;
constexpr void operator-=(const Basis &p_matrix);
constexpr Basis operator-(const Basis &p_matrix) const;
constexpr void operator*=(real_t p_val);
constexpr Basis operator*(real_t p_val) const;
constexpr void operator/=(real_t p_val);
constexpr Basis operator/(real_t p_val) const;
bool is_orthogonal() const;
bool is_orthonormal() const;
@ -204,9 +204,12 @@ struct [[nodiscard]] Basis {
rows[0].z * p_m[0].y + rows[1].z * p_m[1].y + rows[2].z * p_m[2].y,
rows[0].z * p_m[0].z + rows[1].z * p_m[1].z + rows[2].z * p_m[2].z);
}
Basis(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz) {
set(p_xx, p_xy, p_xz, p_yx, p_yy, p_yz, p_zx, p_zy, p_zz);
}
constexpr Basis(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz) :
rows{
{ p_xx, p_xy, p_xz },
{ p_yx, p_yy, p_yz },
{ p_zx, p_zy, p_zz },
} {}
void orthonormalize();
Basis orthonormalized() const;
@ -230,17 +233,36 @@ struct [[nodiscard]] Basis {
Basis(const Vector3 &p_axis, real_t p_angle, const Vector3 &p_scale) { set_axis_angle_scale(p_axis, p_angle, p_scale); }
static Basis from_scale(const Vector3 &p_scale);
_FORCE_INLINE_ Basis(const Vector3 &p_x_axis, const Vector3 &p_y_axis, const Vector3 &p_z_axis) {
set_columns(p_x_axis, p_y_axis, p_z_axis);
}
constexpr Basis(const Vector3 &p_x_axis, const Vector3 &p_y_axis, const Vector3 &p_z_axis) :
rows{
{ p_x_axis.x, p_y_axis.x, p_z_axis.x },
{ p_x_axis.y, p_y_axis.y, p_z_axis.y },
{ p_x_axis.z, p_y_axis.z, p_z_axis.z },
} {}
_FORCE_INLINE_ Basis() {}
Basis() = default;
private:
// Helper method.
void _set_diagonal(const Vector3 &p_diag);
};
constexpr bool Basis::operator==(const Basis &p_matrix) const {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (rows[i][j] != p_matrix.rows[i][j]) {
return false;
}
}
}
return true;
}
constexpr bool Basis::operator!=(const Basis &p_matrix) const {
return (!(*this == p_matrix));
}
_FORCE_INLINE_ void Basis::operator*=(const Basis &p_matrix) {
set(
p_matrix.tdotx(rows[0]), p_matrix.tdoty(rows[0]), p_matrix.tdotz(rows[0]),
@ -255,49 +277,49 @@ _FORCE_INLINE_ Basis Basis::operator*(const Basis &p_matrix) const {
p_matrix.tdotx(rows[2]), p_matrix.tdoty(rows[2]), p_matrix.tdotz(rows[2]));
}
_FORCE_INLINE_ void Basis::operator+=(const Basis &p_matrix) {
constexpr void Basis::operator+=(const Basis &p_matrix) {
rows[0] += p_matrix.rows[0];
rows[1] += p_matrix.rows[1];
rows[2] += p_matrix.rows[2];
}
_FORCE_INLINE_ Basis Basis::operator+(const Basis &p_matrix) const {
constexpr Basis Basis::operator+(const Basis &p_matrix) const {
Basis ret(*this);
ret += p_matrix;
return ret;
}
_FORCE_INLINE_ void Basis::operator-=(const Basis &p_matrix) {
constexpr void Basis::operator-=(const Basis &p_matrix) {
rows[0] -= p_matrix.rows[0];
rows[1] -= p_matrix.rows[1];
rows[2] -= p_matrix.rows[2];
}
_FORCE_INLINE_ Basis Basis::operator-(const Basis &p_matrix) const {
constexpr Basis Basis::operator-(const Basis &p_matrix) const {
Basis ret(*this);
ret -= p_matrix;
return ret;
}
_FORCE_INLINE_ void Basis::operator*=(real_t p_val) {
constexpr void Basis::operator*=(real_t p_val) {
rows[0] *= p_val;
rows[1] *= p_val;
rows[2] *= p_val;
}
_FORCE_INLINE_ Basis Basis::operator*(real_t p_val) const {
constexpr Basis Basis::operator*(real_t p_val) const {
Basis ret(*this);
ret *= p_val;
return ret;
}
_FORCE_INLINE_ void Basis::operator/=(real_t p_val) {
constexpr void Basis::operator/=(real_t p_val) {
rows[0] /= p_val;
rows[1] /= p_val;
rows[2] /= p_val;
}
_FORCE_INLINE_ Basis Basis::operator/(real_t p_val) const {
constexpr Basis Basis::operator/(real_t p_val) const {
Basis ret(*this);
ret /= p_val;
return ret;
@ -322,5 +344,3 @@ real_t Basis::determinant() const {
rows[1][0] * (rows[0][1] * rows[2][2] - rows[2][1] * rows[0][2]) +
rows[2][0] * (rows[0][1] * rows[1][2] - rows[1][1] * rows[0][2]);
}
#endif // BASIS_H

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef BVH_H
#define BVH_H
#pragma once
// BVH
// This class provides a wrapper around BVH tree, which contains most of the functionality
@ -52,6 +51,8 @@
// and pairable_mask is either 0 if static, or set to all if non static
#include "bvh_tree.h"
#include "core/math/geometry_3d.h"
#include "core/os/mutex.h"
#define BVHTREE_CLASS BVH_Tree<T, NUM_TREES, 2, MAX_ITEMS, USER_PAIR_TEST_FUNCTION, USER_CULL_TEST_FUNCTION, USE_PAIRS, BOUNDS, POINT>
@ -405,7 +406,7 @@ public:
}
Vector<Vector3> convex_points = Geometry3D::compute_convex_mesh_points(&p_convex[0], p_convex.size());
if (convex_points.size() == 0) {
if (convex_points.is_empty()) {
return 0;
}
@ -435,8 +436,6 @@ private:
return;
}
BOUNDS bb;
typename BVHTREE_CLASS::CullParams params;
params.result_count_overall = 0;
@ -806,5 +805,3 @@ public:
};
#undef BVHTREE_CLASS
#endif // BVH_H

View file

@ -28,8 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef BVH_ABB_H
#define BVH_ABB_H
#pragma once
#include "core/math/aabb.h"
// special optimized version of axis aligned bounding box
template <typename BOUNDS = AABB, typename POINT = Vector3>
@ -288,5 +289,3 @@ struct BVH_ABB {
return false;
}
};
#endif // BVH_ABB_H

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef BVH_TREE_H
#define BVH_TREE_H
#pragma once
// BVH Tree
// This is an implementation of a dynamic BVH with templated leaf size.
@ -41,7 +40,6 @@
#include "core/math/aabb.h"
#include "core/math/bvh_abb.h"
#include "core/math/geometry_3d.h"
#include "core/math/vector3.h"
#include "core/templates/local_vector.h"
#include "core/templates/pooled_list.h"
@ -454,5 +452,3 @@ private:
};
#undef VERBOSE_PRINT
#endif // BVH_TREE_H

View file

@ -109,36 +109,27 @@ uint64_t Color::to_rgba64() const {
return c;
}
String _to_hex(float p_val) {
void _append_hex(float p_val, char32_t *string) {
int v = Math::round(p_val * 255.0f);
v = CLAMP(v, 0, 255);
String ret;
for (int i = 0; i < 2; i++) {
char32_t c[2] = { 0, 0 };
int lv = v & 0xF;
if (lv < 10) {
c[0] = '0' + lv;
} else {
c[0] = 'a' + lv - 10;
}
v >>= 4;
String cs = (const char32_t *)c;
ret = cs + ret;
}
return ret;
string[0] = hex_char_table_lower[(v >> 4) & 0xF];
string[1] = hex_char_table_lower[v & 0xF];
}
String Color::to_html(bool p_alpha) const {
String txt;
txt += _to_hex(r);
txt += _to_hex(g);
txt += _to_hex(b);
txt.resize(p_alpha ? 9 : 7);
char32_t *ptr = txt.ptrw();
_append_hex(r, ptr + 0);
_append_hex(g, ptr + 2);
_append_hex(b, ptr + 4);
if (p_alpha) {
txt += _to_hex(a);
_append_hex(a, ptr + 6);
}
ptr[txt.size() - 1] = '\0';
return txt;
}
@ -259,6 +250,10 @@ bool Color::is_equal_approx(const Color &p_color) const {
return Math::is_equal_approx(r, p_color.r) && Math::is_equal_approx(g, p_color.g) && Math::is_equal_approx(b, p_color.b) && Math::is_equal_approx(a, p_color.a);
}
bool Color::is_same(const Color &p_color) const {
return Math::is_same(r, p_color.r) && Math::is_same(g, p_color.g) && Math::is_same(b, p_color.b) && Math::is_same(a, p_color.a);
}
Color Color::clamp(const Color &p_min, const Color &p_max) const {
return Color(
CLAMP(r, p_min.r, p_max.r),
@ -321,47 +316,38 @@ Color Color::inverted() const {
}
Color Color::html(const String &p_rgba) {
String color = p_rgba;
if (color.length() == 0) {
if (p_rgba.is_empty()) {
return Color();
}
if (color[0] == '#') {
color = color.substr(1);
}
// If enabled, use 1 hex digit per channel instead of 2.
// Other sizes aren't in the HTML/CSS spec but we could add them if desired.
bool is_shorthand = color.length() < 5;
bool alpha = false;
const int current_pos = (p_rgba[0] == '#') ? 1 : 0;
const int num_of_digits = p_rgba.length() - current_pos;
if (color.length() == 8) {
alpha = true;
} else if (color.length() == 6) {
alpha = false;
} else if (color.length() == 4) {
alpha = true;
} else if (color.length() == 3) {
alpha = false;
float r, g, b, a = 1.0f;
if (num_of_digits == 3) {
// #rgb
r = _parse_col4(p_rgba, current_pos) / 15.0f;
g = _parse_col4(p_rgba, current_pos + 1) / 15.0f;
b = _parse_col4(p_rgba, current_pos + 2) / 15.0f;
} else if (num_of_digits == 4) {
r = _parse_col4(p_rgba, current_pos) / 15.0f;
g = _parse_col4(p_rgba, current_pos + 1) / 15.0f;
b = _parse_col4(p_rgba, current_pos + 2) / 15.0f;
a = _parse_col4(p_rgba, current_pos + 3) / 15.0f;
} else if (num_of_digits == 6) {
r = _parse_col8(p_rgba, current_pos) / 255.0f;
g = _parse_col8(p_rgba, current_pos + 2) / 255.0f;
b = _parse_col8(p_rgba, current_pos + 4) / 255.0f;
} else if (num_of_digits == 8) {
r = _parse_col8(p_rgba, current_pos) / 255.0f;
g = _parse_col8(p_rgba, current_pos + 2) / 255.0f;
b = _parse_col8(p_rgba, current_pos + 4) / 255.0f;
a = _parse_col8(p_rgba, current_pos + 6) / 255.0f;
} else {
ERR_FAIL_V_MSG(Color(), "Invalid color code: " + p_rgba + ".");
}
float r, g, b, a = 1.0f;
if (is_shorthand) {
r = _parse_col4(color, 0) / 15.0f;
g = _parse_col4(color, 1) / 15.0f;
b = _parse_col4(color, 2) / 15.0f;
if (alpha) {
a = _parse_col4(color, 3) / 15.0f;
}
} else {
r = _parse_col8(color, 0) / 255.0f;
g = _parse_col8(color, 2) / 255.0f;
b = _parse_col8(color, 4) / 255.0f;
if (alpha) {
a = _parse_col8(color, 6) / 255.0f;
}
}
ERR_FAIL_COND_V_MSG(r < 0.0f, Color(), "Invalid color code: " + p_rgba + ".");
ERR_FAIL_COND_V_MSG(g < 0.0f, Color(), "Invalid color code: " + p_rgba + ".");
ERR_FAIL_COND_V_MSG(b < 0.0f, Color(), "Invalid color code: " + p_rgba + ".");
@ -373,22 +359,20 @@ Color Color::html(const String &p_rgba) {
bool Color::html_is_valid(const String &p_color) {
String color = p_color;
if (color.length() == 0) {
if (color.is_empty()) {
return false;
}
if (color[0] == '#') {
color = color.substr(1);
}
// Check if the amount of hex digits is valid.
int len = color.length();
if (!(len == 3 || len == 4 || len == 6 || len == 8)) {
const int current_pos = (color[0] == '#') ? 1 : 0;
const int len = color.length();
const int num_of_digits = len - current_pos;
if (!(num_of_digits == 3 || num_of_digits == 4 || num_of_digits == 6 || num_of_digits == 8)) {
return false;
}
// Check if each hex digit is valid.
for (int i = 0; i < len; i++) {
if (_parse_col4(color, i) == -1) {
for (int i = current_pos; i < len; i++) {
if (!is_hex_digit(p_color[i])) {
return false;
}
}
@ -415,18 +399,14 @@ Color Color::named(const String &p_name, const Color &p_default) {
int Color::find_named_color(const String &p_name) {
String name = p_name;
// Normalize name.
name = name.replace(" ", "");
name = name.replace("-", "");
name = name.replace("_", "");
name = name.replace("'", "");
name = name.replace(".", "");
name = name.remove_chars(" -_'.");
name = name.to_upper();
static HashMap<String, int> named_colors_hashmap;
if (unlikely(named_colors_hashmap.is_empty())) {
const int named_color_count = get_named_color_count();
for (int i = 0; i < named_color_count; i++) {
named_colors_hashmap[String(named_colors[i].name).replace("_", "")] = i;
named_colors_hashmap[String(named_colors[i].name).remove_char('_')] = i;
}
}
@ -439,7 +419,7 @@ int Color::find_named_color(const String &p_name) {
}
int Color::get_named_color_count() {
return sizeof(named_colors) / sizeof(NamedColor);
return std::size(named_colors);
}
String Color::get_named_color_name(int p_idx) {
@ -490,104 +470,6 @@ Color::operator String() const {
return "(" + String::num(r, 4) + ", " + String::num(g, 4) + ", " + String::num(b, 4) + ", " + String::num(a, 4) + ")";
}
Color Color::operator+(const Color &p_color) const {
return Color(
r + p_color.r,
g + p_color.g,
b + p_color.b,
a + p_color.a);
}
void Color::operator+=(const Color &p_color) {
r = r + p_color.r;
g = g + p_color.g;
b = b + p_color.b;
a = a + p_color.a;
}
Color Color::operator-(const Color &p_color) const {
return Color(
r - p_color.r,
g - p_color.g,
b - p_color.b,
a - p_color.a);
}
void Color::operator-=(const Color &p_color) {
r = r - p_color.r;
g = g - p_color.g;
b = b - p_color.b;
a = a - p_color.a;
}
Color Color::operator*(const Color &p_color) const {
return Color(
r * p_color.r,
g * p_color.g,
b * p_color.b,
a * p_color.a);
}
Color Color::operator*(float p_scalar) const {
return Color(
r * p_scalar,
g * p_scalar,
b * p_scalar,
a * p_scalar);
}
void Color::operator*=(const Color &p_color) {
r = r * p_color.r;
g = g * p_color.g;
b = b * p_color.b;
a = a * p_color.a;
}
void Color::operator*=(float p_scalar) {
r = r * p_scalar;
g = g * p_scalar;
b = b * p_scalar;
a = a * p_scalar;
}
Color Color::operator/(const Color &p_color) const {
return Color(
r / p_color.r,
g / p_color.g,
b / p_color.b,
a / p_color.a);
}
Color Color::operator/(float p_scalar) const {
return Color(
r / p_scalar,
g / p_scalar,
b / p_scalar,
a / p_scalar);
}
void Color::operator/=(const Color &p_color) {
r = r / p_color.r;
g = g / p_color.g;
b = b / p_color.b;
a = a / p_color.a;
}
void Color::operator/=(float p_scalar) {
r = r / p_scalar;
g = g / p_scalar;
b = b / p_scalar;
a = a / p_scalar;
}
Color Color::operator-() const {
return Color(
1.0f - r,
1.0f - g,
1.0f - b,
1.0f - a);
}
Color Color::from_ok_hsl(float p_h, float p_s, float p_l, float p_alpha) {
Color c;
c.set_ok_hsl(p_h, p_s, p_l, p_alpha);

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef COLOR_H
#define COLOR_H
#pragma once
#include "core/math/math_funcs.h"
@ -37,6 +36,7 @@ class String;
struct [[nodiscard]] Color {
union {
// NOLINTBEGIN(modernize-use-default-member-init)
struct {
float r;
float g;
@ -44,6 +44,7 @@ struct [[nodiscard]] Color {
float a;
};
float components[4] = { 0, 0, 0, 1.0 };
// NOLINTEND(modernize-use-default-member-init)
};
uint32_t to_rgba32() const;
@ -69,31 +70,32 @@ struct [[nodiscard]] Color {
return components[p_idx];
}
bool operator==(const Color &p_color) const {
constexpr bool operator==(const Color &p_color) const {
return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a);
}
bool operator!=(const Color &p_color) const {
constexpr bool operator!=(const Color &p_color) const {
return (r != p_color.r || g != p_color.g || b != p_color.b || a != p_color.a);
}
Color operator+(const Color &p_color) const;
void operator+=(const Color &p_color);
constexpr Color operator+(const Color &p_color) const;
constexpr void operator+=(const Color &p_color);
Color operator-() const;
Color operator-(const Color &p_color) const;
void operator-=(const Color &p_color);
constexpr Color operator-() const;
constexpr Color operator-(const Color &p_color) const;
constexpr void operator-=(const Color &p_color);
Color operator*(const Color &p_color) const;
Color operator*(float p_scalar) const;
void operator*=(const Color &p_color);
void operator*=(float p_scalar);
constexpr Color operator*(const Color &p_color) const;
constexpr Color operator*(float p_scalar) const;
constexpr void operator*=(const Color &p_color);
constexpr void operator*=(float p_scalar);
Color operator/(const Color &p_color) const;
Color operator/(float p_scalar) const;
void operator/=(const Color &p_color);
void operator/=(float p_scalar);
constexpr Color operator/(const Color &p_color) const;
constexpr Color operator/(float p_scalar) const;
constexpr void operator/=(const Color &p_color);
constexpr void operator/=(float p_scalar);
bool is_equal_approx(const Color &p_color) const;
bool is_same(const Color &p_color) const;
Color clamp(const Color &p_min = Color(0, 0, 0, 0), const Color &p_max = Color(1, 1, 1, 1)) const;
void invert();
@ -215,7 +217,7 @@ struct [[nodiscard]] Color {
static Color from_rgbe9995(uint32_t p_rgbe);
static Color from_rgba8(int64_t p_r8, int64_t p_g8, int64_t p_b8, int64_t p_a8 = 255);
_FORCE_INLINE_ bool operator<(const Color &p_color) const; // Used in set keys.
constexpr bool operator<(const Color &p_color) const; // Used in set keys.
operator String() const;
// For the binder.
@ -235,39 +237,29 @@ struct [[nodiscard]] Color {
_FORCE_INLINE_ void set_ok_hsl_s(float p_s) { set_ok_hsl(get_ok_hsl_h(), p_s, get_ok_hsl_l(), a); }
_FORCE_INLINE_ void set_ok_hsl_l(float p_l) { set_ok_hsl(get_ok_hsl_h(), get_ok_hsl_s(), p_l, a); }
_FORCE_INLINE_ Color() {}
constexpr Color() :
r(0), g(0), b(0), a(1) {}
/**
* RGBA construct parameters.
* Alpha is not optional as otherwise we can't bind the RGB version for scripting.
*/
_FORCE_INLINE_ Color(float p_r, float p_g, float p_b, float p_a) {
r = p_r;
g = p_g;
b = p_b;
a = p_a;
}
constexpr Color(float p_r, float p_g, float p_b, float p_a) :
r(p_r), g(p_g), b(p_b), a(p_a) {}
/**
* RGB construct parameters.
*/
_FORCE_INLINE_ Color(float p_r, float p_g, float p_b) {
r = p_r;
g = p_g;
b = p_b;
a = 1.0f;
}
constexpr Color(float p_r, float p_g, float p_b) :
r(p_r), g(p_g), b(p_b), a(1) {}
/**
* Construct a Color from another Color, but with the specified alpha value.
*/
_FORCE_INLINE_ Color(const Color &p_c, float p_a) {
r = p_c.r;
g = p_c.g;
b = p_c.b;
a = p_a;
}
constexpr Color(const Color &p_c, float p_a) :
r(p_c.r), g(p_c.g), b(p_c.b), a(p_a) {}
// NOLINTBEGIN(cppcoreguidelines-pro-type-member-init)
Color(const String &p_code) {
if (html_is_valid(p_code)) {
*this = html(p_code);
@ -280,9 +272,108 @@ struct [[nodiscard]] Color {
*this = Color(p_code);
a = p_a;
}
// NOLINTEND(cppcoreguidelines-pro-type-member-init)
};
bool Color::operator<(const Color &p_color) const {
constexpr Color Color::operator+(const Color &p_color) const {
return Color(
r + p_color.r,
g + p_color.g,
b + p_color.b,
a + p_color.a);
}
constexpr void Color::operator+=(const Color &p_color) {
r = r + p_color.r;
g = g + p_color.g;
b = b + p_color.b;
a = a + p_color.a;
}
constexpr Color Color::operator-(const Color &p_color) const {
return Color(
r - p_color.r,
g - p_color.g,
b - p_color.b,
a - p_color.a);
}
constexpr void Color::operator-=(const Color &p_color) {
r = r - p_color.r;
g = g - p_color.g;
b = b - p_color.b;
a = a - p_color.a;
}
constexpr Color Color::operator*(const Color &p_color) const {
return Color(
r * p_color.r,
g * p_color.g,
b * p_color.b,
a * p_color.a);
}
constexpr Color Color::operator*(float p_scalar) const {
return Color(
r * p_scalar,
g * p_scalar,
b * p_scalar,
a * p_scalar);
}
constexpr void Color::operator*=(const Color &p_color) {
r = r * p_color.r;
g = g * p_color.g;
b = b * p_color.b;
a = a * p_color.a;
}
constexpr void Color::operator*=(float p_scalar) {
r = r * p_scalar;
g = g * p_scalar;
b = b * p_scalar;
a = a * p_scalar;
}
constexpr Color Color::operator/(const Color &p_color) const {
return Color(
r / p_color.r,
g / p_color.g,
b / p_color.b,
a / p_color.a);
}
constexpr Color Color::operator/(float p_scalar) const {
return Color(
r / p_scalar,
g / p_scalar,
b / p_scalar,
a / p_scalar);
}
constexpr void Color::operator/=(const Color &p_color) {
r = r / p_color.r;
g = g / p_color.g;
b = b / p_color.b;
a = a / p_color.a;
}
constexpr void Color::operator/=(float p_scalar) {
r = r / p_scalar;
g = g / p_scalar;
b = b / p_scalar;
a = a / p_scalar;
}
constexpr Color Color::operator-() const {
return Color(
1.0f - r,
1.0f - g,
1.0f - b,
1.0f - a);
}
constexpr bool Color::operator<(const Color &p_color) const {
if (r == p_color.r) {
if (g == p_color.g) {
if (b == p_color.b) {
@ -298,8 +389,6 @@ bool Color::operator<(const Color &p_color) const {
}
}
_FORCE_INLINE_ Color operator*(float p_scalar, const Color &p_color) {
constexpr Color operator*(float p_scalar, const Color &p_color) {
return p_color * p_scalar;
}
#endif // COLOR_H

View file

@ -28,12 +28,16 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#pragma once
// Names from https://en.wikipedia.org/wiki/X11_color_names
// So this in a way that does not require memory allocation
// the old way leaked memory
// this is not used as often as for more performance to make sense
#include "core/math/color.h"
struct NamedColor {
const char *name;
Color color;

View file

@ -2237,7 +2237,7 @@ real_t ConvexHullComputer::compute(const Vector3 *p_coords, int32_t p_count, rea
Error ConvexHullComputer::convex_hull(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_mesh) {
r_mesh = Geometry3D::MeshData(); // clear
if (p_points.size() == 0) {
if (p_points.is_empty()) {
return FAILED; // matches QuickHull
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef CONVEX_HULL_H
#define CONVEX_HULL_H
#pragma once
/*
Copyright (c) 2011 Ole Kniemeyer, MAXON, www.maxon.net
@ -112,5 +111,3 @@ public:
static Error convex_hull(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_mesh);
};
#endif // CONVEX_HULL_H

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef DELAUNAY_2D_H
#define DELAUNAY_2D_H
#pragma once
#include "core/math/rect2.h"
#include "core/templates/vector.h"
@ -156,5 +155,3 @@ public:
return triangles;
}
};
#endif // DELAUNAY_2D_H

View file

@ -28,17 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef DELAUNAY_3D_H
#define DELAUNAY_3D_H
#pragma once
#include "core/io/file_access.h"
#include "core/math/aabb.h"
#include "core/math/projection.h"
#include "core/math/vector3.h"
#include "core/templates/list.h"
#include "core/templates/local_vector.h"
#include "core/templates/oa_hash_map.h"
#include "core/templates/vector.h"
#include "core/variant/variant.h"
#include "thirdparty/misc/r128.h"
@ -187,7 +185,7 @@ class Delaunay3D {
Plane p(p_points[p_simplex.points[i]], p_points[p_simplex.points[(i + 1) % 4]], p_points[p_simplex.points[(i + 2) % 4]]);
// This tolerance should not be smaller than the one used with
// Plane::has_point() when creating the LightmapGI probe BSP tree.
if (ABS(p.distance_to(p_points[p_simplex.points[(i + 3) % 4]])) < 0.001) {
if (Math::abs(p.distance_to(p_points[p_simplex.points[(i + 3) % 4]])) < 0.001) {
return true;
}
}
@ -389,5 +387,3 @@ public:
return ret_simplices;
}
};
#endif // DELAUNAY_3D_H

View file

@ -28,10 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef DISJOINT_SET_H
#define DISJOINT_SET_H
#pragma once
#include "core/templates/rb_map.h"
#include "core/templates/hash_map.h"
#include "core/templates/vector.h"
/* This DisjointSet class uses Find with path compression and Union by rank */
@ -146,5 +145,3 @@ void DisjointSet<T, H, C, AL>::get_members(Vector<T> &out_members, T representat
}
}
}
#endif // DISJOINT_SET_H

View file

@ -181,7 +181,7 @@ DynamicBVH::Volume DynamicBVH::_bounds(Node **leaves, int p_count) {
void DynamicBVH::_bottom_up(Node **leaves, int p_count) {
while (p_count > 1) {
real_t minsize = INFINITY;
real_t minsize = Math::INF;
int minidx[2] = { -1, -1 };
for (int i = 0; i < p_count; ++i) {
for (int j = i + 1; j < p_count; ++j) {

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef DYNAMIC_BVH_H
#define DYNAMIC_BVH_H
#pragma once
#include "core/math/aabb.h"
#include "core/templates/list.h"
@ -474,5 +473,3 @@ void DynamicBVH::ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResu
}
} while (depth > 0);
}
#endif // DYNAMIC_BVH_H

View file

@ -454,16 +454,16 @@ Error Expression::_get_token(Token &r_token) {
r_token.value = false;
} else if (id == "PI") {
r_token.type = TK_CONSTANT;
r_token.value = Math_PI;
r_token.value = Math::PI;
} else if (id == "TAU") {
r_token.type = TK_CONSTANT;
r_token.value = Math_TAU;
r_token.value = Math::TAU;
} else if (id == "INF") {
r_token.type = TK_CONSTANT;
r_token.value = INFINITY;
r_token.value = Math::INF;
} else if (id == "NAN") {
r_token.type = TK_CONSTANT;
r_token.value = NAN;
r_token.value = Math::NaN;
} else if (id == "not") {
r_token.type = TK_OP_NOT;
} else if (id == "or") {

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef EXPRESSION_H
#define EXPRESSION_H
#pragma once
#include "core/object/ref_counted.h"
@ -271,5 +270,3 @@ public:
Expression() {}
~Expression();
};
#endif // EXPRESSION_H

View file

@ -263,7 +263,7 @@ void Face3::get_support(const Vector3 &p_normal, const Transform3D &p_transform,
// check if edge is valid as a support
real_t dot = (vertex[i] - vertex[(i + 1) % 3]).normalized().dot(n);
dot = ABS(dot);
dot = Math::abs(dot);
if (dot < edge_support_threshold) {
*p_count = MIN(2, p_max);

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef FACE3_H
#define FACE3_H
#pragma once
#include "core/math/aabb.h"
#include "core/math/plane.h"
@ -79,12 +78,9 @@ struct [[nodiscard]] Face3 {
_FORCE_INLINE_ bool intersects_aabb2(const AABB &p_aabb) const;
operator String() const;
inline Face3() {}
inline Face3(const Vector3 &p_v1, const Vector3 &p_v2, const Vector3 &p_v3) {
vertex[0] = p_v1;
vertex[1] = p_v2;
vertex[2] = p_v3;
}
Face3() = default;
constexpr Face3(const Vector3 &p_v1, const Vector3 &p_v2, const Vector3 &p_v3) :
vertex{ p_v1, p_v2, p_v3 } {}
};
bool Face3::intersects_aabb2(const AABB &p_aabb) const {
@ -238,4 +234,5 @@ bool Face3::intersects_aabb2(const AABB &p_aabb) const {
return true;
}
#endif // FACE3_H
template <>
struct is_zero_constructible<Face3> : std::true_type {};

View file

@ -38,17 +38,63 @@
const int clipper_precision = 5; // Based on CMP_EPSILON.
const double clipper_scale = Math::pow(10.0, clipper_precision);
Vector<Vector<Vector2>> Geometry2D::decompose_polygon_in_convex(const Vector<Point2> &polygon) {
void Geometry2D::merge_many_polygons(const Vector<Vector<Vector2>> &p_polygons, Vector<Vector<Vector2>> &r_out_polygons, Vector<Vector<Vector2>> &r_out_holes) {
using namespace Clipper2Lib;
PathsD subjects;
for (const Vector<Vector2> &polygon : p_polygons) {
PathD path(polygon.size());
for (int i = 0; i < polygon.size(); i++) {
const Vector2 &point = polygon[i];
path[i] = PointD(point.x, point.y);
}
subjects.push_back(path);
}
PathsD solution = Union(subjects, FillRule::NonZero);
solution = SimplifyPaths(solution, 0.01);
r_out_polygons.clear();
r_out_holes.clear();
for (PathsD::size_type i = 0; i < solution.size(); ++i) {
PathD &path = solution[i];
Vector<Point2> output_polygon;
output_polygon.resize(path.size());
for (PathsD::size_type j = 0; j < path.size(); ++j) {
output_polygon.set(j, Vector2(static_cast<real_t>(path[j].x), static_cast<real_t>(path[j].y)));
}
if (IsPositive(path)) {
r_out_polygons.push_back(output_polygon);
} else {
r_out_holes.push_back(output_polygon);
}
}
}
Vector<Vector<Vector2>> Geometry2D::decompose_many_polygons_in_convex(const Vector<Vector<Point2>> &p_polygons, const Vector<Vector<Point2>> &p_holes) {
Vector<Vector<Vector2>> decomp;
List<TPPLPoly> in_poly, out_poly;
TPPLPoly inp;
inp.Init(polygon.size());
for (int i = 0; i < polygon.size(); i++) {
inp.GetPoint(i) = polygon[i];
for (const Vector<Vector2> &polygon : p_polygons) {
TPPLPoly inp;
inp.Init(polygon.size());
for (int i = 0; i < polygon.size(); i++) {
inp.GetPoint(i) = polygon[i];
}
inp.SetOrientation(TPPL_ORIENTATION_CCW);
in_poly.push_back(inp);
}
for (const Vector<Vector2> &polygon : p_holes) {
TPPLPoly inp;
inp.Init(polygon.size());
for (int i = 0; i < polygon.size(); i++) {
inp.GetPoint(i) = polygon[i];
}
inp.SetOrientation(TPPL_ORIENTATION_CW);
inp.SetHole(true);
in_poly.push_back(inp);
}
inp.SetOrientation(TPPL_ORIENTATION_CCW);
in_poly.push_back(inp);
TPPLPartition tpart;
if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { // Failed.
ERR_PRINT("Convex decomposing failed!");
@ -57,9 +103,7 @@ Vector<Vector<Vector2>> Geometry2D::decompose_polygon_in_convex(const Vector<Poi
decomp.resize(out_poly.size());
int idx = 0;
for (List<TPPLPoly>::Element *I = out_poly.front(); I; I = I->next()) {
TPPLPoly &tp = I->get();
for (TPPLPoly &tp : out_poly) {
decomp.write[idx].resize(tp.GetNumPoints());
for (int64_t i = 0; i < tp.GetNumPoints(); i++) {
@ -72,6 +116,10 @@ Vector<Vector<Vector2>> Geometry2D::decompose_polygon_in_convex(const Vector<Poi
return decomp;
}
Vector<Vector<Vector2>> Geometry2D::decompose_polygon_in_convex(const Vector<Point2> &p_polygon) {
return Geometry2D::decompose_many_polygons_in_convex({ p_polygon }, {});
}
struct _AtlasWorkRect {
Size2i s;
Point2i p;

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef GEOMETRY_2D_H
#define GEOMETRY_2D_H
#pragma once
#include "core/math/delaunay_2d.h"
#include "core/math/math_funcs.h"
@ -100,27 +99,39 @@ public:
return Math::sqrt((c1 - c2).dot(c1 - c2));
}
#ifndef DISABLE_DEPRECATED
static Vector2 get_closest_point_to_segment(const Vector2 &p_point, const Vector2 *p_segment) {
Vector2 p = p_point - p_segment[0];
Vector2 n = p_segment[1] - p_segment[0];
return get_closest_point_to_segment(p_point, p_segment[0], p_segment[1]);
}
#endif // DISABLE_DEPRECATED
static Vector2 get_closest_point_to_segment(const Vector2 &p_point, const Vector2 &p_segment_a, const Vector2 &p_segment_b) {
Vector2 p = p_point - p_segment_a;
Vector2 n = p_segment_b - p_segment_a;
real_t l2 = n.length_squared();
if (l2 < 1e-20f) {
return p_segment[0]; // Both points are the same, just give any.
return p_segment_a; // Both points are the same, just give any.
}
real_t d = n.dot(p) / l2;
if (d <= 0.0f) {
return p_segment[0]; // Before first point.
return p_segment_a; // Before first point.
} else if (d >= 1.0f) {
return p_segment[1]; // After first point.
return p_segment_b; // After first point.
} else {
return p_segment[0] + n * d; // Inside.
return p_segment_a + n * d; // Inside.
}
}
#ifndef DISABLE_DEPRECATED
static real_t get_distance_to_segment(const Vector2 &p_point, const Vector2 *p_segment) {
return p_point.distance_to(get_closest_point_to_segment(p_point, p_segment));
return get_distance_to_segment(p_point, p_segment[0], p_segment[1]);
}
#endif // DISABLE_DEPRECATED
static real_t get_distance_to_segment(const Vector2 &p_point, const Vector2 &p_segment_a, const Vector2 &p_segment_b) {
return p_point.distance_to(get_closest_point_to_segment(p_point, p_segment_a, p_segment_b));
}
static bool is_point_in_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) {
@ -137,24 +148,26 @@ public:
return (cn.cross(an) > 0) == orientation;
}
#ifndef DISABLE_DEPRECATED
static Vector2 get_closest_point_to_segment_uncapped(const Vector2 &p_point, const Vector2 *p_segment) {
Vector2 p = p_point - p_segment[0];
Vector2 n = p_segment[1] - p_segment[0];
return get_closest_point_to_segment_uncapped(p_point, p_segment[0], p_segment[1]);
}
#endif // DISABLE_DEPRECATED
static Vector2 get_closest_point_to_segment_uncapped(const Vector2 &p_point, const Vector2 &p_segment_a, const Vector2 &p_segment_b) {
Vector2 p = p_point - p_segment_a;
Vector2 n = p_segment_b - p_segment_a;
real_t l2 = n.length_squared();
if (l2 < 1e-20f) {
return p_segment[0]; // Both points are the same, just give any.
return p_segment_a; // Both points are the same, just give any.
}
real_t d = n.dot(p) / l2;
return p_segment[0] + n * d; // Inside.
return p_segment_a + n * d; // Inside.
}
// Disable False Positives in MSVC compiler; we correctly check for 0 here to prevent a division by 0.
// See: https://github.com/godotengine/godot/pull/44274
#ifdef _MSC_VER
#pragma warning(disable : 4723)
#endif
GODOT_MSVC_WARNING_PUSH_AND_IGNORE(4723) // Potential divide by 0. False positive (see: GH-44274).
static bool line_intersects_line(const Vector2 &p_from_a, const Vector2 &p_dir_a, const Vector2 &p_from_b, const Vector2 &p_dir_b, Vector2 &r_result) {
// See http://paulbourke.net/geometry/pointlineplane/
@ -170,10 +183,7 @@ public:
return true;
}
// Re-enable division by 0 warning
#ifdef _MSC_VER
#pragma warning(default : 4723)
#endif
GODOT_MSVC_WARNING_POP
static bool segment_intersects_segment(const Vector2 &p_from_a, const Vector2 &p_to_a, const Vector2 &p_from_b, const Vector2 &p_to_b, Vector2 *r_result) {
Vector2 B = p_to_a - p_from_a;
@ -489,7 +499,10 @@ public:
return points;
}
static Vector<Vector<Vector2>> decompose_polygon_in_convex(const Vector<Point2> &polygon);
static void merge_many_polygons(const Vector<Vector<Point2>> &p_polygons, Vector<Vector<Vector2>> &r_out_polygons, Vector<Vector<Vector2>> &r_out_holes);
static Vector<Vector<Vector2>> decompose_many_polygons_in_convex(const Vector<Vector<Point2>> &p_polygons, const Vector<Vector<Point2>> &p_holes);
static Vector<Vector<Vector2>> decompose_polygon_in_convex(const Vector<Point2> &p_polygon);
static void make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_result, Size2i &r_size);
static Vector<Vector3i> partial_pack_rects(const Vector<Vector2i> &p_sizes, const Size2i &p_atlas_size);
@ -498,5 +511,3 @@ private:
static Vector<Vector<Point2>> _polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open = false);
static Vector<Vector<Point2>> _polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type);
};
#endif // GEOMETRY_2D_H

View file

@ -30,6 +30,8 @@
#include "geometry_3d.h"
#include "core/templates/hash_map.h"
void Geometry3D::get_closest_points_between_segments(const Vector3 &p_p0, const Vector3 &p_p1, const Vector3 &p_q0, const Vector3 &p_q1, Vector3 &r_ps, Vector3 &r_qt) {
// Based on David Eberly's Computation of Distance Between Line Segments algorithm.
@ -593,7 +595,7 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes
Vector3 ref = Vector3(0.0, 1.0, 0.0);
if (ABS(p.normal.dot(ref)) > 0.95f) {
if (Math::abs(p.normal.dot(ref)) > 0.95f) {
ref = Vector3(0.0, 0.0, 1.0); // Change axis.
}
@ -742,7 +744,7 @@ Vector<Plane> Geometry3D::build_cylinder_planes(real_t p_radius, real_t p_height
Vector<Plane> planes;
const double sides_step = Math_TAU / p_sides;
const double sides_step = Math::TAU / p_sides;
for (int i = 0; i < p_sides; i++) {
Vector3 normal;
normal[(p_axis + 1) % 3] = Math::cos(i * sides_step);
@ -773,7 +775,7 @@ Vector<Plane> Geometry3D::build_sphere_planes(real_t p_radius, int p_lats, int p
axis_neg[(p_axis + 2) % 3] = 1.0;
axis_neg[p_axis] = -1.0;
const double lon_step = Math_TAU / p_lons;
const double lon_step = Math::TAU / p_lons;
for (int i = 0; i < p_lons; i++) {
Vector3 normal;
normal[(p_axis + 1) % 3] = Math::cos(i * lon_step);
@ -804,7 +806,7 @@ Vector<Plane> Geometry3D::build_capsule_planes(real_t p_radius, real_t p_height,
axis_neg[(p_axis + 2) % 3] = 1.0;
axis_neg[p_axis] = -1.0;
const double sides_step = Math_TAU / p_sides;
const double sides_step = Math::TAU / p_sides;
for (int i = 0; i < p_sides; i++) {
Vector3 normal;
normal[(p_axis + 1) % 3] = Math::cos(i * sides_step);
@ -860,7 +862,6 @@ Vector<Vector3> Geometry3D::compute_convex_mesh_points(const Plane *p_planes, in
}
#define square(m_s) ((m_s) * (m_s))
#define INF 1e20
/* dt of 1d function using squared distance */
static void edt(float *f, int stride, int n) {
@ -870,8 +871,8 @@ static void edt(float *f, int stride, int n) {
int k = 0;
v[0] = 0;
z[0] = -INF;
z[1] = +INF;
z[0] = -Math::INF;
z[1] = +Math::INF;
for (int q = 1; q <= n - 1; q++) {
float s = ((f[q * stride] + square(q)) - (f[v[k] * stride] + square(v[k]))) / (2 * q - 2 * v[k]);
while (s <= z[k]) {
@ -882,7 +883,7 @@ static void edt(float *f, int stride, int n) {
v[k] = q;
z[k] = s;
z[k + 1] = +INF;
z[k + 1] = +Math::INF;
}
k = 0;
@ -907,7 +908,7 @@ Vector<uint32_t> Geometry3D::generate_edf(const Vector<bool> &p_voxels, const Ve
float *work_memory = memnew_arr(float, float_count);
for (uint32_t i = 0; i < float_count; i++) {
work_memory[i] = INF;
work_memory[i] = Math::INF;
}
uint32_t y_mult = p_size.x;

View file

@ -28,12 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef GEOMETRY_3D_H
#define GEOMETRY_3D_H
#pragma once
#include "core/math/delaunay_3d.h"
#include "core/math/face3.h"
#include "core/object/object.h"
#include "core/templates/local_vector.h"
#include "core/templates/vector.h"
@ -274,7 +272,7 @@ public:
return true;
}
static bool segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Plane *p_planes, int p_plane_count, Vector3 *p_res, Vector3 *p_norm) {
static bool segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Plane *p_planes, int p_plane_count, Vector3 *r_res, Vector3 *r_norm) {
real_t min = -1e20, max = 1e20;
Vector3 rel = p_to - p_from;
@ -317,46 +315,58 @@ public:
return false; // No intersection.
}
if (p_res) {
*p_res = p_from + dir * min;
if (r_res) {
*r_res = p_from + dir * min;
}
if (p_norm) {
*p_norm = p_planes[min_index].normal;
if (r_norm) {
*r_norm = p_planes[min_index].normal;
}
return true;
}
#ifndef DISABLE_DEPRECATED
static Vector3 get_closest_point_to_segment(const Vector3 &p_point, const Vector3 *p_segment) {
Vector3 p = p_point - p_segment[0];
Vector3 n = p_segment[1] - p_segment[0];
return get_closest_point_to_segment(p_point, p_segment[0], p_segment[1]);
}
#endif // DISABLE_DEPRECATED
static Vector3 get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_segment_a, const Vector3 &p_segment_b) {
Vector3 p = p_point - p_segment_a;
Vector3 n = p_segment_b - p_segment_a;
real_t l2 = n.length_squared();
if (l2 < 1e-20f) {
return p_segment[0]; // Both points are the same, just give any.
return p_segment_a; // Both points are the same, just give any.
}
real_t d = n.dot(p) / l2;
if (d <= 0.0f) {
return p_segment[0]; // Before first point.
return p_segment_a; // Before first point.
} else if (d >= 1.0f) {
return p_segment[1]; // After first point.
return p_segment_b; // After first point.
} else {
return p_segment[0] + n * d; // Inside.
return p_segment_a + n * d; // Inside.
}
}
#ifndef DISABLE_DEPRECATED
static Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 *p_segment) {
Vector3 p = p_point - p_segment[0];
Vector3 n = p_segment[1] - p_segment[0];
return get_closest_point_to_segment_uncapped(p_point, p_segment[0], p_segment[1]);
}
#endif // DISABLE_DEPRECATED
static Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_segment_a, const Vector3 &p_segment_b) {
Vector3 p = p_point - p_segment_a;
Vector3 n = p_segment_b - p_segment_a;
real_t l2 = n.length_squared();
if (l2 < 1e-20f) {
return p_segment[0]; // Both points are the same, just give any.
return p_segment_a; // Both points are the same, just give any.
}
real_t d = n.dot(p) / l2;
return p_segment[0] + n * d; // Inside.
return p_segment_a + n * d; // Inside.
}
static inline bool point_in_projected_triangle(const Vector3 &p_point, const Vector3 &p_v1, const Vector3 &p_v2, const Vector3 &p_v3) {
@ -383,8 +393,14 @@ public:
return true;
}
#ifndef DISABLE_DEPRECATED
static inline bool triangle_sphere_intersection_test(const Vector3 *p_triangle, const Vector3 &p_normal, const Vector3 &p_sphere_pos, real_t p_sphere_radius, Vector3 &r_triangle_contact, Vector3 &r_sphere_contact) {
real_t d = p_normal.dot(p_sphere_pos) - p_normal.dot(p_triangle[0]);
return triangle_sphere_intersection_test(p_triangle[0], p_triangle[1], p_triangle[2], p_normal, p_sphere_pos, p_sphere_radius, r_triangle_contact, r_sphere_contact);
}
#endif // DISABLE_DEPRECATED
static inline bool triangle_sphere_intersection_test(const Vector3 &p_triangle_a, const Vector3 &p_triangle_b, const Vector3 &p_triangle_c, const Vector3 &p_normal, const Vector3 &p_sphere_pos, real_t p_sphere_radius, Vector3 &r_triangle_contact, Vector3 &r_sphere_contact) {
real_t d = p_normal.dot(p_sphere_pos) - p_normal.dot(p_triangle_a);
if (d > p_sphere_radius || d < -p_sphere_radius) {
// Not touching the plane of the face, return.
@ -395,7 +411,7 @@ public:
/** 2nd) TEST INSIDE TRIANGLE **/
if (Geometry3D::point_in_projected_triangle(contact, p_triangle[0], p_triangle[1], p_triangle[2])) {
if (Geometry3D::point_in_projected_triangle(contact, p_triangle_a, p_triangle_b, p_triangle_c)) {
r_triangle_contact = contact;
r_sphere_contact = p_sphere_pos - p_normal * p_sphere_radius;
//printf("solved inside triangle\n");
@ -404,7 +420,7 @@ public:
/** 3rd TEST INSIDE EDGE CYLINDERS **/
const Vector3 verts[4] = { p_triangle[0], p_triangle[1], p_triangle[2], p_triangle[0] }; // for() friendly
const Vector3 verts[4] = { p_triangle_a, p_triangle_b, p_triangle_c, p_triangle_a }; // for() friendly
for (int i = 0; i < 3; i++) {
// Check edge cylinder.
@ -420,7 +436,7 @@ public:
real_t ad = axis.dot(n2);
if (ABS(ad) > p_sphere_radius) {
if (Math::abs(ad) > p_sphere_radius) {
// No chance with this edge, too far away.
continue;
}
@ -468,7 +484,7 @@ public:
LOC_OUTSIDE = -1
};
if (polygon.size() == 0) {
if (polygon.is_empty()) {
return polygon;
}
@ -840,5 +856,3 @@ public:
return n.normalized();
}
};
#endif // GEOMETRY_3D_H

View file

@ -28,8 +28,24 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef MATH_DEFS_H
#define MATH_DEFS_H
#pragma once
#include "core/typedefs.h"
#include <limits>
namespace Math {
inline constexpr double SQRT2 = 1.4142135623730950488016887242;
inline constexpr double SQRT3 = 1.7320508075688772935274463415059;
inline constexpr double SQRT12 = 0.7071067811865475244008443621048490;
inline constexpr double SQRT13 = 0.57735026918962576450914878050196;
inline constexpr double LN2 = 0.6931471805599453094172321215;
inline constexpr double TAU = 6.2831853071795864769252867666;
inline constexpr double PI = 3.1415926535897932384626433833;
inline constexpr double E = 2.7182818284590452353602874714;
inline constexpr double INF = std::numeric_limits<double>::infinity();
inline constexpr double NaN = std::numeric_limits<double>::quiet_NaN();
} // namespace Math
#define CMP_EPSILON 0.00001
#define CMP_EPSILON2 (CMP_EPSILON * CMP_EPSILON)
@ -37,13 +53,6 @@
#define CMP_NORMALIZE_TOLERANCE 0.000001
#define CMP_POINT_IN_PLANE_EPSILON 0.00001
#define Math_SQRT12 0.7071067811865475244008443621048490
#define Math_SQRT2 1.4142135623730950488016887242
#define Math_LN2 0.6931471805599453094172321215
#define Math_TAU 6.2831853071795864769252867666
#define Math_PI 3.1415926535897932384626433833
#define Math_E 2.7182818284590452353602874714
#ifdef DEBUG_ENABLED
#define MATH_CHECKS
#endif
@ -136,5 +145,3 @@ typedef double real_t;
#else
typedef float real_t;
#endif
#endif // MATH_DEFS_H

View file

@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifdef TOOLS_ENABLED
#ifdef DEBUG_ENABLED
#include "math_fieldwise.h"
@ -242,4 +242,4 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const
/* clang-format on */
}
#endif // TOOLS_ENABLED
#endif // DEBUG_ENABLED

View file

@ -28,15 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef MATH_FIELDWISE_H
#define MATH_FIELDWISE_H
#pragma once
#ifdef TOOLS_ENABLED
#ifdef DEBUG_ENABLED
#include "core/variant/variant.h"
Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const String &p_field);
#endif // TOOLS_ENABLED
#endif // MATH_FIELDWISE_H
#endif // DEBUG_ENABLED

View file

@ -31,18 +31,19 @@
#include "math_funcs.h"
#include "core/error/error_macros.h"
#include "core/math/random_pcg.h"
RandomPCG Math::default_rand(RandomPCG::DEFAULT_SEED, RandomPCG::DEFAULT_INC);
static RandomPCG default_rand;
uint32_t Math::rand_from_seed(uint64_t *seed) {
RandomPCG rng = RandomPCG(*seed, RandomPCG::DEFAULT_INC);
uint32_t Math::rand_from_seed(uint64_t *p_seed) {
RandomPCG rng = RandomPCG(*p_seed);
uint32_t r = rng.rand();
*seed = rng.get_seed();
*p_seed = rng.get_seed();
return r;
}
void Math::seed(uint64_t x) {
default_rand.seed(x);
void Math::seed(uint64_t p_value) {
default_rand.seed(p_value);
}
void Math::randomize() {
@ -53,8 +54,8 @@ uint32_t Math::rand() {
return default_rand.rand();
}
double Math::randfn(double mean, double deviation) {
return default_rand.randfn(mean, deviation);
double Math::randfn(double p_mean, double p_deviation) {
return default_rand.randfn(p_mean, p_deviation);
}
int Math::step_decimals(double p_step) {
@ -168,14 +169,14 @@ uint32_t Math::larger_prime(uint32_t p_val) {
}
}
double Math::random(double from, double to) {
return default_rand.random(from, to);
double Math::random(double p_from, double p_to) {
return default_rand.random(p_from, p_to);
}
float Math::random(float from, float to) {
return default_rand.random(from, to);
float Math::random(float p_from, float p_to) {
return default_rand.random(p_from, p_to);
}
int Math::random(int from, int to) {
return default_rand.random(from, to);
int Math::random(int p_from, int p_to) {
return default_rand.random(p_from, p_to);
}

File diff suppressed because it is too large Load diff

View file

@ -58,7 +58,7 @@ Vector3 Plane::get_any_perpendicular_normal() const {
static const Vector3 p2 = Vector3(0, 1, 0);
Vector3 p;
if (ABS(normal.dot(p1)) > 0.99f) { // if too similar to p1
if (Math::abs(normal.dot(p1)) > 0.99f) { // if too similar to p1
p = p2; // use p2
} else {
p = p1; // use p1
@ -172,6 +172,10 @@ bool Plane::is_equal_approx(const Plane &p_plane) const {
return normal.is_equal_approx(p_plane.normal) && Math::is_equal_approx(d, p_plane.d);
}
bool Plane::is_same(const Plane &p_plane) const {
return normal.is_same(p_plane.normal) && Math::is_same(d, p_plane.d);
}
bool Plane::is_finite() const {
return normal.is_finite() && Math::is_finite(d);
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef PLANE_H
#define PLANE_H
#pragma once
#include "core/math/vector3.h"
@ -71,21 +70,22 @@ struct [[nodiscard]] Plane {
/* misc */
Plane operator-() const { return Plane(-normal, -d); }
constexpr Plane operator-() const { return Plane(-normal, -d); }
bool is_equal_approx(const Plane &p_plane) const;
bool is_same(const Plane &p_plane) const;
bool is_equal_approx_any_side(const Plane &p_plane) const;
bool is_finite() const;
_FORCE_INLINE_ bool operator==(const Plane &p_plane) const;
_FORCE_INLINE_ bool operator!=(const Plane &p_plane) const;
constexpr bool operator==(const Plane &p_plane) const;
constexpr bool operator!=(const Plane &p_plane) const;
operator String() const;
_FORCE_INLINE_ Plane() {}
_FORCE_INLINE_ Plane(real_t p_a, real_t p_b, real_t p_c, real_t p_d) :
Plane() = default;
constexpr Plane(real_t p_a, real_t p_b, real_t p_c, real_t p_d) :
normal(p_a, p_b, p_c),
d(p_d) {}
_FORCE_INLINE_ Plane(const Vector3 &p_normal, real_t p_d = 0.0);
constexpr Plane(const Vector3 &p_normal, real_t p_d = 0.0);
_FORCE_INLINE_ Plane(const Vector3 &p_normal, const Vector3 &p_point);
_FORCE_INLINE_ Plane(const Vector3 &p_point1, const Vector3 &p_point2, const Vector3 &p_point3, ClockDirection p_dir = CLOCKWISE);
};
@ -100,11 +100,11 @@ real_t Plane::distance_to(const Vector3 &p_point) const {
bool Plane::has_point(const Vector3 &p_point, real_t p_tolerance) const {
real_t dist = normal.dot(p_point) - d;
dist = ABS(dist);
dist = Math::abs(dist);
return (dist <= p_tolerance);
}
Plane::Plane(const Vector3 &p_normal, real_t p_d) :
constexpr Plane::Plane(const Vector3 &p_normal, real_t p_d) :
normal(p_normal),
d(p_d) {
}
@ -125,12 +125,13 @@ Plane::Plane(const Vector3 &p_point1, const Vector3 &p_point2, const Vector3 &p_
d = normal.dot(p_point1);
}
bool Plane::operator==(const Plane &p_plane) const {
constexpr bool Plane::operator==(const Plane &p_plane) const {
return normal == p_plane.normal && d == p_plane.d;
}
bool Plane::operator!=(const Plane &p_plane) const {
constexpr bool Plane::operator!=(const Plane &p_plane) const {
return normal != p_plane.normal || d != p_plane.d;
}
#endif // PLANE_H
template <>
struct is_zero_constructible<Plane> : std::true_type {};

View file

@ -402,82 +402,35 @@ void Projection::set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, r
}
real_t Projection::get_z_far() const {
const real_t *matrix = (const real_t *)columns;
Plane new_plane = Plane(matrix[3] - matrix[2],
matrix[7] - matrix[6],
matrix[11] - matrix[10],
matrix[15] - matrix[14]);
new_plane.normalize();
return new_plane.d;
// NOTE: This assumes z-facing near and far planes, i.e. that :
// - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
// - near and far planes are z-facing (i.e. columns[0][2] and [1][2] == 0)
return (columns[3][3] - columns[3][2]) / (columns[2][3] - columns[2][2]);
}
real_t Projection::get_z_near() const {
const real_t *matrix = (const real_t *)columns;
Plane new_plane = Plane(matrix[3] + matrix[2],
matrix[7] + matrix[6],
matrix[11] + matrix[10],
-matrix[15] - matrix[14]);
new_plane.normalize();
return new_plane.d;
// NOTE: This assumes z-facing near and far planes, i.e. that :
// - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
// - near and far planes are z-facing (i.e. columns[0][2] and [1][2] == 0)
return (columns[3][3] + columns[3][2]) / (columns[2][3] + columns[2][2]);
}
Vector2 Projection::get_viewport_half_extents() const {
const real_t *matrix = (const real_t *)columns;
///////--- Near Plane ---///////
Plane near_plane = Plane(matrix[3] + matrix[2],
matrix[7] + matrix[6],
matrix[11] + matrix[10],
-matrix[15] - matrix[14]);
near_plane.normalize();
///////--- Right Plane ---///////
Plane right_plane = Plane(matrix[3] - matrix[0],
matrix[7] - matrix[4],
matrix[11] - matrix[8],
-matrix[15] + matrix[12]);
right_plane.normalize();
Plane top_plane = Plane(matrix[3] - matrix[1],
matrix[7] - matrix[5],
matrix[11] - matrix[9],
-matrix[15] + matrix[13]);
top_plane.normalize();
Vector3 res;
near_plane.intersect_3(right_plane, top_plane, &res);
return Vector2(res.x, res.y);
// NOTE: This assumes a symmetrical frustum, i.e. that :
// - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
// - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0)
// - there is no offset / skew (i.e. columns[2][0] == columns[2][1] == 0)
real_t w = -get_z_near() * columns[2][3] + columns[3][3];
return Vector2(w / columns[0][0], w / columns[1][1]);
}
Vector2 Projection::get_far_plane_half_extents() const {
const real_t *matrix = (const real_t *)columns;
///////--- Far Plane ---///////
Plane far_plane = Plane(matrix[3] - matrix[2],
matrix[7] - matrix[6],
matrix[11] - matrix[10],
-matrix[15] + matrix[14]);
far_plane.normalize();
///////--- Right Plane ---///////
Plane right_plane = Plane(matrix[3] - matrix[0],
matrix[7] - matrix[4],
matrix[11] - matrix[8],
-matrix[15] + matrix[12]);
right_plane.normalize();
Plane top_plane = Plane(matrix[3] - matrix[1],
matrix[7] - matrix[5],
matrix[11] - matrix[9],
-matrix[15] + matrix[13]);
top_plane.normalize();
Vector3 res;
far_plane.intersect_3(right_plane, top_plane, &res);
return Vector2(res.x, res.y);
// NOTE: This assumes a symmetrical frustum, i.e. that :
// - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
// - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0)
// - there is no offset / skew (i.e. columns[2][0] == columns[2][1] == 0)
real_t w = -get_z_far() * columns[2][3] + columns[3][3];
return Vector2(w / columns[0][0], w / columns[1][1]);
}
bool Projection::get_endpoints(const Transform3D &p_transform, Vector3 *p_8points) const {
@ -827,24 +780,8 @@ void Projection::flip_y() {
}
}
Projection::Projection() {
set_identity();
}
Projection Projection::operator*(const Projection &p_matrix) const {
Projection new_matrix;
for (int j = 0; j < 4; j++) {
for (int i = 0; i < 4; i++) {
real_t ab = 0;
for (int k = 0; k < 4; k++) {
ab += columns[k][i] * p_matrix.columns[j][k];
}
new_matrix.columns[j][i] = ab;
}
}
return new_matrix;
bool Projection::is_same(const Projection &p_cam) const {
return columns[0].is_same(p_cam.columns[0]) && columns[1].is_same(p_cam.columns[1]) && columns[2].is_same(p_cam.columns[2]) && columns[3].is_same(p_cam.columns[3]);
}
void Projection::set_depth_correction(bool p_flip_y, bool p_reverse_z, bool p_remap_z) {
@ -919,53 +856,45 @@ Projection::operator String() const {
}
real_t Projection::get_aspect() const {
Vector2 vp_he = get_viewport_half_extents();
return vp_he.x / vp_he.y;
// NOTE: This assumes a rectangular projection plane, i.e. that :
// - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
// - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0)
return columns[1][1] / columns[0][0];
}
int Projection::get_pixels_per_meter(int p_for_pixel_width) const {
Vector3 result = xform(Vector3(1, 0, -1));
return int((result.x * 0.5 + 0.5) * p_for_pixel_width);
// NOTE: This assumes a rectangular projection plane, i.e. that :
// - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
// - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0)
real_t width = 2 * (-get_z_near() * columns[2][3] + columns[3][3]) / columns[0][0];
return p_for_pixel_width / width; // Note : return type should be real_t (kept as int for compatibility for now).
}
bool Projection::is_orthogonal() const {
return columns[3][3] == 1.0;
// NOTE: This assumes that the matrix is a projection across z-axis
// i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0
return columns[2][3] == 0.0;
}
real_t Projection::get_fov() const {
const real_t *matrix = (const real_t *)columns;
Plane right_plane = Plane(matrix[3] - matrix[0],
matrix[7] - matrix[4],
matrix[11] - matrix[8],
-matrix[15] + matrix[12]);
right_plane.normalize();
if ((matrix[8] == 0) && (matrix[9] == 0)) {
return Math::rad_to_deg(Math::acos(Math::abs(right_plane.normal.x))) * 2.0;
// NOTE: This assumes a rectangular projection plane, i.e. that :
// - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
// - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0)
if (columns[2][0] == 0) {
return Math::rad_to_deg(2 * Math::atan2(1, columns[0][0]));
} else {
// our frustum is asymmetrical need to calculate the left planes angle separately..
Plane left_plane = Plane(matrix[3] + matrix[0],
matrix[7] + matrix[4],
matrix[11] + matrix[8],
matrix[15] + matrix[12]);
left_plane.normalize();
return Math::rad_to_deg(Math::acos(Math::abs(left_plane.normal.x))) + Math::rad_to_deg(Math::acos(Math::abs(right_plane.normal.x)));
// The frustum is asymmetrical so we need to calculate the left and right angles separately.
real_t right = Math::atan2(columns[2][0] + 1, columns[0][0]);
real_t left = Math::atan2(columns[2][0] - 1, columns[0][0]);
return Math::rad_to_deg(right - left);
}
}
real_t Projection::get_lod_multiplier() const {
if (is_orthogonal()) {
return get_viewport_half_extents().x;
} else {
const real_t zn = get_z_near();
const real_t width = get_viewport_half_extents().x * 2.0f;
return 1.0f / (zn / width);
}
// Usage is lod_size / (lod_distance * multiplier) < threshold
// NOTE: This assumes a rectangular projection plane, i.e. that :
// - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
// - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0)
return 2 / columns[0][0];
}
void Projection::make_scale(const Vector3 &p_scale) {
@ -1028,13 +957,6 @@ Projection::operator Transform3D() const {
return tr;
}
Projection::Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w) {
columns[0] = p_x;
columns[1] = p_y;
columns[2] = p_z;
columns[3] = p_w;
}
Projection::Projection(const Transform3D &p_transform) {
const Transform3D &tr = p_transform;
real_t *m = &columns[0][0];
@ -1056,6 +978,3 @@ Projection::Projection(const Transform3D &p_transform) {
m[14] = tr.origin.z;
m[15] = 1.0;
}
Projection::~Projection() {
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef PROJECTION_H
#define PROJECTION_H
#pragma once
#include "core/math/vector3.h"
#include "core/math/vector4.h"
@ -53,14 +52,19 @@ struct [[nodiscard]] Projection {
PLANE_BOTTOM
};
Vector4 columns[4];
Vector4 columns[4] = {
{ 1, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 1 },
};
_FORCE_INLINE_ const Vector4 &operator[](int p_axis) const {
constexpr const Vector4 &operator[](int p_axis) const {
DEV_ASSERT((unsigned int)p_axis < 4);
return columns[p_axis];
}
_FORCE_INLINE_ Vector4 &operator[](int p_axis) {
constexpr Vector4 &operator[](int p_axis) {
DEV_ASSERT((unsigned int)p_axis < 4);
return columns[p_axis];
}
@ -115,7 +119,7 @@ struct [[nodiscard]] Projection {
void invert();
Projection inverse() const;
Projection operator*(const Projection &p_matrix) const;
constexpr Projection operator*(const Projection &p_matrix) const;
Plane xform4(const Plane &p_vec4) const;
_FORCE_INLINE_ Vector3 xform(const Vector3 &p_vec3) const;
@ -133,7 +137,9 @@ struct [[nodiscard]] Projection {
void flip_y();
bool operator==(const Projection &p_cam) const {
bool is_same(const Projection &p_cam) const;
constexpr bool operator==(const Projection &p_cam) const {
for (uint32_t i = 0; i < 4; i++) {
for (uint32_t j = 0; j < 4; j++) {
if (columns[i][j] != p_cam.columns[i][j]) {
@ -144,18 +150,41 @@ struct [[nodiscard]] Projection {
return true;
}
bool operator!=(const Projection &p_cam) const {
constexpr bool operator!=(const Projection &p_cam) const {
return !(*this == p_cam);
}
real_t get_lod_multiplier() const;
Projection();
Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w);
Projection() = default;
constexpr Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w) :
columns{ p_x, p_y, p_z, p_w } {}
constexpr Projection(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_xw, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_yw, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_zw, real_t p_wx, real_t p_wy, real_t p_wz, real_t p_ww) :
columns{
{ p_xx, p_xy, p_xz, p_xw },
{ p_yx, p_yy, p_yz, p_yw },
{ p_zx, p_zy, p_zz, p_zw },
{ p_wx, p_wy, p_wz, p_ww },
} {}
Projection(const Transform3D &p_transform);
~Projection();
};
constexpr Projection Projection::operator*(const Projection &p_matrix) const {
Projection new_matrix;
for (int j = 0; j < 4; j++) {
for (int i = 0; i < 4; i++) {
real_t ab = 0;
for (int k = 0; k < 4; k++) {
ab += columns[k][i] * p_matrix.columns[j][k];
}
new_matrix.columns[j][i] = ab;
}
}
return new_matrix;
}
Vector3 Projection::xform(const Vector3 &p_vec3) const {
Vector3 ret;
ret.x = columns[0][0] * p_vec3.x + columns[1][0] * p_vec3.y + columns[2][0] * p_vec3.z + columns[3][0];
@ -164,5 +193,3 @@ Vector3 Projection::xform(const Vector3 &p_vec3) const {
real_t w = columns[0][3] * p_vec3.x + columns[1][3] * p_vec3.y + columns[2][3] * p_vec3.z + columns[3][3];
return ret / w;
}
#endif // PROJECTION_H

View file

@ -46,26 +46,14 @@ Vector3 Quaternion::get_euler(EulerOrder p_order) const {
return Basis(*this).get_euler(p_order);
}
void Quaternion::operator*=(const Quaternion &p_q) {
real_t xx = w * p_q.x + x * p_q.w + y * p_q.z - z * p_q.y;
real_t yy = w * p_q.y + y * p_q.w + z * p_q.x - x * p_q.z;
real_t zz = w * p_q.z + z * p_q.w + x * p_q.y - y * p_q.x;
w = w * p_q.w - x * p_q.x - y * p_q.y - z * p_q.z;
x = xx;
y = yy;
z = zz;
}
Quaternion Quaternion::operator*(const Quaternion &p_q) const {
Quaternion r = *this;
r *= p_q;
return r;
}
bool Quaternion::is_equal_approx(const Quaternion &p_quaternion) const {
return Math::is_equal_approx(x, p_quaternion.x) && Math::is_equal_approx(y, p_quaternion.y) && Math::is_equal_approx(z, p_quaternion.z) && Math::is_equal_approx(w, p_quaternion.w);
}
bool Quaternion::is_same(const Quaternion &p_quaternion) const {
return Math::is_same(x, p_quaternion.x) && Math::is_same(y, p_quaternion.y) && Math::is_same(z, p_quaternion.z) && Math::is_same(w, p_quaternion.w);
}
bool Quaternion::is_finite() const {
return Math::is_finite(x) && Math::is_finite(y) && Math::is_finite(z) && Math::is_finite(w);
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef QUATERNION_H
#define QUATERNION_H
#pragma once
#include "core/math/math_funcs.h"
#include "core/math/vector3.h"
@ -37,6 +36,7 @@
struct [[nodiscard]] Quaternion {
union {
// NOLINTBEGIN(modernize-use-default-member-init)
struct {
real_t x;
real_t y;
@ -44,6 +44,7 @@ struct [[nodiscard]] Quaternion {
real_t w;
};
real_t components[4] = { 0, 0, 0, 1.0 };
// NOLINTEND(modernize-use-default-member-init)
};
_FORCE_INLINE_ real_t &operator[](int p_idx) {
@ -54,6 +55,7 @@ struct [[nodiscard]] Quaternion {
}
_FORCE_INLINE_ real_t length_squared() const;
bool is_equal_approx(const Quaternion &p_quaternion) const;
bool is_same(const Quaternion &p_quaternion) const;
bool is_finite() const;
real_t length() const;
void normalize();
@ -84,8 +86,8 @@ struct [[nodiscard]] Quaternion {
r_axis.z = z * r;
}
void operator*=(const Quaternion &p_q);
Quaternion operator*(const Quaternion &p_q) const;
constexpr void operator*=(const Quaternion &p_q);
constexpr Quaternion operator*(const Quaternion &p_q) const;
_FORCE_INLINE_ Vector3 xform(const Vector3 &p_v) const {
#ifdef MATH_CHECKS
@ -100,40 +102,33 @@ struct [[nodiscard]] Quaternion {
return inverse().xform(p_v);
}
_FORCE_INLINE_ void operator+=(const Quaternion &p_q);
_FORCE_INLINE_ void operator-=(const Quaternion &p_q);
_FORCE_INLINE_ void operator*=(real_t p_s);
_FORCE_INLINE_ void operator/=(real_t p_s);
_FORCE_INLINE_ Quaternion operator+(const Quaternion &p_q2) const;
_FORCE_INLINE_ Quaternion operator-(const Quaternion &p_q2) const;
_FORCE_INLINE_ Quaternion operator-() const;
_FORCE_INLINE_ Quaternion operator*(real_t p_s) const;
_FORCE_INLINE_ Quaternion operator/(real_t p_s) const;
constexpr void operator+=(const Quaternion &p_q);
constexpr void operator-=(const Quaternion &p_q);
constexpr void operator*=(real_t p_s);
constexpr void operator/=(real_t p_s);
constexpr Quaternion operator+(const Quaternion &p_q2) const;
constexpr Quaternion operator-(const Quaternion &p_q2) const;
constexpr Quaternion operator-() const;
constexpr Quaternion operator*(real_t p_s) const;
constexpr Quaternion operator/(real_t p_s) const;
_FORCE_INLINE_ bool operator==(const Quaternion &p_quaternion) const;
_FORCE_INLINE_ bool operator!=(const Quaternion &p_quaternion) const;
constexpr bool operator==(const Quaternion &p_quaternion) const;
constexpr bool operator!=(const Quaternion &p_quaternion) const;
operator String() const;
_FORCE_INLINE_ Quaternion() {}
constexpr Quaternion() :
x(0), y(0), z(0), w(1) {}
_FORCE_INLINE_ Quaternion(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) {
}
constexpr Quaternion(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) {}
Quaternion(const Vector3 &p_axis, real_t p_angle);
Quaternion(const Quaternion &p_q) :
x(p_q.x),
y(p_q.y),
z(p_q.z),
w(p_q.w) {
}
constexpr Quaternion(const Quaternion &p_q) :
x(p_q.x), y(p_q.y), z(p_q.z), w(p_q.w) {}
void operator=(const Quaternion &p_q) {
constexpr void operator=(const Quaternion &p_q) {
x = p_q.x;
y = p_q.y;
z = p_q.z;
@ -178,64 +173,78 @@ real_t Quaternion::length_squared() const {
return dot(*this);
}
void Quaternion::operator+=(const Quaternion &p_q) {
constexpr void Quaternion::operator+=(const Quaternion &p_q) {
x += p_q.x;
y += p_q.y;
z += p_q.z;
w += p_q.w;
}
void Quaternion::operator-=(const Quaternion &p_q) {
constexpr void Quaternion::operator-=(const Quaternion &p_q) {
x -= p_q.x;
y -= p_q.y;
z -= p_q.z;
w -= p_q.w;
}
void Quaternion::operator*=(real_t p_s) {
constexpr void Quaternion::operator*=(real_t p_s) {
x *= p_s;
y *= p_s;
z *= p_s;
w *= p_s;
}
void Quaternion::operator/=(real_t p_s) {
*this *= 1.0f / p_s;
constexpr void Quaternion::operator/=(real_t p_s) {
*this *= (1 / p_s);
}
Quaternion Quaternion::operator+(const Quaternion &p_q2) const {
constexpr Quaternion Quaternion::operator+(const Quaternion &p_q2) const {
const Quaternion &q1 = *this;
return Quaternion(q1.x + p_q2.x, q1.y + p_q2.y, q1.z + p_q2.z, q1.w + p_q2.w);
}
Quaternion Quaternion::operator-(const Quaternion &p_q2) const {
constexpr Quaternion Quaternion::operator-(const Quaternion &p_q2) const {
const Quaternion &q1 = *this;
return Quaternion(q1.x - p_q2.x, q1.y - p_q2.y, q1.z - p_q2.z, q1.w - p_q2.w);
}
Quaternion Quaternion::operator-() const {
constexpr Quaternion Quaternion::operator-() const {
const Quaternion &q2 = *this;
return Quaternion(-q2.x, -q2.y, -q2.z, -q2.w);
}
Quaternion Quaternion::operator*(real_t p_s) const {
constexpr Quaternion Quaternion::operator*(real_t p_s) const {
return Quaternion(x * p_s, y * p_s, z * p_s, w * p_s);
}
Quaternion Quaternion::operator/(real_t p_s) const {
return *this * (1.0f / p_s);
constexpr Quaternion Quaternion::operator/(real_t p_s) const {
return *this * (1 / p_s);
}
bool Quaternion::operator==(const Quaternion &p_quaternion) const {
constexpr bool Quaternion::operator==(const Quaternion &p_quaternion) const {
return x == p_quaternion.x && y == p_quaternion.y && z == p_quaternion.z && w == p_quaternion.w;
}
bool Quaternion::operator!=(const Quaternion &p_quaternion) const {
constexpr bool Quaternion::operator!=(const Quaternion &p_quaternion) const {
return x != p_quaternion.x || y != p_quaternion.y || z != p_quaternion.z || w != p_quaternion.w;
}
_FORCE_INLINE_ Quaternion operator*(real_t p_real, const Quaternion &p_quaternion) {
return p_quaternion * p_real;
constexpr void Quaternion::operator*=(const Quaternion &p_q) {
real_t xx = w * p_q.x + x * p_q.w + y * p_q.z - z * p_q.y;
real_t yy = w * p_q.y + y * p_q.w + z * p_q.x - x * p_q.z;
real_t zz = w * p_q.z + z * p_q.w + x * p_q.y - y * p_q.x;
w = w * p_q.w - x * p_q.x - y * p_q.y - z * p_q.z;
x = xx;
y = yy;
z = zz;
}
#endif // QUATERNION_H
constexpr Quaternion Quaternion::operator*(const Quaternion &p_q) const {
Quaternion r = *this;
r *= p_q;
return r;
}
constexpr Quaternion operator*(real_t p_real, const Quaternion &p_quaternion) {
return p_quaternion * p_real;
}

View file

@ -30,6 +30,9 @@
#include "quick_hull.h"
#include "core/templates/hash_map.h"
#include "core/templates/hash_set.h"
uint32_t QuickHull::debug_stop_after = 0xFFFFFFFF;
Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_mesh) {
@ -320,7 +323,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_
for (List<Face>::Element *&E : new_faces) {
Face &f2 = E->get();
if (f2.points_over.size() == 0) {
if (f2.points_over.is_empty()) {
faces.move_to_front(E);
}
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef QUICK_HULL_H
#define QUICK_HULL_H
#pragma once
#include "core/math/geometry_3d.h"
#include "core/templates/list.h"
@ -89,5 +88,3 @@ public:
static uint32_t debug_stop_after;
static Error build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_mesh);
};
#endif // QUICK_HULL_H

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef RANDOM_NUMBER_GENERATOR_H
#define RANDOM_NUMBER_GENERATOR_H
#pragma once
#include "core/math/random_pcg.h"
#include "core/object/ref_counted.h"
@ -61,5 +60,3 @@ public:
RandomNumberGenerator() { randbase.randomize(); }
};
#endif // RANDOM_NUMBER_GENERATOR_H

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef RANDOM_PCG_H
#define RANDOM_PCG_H
#pragma once
#include "core/math/math_defs.h"
@ -135,19 +134,17 @@ public:
if (temp < CMP_EPSILON) {
temp += CMP_EPSILON; // To prevent generating of INF value in log function, resulting to return NaN value from this function.
}
return p_mean + p_deviation * (cos(Math_TAU * randd()) * sqrt(-2.0 * log(temp))); // Box-Muller transform.
return p_mean + p_deviation * (cos(Math::TAU * randd()) * sqrt(-2.0 * log(temp))); // Box-Muller transform.
}
_FORCE_INLINE_ float randfn(float p_mean, float p_deviation) {
float temp = randf();
if (temp < CMP_EPSILON) {
temp += CMP_EPSILON; // To prevent generating of INF value in log function, resulting to return NaN value from this function.
}
return p_mean + p_deviation * (cos((float)Math_TAU * randf()) * sqrt(-2.0 * log(temp))); // Box-Muller transform.
return p_mean + p_deviation * (cos((float)Math::TAU * randf()) * sqrt(-2.0 * log(temp))); // Box-Muller transform.
}
double random(double p_from, double p_to);
float random(float p_from, float p_to);
int random(int p_from, int p_to);
};
#endif // RANDOM_PCG_H

View file

@ -38,6 +38,10 @@ 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);
}
bool Rect2::is_same(const Rect2 &p_rect) const {
return position.is_same(p_rect.position) && size.is_same(p_rect.size);
}
bool Rect2::is_finite() const {
return position.is_finite() && size.is_finite();
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef RECT2_H
#define RECT2_H
#pragma once
#include "core/error/error_macros.h"
#include "core/math/vector2.h"
@ -203,10 +202,11 @@ struct [[nodiscard]] Rect2 {
}
bool is_equal_approx(const Rect2 &p_rect) const;
bool is_same(const Rect2 &p_rect) const;
bool is_finite() const;
bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; }
bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; }
constexpr bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; }
constexpr bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; }
inline Rect2 grow(real_t p_amount) const {
Rect2 g = *this;
@ -361,15 +361,16 @@ struct [[nodiscard]] Rect2 {
operator String() const;
operator Rect2i() const;
Rect2() {}
Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height) :
Rect2() = default;
constexpr Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height) :
position(Point2(p_x, p_y)),
size(Size2(p_width, p_height)) {
}
Rect2(const Point2 &p_pos, const Size2 &p_size) :
constexpr Rect2(const Point2 &p_pos, const Size2 &p_size) :
position(p_pos),
size(p_size) {
}
};
#endif // RECT2_H
template <>
struct is_zero_constructible<Rect2> : std::true_type {};

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef RECT2I_H
#define RECT2I_H
#pragma once
#include "core/error/error_macros.h"
#include "core/math/vector2i.h"
@ -144,8 +143,8 @@ struct [[nodiscard]] Rect2i {
return true;
}
bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; }
bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; }
constexpr bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; }
constexpr bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; }
Rect2i grow(int p_amount) const {
Rect2i g = *this;
@ -227,15 +226,16 @@ struct [[nodiscard]] Rect2i {
operator String() const;
operator Rect2() const;
Rect2i() {}
Rect2i(int p_x, int p_y, int p_width, int p_height) :
Rect2i() = default;
constexpr Rect2i(int p_x, int p_y, int p_width, int p_height) :
position(Point2i(p_x, p_y)),
size(Size2i(p_width, p_height)) {
}
Rect2i(const Point2i &p_pos, const Size2i &p_size) :
constexpr Rect2i(const Point2i &p_pos, const Size2i &p_size) :
position(p_pos),
size(p_size) {
}
};
#endif // RECT2I_H
template <>
struct is_zero_constructible<Rect2i> : std::true_type {};

View file

@ -28,21 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef STATIC_RAYCASTER_H
#define STATIC_RAYCASTER_H
#pragma once
#include "core/object/ref_counted.h"
#if !defined(__aligned)
#if defined(_WIN32) && defined(_MSC_VER)
#define __aligned(...) __declspec(align(__VA_ARGS__))
#else
#define __aligned(...) __attribute__((aligned(__VA_ARGS__)))
#endif
#endif
class StaticRaycaster : public RefCounted {
GDCLASS(StaticRaycaster, RefCounted)
protected:
@ -50,7 +39,7 @@ protected:
public:
// Compatible with embree4 rays.
struct __aligned(16) Ray {
struct alignas(16) Ray {
const static unsigned int INVALID_GEOMETRY_ID = ((unsigned int)-1); // from rtcore_common.h
/*! Default construction does nothing. */
@ -62,7 +51,7 @@ public:
_FORCE_INLINE_ Ray(const Vector3 &p_org,
const Vector3 &p_dir,
float p_tnear = 0.0f,
float p_tfar = INFINITY) :
float p_tfar = Math::INF) :
org(p_org),
tnear(p_tnear),
dir(p_dir),
@ -107,5 +96,3 @@ public:
static Ref<StaticRaycaster> create();
};
#endif // STATIC_RAYCASTER_H

View file

@ -71,12 +71,12 @@ void Transform2D::rotate(real_t p_angle) {
real_t Transform2D::get_skew() const {
real_t det = determinant();
return Math::acos(columns[0].normalized().dot(SIGN(det) * columns[1].normalized())) - (real_t)Math_PI * 0.5f;
return Math::acos(columns[0].normalized().dot(SIGN(det) * columns[1].normalized())) - (real_t)Math::PI * 0.5f;
}
void Transform2D::set_skew(real_t p_angle) {
real_t det = determinant();
columns[1] = SIGN(det) * columns[0].rotated(((real_t)Math_PI * 0.5f + p_angle)).normalized() * columns[1].length();
columns[1] = SIGN(det) * columns[0].rotated(((real_t)Math::PI * 0.5f + p_angle)).normalized() * columns[1].length();
}
real_t Transform2D::get_rotation() const {
@ -180,6 +180,10 @@ bool Transform2D::is_equal_approx(const Transform2D &p_transform) const {
return columns[0].is_equal_approx(p_transform.columns[0]) && columns[1].is_equal_approx(p_transform.columns[1]) && columns[2].is_equal_approx(p_transform.columns[2]);
}
bool Transform2D::is_same(const Transform2D &p_transform) const {
return columns[0].is_same(p_transform.columns[0]) && columns[1].is_same(p_transform.columns[1]) && columns[2].is_same(p_transform.columns[2]);
}
bool Transform2D::is_finite() const {
return columns[0].is_finite() && columns[1].is_finite() && columns[2].is_finite();
}
@ -191,26 +195,6 @@ Transform2D Transform2D::looking_at(const Vector2 &p_target) const {
return return_trans;
}
bool Transform2D::operator==(const Transform2D &p_transform) const {
for (int i = 0; i < 3; i++) {
if (columns[i] != p_transform.columns[i]) {
return false;
}
}
return true;
}
bool Transform2D::operator!=(const Transform2D &p_transform) const {
for (int i = 0; i < 3; i++) {
if (columns[i] != p_transform.columns[i]) {
return true;
}
}
return false;
}
void Transform2D::operator*=(const Transform2D &p_transform) {
columns[2] = xform(p_transform.columns[2]);
@ -283,30 +267,6 @@ Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, real_t
get_origin().lerp(p_transform.get_origin(), p_weight));
}
void Transform2D::operator*=(real_t p_val) {
columns[0] *= p_val;
columns[1] *= p_val;
columns[2] *= p_val;
}
Transform2D Transform2D::operator*(real_t p_val) const {
Transform2D ret(*this);
ret *= p_val;
return ret;
}
void Transform2D::operator/=(real_t p_val) {
columns[0] /= p_val;
columns[1] /= p_val;
columns[2] /= p_val;
}
Transform2D Transform2D::operator/(real_t p_val) const {
Transform2D ret(*this);
ret /= p_val;
return ret;
}
Transform2D::operator String() const {
return "[X: " + columns[0].operator String() +
", Y: " + columns[1].operator String() +

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef TRANSFORM_2D_H
#define TRANSFORM_2D_H
#pragma once
#include "core/math/math_funcs.h"
#include "core/math/rect2.h"
@ -53,13 +52,17 @@ struct [[nodiscard]] Transform2D {
// WARNING: Be aware that unlike 3D code, 2D code uses a left-handed coordinate system:
// Y-axis points down, and angle is measure from +X to +Y in a clockwise-fashion.
Vector2 columns[3];
Vector2 columns[3] = {
{ 1, 0 },
{ 0, 1 },
{ 0, 0 },
};
_FORCE_INLINE_ real_t tdotx(const Vector2 &p_v) const { return columns[0][0] * p_v.x + columns[1][0] * p_v.y; }
_FORCE_INLINE_ real_t tdoty(const Vector2 &p_v) const { return columns[0][1] * p_v.x + columns[1][1] * p_v.y; }
const Vector2 &operator[](int p_idx) const { return columns[p_idx]; }
Vector2 &operator[](int p_idx) { return columns[p_idx]; }
constexpr const Vector2 &operator[](int p_idx) const { return columns[p_idx]; }
constexpr Vector2 &operator[](int p_idx) { return columns[p_idx]; }
void invert();
Transform2D inverse() const;
@ -101,19 +104,20 @@ struct [[nodiscard]] Transform2D {
Transform2D orthonormalized() const;
bool is_conformal() const;
bool is_equal_approx(const Transform2D &p_transform) const;
bool is_same(const Transform2D &p_transform) const;
bool is_finite() const;
Transform2D looking_at(const Vector2 &p_target) const;
bool operator==(const Transform2D &p_transform) const;
bool operator!=(const Transform2D &p_transform) const;
constexpr bool operator==(const Transform2D &p_transform) const;
constexpr bool operator!=(const Transform2D &p_transform) const;
void operator*=(const Transform2D &p_transform);
Transform2D operator*(const Transform2D &p_transform) const;
void operator*=(real_t p_val);
Transform2D operator*(real_t p_val) const;
void operator/=(real_t p_val);
Transform2D operator/(real_t p_val) const;
constexpr void operator*=(real_t p_val);
constexpr Transform2D operator*(real_t p_val) const;
constexpr void operator/=(real_t p_val);
constexpr Transform2D operator/(real_t p_val) const;
Transform2D interpolate_with(const Transform2D &p_transform, real_t p_c) const;
@ -128,31 +132,67 @@ struct [[nodiscard]] Transform2D {
operator String() const;
Transform2D(real_t p_xx, real_t p_xy, real_t p_yx, real_t p_yy, real_t p_ox, real_t p_oy) {
columns[0][0] = p_xx;
columns[0][1] = p_xy;
columns[1][0] = p_yx;
columns[1][1] = p_yy;
columns[2][0] = p_ox;
columns[2][1] = p_oy;
}
constexpr Transform2D(real_t p_xx, real_t p_xy, real_t p_yx, real_t p_yy, real_t p_ox, real_t p_oy) :
columns{
{ p_xx, p_xy },
{ p_yx, p_yy },
{ p_ox, p_oy },
} {}
Transform2D(const Vector2 &p_x, const Vector2 &p_y, const Vector2 &p_origin) {
columns[0] = p_x;
columns[1] = p_y;
columns[2] = p_origin;
}
constexpr Transform2D(const Vector2 &p_x, const Vector2 &p_y, const Vector2 &p_origin) :
columns{ p_x, p_y, p_origin } {}
Transform2D(real_t p_rot, const Vector2 &p_pos);
Transform2D(real_t p_rot, const Size2 &p_scale, real_t p_skew, const Vector2 &p_pos);
Transform2D() {
columns[0][0] = 1.0;
columns[1][1] = 1.0;
}
Transform2D() = default;
};
constexpr bool Transform2D::operator==(const Transform2D &p_transform) const {
for (int i = 0; i < 3; i++) {
if (columns[i] != p_transform.columns[i]) {
return false;
}
}
return true;
}
constexpr bool Transform2D::operator!=(const Transform2D &p_transform) const {
for (int i = 0; i < 3; i++) {
if (columns[i] != p_transform.columns[i]) {
return true;
}
}
return false;
}
constexpr void Transform2D::operator*=(real_t p_val) {
columns[0] *= p_val;
columns[1] *= p_val;
columns[2] *= p_val;
}
constexpr Transform2D Transform2D::operator*(real_t p_val) const {
Transform2D ret(*this);
ret *= p_val;
return ret;
}
constexpr void Transform2D::operator/=(real_t p_val) {
columns[0] /= p_val;
columns[1] /= p_val;
columns[2] /= p_val;
}
constexpr Transform2D Transform2D::operator/(real_t p_val) const {
Transform2D ret(*this);
ret /= p_val;
return ret;
}
Vector2 Transform2D::basis_xform(const Vector2 &p_vec) const {
return Vector2(
tdotx(p_vec),
@ -249,5 +289,3 @@ Vector<Vector2> Transform2D::xform_inv(const Vector<Vector2> &p_array) const {
}
return array;
}
#endif // TRANSFORM_2D_H

View file

@ -173,18 +173,14 @@ bool Transform3D::is_equal_approx(const Transform3D &p_transform) const {
return basis.is_equal_approx(p_transform.basis) && origin.is_equal_approx(p_transform.origin);
}
bool Transform3D::is_same(const Transform3D &p_transform) const {
return basis.is_same(p_transform.basis) && origin.is_same(p_transform.origin);
}
bool Transform3D::is_finite() const {
return basis.is_finite() && origin.is_finite();
}
bool Transform3D::operator==(const Transform3D &p_transform) const {
return (basis == p_transform.basis && origin == p_transform.origin);
}
bool Transform3D::operator!=(const Transform3D &p_transform) const {
return (basis != p_transform.basis || origin != p_transform.origin);
}
void Transform3D::operator*=(const Transform3D &p_transform) {
origin = xform(p_transform.origin);
basis *= p_transform.basis;
@ -196,48 +192,9 @@ Transform3D Transform3D::operator*(const Transform3D &p_transform) const {
return t;
}
void Transform3D::operator*=(real_t p_val) {
origin *= p_val;
basis *= p_val;
}
Transform3D Transform3D::operator*(real_t p_val) const {
Transform3D ret(*this);
ret *= p_val;
return ret;
}
void Transform3D::operator/=(real_t p_val) {
basis /= p_val;
origin /= p_val;
}
Transform3D Transform3D::operator/(real_t p_val) const {
Transform3D ret(*this);
ret /= p_val;
return ret;
}
Transform3D::operator String() const {
return "[X: " + basis.get_column(0).operator String() +
", Y: " + basis.get_column(1).operator String() +
", Z: " + basis.get_column(2).operator String() +
", O: " + origin.operator String() + "]";
}
Transform3D::Transform3D(const Basis &p_basis, const Vector3 &p_origin) :
basis(p_basis),
origin(p_origin) {
}
Transform3D::Transform3D(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin) :
origin(p_origin) {
basis.set_column(0, p_x);
basis.set_column(1, p_y);
basis.set_column(2, p_z);
}
Transform3D::Transform3D(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_ox, real_t p_oy, real_t p_oz) {
basis = Basis(p_xx, p_xy, p_xz, p_yx, p_yy, p_yz, p_zx, p_zy, p_zz);
origin = Vector3(p_ox, p_oy, p_oz);
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef TRANSFORM_3D_H
#define TRANSFORM_3D_H
#pragma once
#include "core/math/aabb.h"
#include "core/math/basis.h"
@ -75,10 +74,11 @@ struct [[nodiscard]] Transform3D {
void orthogonalize();
Transform3D orthogonalized() const;
bool is_equal_approx(const Transform3D &p_transform) const;
bool is_same(const Transform3D &p_transform) const;
bool is_finite() const;
bool operator==(const Transform3D &p_transform) const;
bool operator!=(const Transform3D &p_transform) const;
constexpr bool operator==(const Transform3D &p_transform) const;
constexpr bool operator!=(const Transform3D &p_transform) const;
_FORCE_INLINE_ Vector3 xform(const Vector3 &p_vector) const;
_FORCE_INLINE_ AABB xform(const AABB &p_aabb) const;
@ -102,10 +102,10 @@ struct [[nodiscard]] Transform3D {
void operator*=(const Transform3D &p_transform);
Transform3D operator*(const Transform3D &p_transform) const;
void operator*=(real_t p_val);
Transform3D operator*(real_t p_val) const;
void operator/=(real_t p_val);
Transform3D operator/(real_t p_val) const;
constexpr void operator*=(real_t p_val);
constexpr Transform3D operator*(real_t p_val) const;
constexpr void operator/=(real_t p_val);
constexpr Transform3D operator/(real_t p_val) const;
Transform3D interpolate_with(const Transform3D &p_transform, real_t p_c) const;
@ -124,12 +124,48 @@ struct [[nodiscard]] Transform3D {
operator String() const;
Transform3D() {}
Transform3D(const Basis &p_basis, const Vector3 &p_origin = Vector3());
Transform3D(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin);
Transform3D(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_ox, real_t p_oy, real_t p_oz);
Transform3D() = default;
constexpr Transform3D(const Basis &p_basis, const Vector3 &p_origin = Vector3()) :
basis(p_basis),
origin(p_origin) {}
constexpr Transform3D(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin) :
basis(p_x, p_y, p_z),
origin(p_origin) {}
constexpr Transform3D(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_ox, real_t p_oy, real_t p_oz) :
basis(p_xx, p_xy, p_xz, p_yx, p_yy, p_yz, p_zx, p_zy, p_zz),
origin(p_ox, p_oy, p_oz) {}
};
constexpr bool Transform3D::operator==(const Transform3D &p_transform) const {
return (basis == p_transform.basis && origin == p_transform.origin);
}
constexpr bool Transform3D::operator!=(const Transform3D &p_transform) const {
return (basis != p_transform.basis || origin != p_transform.origin);
}
constexpr void Transform3D::operator*=(real_t p_val) {
origin *= p_val;
basis *= p_val;
}
constexpr Transform3D Transform3D::operator*(real_t p_val) const {
Transform3D ret(*this);
ret *= p_val;
return ret;
}
constexpr void Transform3D::operator/=(real_t p_val) {
basis /= p_val;
origin /= p_val;
}
constexpr Transform3D Transform3D::operator/(real_t p_val) const {
Transform3D ret(*this);
ret /= p_val;
return ret;
}
_FORCE_INLINE_ Vector3 Transform3D::xform(const Vector3 &p_vector) const {
return Vector3(
basis[0].dot(p_vector) + origin.x,
@ -269,5 +305,3 @@ _FORCE_INLINE_ Plane Transform3D::xform_inv_fast(const Plane &p_plane, const Tra
real_t d = normal.dot(point);
return Plane(normal, d);
}
#endif // TRANSFORM_3D_H

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef TRANSFORM_INTERPOLATOR_H
#define TRANSFORM_INTERPOLATOR_H
#pragma once
#include "core/math/math_defs.h"
#include "core/math/vector3.h"
@ -91,5 +90,3 @@ public:
static Method find_method(const Basis &p_a, const Basis &p_b);
};
#endif // TRANSFORM_INTERPOLATOR_H

View file

@ -182,7 +182,11 @@ void TriangleMesh::create(const Vector<Vector3> &p_faces, const Vector<int32_t>
valid = true;
}
bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index) const {
bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index, int32_t *r_face_index) const {
if (!valid) {
return false;
}
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth);
enum {
@ -234,6 +238,9 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en
if (r_surf_index) {
*r_surf_index = s.surface_index;
}
if (r_face_index) {
*r_face_index = b.face_index;
}
inters = true;
}
}
@ -283,7 +290,11 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en
return inters;
}
bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index) const {
bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index, int32_t *r_face_index) const {
if (!valid) {
return false;
}
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth);
enum {
@ -335,6 +346,9 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V
if (r_surf_index) {
*r_surf_index = s.surface_index;
}
if (r_face_index) {
*r_face_index = b.face_index;
}
inters = true;
}
}
@ -385,6 +399,10 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V
}
bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, Vector3 p_scale) const {
if (!valid) {
return false;
}
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth);
enum {
@ -503,6 +521,85 @@ Vector<Face3> TriangleMesh::get_faces() const {
return faces;
}
bool TriangleMesh::create_from_faces(const Vector<Vector3> &p_faces) {
create(p_faces);
return is_valid();
}
Dictionary TriangleMesh::intersect_segment_scriptwrap(const Vector3 &p_begin, const Vector3 &p_end) const {
if (!valid) {
return Dictionary();
}
Vector3 r_point;
Vector3 r_normal;
int32_t r_face_index = -1;
bool intersected = intersect_segment(p_begin, p_end, r_point, r_normal, nullptr, &r_face_index);
if (!intersected) {
return Dictionary();
}
Dictionary result;
result["position"] = r_point;
result["normal"] = r_normal;
result["face_index"] = r_face_index;
return result;
}
Dictionary TriangleMesh::intersect_ray_scriptwrap(const Vector3 &p_begin, const Vector3 &p_dir) const {
if (!valid) {
return Dictionary();
}
Vector3 r_point;
Vector3 r_normal;
int32_t r_face_index = -1;
bool intersected = intersect_ray(p_begin, p_dir, r_point, r_normal, nullptr, &r_face_index);
if (!intersected) {
return Dictionary();
}
Dictionary result;
result["position"] = r_point;
result["normal"] = r_normal;
result["face_index"] = r_face_index;
return result;
}
Vector<Vector3> TriangleMesh::get_faces_scriptwrap() const {
if (!valid) {
return Vector<Vector3>();
}
Vector<Vector3> faces;
int ts = triangles.size();
faces.resize(triangles.size() * 3);
Vector3 *w = faces.ptrw();
const Triangle *r = triangles.ptr();
const Vector3 *rv = vertices.ptr();
for (int i = 0; i < ts; i++) {
for (int j = 0; j < 3; j++) {
w[i * 3 + j] = rv[r[i].indices[j]];
}
}
return faces;
}
void TriangleMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_from_faces", "faces"), &TriangleMesh::create_from_faces);
ClassDB::bind_method(D_METHOD("get_faces"), &TriangleMesh::get_faces_scriptwrap);
ClassDB::bind_method(D_METHOD("intersect_segment", "begin", "end"), &TriangleMesh::intersect_segment_scriptwrap);
ClassDB::bind_method(D_METHOD("intersect_ray", "begin", "dir"), &TriangleMesh::intersect_ray_scriptwrap);
}
TriangleMesh::TriangleMesh() {
valid = false;
max_depth = 0;

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef TRIANGLE_MESH_H
#define TRIANGLE_MESH_H
#pragma once
#include "core/math/face3.h"
#include "core/object/ref_counted.h"
@ -41,9 +40,12 @@ public:
struct Triangle {
Vector3 normal;
int indices[3];
int32_t surface_index;
int32_t surface_index = 0;
};
protected:
static void _bind_methods();
private:
Vector<Triangle> triangles;
Vector<Vector3> vertices;
@ -51,10 +53,10 @@ private:
struct BVH {
AABB aabb;
Vector3 center; //used for sorting
int left;
int right;
int left = -1;
int right = -1;
int face_index;
int32_t face_index = -1;
};
struct BVHCmpX {
@ -77,13 +79,13 @@ private:
int _create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc);
Vector<BVH> bvh;
int max_depth;
bool valid;
int max_depth = 0;
bool valid = false;
public:
bool is_valid() const;
bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const;
bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const;
bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr, int32_t *r_face_index = nullptr) const;
bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr, int32_t *r_face_index = nullptr) const;
bool inside_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, Vector3 p_scale = Vector3(1, 1, 1)) const;
Vector<Face3> get_faces() const;
@ -92,7 +94,13 @@ public:
void get_indices(Vector<int> *r_triangles_indices) const;
void create(const Vector<Vector3> &p_faces, const Vector<int32_t> &p_surface_indices = Vector<int32_t>());
// Wrapped functions for compatibility with method bindings
// and user exposed script api that can't use more native types.
bool create_from_faces(const Vector<Vector3> &p_faces);
Dictionary intersect_segment_scriptwrap(const Vector3 &p_begin, const Vector3 &p_end) const;
Dictionary intersect_ray_scriptwrap(const Vector3 &p_begin, const Vector3 &p_dir) const;
Vector<Vector3> get_faces_scriptwrap() const;
TriangleMesh();
};
#endif // TRIANGLE_MESH_H

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef TRIANGULATE_H
#define TRIANGULATE_H
#pragma once
#include "core/math/vector2.h"
#include "core/templates/vector.h"
@ -58,5 +57,3 @@ public:
private:
static bool snip(const Vector<Vector2> &p_contour, int u, int v, int w, int n, const Vector<int> &V, bool relaxed);
};
#endif // TRIANGULATE_H

View file

@ -194,6 +194,10 @@ bool Vector2::is_equal_approx(const Vector2 &p_v) const {
return Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y);
}
bool Vector2::is_same(const Vector2 &p_v) const {
return Math::is_same(x, p_v.x) && Math::is_same(y, p_v.y);
}
bool Vector2::is_zero_approx() const {
return Math::is_zero_approx(x) && Math::is_zero_approx(y);
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef VECTOR2_H
#define VECTOR2_H
#pragma once
#include "core/error/error_macros.h"
#include "core/math/math_funcs.h"
@ -46,18 +45,19 @@ struct [[nodiscard]] Vector2 {
};
union {
// NOLINTBEGIN(modernize-use-default-member-init)
struct {
union {
real_t x;
real_t width;
};
union {
real_t y;
real_t height;
};
real_t x;
real_t y;
};
struct {
real_t width;
real_t height;
};
real_t coord[2] = { 0 };
// NOLINTEND(modernize-use-default-member-init)
};
_FORCE_INLINE_ real_t &operator[](int p_axis) {
@ -129,35 +129,36 @@ struct [[nodiscard]] Vector2 {
Vector2 reflect(const Vector2 &p_normal) const;
bool is_equal_approx(const Vector2 &p_v) const;
bool is_same(const Vector2 &p_v) const;
bool is_zero_approx() const;
bool is_finite() const;
Vector2 operator+(const Vector2 &p_v) const;
void operator+=(const Vector2 &p_v);
Vector2 operator-(const Vector2 &p_v) const;
void operator-=(const Vector2 &p_v);
Vector2 operator*(const Vector2 &p_v1) const;
constexpr Vector2 operator+(const Vector2 &p_v) const;
constexpr void operator+=(const Vector2 &p_v);
constexpr Vector2 operator-(const Vector2 &p_v) const;
constexpr void operator-=(const Vector2 &p_v);
constexpr Vector2 operator*(const Vector2 &p_v1) const;
Vector2 operator*(real_t p_rvalue) const;
void operator*=(real_t p_rvalue);
void operator*=(const Vector2 &p_rvalue) { *this = *this * p_rvalue; }
constexpr Vector2 operator*(real_t p_rvalue) const;
constexpr void operator*=(real_t p_rvalue);
constexpr void operator*=(const Vector2 &p_rvalue) { *this = *this * p_rvalue; }
Vector2 operator/(const Vector2 &p_v1) const;
constexpr Vector2 operator/(const Vector2 &p_v1) const;
Vector2 operator/(real_t p_rvalue) const;
constexpr Vector2 operator/(real_t p_rvalue) const;
void operator/=(real_t p_rvalue);
void operator/=(const Vector2 &p_rvalue) { *this = *this / p_rvalue; }
constexpr void operator/=(real_t p_rvalue);
constexpr void operator/=(const Vector2 &p_rvalue) { *this = *this / p_rvalue; }
Vector2 operator-() const;
constexpr Vector2 operator-() const;
bool operator==(const Vector2 &p_vec2) const;
bool operator!=(const Vector2 &p_vec2) const;
constexpr bool operator==(const Vector2 &p_vec2) const;
constexpr bool operator!=(const Vector2 &p_vec2) const;
bool operator<(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y < p_vec2.y) : (x < p_vec2.x); }
bool operator>(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y > p_vec2.y) : (x > p_vec2.x); }
bool operator<=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); }
bool operator>=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); }
constexpr bool operator<(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y < p_vec2.y) : (x < p_vec2.x); }
constexpr bool operator>(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y > p_vec2.y) : (x > p_vec2.x); }
constexpr bool operator<=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); }
constexpr bool operator>=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); }
real_t angle() const;
static Vector2 from_angle(real_t p_angle);
@ -184,70 +185,71 @@ struct [[nodiscard]] Vector2 {
operator String() const;
operator Vector2i() const;
_FORCE_INLINE_ Vector2() {}
_FORCE_INLINE_ Vector2(real_t p_x, real_t p_y) {
x = p_x;
y = p_y;
}
// NOLINTBEGIN(cppcoreguidelines-pro-type-member-init)
constexpr Vector2() :
x(0), y(0) {}
constexpr Vector2(real_t p_x, real_t p_y) :
x(p_x), y(p_y) {}
// NOLINTEND(cppcoreguidelines-pro-type-member-init)
};
_FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2 &p_vec) const {
return p_vec - *this * (dot(p_vec) - p_d);
}
_FORCE_INLINE_ Vector2 Vector2::operator+(const Vector2 &p_v) const {
constexpr Vector2 Vector2::operator+(const Vector2 &p_v) const {
return Vector2(x + p_v.x, y + p_v.y);
}
_FORCE_INLINE_ void Vector2::operator+=(const Vector2 &p_v) {
constexpr void Vector2::operator+=(const Vector2 &p_v) {
x += p_v.x;
y += p_v.y;
}
_FORCE_INLINE_ Vector2 Vector2::operator-(const Vector2 &p_v) const {
constexpr Vector2 Vector2::operator-(const Vector2 &p_v) const {
return Vector2(x - p_v.x, y - p_v.y);
}
_FORCE_INLINE_ void Vector2::operator-=(const Vector2 &p_v) {
constexpr void Vector2::operator-=(const Vector2 &p_v) {
x -= p_v.x;
y -= p_v.y;
}
_FORCE_INLINE_ Vector2 Vector2::operator*(const Vector2 &p_v1) const {
constexpr Vector2 Vector2::operator*(const Vector2 &p_v1) const {
return Vector2(x * p_v1.x, y * p_v1.y);
}
_FORCE_INLINE_ Vector2 Vector2::operator*(real_t p_rvalue) const {
constexpr Vector2 Vector2::operator*(real_t p_rvalue) const {
return Vector2(x * p_rvalue, y * p_rvalue);
}
_FORCE_INLINE_ void Vector2::operator*=(real_t p_rvalue) {
constexpr void Vector2::operator*=(real_t p_rvalue) {
x *= p_rvalue;
y *= p_rvalue;
}
_FORCE_INLINE_ Vector2 Vector2::operator/(const Vector2 &p_v1) const {
constexpr Vector2 Vector2::operator/(const Vector2 &p_v1) const {
return Vector2(x / p_v1.x, y / p_v1.y);
}
_FORCE_INLINE_ Vector2 Vector2::operator/(real_t p_rvalue) const {
constexpr Vector2 Vector2::operator/(real_t p_rvalue) const {
return Vector2(x / p_rvalue, y / p_rvalue);
}
_FORCE_INLINE_ void Vector2::operator/=(real_t p_rvalue) {
constexpr void Vector2::operator/=(real_t p_rvalue) {
x /= p_rvalue;
y /= p_rvalue;
}
_FORCE_INLINE_ Vector2 Vector2::operator-() const {
constexpr Vector2 Vector2::operator-() const {
return Vector2(-x, -y);
}
_FORCE_INLINE_ bool Vector2::operator==(const Vector2 &p_vec2) const {
constexpr bool Vector2::operator==(const Vector2 &p_vec2) const {
return x == p_vec2.x && y == p_vec2.y;
}
_FORCE_INLINE_ bool Vector2::operator!=(const Vector2 &p_vec2) const {
constexpr bool Vector2::operator!=(const Vector2 &p_vec2) const {
return x != p_vec2.x || y != p_vec2.y;
}
@ -308,23 +310,24 @@ Vector2 Vector2::direction_to(const Vector2 &p_to) const {
// Multiplication operators required to workaround issues with LLVM using implicit conversion
// to Vector2i instead for integers where it should not.
_FORCE_INLINE_ Vector2 operator*(float p_scalar, const Vector2 &p_vec) {
constexpr Vector2 operator*(float p_scalar, const Vector2 &p_vec) {
return p_vec * p_scalar;
}
_FORCE_INLINE_ Vector2 operator*(double p_scalar, const Vector2 &p_vec) {
constexpr Vector2 operator*(double p_scalar, const Vector2 &p_vec) {
return p_vec * p_scalar;
}
_FORCE_INLINE_ Vector2 operator*(int32_t p_scalar, const Vector2 &p_vec) {
constexpr Vector2 operator*(int32_t p_scalar, const Vector2 &p_vec) {
return p_vec * p_scalar;
}
_FORCE_INLINE_ Vector2 operator*(int64_t p_scalar, const Vector2 &p_vec) {
constexpr Vector2 operator*(int64_t p_scalar, const Vector2 &p_vec) {
return p_vec * p_scalar;
}
typedef Vector2 Size2;
typedef Vector2 Point2;
#endif // VECTOR2_H
template <>
struct is_zero_constructible<Vector2> : std::true_type {};

View file

@ -65,75 +65,6 @@ double Vector2i::length() const {
return Math::sqrt((double)length_squared());
}
Vector2i Vector2i::operator+(const Vector2i &p_v) const {
return Vector2i(x + p_v.x, y + p_v.y);
}
void Vector2i::operator+=(const Vector2i &p_v) {
x += p_v.x;
y += p_v.y;
}
Vector2i Vector2i::operator-(const Vector2i &p_v) const {
return Vector2i(x - p_v.x, y - p_v.y);
}
void Vector2i::operator-=(const Vector2i &p_v) {
x -= p_v.x;
y -= p_v.y;
}
Vector2i Vector2i::operator*(const Vector2i &p_v1) const {
return Vector2i(x * p_v1.x, y * p_v1.y);
}
Vector2i Vector2i::operator*(int32_t p_rvalue) const {
return Vector2i(x * p_rvalue, y * p_rvalue);
}
void Vector2i::operator*=(int32_t p_rvalue) {
x *= p_rvalue;
y *= p_rvalue;
}
Vector2i Vector2i::operator/(const Vector2i &p_v1) const {
return Vector2i(x / p_v1.x, y / p_v1.y);
}
Vector2i Vector2i::operator/(int32_t p_rvalue) const {
return Vector2i(x / p_rvalue, y / p_rvalue);
}
void Vector2i::operator/=(int32_t p_rvalue) {
x /= p_rvalue;
y /= p_rvalue;
}
Vector2i Vector2i::operator%(const Vector2i &p_v1) const {
return Vector2i(x % p_v1.x, y % p_v1.y);
}
Vector2i Vector2i::operator%(int32_t p_rvalue) const {
return Vector2i(x % p_rvalue, y % p_rvalue);
}
void Vector2i::operator%=(int32_t p_rvalue) {
x %= p_rvalue;
y %= p_rvalue;
}
Vector2i Vector2i::operator-() const {
return Vector2i(-x, -y);
}
bool Vector2i::operator==(const Vector2i &p_vec2) const {
return x == p_vec2.x && y == p_vec2.y;
}
bool Vector2i::operator!=(const Vector2i &p_vec2) const {
return x != p_vec2.x || y != p_vec2.y;
}
Vector2i::operator String() const {
return "(" + itos(x) + ", " + itos(y) + ")";
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef VECTOR2I_H
#define VECTOR2I_H
#pragma once
#include "core/error/error_macros.h"
#include "core/math/math_funcs.h"
@ -46,18 +45,19 @@ struct [[nodiscard]] Vector2i {
};
union {
// NOLINTBEGIN(modernize-use-default-member-init)
struct {
union {
int32_t x;
int32_t width;
};
union {
int32_t y;
int32_t height;
};
int32_t x;
int32_t y;
};
struct {
int32_t width;
int32_t height;
};
int32_t coord[2] = { 0 };
// NOLINTEND(modernize-use-default-member-init)
};
_FORCE_INLINE_ int32_t &operator[](int p_axis) {
@ -101,32 +101,32 @@ struct [[nodiscard]] Vector2i {
return (p_to - *this).length_squared();
}
Vector2i operator+(const Vector2i &p_v) const;
void operator+=(const Vector2i &p_v);
Vector2i operator-(const Vector2i &p_v) const;
void operator-=(const Vector2i &p_v);
Vector2i operator*(const Vector2i &p_v1) const;
constexpr Vector2i operator+(const Vector2i &p_v) const;
constexpr void operator+=(const Vector2i &p_v);
constexpr Vector2i operator-(const Vector2i &p_v) const;
constexpr void operator-=(const Vector2i &p_v);
constexpr Vector2i operator*(const Vector2i &p_v1) const;
Vector2i operator*(int32_t p_rvalue) const;
void operator*=(int32_t p_rvalue);
constexpr Vector2i operator*(int32_t p_rvalue) const;
constexpr void operator*=(int32_t p_rvalue);
Vector2i operator/(const Vector2i &p_v1) const;
Vector2i operator/(int32_t p_rvalue) const;
void operator/=(int32_t p_rvalue);
constexpr Vector2i operator/(const Vector2i &p_v1) const;
constexpr Vector2i operator/(int32_t p_rvalue) const;
constexpr void operator/=(int32_t p_rvalue);
Vector2i operator%(const Vector2i &p_v1) const;
Vector2i operator%(int32_t p_rvalue) const;
void operator%=(int32_t p_rvalue);
constexpr Vector2i operator%(const Vector2i &p_v1) const;
constexpr Vector2i operator%(int32_t p_rvalue) const;
constexpr void operator%=(int32_t p_rvalue);
Vector2i operator-() const;
bool operator<(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); }
bool operator>(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); }
constexpr Vector2i operator-() const;
constexpr bool operator<(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); }
constexpr bool operator>(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); }
bool operator<=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); }
bool operator>=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); }
constexpr bool operator<=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); }
constexpr bool operator>=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); }
bool operator==(const Vector2i &p_vec2) const;
bool operator!=(const Vector2i &p_vec2) const;
constexpr bool operator==(const Vector2i &p_vec2) const;
constexpr bool operator!=(const Vector2i &p_vec2) const;
int64_t length_squared() const;
double length() const;
@ -142,32 +142,103 @@ struct [[nodiscard]] Vector2i {
operator String() const;
operator Vector2() const;
inline Vector2i() {}
inline Vector2i(int32_t p_x, int32_t p_y) {
x = p_x;
y = p_y;
}
// NOLINTBEGIN(cppcoreguidelines-pro-type-member-init)
constexpr Vector2i() :
x(0), y(0) {}
constexpr Vector2i(int32_t p_x, int32_t p_y) :
x(p_x), y(p_y) {}
// NOLINTEND(cppcoreguidelines-pro-type-member-init)
};
constexpr Vector2i Vector2i::operator+(const Vector2i &p_v) const {
return Vector2i(x + p_v.x, y + p_v.y);
}
constexpr void Vector2i::operator+=(const Vector2i &p_v) {
x += p_v.x;
y += p_v.y;
}
constexpr Vector2i Vector2i::operator-(const Vector2i &p_v) const {
return Vector2i(x - p_v.x, y - p_v.y);
}
constexpr void Vector2i::operator-=(const Vector2i &p_v) {
x -= p_v.x;
y -= p_v.y;
}
constexpr Vector2i Vector2i::operator*(const Vector2i &p_v1) const {
return Vector2i(x * p_v1.x, y * p_v1.y);
}
constexpr Vector2i Vector2i::operator*(int32_t p_rvalue) const {
return Vector2i(x * p_rvalue, y * p_rvalue);
}
constexpr void Vector2i::operator*=(int32_t p_rvalue) {
x *= p_rvalue;
y *= p_rvalue;
}
constexpr Vector2i Vector2i::operator/(const Vector2i &p_v1) const {
return Vector2i(x / p_v1.x, y / p_v1.y);
}
constexpr Vector2i Vector2i::operator/(int32_t p_rvalue) const {
return Vector2i(x / p_rvalue, y / p_rvalue);
}
constexpr void Vector2i::operator/=(int32_t p_rvalue) {
x /= p_rvalue;
y /= p_rvalue;
}
constexpr Vector2i Vector2i::operator%(const Vector2i &p_v1) const {
return Vector2i(x % p_v1.x, y % p_v1.y);
}
constexpr Vector2i Vector2i::operator%(int32_t p_rvalue) const {
return Vector2i(x % p_rvalue, y % p_rvalue);
}
constexpr void Vector2i::operator%=(int32_t p_rvalue) {
x %= p_rvalue;
y %= p_rvalue;
}
constexpr Vector2i Vector2i::operator-() const {
return Vector2i(-x, -y);
}
constexpr bool Vector2i::operator==(const Vector2i &p_vec2) const {
return x == p_vec2.x && y == p_vec2.y;
}
constexpr bool Vector2i::operator!=(const Vector2i &p_vec2) const {
return x != p_vec2.x || y != p_vec2.y;
}
// Multiplication operators required to workaround issues with LLVM using implicit conversion.
_FORCE_INLINE_ Vector2i operator*(int32_t p_scalar, const Vector2i &p_vector) {
constexpr Vector2i operator*(int32_t p_scalar, const Vector2i &p_vector) {
return p_vector * p_scalar;
}
_FORCE_INLINE_ Vector2i operator*(int64_t p_scalar, const Vector2i &p_vector) {
constexpr Vector2i operator*(int64_t p_scalar, const Vector2i &p_vector) {
return p_vector * p_scalar;
}
_FORCE_INLINE_ Vector2i operator*(float p_scalar, const Vector2i &p_vector) {
constexpr Vector2i operator*(float p_scalar, const Vector2i &p_vector) {
return p_vector * p_scalar;
}
_FORCE_INLINE_ Vector2i operator*(double p_scalar, const Vector2i &p_vector) {
constexpr Vector2i operator*(double p_scalar, const Vector2i &p_vector) {
return p_vector * p_scalar;
}
typedef Vector2i Size2i;
typedef Vector2i Point2i;
#endif // VECTOR2I_H
template <>
struct is_zero_constructible<Vector2i> : std::true_type {};

View file

@ -156,6 +156,10 @@ bool Vector3::is_equal_approx(const Vector3 &p_v) const {
return Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y) && Math::is_equal_approx(z, p_v.z);
}
bool Vector3::is_same(const Vector3 &p_v) const {
return Math::is_same(x, p_v.x) && Math::is_same(y, p_v.y) && Math::is_same(z, p_v.z);
}
bool Vector3::is_zero_approx() const {
return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z);
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef VECTOR3_H
#define VECTOR3_H
#pragma once
#include "core/error/error_macros.h"
#include "core/math/math_funcs.h"
@ -49,6 +48,7 @@ struct [[nodiscard]] Vector3 {
};
union {
// NOLINTBEGIN(modernize-use-default-member-init)
struct {
real_t x;
real_t y;
@ -56,6 +56,7 @@ struct [[nodiscard]] Vector3 {
};
real_t coord[3] = { 0 };
// NOLINTEND(modernize-use-default-member-init)
};
_FORCE_INLINE_ const real_t &operator[](int p_axis) const {
@ -156,43 +157,42 @@ struct [[nodiscard]] Vector3 {
_FORCE_INLINE_ Vector3 reflect(const Vector3 &p_normal) const;
bool is_equal_approx(const Vector3 &p_v) const;
bool is_same(const Vector3 &p_v) const;
bool is_zero_approx() const;
bool is_finite() const;
/* Operators */
_FORCE_INLINE_ Vector3 &operator+=(const Vector3 &p_v);
_FORCE_INLINE_ Vector3 operator+(const Vector3 &p_v) const;
_FORCE_INLINE_ Vector3 &operator-=(const Vector3 &p_v);
_FORCE_INLINE_ Vector3 operator-(const Vector3 &p_v) const;
_FORCE_INLINE_ Vector3 &operator*=(const Vector3 &p_v);
_FORCE_INLINE_ Vector3 operator*(const Vector3 &p_v) const;
_FORCE_INLINE_ Vector3 &operator/=(const Vector3 &p_v);
_FORCE_INLINE_ Vector3 operator/(const Vector3 &p_v) const;
constexpr Vector3 &operator+=(const Vector3 &p_v);
constexpr Vector3 operator+(const Vector3 &p_v) const;
constexpr Vector3 &operator-=(const Vector3 &p_v);
constexpr Vector3 operator-(const Vector3 &p_v) const;
constexpr Vector3 &operator*=(const Vector3 &p_v);
constexpr Vector3 operator*(const Vector3 &p_v) const;
constexpr Vector3 &operator/=(const Vector3 &p_v);
constexpr Vector3 operator/(const Vector3 &p_v) const;
_FORCE_INLINE_ Vector3 &operator*=(real_t p_scalar);
_FORCE_INLINE_ Vector3 operator*(real_t p_scalar) const;
_FORCE_INLINE_ Vector3 &operator/=(real_t p_scalar);
_FORCE_INLINE_ Vector3 operator/(real_t p_scalar) const;
constexpr Vector3 &operator*=(real_t p_scalar);
constexpr Vector3 operator*(real_t p_scalar) const;
constexpr Vector3 &operator/=(real_t p_scalar);
constexpr Vector3 operator/(real_t p_scalar) const;
_FORCE_INLINE_ Vector3 operator-() const;
constexpr Vector3 operator-() const;
_FORCE_INLINE_ bool operator==(const Vector3 &p_v) const;
_FORCE_INLINE_ bool operator!=(const Vector3 &p_v) const;
_FORCE_INLINE_ bool operator<(const Vector3 &p_v) const;
_FORCE_INLINE_ bool operator<=(const Vector3 &p_v) const;
_FORCE_INLINE_ bool operator>(const Vector3 &p_v) const;
_FORCE_INLINE_ bool operator>=(const Vector3 &p_v) const;
constexpr bool operator==(const Vector3 &p_v) const;
constexpr bool operator!=(const Vector3 &p_v) const;
constexpr bool operator<(const Vector3 &p_v) const;
constexpr bool operator<=(const Vector3 &p_v) const;
constexpr bool operator>(const Vector3 &p_v) const;
constexpr bool operator>=(const Vector3 &p_v) const;
operator String() const;
operator Vector3i() const;
_FORCE_INLINE_ Vector3() {}
_FORCE_INLINE_ Vector3(real_t p_x, real_t p_y, real_t p_z) {
x = p_x;
y = p_y;
z = p_z;
}
constexpr Vector3() :
x(0), y(0), z(0) {}
constexpr Vector3(real_t p_x, real_t p_y, real_t p_z) :
x(p_x), y(p_y), z(p_z) {}
};
Vector3 Vector3::cross(const Vector3 &p_with) const {
@ -339,51 +339,51 @@ Vector3 Vector3::get_any_perpendicular() const {
/* Operators */
Vector3 &Vector3::operator+=(const Vector3 &p_v) {
constexpr Vector3 &Vector3::operator+=(const Vector3 &p_v) {
x += p_v.x;
y += p_v.y;
z += p_v.z;
return *this;
}
Vector3 Vector3::operator+(const Vector3 &p_v) const {
constexpr Vector3 Vector3::operator+(const Vector3 &p_v) const {
return Vector3(x + p_v.x, y + p_v.y, z + p_v.z);
}
Vector3 &Vector3::operator-=(const Vector3 &p_v) {
constexpr Vector3 &Vector3::operator-=(const Vector3 &p_v) {
x -= p_v.x;
y -= p_v.y;
z -= p_v.z;
return *this;
}
Vector3 Vector3::operator-(const Vector3 &p_v) const {
constexpr Vector3 Vector3::operator-(const Vector3 &p_v) const {
return Vector3(x - p_v.x, y - p_v.y, z - p_v.z);
}
Vector3 &Vector3::operator*=(const Vector3 &p_v) {
constexpr Vector3 &Vector3::operator*=(const Vector3 &p_v) {
x *= p_v.x;
y *= p_v.y;
z *= p_v.z;
return *this;
}
Vector3 Vector3::operator*(const Vector3 &p_v) const {
constexpr Vector3 Vector3::operator*(const Vector3 &p_v) const {
return Vector3(x * p_v.x, y * p_v.y, z * p_v.z);
}
Vector3 &Vector3::operator/=(const Vector3 &p_v) {
constexpr Vector3 &Vector3::operator/=(const Vector3 &p_v) {
x /= p_v.x;
y /= p_v.y;
z /= p_v.z;
return *this;
}
Vector3 Vector3::operator/(const Vector3 &p_v) const {
constexpr Vector3 Vector3::operator/(const Vector3 &p_v) const {
return Vector3(x / p_v.x, y / p_v.y, z / p_v.z);
}
Vector3 &Vector3::operator*=(real_t p_scalar) {
constexpr Vector3 &Vector3::operator*=(real_t p_scalar) {
x *= p_scalar;
y *= p_scalar;
z *= p_scalar;
@ -393,50 +393,50 @@ Vector3 &Vector3::operator*=(real_t p_scalar) {
// Multiplication operators required to workaround issues with LLVM using implicit conversion
// to Vector3i instead for integers where it should not.
_FORCE_INLINE_ Vector3 operator*(float p_scalar, const Vector3 &p_vec) {
constexpr Vector3 operator*(float p_scalar, const Vector3 &p_vec) {
return p_vec * p_scalar;
}
_FORCE_INLINE_ Vector3 operator*(double p_scalar, const Vector3 &p_vec) {
constexpr Vector3 operator*(double p_scalar, const Vector3 &p_vec) {
return p_vec * p_scalar;
}
_FORCE_INLINE_ Vector3 operator*(int32_t p_scalar, const Vector3 &p_vec) {
constexpr Vector3 operator*(int32_t p_scalar, const Vector3 &p_vec) {
return p_vec * p_scalar;
}
_FORCE_INLINE_ Vector3 operator*(int64_t p_scalar, const Vector3 &p_vec) {
constexpr Vector3 operator*(int64_t p_scalar, const Vector3 &p_vec) {
return p_vec * p_scalar;
}
Vector3 Vector3::operator*(real_t p_scalar) const {
constexpr Vector3 Vector3::operator*(real_t p_scalar) const {
return Vector3(x * p_scalar, y * p_scalar, z * p_scalar);
}
Vector3 &Vector3::operator/=(real_t p_scalar) {
constexpr Vector3 &Vector3::operator/=(real_t p_scalar) {
x /= p_scalar;
y /= p_scalar;
z /= p_scalar;
return *this;
}
Vector3 Vector3::operator/(real_t p_scalar) const {
constexpr Vector3 Vector3::operator/(real_t p_scalar) const {
return Vector3(x / p_scalar, y / p_scalar, z / p_scalar);
}
Vector3 Vector3::operator-() const {
constexpr Vector3 Vector3::operator-() const {
return Vector3(-x, -y, -z);
}
bool Vector3::operator==(const Vector3 &p_v) const {
constexpr bool Vector3::operator==(const Vector3 &p_v) const {
return x == p_v.x && y == p_v.y && z == p_v.z;
}
bool Vector3::operator!=(const Vector3 &p_v) const {
constexpr bool Vector3::operator!=(const Vector3 &p_v) const {
return x != p_v.x || y != p_v.y || z != p_v.z;
}
bool Vector3::operator<(const Vector3 &p_v) const {
constexpr bool Vector3::operator<(const Vector3 &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
return z < p_v.z;
@ -446,7 +446,7 @@ bool Vector3::operator<(const Vector3 &p_v) const {
return x < p_v.x;
}
bool Vector3::operator>(const Vector3 &p_v) const {
constexpr bool Vector3::operator>(const Vector3 &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
return z > p_v.z;
@ -456,7 +456,7 @@ bool Vector3::operator>(const Vector3 &p_v) const {
return x > p_v.x;
}
bool Vector3::operator<=(const Vector3 &p_v) const {
constexpr bool Vector3::operator<=(const Vector3 &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
return z <= p_v.z;
@ -466,7 +466,7 @@ bool Vector3::operator<=(const Vector3 &p_v) const {
return x < p_v.x;
}
bool Vector3::operator>=(const Vector3 &p_v) const {
constexpr bool Vector3::operator>=(const Vector3 &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
return z >= p_v.z;
@ -550,4 +550,5 @@ Vector3 Vector3::reflect(const Vector3 &p_normal) const {
return 2.0f * p_normal * dot(p_normal) - *this;
}
#endif // VECTOR3_H
template <>
struct is_zero_constructible<Vector3> : std::true_type {};

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef VECTOR3I_H
#define VECTOR3I_H
#pragma once
#include "core/error/error_macros.h"
#include "core/math/math_funcs.h"
@ -47,6 +46,7 @@ struct [[nodiscard]] Vector3i {
};
union {
// NOLINTBEGIN(modernize-use-default-member-init)
struct {
int32_t x;
int32_t y;
@ -54,6 +54,7 @@ struct [[nodiscard]] Vector3i {
};
int32_t coord[3] = { 0 };
// NOLINTEND(modernize-use-default-member-init)
};
_FORCE_INLINE_ const int32_t &operator[](int p_axis) const {
@ -102,42 +103,40 @@ struct [[nodiscard]] Vector3i {
/* Operators */
_FORCE_INLINE_ Vector3i &operator+=(const Vector3i &p_v);
_FORCE_INLINE_ Vector3i operator+(const Vector3i &p_v) const;
_FORCE_INLINE_ Vector3i &operator-=(const Vector3i &p_v);
_FORCE_INLINE_ Vector3i operator-(const Vector3i &p_v) const;
_FORCE_INLINE_ Vector3i &operator*=(const Vector3i &p_v);
_FORCE_INLINE_ Vector3i operator*(const Vector3i &p_v) const;
_FORCE_INLINE_ Vector3i &operator/=(const Vector3i &p_v);
_FORCE_INLINE_ Vector3i operator/(const Vector3i &p_v) const;
_FORCE_INLINE_ Vector3i &operator%=(const Vector3i &p_v);
_FORCE_INLINE_ Vector3i operator%(const Vector3i &p_v) const;
constexpr Vector3i &operator+=(const Vector3i &p_v);
constexpr Vector3i operator+(const Vector3i &p_v) const;
constexpr Vector3i &operator-=(const Vector3i &p_v);
constexpr Vector3i operator-(const Vector3i &p_v) const;
constexpr Vector3i &operator*=(const Vector3i &p_v);
constexpr Vector3i operator*(const Vector3i &p_v) const;
constexpr Vector3i &operator/=(const Vector3i &p_v);
constexpr Vector3i operator/(const Vector3i &p_v) const;
constexpr Vector3i &operator%=(const Vector3i &p_v);
constexpr Vector3i operator%(const Vector3i &p_v) const;
_FORCE_INLINE_ Vector3i &operator*=(int32_t p_scalar);
_FORCE_INLINE_ Vector3i operator*(int32_t p_scalar) const;
_FORCE_INLINE_ Vector3i &operator/=(int32_t p_scalar);
_FORCE_INLINE_ Vector3i operator/(int32_t p_scalar) const;
_FORCE_INLINE_ Vector3i &operator%=(int32_t p_scalar);
_FORCE_INLINE_ Vector3i operator%(int32_t p_scalar) const;
constexpr Vector3i &operator*=(int32_t p_scalar);
constexpr Vector3i operator*(int32_t p_scalar) const;
constexpr Vector3i &operator/=(int32_t p_scalar);
constexpr Vector3i operator/(int32_t p_scalar) const;
constexpr Vector3i &operator%=(int32_t p_scalar);
constexpr Vector3i operator%(int32_t p_scalar) const;
_FORCE_INLINE_ Vector3i operator-() const;
constexpr Vector3i operator-() const;
_FORCE_INLINE_ bool operator==(const Vector3i &p_v) const;
_FORCE_INLINE_ bool operator!=(const Vector3i &p_v) const;
_FORCE_INLINE_ bool operator<(const Vector3i &p_v) const;
_FORCE_INLINE_ bool operator<=(const Vector3i &p_v) const;
_FORCE_INLINE_ bool operator>(const Vector3i &p_v) const;
_FORCE_INLINE_ bool operator>=(const Vector3i &p_v) const;
constexpr bool operator==(const Vector3i &p_v) const;
constexpr bool operator!=(const Vector3i &p_v) const;
constexpr bool operator<(const Vector3i &p_v) const;
constexpr bool operator<=(const Vector3i &p_v) const;
constexpr bool operator>(const Vector3i &p_v) const;
constexpr bool operator>=(const Vector3i &p_v) const;
operator String() const;
operator Vector3() const;
_FORCE_INLINE_ Vector3i() {}
_FORCE_INLINE_ Vector3i(int32_t p_x, int32_t p_y, int32_t p_z) {
x = p_x;
y = p_y;
z = p_z;
}
constexpr Vector3i() :
x(0), y(0), z(0) {}
constexpr Vector3i(int32_t p_x, int32_t p_y, int32_t p_z) :
x(p_x), y(p_y), z(p_z) {}
};
int64_t Vector3i::length_squared() const {
@ -166,125 +165,125 @@ int64_t Vector3i::distance_squared_to(const Vector3i &p_to) const {
/* Operators */
Vector3i &Vector3i::operator+=(const Vector3i &p_v) {
constexpr Vector3i &Vector3i::operator+=(const Vector3i &p_v) {
x += p_v.x;
y += p_v.y;
z += p_v.z;
return *this;
}
Vector3i Vector3i::operator+(const Vector3i &p_v) const {
constexpr Vector3i Vector3i::operator+(const Vector3i &p_v) const {
return Vector3i(x + p_v.x, y + p_v.y, z + p_v.z);
}
Vector3i &Vector3i::operator-=(const Vector3i &p_v) {
constexpr Vector3i &Vector3i::operator-=(const Vector3i &p_v) {
x -= p_v.x;
y -= p_v.y;
z -= p_v.z;
return *this;
}
Vector3i Vector3i::operator-(const Vector3i &p_v) const {
constexpr Vector3i Vector3i::operator-(const Vector3i &p_v) const {
return Vector3i(x - p_v.x, y - p_v.y, z - p_v.z);
}
Vector3i &Vector3i::operator*=(const Vector3i &p_v) {
constexpr Vector3i &Vector3i::operator*=(const Vector3i &p_v) {
x *= p_v.x;
y *= p_v.y;
z *= p_v.z;
return *this;
}
Vector3i Vector3i::operator*(const Vector3i &p_v) const {
constexpr Vector3i Vector3i::operator*(const Vector3i &p_v) const {
return Vector3i(x * p_v.x, y * p_v.y, z * p_v.z);
}
Vector3i &Vector3i::operator/=(const Vector3i &p_v) {
constexpr Vector3i &Vector3i::operator/=(const Vector3i &p_v) {
x /= p_v.x;
y /= p_v.y;
z /= p_v.z;
return *this;
}
Vector3i Vector3i::operator/(const Vector3i &p_v) const {
constexpr Vector3i Vector3i::operator/(const Vector3i &p_v) const {
return Vector3i(x / p_v.x, y / p_v.y, z / p_v.z);
}
Vector3i &Vector3i::operator%=(const Vector3i &p_v) {
constexpr Vector3i &Vector3i::operator%=(const Vector3i &p_v) {
x %= p_v.x;
y %= p_v.y;
z %= p_v.z;
return *this;
}
Vector3i Vector3i::operator%(const Vector3i &p_v) const {
constexpr Vector3i Vector3i::operator%(const Vector3i &p_v) const {
return Vector3i(x % p_v.x, y % p_v.y, z % p_v.z);
}
Vector3i &Vector3i::operator*=(int32_t p_scalar) {
constexpr Vector3i &Vector3i::operator*=(int32_t p_scalar) {
x *= p_scalar;
y *= p_scalar;
z *= p_scalar;
return *this;
}
Vector3i Vector3i::operator*(int32_t p_scalar) const {
constexpr Vector3i Vector3i::operator*(int32_t p_scalar) const {
return Vector3i(x * p_scalar, y * p_scalar, z * p_scalar);
}
// Multiplication operators required to workaround issues with LLVM using implicit conversion.
_FORCE_INLINE_ Vector3i operator*(int32_t p_scalar, const Vector3i &p_vector) {
constexpr Vector3i operator*(int32_t p_scalar, const Vector3i &p_vector) {
return p_vector * p_scalar;
}
_FORCE_INLINE_ Vector3i operator*(int64_t p_scalar, const Vector3i &p_vector) {
constexpr Vector3i operator*(int64_t p_scalar, const Vector3i &p_vector) {
return p_vector * p_scalar;
}
_FORCE_INLINE_ Vector3i operator*(float p_scalar, const Vector3i &p_vector) {
constexpr Vector3i operator*(float p_scalar, const Vector3i &p_vector) {
return p_vector * p_scalar;
}
_FORCE_INLINE_ Vector3i operator*(double p_scalar, const Vector3i &p_vector) {
constexpr Vector3i operator*(double p_scalar, const Vector3i &p_vector) {
return p_vector * p_scalar;
}
Vector3i &Vector3i::operator/=(int32_t p_scalar) {
constexpr Vector3i &Vector3i::operator/=(int32_t p_scalar) {
x /= p_scalar;
y /= p_scalar;
z /= p_scalar;
return *this;
}
Vector3i Vector3i::operator/(int32_t p_scalar) const {
constexpr Vector3i Vector3i::operator/(int32_t p_scalar) const {
return Vector3i(x / p_scalar, y / p_scalar, z / p_scalar);
}
Vector3i &Vector3i::operator%=(int32_t p_scalar) {
constexpr Vector3i &Vector3i::operator%=(int32_t p_scalar) {
x %= p_scalar;
y %= p_scalar;
z %= p_scalar;
return *this;
}
Vector3i Vector3i::operator%(int32_t p_scalar) const {
constexpr Vector3i Vector3i::operator%(int32_t p_scalar) const {
return Vector3i(x % p_scalar, y % p_scalar, z % p_scalar);
}
Vector3i Vector3i::operator-() const {
constexpr Vector3i Vector3i::operator-() const {
return Vector3i(-x, -y, -z);
}
bool Vector3i::operator==(const Vector3i &p_v) const {
constexpr bool Vector3i::operator==(const Vector3i &p_v) const {
return (x == p_v.x && y == p_v.y && z == p_v.z);
}
bool Vector3i::operator!=(const Vector3i &p_v) const {
constexpr bool Vector3i::operator!=(const Vector3i &p_v) const {
return (x != p_v.x || y != p_v.y || z != p_v.z);
}
bool Vector3i::operator<(const Vector3i &p_v) const {
constexpr bool Vector3i::operator<(const Vector3i &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
return z < p_v.z;
@ -296,7 +295,7 @@ bool Vector3i::operator<(const Vector3i &p_v) const {
}
}
bool Vector3i::operator>(const Vector3i &p_v) const {
constexpr bool Vector3i::operator>(const Vector3i &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
return z > p_v.z;
@ -308,7 +307,7 @@ bool Vector3i::operator>(const Vector3i &p_v) const {
}
}
bool Vector3i::operator<=(const Vector3i &p_v) const {
constexpr bool Vector3i::operator<=(const Vector3i &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
return z <= p_v.z;
@ -320,7 +319,7 @@ bool Vector3i::operator<=(const Vector3i &p_v) const {
}
}
bool Vector3i::operator>=(const Vector3i &p_v) const {
constexpr bool Vector3i::operator>=(const Vector3i &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
return z >= p_v.z;
@ -336,4 +335,5 @@ void Vector3i::zero() {
x = y = z = 0;
}
#endif // VECTOR3I_H
template <>
struct is_zero_constructible<Vector3i> : std::true_type {};

View file

@ -62,6 +62,10 @@ bool Vector4::is_equal_approx(const Vector4 &p_vec4) const {
return Math::is_equal_approx(x, p_vec4.x) && Math::is_equal_approx(y, p_vec4.y) && Math::is_equal_approx(z, p_vec4.z) && Math::is_equal_approx(w, p_vec4.w);
}
bool Vector4::is_same(const Vector4 &p_vec4) const {
return Math::is_same(x, p_vec4.x) && Math::is_same(y, p_vec4.y) && Math::is_same(z, p_vec4.z) && Math::is_same(w, p_vec4.w);
}
bool Vector4::is_zero_approx() const {
return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z) && Math::is_zero_approx(w);
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef VECTOR4_H
#define VECTOR4_H
#pragma once
#include "core/error/error_macros.h"
#include "core/math/math_defs.h"
@ -49,6 +48,7 @@ struct [[nodiscard]] Vector4 {
};
union {
// NOLINTBEGIN(modernize-use-default-member-init)
struct {
real_t x;
real_t y;
@ -56,6 +56,7 @@ struct [[nodiscard]] Vector4 {
real_t w;
};
real_t coord[4] = { 0, 0, 0, 0 };
// NOLINTEND(modernize-use-default-member-init)
};
_FORCE_INLINE_ real_t &operator[](int p_axis) {
@ -89,6 +90,7 @@ struct [[nodiscard]] Vector4 {
_FORCE_INLINE_ real_t length_squared() const;
bool is_equal_approx(const Vector4 &p_vec4) const;
bool is_zero_approx() const;
bool is_same(const Vector4 &p_vec4) const;
bool is_finite() const;
real_t length() const;
void normalize();
@ -120,37 +122,34 @@ struct [[nodiscard]] Vector4 {
Vector4 inverse() const;
_FORCE_INLINE_ real_t dot(const Vector4 &p_vec4) const;
_FORCE_INLINE_ void operator+=(const Vector4 &p_vec4);
_FORCE_INLINE_ void operator-=(const Vector4 &p_vec4);
_FORCE_INLINE_ void operator*=(const Vector4 &p_vec4);
_FORCE_INLINE_ void operator/=(const Vector4 &p_vec4);
_FORCE_INLINE_ void operator*=(real_t p_s);
_FORCE_INLINE_ void operator/=(real_t p_s);
_FORCE_INLINE_ Vector4 operator+(const Vector4 &p_vec4) const;
_FORCE_INLINE_ Vector4 operator-(const Vector4 &p_vec4) const;
_FORCE_INLINE_ Vector4 operator*(const Vector4 &p_vec4) const;
_FORCE_INLINE_ Vector4 operator/(const Vector4 &p_vec4) const;
_FORCE_INLINE_ Vector4 operator-() const;
_FORCE_INLINE_ Vector4 operator*(real_t p_s) const;
_FORCE_INLINE_ Vector4 operator/(real_t p_s) const;
constexpr void operator+=(const Vector4 &p_vec4);
constexpr void operator-=(const Vector4 &p_vec4);
constexpr void operator*=(const Vector4 &p_vec4);
constexpr void operator/=(const Vector4 &p_vec4);
constexpr void operator*=(real_t p_s);
constexpr void operator/=(real_t p_s);
constexpr Vector4 operator+(const Vector4 &p_vec4) const;
constexpr Vector4 operator-(const Vector4 &p_vec4) const;
constexpr Vector4 operator*(const Vector4 &p_vec4) const;
constexpr Vector4 operator/(const Vector4 &p_vec4) const;
constexpr Vector4 operator-() const;
constexpr Vector4 operator*(real_t p_s) const;
constexpr Vector4 operator/(real_t p_s) const;
_FORCE_INLINE_ bool operator==(const Vector4 &p_vec4) const;
_FORCE_INLINE_ bool operator!=(const Vector4 &p_vec4) const;
_FORCE_INLINE_ bool operator>(const Vector4 &p_vec4) const;
_FORCE_INLINE_ bool operator<(const Vector4 &p_vec4) const;
_FORCE_INLINE_ bool operator>=(const Vector4 &p_vec4) const;
_FORCE_INLINE_ bool operator<=(const Vector4 &p_vec4) const;
constexpr bool operator==(const Vector4 &p_vec4) const;
constexpr bool operator!=(const Vector4 &p_vec4) const;
constexpr bool operator>(const Vector4 &p_vec4) const;
constexpr bool operator<(const Vector4 &p_vec4) const;
constexpr bool operator>=(const Vector4 &p_vec4) const;
constexpr 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;
}
constexpr Vector4() :
x(0), y(0), z(0), w(0) {}
constexpr 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) {}
};
real_t Vector4::dot(const Vector4 &p_vec4) const {
@ -161,81 +160,81 @@ real_t Vector4::length_squared() const {
return dot(*this);
}
void Vector4::operator+=(const Vector4 &p_vec4) {
constexpr void Vector4::operator+=(const Vector4 &p_vec4) {
x += p_vec4.x;
y += p_vec4.y;
z += p_vec4.z;
w += p_vec4.w;
}
void Vector4::operator-=(const Vector4 &p_vec4) {
constexpr void Vector4::operator-=(const Vector4 &p_vec4) {
x -= p_vec4.x;
y -= p_vec4.y;
z -= p_vec4.z;
w -= p_vec4.w;
}
void Vector4::operator*=(const Vector4 &p_vec4) {
constexpr void Vector4::operator*=(const Vector4 &p_vec4) {
x *= p_vec4.x;
y *= p_vec4.y;
z *= p_vec4.z;
w *= p_vec4.w;
}
void Vector4::operator/=(const Vector4 &p_vec4) {
constexpr void Vector4::operator/=(const Vector4 &p_vec4) {
x /= p_vec4.x;
y /= p_vec4.y;
z /= p_vec4.z;
w /= p_vec4.w;
}
void Vector4::operator*=(real_t p_s) {
constexpr void Vector4::operator*=(real_t p_s) {
x *= p_s;
y *= p_s;
z *= p_s;
w *= p_s;
}
void Vector4::operator/=(real_t p_s) {
*this *= 1.0f / p_s;
constexpr void Vector4::operator/=(real_t p_s) {
*this *= (1 / p_s);
}
Vector4 Vector4::operator+(const Vector4 &p_vec4) const {
constexpr Vector4 Vector4::operator+(const Vector4 &p_vec4) const {
return Vector4(x + p_vec4.x, y + p_vec4.y, z + p_vec4.z, w + p_vec4.w);
}
Vector4 Vector4::operator-(const Vector4 &p_vec4) const {
constexpr Vector4 Vector4::operator-(const Vector4 &p_vec4) const {
return Vector4(x - p_vec4.x, y - p_vec4.y, z - p_vec4.z, w - p_vec4.w);
}
Vector4 Vector4::operator*(const Vector4 &p_vec4) const {
constexpr Vector4 Vector4::operator*(const Vector4 &p_vec4) const {
return Vector4(x * p_vec4.x, y * p_vec4.y, z * p_vec4.z, w * p_vec4.w);
}
Vector4 Vector4::operator/(const Vector4 &p_vec4) const {
constexpr Vector4 Vector4::operator/(const Vector4 &p_vec4) const {
return Vector4(x / p_vec4.x, y / p_vec4.y, z / p_vec4.z, w / p_vec4.w);
}
Vector4 Vector4::operator-() const {
constexpr Vector4 Vector4::operator-() const {
return Vector4(-x, -y, -z, -w);
}
Vector4 Vector4::operator*(real_t p_s) const {
constexpr Vector4 Vector4::operator*(real_t p_s) const {
return Vector4(x * p_s, y * p_s, z * p_s, w * p_s);
}
Vector4 Vector4::operator/(real_t p_s) const {
return *this * (1.0f / p_s);
constexpr Vector4 Vector4::operator/(real_t p_s) const {
return *this * (1 / p_s);
}
bool Vector4::operator==(const Vector4 &p_vec4) const {
constexpr bool Vector4::operator==(const Vector4 &p_vec4) const {
return x == p_vec4.x && y == p_vec4.y && z == p_vec4.z && w == p_vec4.w;
}
bool Vector4::operator!=(const Vector4 &p_vec4) const {
constexpr bool Vector4::operator!=(const Vector4 &p_vec4) const {
return x != p_vec4.x || y != p_vec4.y || z != p_vec4.z || w != p_vec4.w;
}
bool Vector4::operator<(const Vector4 &p_v) const {
constexpr bool Vector4::operator<(const Vector4 &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
if (z == p_v.z) {
@ -248,7 +247,7 @@ bool Vector4::operator<(const Vector4 &p_v) const {
return x < p_v.x;
}
bool Vector4::operator>(const Vector4 &p_v) const {
constexpr bool Vector4::operator>(const Vector4 &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
if (z == p_v.z) {
@ -261,7 +260,7 @@ bool Vector4::operator>(const Vector4 &p_v) const {
return x > p_v.x;
}
bool Vector4::operator<=(const Vector4 &p_v) const {
constexpr bool Vector4::operator<=(const Vector4 &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
if (z == p_v.z) {
@ -274,7 +273,7 @@ bool Vector4::operator<=(const Vector4 &p_v) const {
return x < p_v.x;
}
bool Vector4::operator>=(const Vector4 &p_v) const {
constexpr bool Vector4::operator>=(const Vector4 &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
if (z == p_v.z) {
@ -287,20 +286,21 @@ bool Vector4::operator>=(const Vector4 &p_v) const {
return x > p_v.x;
}
_FORCE_INLINE_ Vector4 operator*(float p_scalar, const Vector4 &p_vec) {
constexpr Vector4 operator*(float p_scalar, const Vector4 &p_vec) {
return p_vec * p_scalar;
}
_FORCE_INLINE_ Vector4 operator*(double p_scalar, const Vector4 &p_vec) {
constexpr Vector4 operator*(double p_scalar, const Vector4 &p_vec) {
return p_vec * p_scalar;
}
_FORCE_INLINE_ Vector4 operator*(int32_t p_scalar, const Vector4 &p_vec) {
constexpr Vector4 operator*(int32_t p_scalar, const Vector4 &p_vec) {
return p_vec * p_scalar;
}
_FORCE_INLINE_ Vector4 operator*(int64_t p_scalar, const Vector4 &p_vec) {
constexpr Vector4 operator*(int64_t p_scalar, const Vector4 &p_vec) {
return p_vec * p_scalar;
}
#endif // VECTOR4_H
template <>
struct is_zero_constructible<Vector4> : std::true_type {};

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef VECTOR4I_H
#define VECTOR4I_H
#pragma once
#include "core/error/error_macros.h"
#include "core/math/math_funcs.h"
@ -48,6 +47,7 @@ struct [[nodiscard]] Vector4i {
};
union {
// NOLINTBEGIN(modernize-use-default-member-init)
struct {
int32_t x;
int32_t y;
@ -56,6 +56,7 @@ struct [[nodiscard]] Vector4i {
};
int32_t coord[4] = { 0 };
// NOLINTEND(modernize-use-default-member-init)
};
_FORCE_INLINE_ const int32_t &operator[](int p_axis) const {
@ -104,44 +105,41 @@ struct [[nodiscard]] Vector4i {
/* Operators */
_FORCE_INLINE_ Vector4i &operator+=(const Vector4i &p_v);
_FORCE_INLINE_ Vector4i operator+(const Vector4i &p_v) const;
_FORCE_INLINE_ Vector4i &operator-=(const Vector4i &p_v);
_FORCE_INLINE_ Vector4i operator-(const Vector4i &p_v) const;
_FORCE_INLINE_ Vector4i &operator*=(const Vector4i &p_v);
_FORCE_INLINE_ Vector4i operator*(const Vector4i &p_v) const;
_FORCE_INLINE_ Vector4i &operator/=(const Vector4i &p_v);
_FORCE_INLINE_ Vector4i operator/(const Vector4i &p_v) const;
_FORCE_INLINE_ Vector4i &operator%=(const Vector4i &p_v);
_FORCE_INLINE_ Vector4i operator%(const Vector4i &p_v) const;
constexpr Vector4i &operator+=(const Vector4i &p_v);
constexpr Vector4i operator+(const Vector4i &p_v) const;
constexpr Vector4i &operator-=(const Vector4i &p_v);
constexpr Vector4i operator-(const Vector4i &p_v) const;
constexpr Vector4i &operator*=(const Vector4i &p_v);
constexpr Vector4i operator*(const Vector4i &p_v) const;
constexpr Vector4i &operator/=(const Vector4i &p_v);
constexpr Vector4i operator/(const Vector4i &p_v) const;
constexpr Vector4i &operator%=(const Vector4i &p_v);
constexpr Vector4i operator%(const Vector4i &p_v) const;
_FORCE_INLINE_ Vector4i &operator*=(int32_t p_scalar);
_FORCE_INLINE_ Vector4i operator*(int32_t p_scalar) const;
_FORCE_INLINE_ Vector4i &operator/=(int32_t p_scalar);
_FORCE_INLINE_ Vector4i operator/(int32_t p_scalar) const;
_FORCE_INLINE_ Vector4i &operator%=(int32_t p_scalar);
_FORCE_INLINE_ Vector4i operator%(int32_t p_scalar) const;
constexpr Vector4i &operator*=(int32_t p_scalar);
constexpr Vector4i operator*(int32_t p_scalar) const;
constexpr Vector4i &operator/=(int32_t p_scalar);
constexpr Vector4i operator/(int32_t p_scalar) const;
constexpr Vector4i &operator%=(int32_t p_scalar);
constexpr Vector4i operator%(int32_t p_scalar) const;
_FORCE_INLINE_ Vector4i operator-() const;
constexpr Vector4i operator-() const;
_FORCE_INLINE_ bool operator==(const Vector4i &p_v) const;
_FORCE_INLINE_ bool operator!=(const Vector4i &p_v) const;
_FORCE_INLINE_ bool operator<(const Vector4i &p_v) const;
_FORCE_INLINE_ bool operator<=(const Vector4i &p_v) const;
_FORCE_INLINE_ bool operator>(const Vector4i &p_v) const;
_FORCE_INLINE_ bool operator>=(const Vector4i &p_v) const;
constexpr bool operator==(const Vector4i &p_v) const;
constexpr bool operator!=(const Vector4i &p_v) const;
constexpr bool operator<(const Vector4i &p_v) const;
constexpr bool operator<=(const Vector4i &p_v) const;
constexpr bool operator>(const Vector4i &p_v) const;
constexpr bool operator>=(const Vector4i &p_v) const;
operator String() const;
operator Vector4() const;
_FORCE_INLINE_ Vector4i() {}
constexpr Vector4i() :
x(0), y(0), z(0), w(0) {}
Vector4i(const Vector4 &p_vec4);
_FORCE_INLINE_ Vector4i(int32_t p_x, int32_t p_y, int32_t p_z, int32_t p_w) {
x = p_x;
y = p_y;
z = p_z;
w = p_w;
}
constexpr Vector4i(int32_t p_x, int32_t p_y, int32_t p_z, int32_t p_w) :
x(p_x), y(p_y), z(p_z), w(p_w) {}
};
int64_t Vector4i::length_squared() const {
@ -170,7 +168,7 @@ Vector4i Vector4i::sign() const {
/* Operators */
Vector4i &Vector4i::operator+=(const Vector4i &p_v) {
constexpr Vector4i &Vector4i::operator+=(const Vector4i &p_v) {
x += p_v.x;
y += p_v.y;
z += p_v.z;
@ -178,11 +176,11 @@ Vector4i &Vector4i::operator+=(const Vector4i &p_v) {
return *this;
}
Vector4i Vector4i::operator+(const Vector4i &p_v) const {
constexpr Vector4i Vector4i::operator+(const Vector4i &p_v) const {
return Vector4i(x + p_v.x, y + p_v.y, z + p_v.z, w + p_v.w);
}
Vector4i &Vector4i::operator-=(const Vector4i &p_v) {
constexpr Vector4i &Vector4i::operator-=(const Vector4i &p_v) {
x -= p_v.x;
y -= p_v.y;
z -= p_v.z;
@ -190,11 +188,11 @@ Vector4i &Vector4i::operator-=(const Vector4i &p_v) {
return *this;
}
Vector4i Vector4i::operator-(const Vector4i &p_v) const {
constexpr Vector4i Vector4i::operator-(const Vector4i &p_v) const {
return Vector4i(x - p_v.x, y - p_v.y, z - p_v.z, w - p_v.w);
}
Vector4i &Vector4i::operator*=(const Vector4i &p_v) {
constexpr Vector4i &Vector4i::operator*=(const Vector4i &p_v) {
x *= p_v.x;
y *= p_v.y;
z *= p_v.z;
@ -202,11 +200,11 @@ Vector4i &Vector4i::operator*=(const Vector4i &p_v) {
return *this;
}
Vector4i Vector4i::operator*(const Vector4i &p_v) const {
constexpr Vector4i Vector4i::operator*(const Vector4i &p_v) const {
return Vector4i(x * p_v.x, y * p_v.y, z * p_v.z, w * p_v.w);
}
Vector4i &Vector4i::operator/=(const Vector4i &p_v) {
constexpr Vector4i &Vector4i::operator/=(const Vector4i &p_v) {
x /= p_v.x;
y /= p_v.y;
z /= p_v.z;
@ -214,11 +212,11 @@ Vector4i &Vector4i::operator/=(const Vector4i &p_v) {
return *this;
}
Vector4i Vector4i::operator/(const Vector4i &p_v) const {
constexpr Vector4i Vector4i::operator/(const Vector4i &p_v) const {
return Vector4i(x / p_v.x, y / p_v.y, z / p_v.z, w / p_v.w);
}
Vector4i &Vector4i::operator%=(const Vector4i &p_v) {
constexpr Vector4i &Vector4i::operator%=(const Vector4i &p_v) {
x %= p_v.x;
y %= p_v.y;
z %= p_v.z;
@ -226,11 +224,11 @@ Vector4i &Vector4i::operator%=(const Vector4i &p_v) {
return *this;
}
Vector4i Vector4i::operator%(const Vector4i &p_v) const {
constexpr Vector4i Vector4i::operator%(const Vector4i &p_v) const {
return Vector4i(x % p_v.x, y % p_v.y, z % p_v.z, w % p_v.w);
}
Vector4i &Vector4i::operator*=(int32_t p_scalar) {
constexpr Vector4i &Vector4i::operator*=(int32_t p_scalar) {
x *= p_scalar;
y *= p_scalar;
z *= p_scalar;
@ -238,29 +236,29 @@ Vector4i &Vector4i::operator*=(int32_t p_scalar) {
return *this;
}
Vector4i Vector4i::operator*(int32_t p_scalar) const {
constexpr Vector4i Vector4i::operator*(int32_t p_scalar) const {
return Vector4i(x * p_scalar, y * p_scalar, z * p_scalar, w * p_scalar);
}
// Multiplication operators required to workaround issues with LLVM using implicit conversion.
_FORCE_INLINE_ Vector4i operator*(int32_t p_scalar, const Vector4i &p_vector) {
constexpr Vector4i operator*(int32_t p_scalar, const Vector4i &p_vector) {
return p_vector * p_scalar;
}
_FORCE_INLINE_ Vector4i operator*(int64_t p_scalar, const Vector4i &p_vector) {
constexpr Vector4i operator*(int64_t p_scalar, const Vector4i &p_vector) {
return p_vector * p_scalar;
}
_FORCE_INLINE_ Vector4i operator*(float p_scalar, const Vector4i &p_vector) {
constexpr Vector4i operator*(float p_scalar, const Vector4i &p_vector) {
return p_vector * p_scalar;
}
_FORCE_INLINE_ Vector4i operator*(double p_scalar, const Vector4i &p_vector) {
constexpr Vector4i operator*(double p_scalar, const Vector4i &p_vector) {
return p_vector * p_scalar;
}
Vector4i &Vector4i::operator/=(int32_t p_scalar) {
constexpr Vector4i &Vector4i::operator/=(int32_t p_scalar) {
x /= p_scalar;
y /= p_scalar;
z /= p_scalar;
@ -268,11 +266,11 @@ Vector4i &Vector4i::operator/=(int32_t p_scalar) {
return *this;
}
Vector4i Vector4i::operator/(int32_t p_scalar) const {
constexpr Vector4i Vector4i::operator/(int32_t p_scalar) const {
return Vector4i(x / p_scalar, y / p_scalar, z / p_scalar, w / p_scalar);
}
Vector4i &Vector4i::operator%=(int32_t p_scalar) {
constexpr Vector4i &Vector4i::operator%=(int32_t p_scalar) {
x %= p_scalar;
y %= p_scalar;
z %= p_scalar;
@ -280,23 +278,23 @@ Vector4i &Vector4i::operator%=(int32_t p_scalar) {
return *this;
}
Vector4i Vector4i::operator%(int32_t p_scalar) const {
constexpr Vector4i Vector4i::operator%(int32_t p_scalar) const {
return Vector4i(x % p_scalar, y % p_scalar, z % p_scalar, w % p_scalar);
}
Vector4i Vector4i::operator-() const {
constexpr Vector4i Vector4i::operator-() const {
return Vector4i(-x, -y, -z, -w);
}
bool Vector4i::operator==(const Vector4i &p_v) const {
constexpr bool Vector4i::operator==(const Vector4i &p_v) const {
return (x == p_v.x && y == p_v.y && z == p_v.z && w == p_v.w);
}
bool Vector4i::operator!=(const Vector4i &p_v) const {
constexpr bool Vector4i::operator!=(const Vector4i &p_v) const {
return (x != p_v.x || y != p_v.y || z != p_v.z || w != p_v.w);
}
bool Vector4i::operator<(const Vector4i &p_v) const {
constexpr bool Vector4i::operator<(const Vector4i &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
if (z == p_v.z) {
@ -312,7 +310,7 @@ bool Vector4i::operator<(const Vector4i &p_v) const {
}
}
bool Vector4i::operator>(const Vector4i &p_v) const {
constexpr bool Vector4i::operator>(const Vector4i &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
if (z == p_v.z) {
@ -328,7 +326,7 @@ bool Vector4i::operator>(const Vector4i &p_v) const {
}
}
bool Vector4i::operator<=(const Vector4i &p_v) const {
constexpr bool Vector4i::operator<=(const Vector4i &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
if (z == p_v.z) {
@ -344,7 +342,7 @@ bool Vector4i::operator<=(const Vector4i &p_v) const {
}
}
bool Vector4i::operator>=(const Vector4i &p_v) const {
constexpr bool Vector4i::operator>=(const Vector4i &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
if (z == p_v.z) {
@ -364,4 +362,5 @@ void Vector4i::zero() {
x = y = z = w = 0;
}
#endif // VECTOR4I_H
template <>
struct is_zero_constructible<Vector4i> : std::true_type {};