aboutsummaryrefslogtreecommitdiff
path: root/src/math/quat.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/math/quat.hpp')
-rw-r--r--src/math/quat.hpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/math/quat.hpp b/src/math/quat.hpp
index 51392e7..9687c98 100644
--- a/src/math/quat.hpp
+++ b/src/math/quat.hpp
@@ -2,6 +2,7 @@
#define MATH_QUAT_HPP
#include <cmath>
+#include "math/vector.hpp"
namespace engine::math {
@@ -30,6 +31,23 @@ struct Quaternion {
return {std::cos(a / 2.f), 0.f, std::sin(a / 2.f), 0.f};
}
+ static constexpr Quaternion look_towards(const Vector3& dir, const Vector3& up) {
+ // TODO: extract common code between Matrix4::look_at and this. We should have something
+ // similar to a function returning a 3x3 matrix which does:
+ // e_x -> up.cross(-dir).normalize()
+ // e_y -> (-dir).cross(e_x).normalize()
+ // e_z -> (-dir).normalize()
+ Vector3 new_x = up.cross(-dir).normalize();
+ Vector3 new_y = (-dir).cross(new_x).normalize();
+ Vector3 new_z = (-dir).normalize();
+ return {
+ std::sqrt(std::max(0.f, new_x.x + new_y.y + new_z.z + 1.f)) / 2.f,
+ std::copysign(std::sqrt(std::max(0.f, new_x.x - new_y.y - new_z.z + 1.f)) / 2.f, new_y.z - new_z.y),
+ std::copysign(std::sqrt(std::max(0.f, -new_x.x + new_y.y - new_z.z + 1.f)) / 2.f, new_z.x - new_x.z),
+ std::copysign(std::sqrt(std::max(0.f, -new_x.x - new_y.y + new_z.z + 1.f)) / 2.f, new_x.y - new_y.x),
+ };
+ }
+
float w, x, y, z;
constexpr Quaternion() {}
@@ -71,6 +89,14 @@ struct Quaternion {
constexpr Quaternion conjugate() const & {
return {w, -x, -y, -z};
}
+
+ constexpr Vector3 rot(const Vector3& v) const & {
+ return {
+ (2.f * (w * w + x * x) - 1.f) * v.x + (2.f * (x * y - w * z) ) * v.y + (2.f * (x * z + w * y) ) * v.z,
+ (2.f * (x * y + w * z) ) * v.x + (2.f * (w * w + y * y) - 1.f) * v.y + (2.f * (y * z - w * x) ) * v.z,
+ (2.f * (x * z - w * y) ) * v.x + (2.f * (y * z + w * x) ) * v.y + (2.f * (w * w + z * z) - 1.f) * v.z,
+ };
+ }
};
}