summaryrefslogtreecommitdiff
path: root/core/math
diff options
context:
space:
mode:
Diffstat (limited to 'core/math')
-rw-r--r--core/math/basis.cpp7
-rw-r--r--core/math/dynamic_bvh.cpp68
-rw-r--r--core/math/dynamic_bvh.h28
-rw-r--r--core/math/math_funcs.h2
-rw-r--r--core/math/quick_hull.cpp10
-rw-r--r--core/math/transform_2d.cpp47
-rw-r--r--core/math/vector3.h8
-rw-r--r--core/math/vector3i.h8
-rw-r--r--core/math/vector4.h8
-rw-r--r--core/math/vector4i.h8
10 files changed, 103 insertions, 91 deletions
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index 234a4ddb79..95a4187062 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -239,13 +239,18 @@ void Basis::scale_orthogonal(const Vector3 &p_scale) {
Basis Basis::scaled_orthogonal(const Vector3 &p_scale) const {
Basis m = *this;
Vector3 s = Vector3(-1, -1, -1) + p_scale;
+ bool sign = signbit(s.x + s.y + s.z);
+ Basis b = m.orthonormalized();
+ s = b.xform_inv(s);
Vector3 dots;
- Basis b;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
dots[j] += s[i] * abs(m.get_column(i).normalized().dot(b.get_column(j)));
}
}
+ if (sign != signbit(dots.x + dots.y + dots.z)) {
+ dots = -dots;
+ }
m.scale_local(Vector3(1, 1, 1) + dots);
return m;
}
diff --git a/core/math/dynamic_bvh.cpp b/core/math/dynamic_bvh.cpp
index 4452445241..e1315d1c64 100644
--- a/core/math/dynamic_bvh.cpp
+++ b/core/math/dynamic_bvh.cpp
@@ -36,8 +36,8 @@ void DynamicBVH::_delete_node(Node *p_node) {
void DynamicBVH::_recurse_delete_node(Node *p_node) {
if (!p_node->is_leaf()) {
- _recurse_delete_node(p_node->childs[0]);
- _recurse_delete_node(p_node->childs[1]);
+ _recurse_delete_node(p_node->children[0]);
+ _recurse_delete_node(p_node->children[1]);
}
if (p_node == bvh_root) {
bvh_root = nullptr;
@@ -65,31 +65,31 @@ void DynamicBVH::_insert_leaf(Node *p_root, Node *p_leaf) {
} else {
if (!p_root->is_leaf()) {
do {
- p_root = p_root->childs[p_leaf->volume.select_by_proximity(
- p_root->childs[0]->volume,
- p_root->childs[1]->volume)];
+ p_root = p_root->children[p_leaf->volume.select_by_proximity(
+ p_root->children[0]->volume,
+ p_root->children[1]->volume)];
} while (!p_root->is_leaf());
}
Node *prev = p_root->parent;
Node *node = _create_node_with_volume(prev, p_leaf->volume.merge(p_root->volume), nullptr);
if (prev) {
- prev->childs[p_root->get_index_in_parent()] = node;
- node->childs[0] = p_root;
+ prev->children[p_root->get_index_in_parent()] = node;
+ node->children[0] = p_root;
p_root->parent = node;
- node->childs[1] = p_leaf;
+ node->children[1] = p_leaf;
p_leaf->parent = node;
do {
if (!prev->volume.contains(node->volume)) {
- prev->volume = prev->childs[0]->volume.merge(prev->childs[1]->volume);
+ prev->volume = prev->children[0]->volume.merge(prev->children[1]->volume);
} else {
break;
}
node = prev;
} while (nullptr != (prev = node->parent));
} else {
- node->childs[0] = p_root;
+ node->children[0] = p_root;
p_root->parent = node;
- node->childs[1] = p_leaf;
+ node->children[1] = p_leaf;
p_leaf->parent = node;
bvh_root = node;
}
@@ -103,14 +103,14 @@ DynamicBVH::Node *DynamicBVH::_remove_leaf(Node *leaf) {
} else {
Node *parent = leaf->parent;
Node *prev = parent->parent;
- Node *sibling = parent->childs[1 - leaf->get_index_in_parent()];
+ Node *sibling = parent->children[1 - leaf->get_index_in_parent()];
if (prev) {
- prev->childs[parent->get_index_in_parent()] = sibling;
+ prev->children[parent->get_index_in_parent()] = sibling;
sibling->parent = prev;
_delete_node(parent);
while (prev) {
const Volume pb = prev->volume;
- prev->volume = prev->childs[0]->volume.merge(prev->childs[1]->volume);
+ prev->volume = prev->children[0]->volume.merge(prev->children[1]->volume);
if (pb.is_not_equal_to(prev->volume)) {
prev = prev->parent;
} else {
@@ -129,8 +129,8 @@ DynamicBVH::Node *DynamicBVH::_remove_leaf(Node *leaf) {
void DynamicBVH::_fetch_leaves(Node *p_root, LocalVector<Node *> &r_leaves, int p_depth) {
if (p_root->is_internal() && p_depth) {
- _fetch_leaves(p_root->childs[0], r_leaves, p_depth - 1);
- _fetch_leaves(p_root->childs[1], r_leaves, p_depth - 1);
+ _fetch_leaves(p_root->children[0], r_leaves, p_depth - 1);
+ _fetch_leaves(p_root->children[1], r_leaves, p_depth - 1);
_delete_node(p_root);
} else {
r_leaves.push_back(p_root);
@@ -195,8 +195,8 @@ void DynamicBVH::_bottom_up(Node **leaves, int p_count) {
}
Node *n[] = { leaves[minidx[0]], leaves[minidx[1]] };
Node *p = _create_node_with_volume(nullptr, n[0]->volume.merge(n[1]->volume), nullptr);
- p->childs[0] = n[0];
- p->childs[1] = n[1];
+ p->children[0] = n[0];
+ p->children[1] = n[1];
n[0]->parent = p;
n[1]->parent = p;
leaves[minidx[0]] = p;
@@ -241,10 +241,10 @@ DynamicBVH::Node *DynamicBVH::_top_down(Node **leaves, int p_count, int p_bu_thr
}
Node *node = _create_node_with_volume(nullptr, vol, nullptr);
- node->childs[0] = _top_down(&leaves[0], partition, p_bu_threshold);
- node->childs[1] = _top_down(&leaves[partition], p_count - partition, p_bu_threshold);
- node->childs[0]->parent = node;
- node->childs[1]->parent = node;
+ node->children[0] = _top_down(&leaves[0], partition, p_bu_threshold);
+ node->children[1] = _top_down(&leaves[partition], p_count - partition, p_bu_threshold);
+ node->children[0]->parent = node;
+ node->children[1]->parent = node;
return (node);
} else {
_bottom_up(leaves, p_count);
@@ -260,23 +260,23 @@ DynamicBVH::Node *DynamicBVH::_node_sort(Node *n, Node *&r) {
if (p > n) {
const int i = n->get_index_in_parent();
const int j = 1 - i;
- Node *s = p->childs[j];
+ Node *s = p->children[j];
Node *q = p->parent;
- ERR_FAIL_COND_V(n != p->childs[i], nullptr);
+ ERR_FAIL_COND_V(n != p->children[i], nullptr);
if (q) {
- q->childs[p->get_index_in_parent()] = n;
+ q->children[p->get_index_in_parent()] = n;
} else {
r = n;
}
s->parent = n;
p->parent = n;
n->parent = q;
- p->childs[0] = n->childs[0];
- p->childs[1] = n->childs[1];
- n->childs[0]->parent = p;
- n->childs[1]->parent = p;
- n->childs[i] = p;
- n->childs[j] = s;
+ p->children[0] = n->children[0];
+ p->children[1] = n->children[1];
+ n->children[0]->parent = p;
+ n->children[1]->parent = p;
+ n->children[i] = p;
+ n->children[j] = s;
SWAP(p->volume, n->volume);
return (p);
}
@@ -320,7 +320,7 @@ void DynamicBVH::optimize_incremental(int passes) {
Node *node = bvh_root;
unsigned bit = 0;
while (node->is_internal()) {
- node = _node_sort(node, bvh_root)->childs[(opath >> bit) & 1];
+ node = _node_sort(node, bvh_root)->children[(opath >> bit) & 1];
bit = (bit + 1) & (sizeof(unsigned) * 8 - 1);
}
_update(node);
@@ -396,8 +396,8 @@ void DynamicBVH::remove(const ID &p_id) {
void DynamicBVH::_extract_leaves(Node *p_node, List<ID> *r_elements) {
if (p_node->is_internal()) {
- _extract_leaves(p_node->childs[0], r_elements);
- _extract_leaves(p_node->childs[1], r_elements);
+ _extract_leaves(p_node->children[0], r_elements);
+ _extract_leaves(p_node->children[1], r_elements);
} else {
ID id;
id.node = p_node;
diff --git a/core/math/dynamic_bvh.h b/core/math/dynamic_bvh.h
index 46bf56ae58..21b5340aaa 100644
--- a/core/math/dynamic_bvh.h
+++ b/core/math/dynamic_bvh.h
@@ -182,21 +182,21 @@ private:
Volume volume;
Node *parent = nullptr;
union {
- Node *childs[2];
+ Node *children[2];
void *data;
};
- _FORCE_INLINE_ bool is_leaf() const { return childs[1] == nullptr; }
+ _FORCE_INLINE_ bool is_leaf() const { return children[1] == nullptr; }
_FORCE_INLINE_ bool is_internal() const { return (!is_leaf()); }
_FORCE_INLINE_ int get_index_in_parent() const {
ERR_FAIL_COND_V(!parent, 0);
- return (parent->childs[1] == this) ? 1 : 0;
+ return (parent->children[1] == this) ? 1 : 0;
}
void get_max_depth(int depth, int &maxdepth) {
if (is_internal()) {
- childs[0]->get_max_depth(depth + 1, maxdepth);
- childs[1]->get_max_depth(depth + 1, maxdepth);
+ children[0]->get_max_depth(depth + 1, maxdepth);
+ children[1]->get_max_depth(depth + 1, maxdepth);
} else {
maxdepth = MAX(maxdepth, depth);
}
@@ -205,7 +205,7 @@ private:
//
int count_leaves() const {
if (is_internal()) {
- return childs[0]->count_leaves() + childs[1]->count_leaves();
+ return children[0]->count_leaves() + children[1]->count_leaves();
} else {
return (1);
}
@@ -216,8 +216,8 @@ private:
}
Node() {
- childs[0] = nullptr;
- childs[1] = nullptr;
+ children[0] = nullptr;
+ children[1] = nullptr;
}
};
@@ -350,8 +350,8 @@ void DynamicBVH::aabb_query(const AABB &p_box, QueryResult &r_result) {
stack = aux_stack.ptr();
threshold = aux_stack.size() - 2;
}
- stack[depth++] = n->childs[0];
- stack[depth++] = n->childs[1];
+ stack[depth++] = n->children[0];
+ stack[depth++] = n->children[1];
} else {
if (r_result(n->data)) {
return;
@@ -406,8 +406,8 @@ void DynamicBVH::convex_query(const Plane *p_planes, int p_plane_count, const Ve
stack = aux_stack.ptr();
threshold = aux_stack.size() - 2;
}
- stack[depth++] = n->childs[0];
- stack[depth++] = n->childs[1];
+ stack[depth++] = n->children[0];
+ stack[depth++] = n->children[1];
} else {
if (r_result(n->data)) {
return;
@@ -463,8 +463,8 @@ void DynamicBVH::ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResu
stack = aux_stack.ptr();
threshold = aux_stack.size() - 2;
}
- stack[depth++] = node->childs[0];
- stack[depth++] = node->childs[1];
+ stack[depth++] = node->children[0];
+ stack[depth++] = node->children[1];
} else {
if (r_result(node->data)) {
return;
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 0fa82bb8c1..078320d620 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -31,6 +31,7 @@
#ifndef MATH_FUNCS_H
#define MATH_FUNCS_H
+#include "core/error/error_macros.h"
#include "core/math/math_defs.h"
#include "core/math/random_pcg.h"
#include "core/typedefs.h"
@@ -225,6 +226,7 @@ public:
}
static _ALWAYS_INLINE_ int64_t posmod(int64_t p_x, int64_t p_y) {
+ ERR_FAIL_COND_V_MSG(p_y == 0, 0, "Division by zero in posmod is undefined. Returning 0 as fallback.");
int64_t value = p_x % p_y;
if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) {
value += p_y;
diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp
index 9488c6bcff..4483f61bc4 100644
--- a/core/math/quick_hull.cpp
+++ b/core/math/quick_hull.cpp
@@ -383,15 +383,15 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_
if (O->get().plane.is_equal_approx(f.plane)) {
//merge and delete edge and contiguous face, while repointing edges (uuugh!)
- int ois = O->get().indices.size();
+ int o_index_size = O->get().indices.size();
- for (int j = 0; j < ois; j++) {
+ for (int j = 0; j < o_index_size; j++) {
//search a
if (O->get().indices[j] == a) {
//append the rest
- for (int k = 0; k < ois; k++) {
- int idx = O->get().indices[(k + j) % ois];
- int idxn = O->get().indices[(k + j + 1) % ois];
+ for (int k = 0; k < o_index_size; k++) {
+ int idx = O->get().indices[(k + j) % o_index_size];
+ int idxn = O->get().indices[(k + j + 1) % o_index_size];
if (idx == b && idxn == a) { //already have b!
break;
}
diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp
index 910995d717..868665cb5c 100644
--- a/core/math/transform_2d.cpp
+++ b/core/math/transform_2d.cpp
@@ -151,7 +151,7 @@ void Transform2D::orthonormalize() {
Vector2 y = columns[1];
x.normalize();
- y = (y - x * (x.dot(y)));
+ y = y - x * x.dot(y);
y.normalize();
columns[0] = x;
@@ -159,9 +159,9 @@ void Transform2D::orthonormalize() {
}
Transform2D Transform2D::orthonormalized() const {
- Transform2D on = *this;
- on.orthonormalize();
- return on;
+ Transform2D ortho = *this;
+ ortho.orthonormalize();
+ return ortho;
}
bool Transform2D::is_equal_approx(const Transform2D &p_transform) const {
@@ -263,39 +263,12 @@ real_t Transform2D::basis_determinant() const {
return columns[0].x * columns[1].y - columns[0].y * columns[1].x;
}
-Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, const real_t p_c) const {
- //extract parameters
- Vector2 p1 = get_origin();
- Vector2 p2 = p_transform.get_origin();
-
- real_t r1 = get_rotation();
- real_t r2 = p_transform.get_rotation();
-
- Size2 s1 = get_scale();
- Size2 s2 = p_transform.get_scale();
-
- //slerp rotation
- Vector2 v1(Math::cos(r1), Math::sin(r1));
- Vector2 v2(Math::cos(r2), Math::sin(r2));
-
- real_t dot = v1.dot(v2);
-
- dot = CLAMP(dot, (real_t)-1.0, (real_t)1.0);
-
- Vector2 v;
-
- if (dot > 0.9995f) {
- v = v1.lerp(v2, p_c).normalized(); //linearly interpolate to avoid numerical precision issues
- } else {
- real_t angle = p_c * Math::acos(dot);
- Vector2 v3 = (v2 - v1 * dot).normalized();
- v = v1 * Math::cos(angle) + v3 * Math::sin(angle);
- }
-
- //construct matrix
- Transform2D res(v.angle(), p1.lerp(p2, p_c));
- res.scale_basis(s1.lerp(s2, p_c));
- return res;
+Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, const real_t p_weight) const {
+ return Transform2D(
+ Math::lerp_angle(get_rotation(), p_transform.get_rotation(), p_weight),
+ get_scale().lerp(p_transform.get_scale(), p_weight),
+ Math::lerp_angle(get_skew(), p_transform.get_skew(), p_weight),
+ get_origin().lerp(p_transform.get_origin(), p_weight));
}
void Transform2D::operator*=(const real_t p_val) {
diff --git a/core/math/vector3.h b/core/math/vector3.h
index bd8739d024..18943a820f 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -76,6 +76,14 @@ struct _NO_DISCARD_ Vector3 {
return x < y ? (y < z ? Vector3::AXIS_Z : Vector3::AXIS_Y) : (x < z ? Vector3::AXIS_Z : Vector3::AXIS_X);
}
+ Vector3 min(const Vector3 &p_vector3) const {
+ return Vector3(MIN(x, p_vector3.x), MIN(y, p_vector3.y), MIN(z, p_vector3.z));
+ }
+
+ Vector3 max(const Vector3 &p_vector3) const {
+ return Vector3(MAX(x, p_vector3.x), MAX(y, p_vector3.y), MAX(z, p_vector3.z));
+ }
+
_FORCE_INLINE_ real_t length() const;
_FORCE_INLINE_ real_t length_squared() const;
diff --git a/core/math/vector3i.h b/core/math/vector3i.h
index 96f9beef12..53d3829a99 100644
--- a/core/math/vector3i.h
+++ b/core/math/vector3i.h
@@ -69,6 +69,14 @@ struct _NO_DISCARD_ Vector3i {
Vector3i::Axis min_axis_index() const;
Vector3i::Axis max_axis_index() const;
+ Vector3i min(const Vector3i &p_vector3i) const {
+ return Vector3i(MIN(x, p_vector3i.x), MIN(y, p_vector3i.y), MIN(z, p_vector3i.z));
+ }
+
+ Vector3i max(const Vector3i &p_vector3i) const {
+ return Vector3i(MAX(x, p_vector3i.x), MAX(y, p_vector3i.y), MAX(z, p_vector3i.z));
+ }
+
_FORCE_INLINE_ int64_t length_squared() const;
_FORCE_INLINE_ double length() const;
diff --git a/core/math/vector4.h b/core/math/vector4.h
index 0509261f33..f16b040317 100644
--- a/core/math/vector4.h
+++ b/core/math/vector4.h
@@ -68,6 +68,14 @@ struct _NO_DISCARD_ Vector4 {
Vector4::Axis min_axis_index() const;
Vector4::Axis max_axis_index() const;
+ Vector4 min(const Vector4 &p_vector4) const {
+ return Vector4(MIN(x, p_vector4.x), MIN(y, p_vector4.y), MIN(z, p_vector4.z), MIN(w, p_vector4.w));
+ }
+
+ Vector4 max(const Vector4 &p_vector4) const {
+ return Vector4(MAX(x, p_vector4.x), MAX(y, p_vector4.y), MAX(z, p_vector4.z), MAX(w, p_vector4.w));
+ }
+
_FORCE_INLINE_ real_t length_squared() const;
bool is_equal_approx(const Vector4 &p_vec4) const;
bool is_zero_approx() const;
diff --git a/core/math/vector4i.h b/core/math/vector4i.h
index d38a9de6f1..b815aa8e76 100644
--- a/core/math/vector4i.h
+++ b/core/math/vector4i.h
@@ -71,6 +71,14 @@ struct _NO_DISCARD_ Vector4i {
Vector4i::Axis min_axis_index() const;
Vector4i::Axis max_axis_index() const;
+ Vector4i min(const Vector4i &p_vector4i) const {
+ return Vector4i(MIN(x, p_vector4i.x), MIN(y, p_vector4i.y), MIN(z, p_vector4i.z), MIN(w, p_vector4i.w));
+ }
+
+ Vector4i max(const Vector4i &p_vector4i) const {
+ return Vector4i(MAX(x, p_vector4i.x), MAX(y, p_vector4i.y), MAX(z, p_vector4i.z), MAX(w, p_vector4i.w));
+ }
+
_FORCE_INLINE_ int64_t length_squared() const;
_FORCE_INLINE_ double length() const;