From 71c8c20af80780ef45ea014880978cb7531e23eb Mon Sep 17 00:00:00 2001 From: Emmett Lalish Date: Fri, 11 Oct 2024 21:27:03 -0700 Subject: [PATCH] more matrix constructors --- include/manifold/linalg.h | 44 ++++++++++++++++++++++++++++----------- src/csg_tree.cpp | 6 +++--- src/impl.cpp | 2 +- src/impl.h | 10 ++++----- src/svd.h | 4 ++-- src/utils.h | 4 ++++ 6 files changed, 47 insertions(+), 23 deletions(-) diff --git a/include/manifold/linalg.h b/include/manifold/linalg.h index 0dfc9ec71..383a76b11 100644 --- a/include/manifold/linalg.h +++ b/include/manifold/linalg.h @@ -788,7 +788,11 @@ struct vec { constexpr explicit vec(const T *p) : vec(p[0], p[1]) {} template constexpr explicit vec(const vec &v) - : vec(static_cast(v.x), N < 2 ? 0 : static_cast(v.y)) {} + : vec(static_cast(v.x), static_cast(v.y)) { + static_assert( + N >= 2, + "You must give extra arguments if your input vector is shorter."); + } constexpr const T &operator[](int i) const { return i == 0 ? x : y; } LINALG_CONSTEXPR14 T &operator[](int i) { return i == 0 ? x : y; } @@ -809,8 +813,11 @@ struct vec { constexpr explicit vec(const T *p) : vec(p[0], p[1], p[2]) {} template constexpr explicit vec(const vec &v) - : vec(static_cast(v.x), N < 2 ? 0 : static_cast(v.y), - N < 3 ? 0 : static_cast(v.z)) {} + : vec(static_cast(v.x), static_cast(v.y), static_cast(v.z)) { + static_assert( + N >= 3, + "You must give extra arguments if your input vector is shorter."); + } constexpr const T &operator[](int i) const { return i == 0 ? x : i == 1 ? y : z; } @@ -843,8 +850,12 @@ struct vec { constexpr explicit vec(const T *p) : vec(p[0], p[1], p[2], p[3]) {} template constexpr explicit vec(const vec &v) - : vec(static_cast(v.x), N < 2 ? 0 : static_cast(v.y), - N < 3 ? 0 : static_cast(v.z), N < 4 ? 0 : static_cast(v.w)) {} + : vec(static_cast(v.x), static_cast(v.y), static_cast(v.z), + static_cast(v.w)) { + static_assert( + N >= 4, + "You must give extra arguments if your input vector is shorter."); + } constexpr const T &operator[](int i) const { return i == 0 ? x : i == 1 ? y : i == 2 ? z : w; } @@ -899,8 +910,10 @@ struct mat { constexpr mat(const V &x_, const V &y_) : x(x_), y(y_) {} constexpr explicit mat(const T &s) : x(s), y(s) {} constexpr explicit mat(const T *p) : x(p + M * 0), y(p + M * 1) {} - template - constexpr explicit mat(const mat &m) : mat(V(m.x), V(m.y)) {} + template + constexpr explicit mat(const mat &m) : mat(V(m.x), V(m.y)) { + static_assert(P >= 2, "Input matrix dimensions must be at least as big."); + } constexpr vec row(int i) const { return {x[i], y[i]}; } constexpr const V &operator[](int j) const { return j == 0 ? x : y; } LINALG_CONSTEXPR14 V &operator[](int j) { return j == 0 ? x : y; } @@ -921,8 +934,10 @@ struct mat { constexpr explicit mat(const T &s) : x(s), y(s), z(s) {} constexpr explicit mat(const T *p) : x(p + M * 0), y(p + M * 1), z(p + M * 2) {} - template - constexpr explicit mat(const mat &m) : mat(V(m.x), V(m.y), V(m.z)) {} + template + constexpr explicit mat(const mat &m) : mat(V(m.x), V(m.y), V(m.z)) { + static_assert(P >= 3, "Input matrix dimensions must be at least as big."); + } constexpr vec row(int i) const { return {x[i], y[i], z[i]}; } constexpr const V &operator[](int j) const { return j == 0 ? x : j == 1 ? y : z; @@ -945,12 +960,17 @@ struct mat { constexpr mat() : x(), y(), z(), w() {} constexpr mat(const V &x_, const V &y_, const V &z_, const V &w_) : x(x_), y(y_), z(z_), w(w_) {} + constexpr mat(const mat &m_, const V &w_) + : x(m_.x), y(m_.y), z(m_.z), w(w_) {} constexpr explicit mat(const T &s) : x(s), y(s), z(s), w(s) {} constexpr explicit mat(const T *p) : x(p + M * 0), y(p + M * 1), z(p + M * 2), w(p + M * 3) {} - template - constexpr explicit mat(const mat &m) - : mat(V(m.x), V(m.y), V(m.z), V(m.w)) {} + template + constexpr explicit mat(const mat &m) + : mat(V(m.x), V(m.y), V(m.z), V(m.w)) { + static_assert(P >= 4, "Input matrix dimensions must be at least as big."); + } + constexpr vec row(int i) const { return {x[i], y[i], z[i], w[i]}; } constexpr const V &operator[](int j) const { return j == 0 ? x : j == 1 ? y : j == 2 ? z : w; diff --git a/src/csg_tree.cpp b/src/csg_tree.cpp index 4294ab2c8..328122133 100644 --- a/src/csg_tree.cpp +++ b/src/csg_tree.cpp @@ -133,7 +133,7 @@ std::shared_ptr CsgNode::Rotate(double xDegrees, double yDegrees, mat3 rZ({cosd(zDegrees), sind(zDegrees), 0.0}, // {-sind(zDegrees), cosd(zDegrees), 0.0}, // {0.0, 0.0, 1.0}); - mat4x3 transform(la::mul(rZ, rY, rX)); + mat4x3 transform(rZ * rY * rX, vec3()); return Transform(transform); } @@ -161,7 +161,7 @@ std::shared_ptr CsgLeafNode::ToLeafNode() const { } std::shared_ptr CsgLeafNode::Transform(const mat4x3 &m) const { - return std::make_shared(pImpl_, la::mul(m, mat4(transform_))); + return std::make_shared(pImpl_, m * Mat4(transform_)); } CsgNodeType CsgLeafNode::GetNodeType() const { return CsgNodeType::Leaf; } @@ -392,7 +392,7 @@ std::shared_ptr CsgOpNode::Boolean( std::shared_ptr CsgOpNode::Transform(const mat4x3 &m) const { auto node = std::make_shared(); node->impl_ = impl_; - node->transform_ = la::mul(m, mat4(transform_)); + node->transform_ = m * Mat4(transform_); node->op_ = op_; return node; } diff --git a/src/impl.cpp b/src/impl.cpp index 8ebc9304d..11584c8a6 100644 --- a/src/impl.cpp +++ b/src/impl.cpp @@ -533,7 +533,7 @@ Manifold::Impl Manifold::Impl::Transform(const mat4x3& transform_) const { result.meshRelation_.originalID = -1; for (auto& m : result.meshRelation_.meshIDtransform) { - m.second.transform = transform_ * mat4(m.second.transform); + m.second.transform = transform_ * Mat4(m.second.transform); } result.vertPos_.resize(NumVert()); diff --git a/src/impl.h b/src/impl.h index 0a0f217eb..8011196c3 100644 --- a/src/impl.h +++ b/src/impl.h @@ -153,11 +153,11 @@ struct Manifold::Impl { meshRelation_.meshIDtransform[meshID] = {originalID}; } else { const Precision* m = meshGL.runTransform.data() + 12 * i; - meshRelation_.meshIDtransform[meshID] = { - originalID, - {{m[0], m[1], m[2], m[3]}, - {m[4], m[5], m[6], m[7]}, - {m[8], m[9], m[10], m[11]}}}; + meshRelation_.meshIDtransform[meshID] = {originalID, + {{m[0], m[1], m[2]}, + {m[3], m[4], m[5]}, + {m[6], m[7], m[8]}, + {m[9], m[10], m[11]}}}; } } } diff --git a/src/svd.h b/src/svd.h index 54fb4d236..f702b42b6 100644 --- a/src/svd.h +++ b/src/svd.h @@ -292,8 +292,8 @@ struct SVDSet { * @param A The matrix to decompose. */ inline SVDSet SVD(mat3 A) { - mat3 V = JacobiEigenAnalysis(la::mul(la::transpose(A), A)); - auto B = la::mul(A, V); + mat3 V = JacobiEigenAnalysis(la::transpose(A) * A); + auto B = A * V; SortSingularValues(B, V); QR qr = QRDecomposition(B); return SVDSet{qr.Q, qr.R, V}; diff --git a/src/utils.h b/src/utils.h index 70982266c..fc98c14f5 100644 --- a/src/utils.h +++ b/src/utils.h @@ -244,6 +244,10 @@ inline mat4x3 RotateUp(vec3 up) { return mat4x3(la::rotate(mat4(1), angle, axis)); } +inline mat4 Mat4(mat4x3 a) { + return mat4({a[0], 0}, {a[1], 0}, {a[2], 0}, {a[3], 1}); +} + /** @} */ /** @defgroup Debug