16 const T halfAngle = angle / 2;
17 const T sinHalf =
std::sin(halfAngle);
20 _data[1] = axis(0) * sinHalf;
21 _data[2] = axis(1) * sinHalf;
22 _data[3] = axis(2) * sinHalf;
79 Mat4x4<T> result{Mat4x4<T>::identity()};
82 const T xy = _data[1] * _data[2];
83 const T xz = _data[1] * _data[3];
84 const T wx = _data[0] * _data[1];
86 const T yy = _data[2] * _data[2];
87 const T yz = _data[2] * _data[3];
88 const T wy = _data[0] * _data[2];
90 const T zz = _data[3] * _data[3];
91 const T wz = _data[0] * _data[3];
93 result(0, 0) = T(1) - T(2) * (yy + zz);
94 result(1, 0) = T(2) * (xy + wz);
95 result(2, 0) = T(2) * (xz - wy);
97 result(0, 1) = T(2) * (xy - wz);
98 result(1, 1) = T(1) - T(2) * (xx + zz);
99 result(2, 1) = T(2) * (yz + wx);
101 result(0, 2) = T(2) * (xz + wy);
102 result(1, 2) = T(2) * (yz - wx);
103 result(2, 2) = T(1) - T(2) * (xx + yy);
108 template <
typename T>
110 return {T(1), T(0), T(0), T(0)};
113 template <
typename T>
117 rotMatrix(0, 0) = xAxis.x();
118 rotMatrix(1, 0) = xAxis.y();
119 rotMatrix(2, 0) = xAxis.z();
121 rotMatrix(0, 1) = yAxis.x();
122 rotMatrix(1, 1) = yAxis.y();
123 rotMatrix(2, 1) = yAxis.z();
125 rotMatrix(0, 2) = zAxis.x();
126 rotMatrix(1, 2) = zAxis.y();
127 rotMatrix(2, 2) = zAxis.z();
132 template <
typename T>
134 const T tr = rotMatrix(0, 0) + rotMatrix(1, 1) + rotMatrix(2, 2);
137 const T s = sqrt(T(1) + tr) * T(2);
141 (rotMatrix(2, 1) - rotMatrix(1, 2)) / s,
142 (rotMatrix(0, 2) - rotMatrix(2, 0)) / s,
143 (rotMatrix(1, 0) - rotMatrix(0, 1)) / s
145 }
else if ((rotMatrix(0, 0) > rotMatrix(1, 1)) && (rotMatrix(0, 0) > rotMatrix(2, 2))) {
146 const T s = sqrt(T(1) + rotMatrix(0, 0) - rotMatrix(1, 1) - rotMatrix(2, 2)) * T(2);
149 (rotMatrix(2, 1) - rotMatrix(1, 2)) / s,
151 (rotMatrix(0, 1) + rotMatrix(1, 0)) / s,
152 (rotMatrix(0, 2) + rotMatrix(2, 0)) / s
154 }
else if (rotMatrix(1, 1) > rotMatrix(2, 2)) {
155 const T s = sqrt(T(1) + rotMatrix(1, 1) - rotMatrix(0, 0) - rotMatrix(2, 2)) * T(2);
158 (rotMatrix(0, 2) - rotMatrix(2, 0)) / s,
159 (rotMatrix(0, 1) + rotMatrix(1, 0)) / s,
161 (rotMatrix(1, 2) + rotMatrix(2, 1)) / s
164 const T s = sqrt(T(1) + rotMatrix(2, 2) - rotMatrix(0, 0) - rotMatrix(1, 1)) * T(2);
167 (rotMatrix(1, 0) - rotMatrix(0, 1)) / s,
168 (rotMatrix(0, 2) + rotMatrix(2, 0)) / s,
169 (rotMatrix(1, 2) + rotMatrix(2, 1)) / s,
175 template <
typename T>
176 inline Quaternion<T>
conjugate(
const Quaternion<T>& lhs) {
177 return {lhs.w(), -lhs.x(), -lhs.y(), -lhs.z()};
180 template <
typename T>
181 inline Quaternion<T>
normalize(
const Quaternion<T>& lhs) {
182 const T
length = lhs.length();
186 template <
typename T>
187 inline Quaternion<T>
inverse(
const Quaternion<T>& lhs) {
188 Quaternion<T> result{lhs};
192 const T
length = result.squaredLength();
194 result[0] /= length *
length;
195 result[1] /= length *
length;
196 result[2] /= length *
length;
197 result[3] /= length *
length;
204 template <
typename T>
205 inline T
dot(
const Quaternion<T>& lhs,
const Quaternion<T>& rhs) {
206 return lhs[0] * rhs[0] + lhs[1] * rhs[1] + lhs[2] * rhs[2] + lhs[3] * rhs[3];
209 template <
typename T>
210 Quaternion<T>
directionTo(
const Vector<3, T>& original,
const Vector<3, T>& expected) {
211 Quaternion<T> result;
216 T cosTheta =
dot(v0, v1);
218 if (cosTheta >= T(1) - epsilon<T>()) {
223 if (cosTheta < T(-1) + epsilon<T>()) {
225 Vector<3, T> axis =
cross(Vector<3, T>{0.0f, 0.0f, 1.0f}, v0);
226 if (axis.squaredLength() <= (1
e-06 * 1
e-06)) {
227 axis =
cross(Vector<3, T>{1.0f, 0.0f, 0.0f}, v0);
231 result = Quaternion<T>(pi<T>(), axis);
233 T s = sqrt((T(1) + cosTheta) * T(2));
236 Vector<3, T> c =
cross(v0, v1);
238 result.w() = s * 0.5f;
239 result.x() = c.x() * invs;
240 result.y() = c.y() * invs;
241 result.z() = c.z() * invs;
249 template <
typename T>
250 inline Quaternion<T>
operator-(
const Quaternion<T>& lhs) {
251 return {-lhs[0], -lhs[1], -lhs[2], -lhs[3]};
254 template <
typename T>
255 inline Quaternion<T>
operator+(
const Quaternion<T>& lhs,
const Quaternion<T>& rhs) {
256 return {lhs[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2], lhs[3] + rhs[3]};
259 template <
typename T>
260 inline Quaternion<T>
operator-(
const Quaternion<T>& lhs,
const Quaternion<T>& rhs) {
261 return {lhs[0] - rhs[0], lhs[1] - rhs[1], lhs[2] - rhs[2], lhs[3] - rhs[3]};
264 template <
typename T>
265 inline Quaternion<T>
operator*(
const Quaternion<T>& lhs,
const Quaternion<T>& rhs) {
267 lhs[0] * rhs[0] - lhs[1] * rhs[1] - lhs[2] * rhs[2] - lhs[3] * rhs[3],
268 lhs[0] * rhs[1] + lhs[1] * rhs[0] + lhs[2] * rhs[3] - lhs[3] * rhs[2],
269 lhs[0] * rhs[2] - lhs[1] * rhs[3] + lhs[2] * rhs[0] + lhs[3] * rhs[1],
270 lhs[0] * rhs[3] + lhs[1] * rhs[2] - lhs[2] * rhs[1] + lhs[3] * rhs[0]
274 template <
typename T>
275 inline Quaternion<T>
operator/(
const Quaternion<T>& lhs,
const Quaternion<T>& rhs) {
279 template <
typename T>
280 inline bool operator==(
const Quaternion<T>& lhs,
const Quaternion<T>& rhs) {
281 return lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] == rhs[2] && lhs[3] == rhs[3];
284 template <
typename T>
285 inline bool operator!=(
const Quaternion<T>& lhs,
const Quaternion<T>& rhs) {
286 return lhs[0] != rhs[0] || lhs[1] != rhs[1] || lhs[2] != rhs[2] || lhs[3] != rhs[3];
289 template <
typename T>
290 std::ostream& operator<<(std::ostream& os, const Quaternion<T>& quaternion) {
291 os <<
"{w: " << quaternion.w() <<
", x: " << quaternion.x() <<
", y: " << quaternion.y() <<
", z: " << quaternion.z() <<
"}";
bool operator!=(const Matrix< Rows, Columns, T > &lhs, const Matrix< Rows, Columns, T > &rhs)
Quaternion< T > conjugate(const Quaternion< T > &lhs)
bool operator==(const Matrix< Rows, Columns, T > &lhs, const Matrix< Rows, Columns, T > &rhs)
constexpr Vector< 3, T > cross(const Vector< 3, T > &lhs, const Vector< 3, T > &rhs)
T & operator[](std::size_t idx)
static Quaternion< T > fromAxes(const Vector< 3, T > &xAxis, const Vector< 3, T > &yAxis, const Vector< 3, T > &zAxis)
Matrix< Rows, Columns, T > operator-(const Matrix< Rows, Columns, T > &lhs)
static std::enable_if<(Rows==Columns) &&EnableBool, Matrix< Rows, Columns, T > >::type identity()
static Quaternion< T > identity()
Vector< 3, T > getAxis() const
Mat4x4< T > transform() const
Quaternion< T > directionTo(const Vector< 3, T > &original, const Vector< 3, T > &expected)
constexpr T length() const
Matrix< Rows, Columns, T > operator+(const Matrix< Rows, Columns, T > &lhs, T rhs)
Matrix< Rows, Columns, T > operator/(const Matrix< Rows, Columns, T > &lhs, T rhs)
Matrix< Rows, Columns, T > operator*(const Matrix< Rows, Columns, T > &lhs, T rhs)
T dot(const Quaternion< T > &lhs, const Quaternion< T > &rhs)
constexpr T squaredLength() const
Quaternion< T > normalize(const Quaternion< T > &lhs)
static Quaternion< T > fromRotationMatrix(const Matrix< 4, 4, T > &rotMatrix)