diff options
Diffstat (limited to 'core/math')
-rw-r--r-- | core/math/basis.cpp | 7 | ||||
-rw-r--r-- | core/math/dynamic_bvh.cpp | 68 | ||||
-rw-r--r-- | core/math/dynamic_bvh.h | 28 | ||||
-rw-r--r-- | core/math/math_funcs.h | 2 | ||||
-rw-r--r-- | core/math/quick_hull.cpp | 10 | ||||
-rw-r--r-- | core/math/transform_2d.cpp | 47 | ||||
-rw-r--r-- | core/math/vector3.h | 8 | ||||
-rw-r--r-- | core/math/vector3i.h | 8 | ||||
-rw-r--r-- | core/math/vector4.h | 8 | ||||
-rw-r--r-- | core/math/vector4i.h | 8 |
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; |