summaryrefslogtreecommitdiffstats
path: root/core/math
diff options
context:
space:
mode:
Diffstat (limited to 'core/math')
-rw-r--r--core/math/basis.cpp23
-rw-r--r--core/math/basis.h1
-rw-r--r--core/math/dynamic_bvh.h18
3 files changed, 32 insertions, 10 deletions
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index 9796ac59c2..cd8c87b158 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -89,13 +89,26 @@ Basis Basis::orthogonalized() const {
return c;
}
+// Returns true if the basis vectors are orthogonal (perpendicular), so it has no skew or shear, and can be decomposed into rotation and scale.
+// See https://en.wikipedia.org/wiki/Orthogonal_basis
bool Basis::is_orthogonal() const {
- Basis identity;
- Basis m = (*this) * transposed();
+ const Vector3 x = get_column(0);
+ const Vector3 y = get_column(1);
+ const Vector3 z = get_column(2);
+ return Math::is_zero_approx(x.dot(y)) && Math::is_zero_approx(x.dot(z)) && Math::is_zero_approx(y.dot(z));
+}
- return m.is_equal_approx(identity);
+// Returns true if the basis vectors are orthonormal (orthogonal and normalized), so it has no scale, skew, or shear.
+// See https://en.wikipedia.org/wiki/Orthonormal_basis
+bool Basis::is_orthonormal() const {
+ const Vector3 x = get_column(0);
+ const Vector3 y = get_column(1);
+ const Vector3 z = get_column(2);
+ return Math::is_equal_approx(x.length_squared(), 1) && Math::is_equal_approx(y.length_squared(), 1) && Math::is_equal_approx(z.length_squared(), 1) && Math::is_zero_approx(x.dot(y)) && Math::is_zero_approx(x.dot(z)) && Math::is_zero_approx(y.dot(z));
}
+// Returns true if the basis is conformal (orthogonal, uniform scale, preserves angles and distance ratios).
+// See https://en.wikipedia.org/wiki/Conformal_linear_transformation
bool Basis::is_conformal() const {
const Vector3 x = get_column(0);
const Vector3 y = get_column(1);
@@ -104,6 +117,7 @@ bool Basis::is_conformal() const {
return Math::is_equal_approx(x_len_sq, y.length_squared()) && Math::is_equal_approx(x_len_sq, z.length_squared()) && Math::is_zero_approx(x.dot(y)) && Math::is_zero_approx(x.dot(z)) && Math::is_zero_approx(y.dot(z));
}
+// Returns true if the basis only has diagonal elements, so it may only have scale or flip, but no rotation, skew, or shear.
bool Basis::is_diagonal() const {
return (
Math::is_zero_approx(rows[0][1]) && Math::is_zero_approx(rows[0][2]) &&
@@ -111,8 +125,9 @@ bool Basis::is_diagonal() const {
Math::is_zero_approx(rows[2][0]) && Math::is_zero_approx(rows[2][1]));
}
+// Returns true if the basis is a pure rotation matrix, so it has no scale, skew, shear, or flip.
bool Basis::is_rotation() const {
- return Math::is_equal_approx(determinant(), 1, (real_t)UNIT_EPSILON) && is_orthogonal();
+ return is_conformal() && Math::is_equal_approx(determinant(), 1, (real_t)UNIT_EPSILON);
}
#ifdef MATH_CHECKS
diff --git a/core/math/basis.h b/core/math/basis.h
index adacd1c216..b4d971464e 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -138,6 +138,7 @@ struct _NO_DISCARD_ Basis {
_FORCE_INLINE_ Basis operator*(const real_t p_val) const;
bool is_orthogonal() const;
+ bool is_orthonormal() const;
bool is_conformal() const;
bool is_diagonal() const;
bool is_rotation() const;
diff --git a/core/math/dynamic_bvh.h b/core/math/dynamic_bvh.h
index dbc1cb31de..9b49fcc3c8 100644
--- a/core/math/dynamic_bvh.h
+++ b/core/math/dynamic_bvh.h
@@ -328,7 +328,8 @@ void DynamicBVH::aabb_query(const AABB &p_box, QueryResult &r_result) {
volume.min = p_box.position;
volume.max = p_box.position + p_box.size;
- const Node **stack = (const Node **)alloca(ALLOCA_STACK_SIZE * sizeof(const Node *));
+ const Node **alloca_stack = (const Node **)alloca(ALLOCA_STACK_SIZE * sizeof(const Node *));
+ const Node **stack = alloca_stack;
stack[0] = bvh_root;
int32_t depth = 1;
int32_t threshold = ALLOCA_STACK_SIZE - 2;
@@ -343,7 +344,8 @@ void DynamicBVH::aabb_query(const AABB &p_box, QueryResult &r_result) {
if (depth > threshold) {
if (aux_stack.is_empty()) {
aux_stack.resize(ALLOCA_STACK_SIZE * 2);
- memcpy(aux_stack.ptr(), stack, ALLOCA_STACK_SIZE * sizeof(const Node *));
+ memcpy(aux_stack.ptr(), alloca_stack, ALLOCA_STACK_SIZE * sizeof(const Node *));
+ alloca_stack = nullptr;
} else {
aux_stack.resize(aux_stack.size() * 2);
}
@@ -384,7 +386,8 @@ void DynamicBVH::convex_query(const Plane *p_planes, int p_plane_count, const Ve
}
}
- const Node **stack = (const Node **)alloca(ALLOCA_STACK_SIZE * sizeof(const Node *));
+ const Node **alloca_stack = (const Node **)alloca(ALLOCA_STACK_SIZE * sizeof(const Node *));
+ const Node **stack = alloca_stack;
stack[0] = bvh_root;
int32_t depth = 1;
int32_t threshold = ALLOCA_STACK_SIZE - 2;
@@ -399,7 +402,8 @@ void DynamicBVH::convex_query(const Plane *p_planes, int p_plane_count, const Ve
if (depth > threshold) {
if (aux_stack.is_empty()) {
aux_stack.resize(ALLOCA_STACK_SIZE * 2);
- memcpy(aux_stack.ptr(), stack, ALLOCA_STACK_SIZE * sizeof(const Node *));
+ memcpy(aux_stack.ptr(), alloca_stack, ALLOCA_STACK_SIZE * sizeof(const Node *));
+ alloca_stack = nullptr;
} else {
aux_stack.resize(aux_stack.size() * 2);
}
@@ -436,7 +440,8 @@ void DynamicBVH::ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResu
Vector3 bounds[2];
- const Node **stack = (const Node **)alloca(ALLOCA_STACK_SIZE * sizeof(const Node *));
+ const Node **alloca_stack = (const Node **)alloca(ALLOCA_STACK_SIZE * sizeof(const Node *));
+ const Node **stack = alloca_stack;
stack[0] = bvh_root;
int32_t depth = 1;
int32_t threshold = ALLOCA_STACK_SIZE - 2;
@@ -456,7 +461,8 @@ void DynamicBVH::ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResu
if (depth > threshold) {
if (aux_stack.is_empty()) {
aux_stack.resize(ALLOCA_STACK_SIZE * 2);
- memcpy(aux_stack.ptr(), stack, ALLOCA_STACK_SIZE * sizeof(const Node *));
+ memcpy(aux_stack.ptr(), alloca_stack, ALLOCA_STACK_SIZE * sizeof(const Node *));
+ alloca_stack = nullptr;
} else {
aux_stack.resize(aux_stack.size() * 2);
}