2 Copyright (C) 2001-2006, William Joseph.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #if !defined(INCLUDED_MATH_MATRIX_H)
23 #define INCLUDED_MATH_MATRIX_H
26 /// \brief Matrix data types and related operations.
28 #include "math/vector.h"
30 /// \brief A 4x4 matrix stored in single-precision floating-point.
39 Matrix4(float xx_, float xy_, float xz_, float xw_,
40 float yx_, float yy_, float yz_, float yw_,
41 float zx_, float zy_, float zz_, float zw_,
42 float tx_, float ty_, float tz_, float tw_)
66 const float& xx() const
74 const float& xy() const
82 const float& xz() const
90 const float& xw() const
98 const float& yx() const
100 return m_elements[4];
104 return m_elements[5];
106 const float& yy() const
108 return m_elements[5];
112 return m_elements[6];
114 const float& yz() const
116 return m_elements[6];
120 return m_elements[7];
122 const float& yw() const
124 return m_elements[7];
128 return m_elements[8];
130 const float& zx() const
132 return m_elements[8];
136 return m_elements[9];
138 const float& zy() const
140 return m_elements[9];
144 return m_elements[10];
146 const float& zz() const
148 return m_elements[10];
152 return m_elements[11];
154 const float& zw() const
156 return m_elements[11];
160 return m_elements[12];
162 const float& tx() const
164 return m_elements[12];
168 return m_elements[13];
170 const float& ty() const
172 return m_elements[13];
176 return m_elements[14];
178 const float& tz() const
180 return m_elements[14];
184 return m_elements[15];
186 const float& tw() const
188 return m_elements[15];
193 return reinterpret_cast<Vector4&>(xx());
195 const Vector4& x() const
197 return reinterpret_cast<const Vector4&>(xx());
201 return reinterpret_cast<Vector4&>(yx());
203 const Vector4& y() const
205 return reinterpret_cast<const Vector4&>(yx());
209 return reinterpret_cast<Vector4&>(zx());
211 const Vector4& z() const
213 return reinterpret_cast<const Vector4&>(zx());
217 return reinterpret_cast<Vector4&>(tx());
219 const Vector4& t() const
221 return reinterpret_cast<const Vector4&>(tx());
224 const float& index(std::size_t i) const
226 return m_elements[i];
228 float& index(std::size_t i)
230 return m_elements[i];
232 const float& operator[](std::size_t i) const
234 return m_elements[i];
236 float& operator[](std::size_t i)
238 return m_elements[i];
240 const float& index(std::size_t r, std::size_t c) const
242 return m_elements[(r << 2) + c];
244 float& index(std::size_t r, std::size_t c)
246 return m_elements[(r << 2) + c];
250 /// \brief The 4x4 identity matrix.
251 const Matrix4 g_matrix4_identity(
259 /// \brief Returns true if \p self and \p other are exactly element-wise equal.
260 inline bool operator==(const Matrix4& self, const Matrix4& other)
262 return self.xx() == other.xx() && self.xy() == other.xy() && self.xz() == other.xz() && self.xw() == other.xw()
263 && self.yx() == other.yx() && self.yy() == other.yy() && self.yz() == other.yz() && self.yw() == other.yw()
264 && self.zx() == other.zx() && self.zy() == other.zy() && self.zz() == other.zz() && self.zw() == other.zw()
265 && self.tx() == other.tx() && self.ty() == other.ty() && self.tz() == other.tz() && self.tw() == other.tw();
268 /// \brief Returns true if \p self and \p other are exactly element-wise equal.
269 inline bool matrix4_equal(const Matrix4& self, const Matrix4& other)
271 return self == other;
274 /// \brief Returns true if \p self and \p other are element-wise equal within \p epsilon.
275 inline bool matrix4_equal_epsilon(const Matrix4& self, const Matrix4& other, float epsilon)
277 return float_equal_epsilon(self.xx(), other.xx(), epsilon)
278 && float_equal_epsilon(self.xy(), other.xy(), epsilon)
279 && float_equal_epsilon(self.xz(), other.xz(), epsilon)
280 && float_equal_epsilon(self.xw(), other.xw(), epsilon)
281 && float_equal_epsilon(self.yx(), other.yx(), epsilon)
282 && float_equal_epsilon(self.yy(), other.yy(), epsilon)
283 && float_equal_epsilon(self.yz(), other.yz(), epsilon)
284 && float_equal_epsilon(self.yw(), other.yw(), epsilon)
285 && float_equal_epsilon(self.zx(), other.zx(), epsilon)
286 && float_equal_epsilon(self.zy(), other.zy(), epsilon)
287 && float_equal_epsilon(self.zz(), other.zz(), epsilon)
288 && float_equal_epsilon(self.zw(), other.zw(), epsilon)
289 && float_equal_epsilon(self.tx(), other.tx(), epsilon)
290 && float_equal_epsilon(self.ty(), other.ty(), epsilon)
291 && float_equal_epsilon(self.tz(), other.tz(), epsilon)
292 && float_equal_epsilon(self.tw(), other.tw(), epsilon);
295 /// \brief Returns true if \p self and \p other are exactly element-wise equal.
296 /// \p self and \p other must be affine.
297 inline bool matrix4_affine_equal(const Matrix4& self, const Matrix4& other)
299 return self[0] == other[0]
300 && self[1] == other[1]
301 && self[2] == other[2]
302 && self[4] == other[4]
303 && self[5] == other[5]
304 && self[6] == other[6]
305 && self[8] == other[8]
306 && self[9] == other[9]
307 && self[10] == other[10]
308 && self[12] == other[12]
309 && self[13] == other[13]
310 && self[14] == other[14];
313 enum Matrix4Handedness
315 MATRIX4_RIGHTHANDED = 0,
316 MATRIX4_LEFTHANDED = 1,
319 /// \brief Returns MATRIX4_RIGHTHANDED if \p self is right-handed, else returns MATRIX4_LEFTHANDED.
320 inline Matrix4Handedness matrix4_handedness(const Matrix4& self)
324 vector3_cross(vector4_to_vector3(self.x()), vector4_to_vector3(self.y())),
325 vector4_to_vector3(self.z())
328 ) ? MATRIX4_LEFTHANDED : MATRIX4_RIGHTHANDED;
335 /// \brief Returns \p self post-multiplied by \p other.
336 inline Matrix4 matrix4_multiplied_by_matrix4(const Matrix4& self, const Matrix4& other)
339 other[0] * self[0] + other[1] * self[4] + other[2] * self[8] + other[3] * self[12],
340 other[0] * self[1] + other[1] * self[5] + other[2] * self[9] + other[3] * self[13],
341 other[0] * self[2] + other[1] * self[6] + other[2] * self[10]+ other[3] * self[14],
342 other[0] * self[3] + other[1] * self[7] + other[2] * self[11]+ other[3] * self[15],
343 other[4] * self[0] + other[5] * self[4] + other[6] * self[8] + other[7] * self[12],
344 other[4] * self[1] + other[5] * self[5] + other[6] * self[9] + other[7] * self[13],
345 other[4] * self[2] + other[5] * self[6] + other[6] * self[10]+ other[7] * self[14],
346 other[4] * self[3] + other[5] * self[7] + other[6] * self[11]+ other[7] * self[15],
347 other[8] * self[0] + other[9] * self[4] + other[10]* self[8] + other[11]* self[12],
348 other[8] * self[1] + other[9] * self[5] + other[10]* self[9] + other[11]* self[13],
349 other[8] * self[2] + other[9] * self[6] + other[10]* self[10]+ other[11]* self[14],
350 other[8] * self[3] + other[9] * self[7] + other[10]* self[11]+ other[11]* self[15],
351 other[12]* self[0] + other[13]* self[4] + other[14]* self[8] + other[15]* self[12],
352 other[12]* self[1] + other[13]* self[5] + other[14]* self[9] + other[15]* self[13],
353 other[12]* self[2] + other[13]* self[6] + other[14]* self[10]+ other[15]* self[14],
354 other[12]* self[3] + other[13]* self[7] + other[14]* self[11]+ other[15]* self[15]
358 /// \brief Post-multiplies \p self by \p other in-place.
359 inline void matrix4_multiply_by_matrix4(Matrix4& self, const Matrix4& other)
361 self = matrix4_multiplied_by_matrix4(self, other);
365 /// \brief Returns \p self pre-multiplied by \p other.
366 inline Matrix4 matrix4_premultiplied_by_matrix4(const Matrix4& self, const Matrix4& other)
369 return matrix4_multiplied_by_matrix4(other, self);
372 self[0] * other[0] + self[1] * other[4] + self[2] * other[8] + self[3] * other[12],
373 self[0] * other[1] + self[1] * other[5] + self[2] * other[9] + self[3] * other[13],
374 self[0] * other[2] + self[1] * other[6] + self[2] * other[10]+ self[3] * other[14],
375 self[0] * other[3] + self[1] * other[7] + self[2] * other[11]+ self[3] * other[15],
376 self[4] * other[0] + self[5] * other[4] + self[6] * other[8] + self[7] * other[12],
377 self[4] * other[1] + self[5] * other[5] + self[6] * other[9] + self[7] * other[13],
378 self[4] * other[2] + self[5] * other[6] + self[6] * other[10]+ self[7] * other[14],
379 self[4] * other[3] + self[5] * other[7] + self[6] * other[11]+ self[7] * other[15],
380 self[8] * other[0] + self[9] * other[4] + self[10]* other[8] + self[11]* other[12],
381 self[8] * other[1] + self[9] * other[5] + self[10]* other[9] + self[11]* other[13],
382 self[8] * other[2] + self[9] * other[6] + self[10]* other[10]+ self[11]* other[14],
383 self[8] * other[3] + self[9] * other[7] + self[10]* other[11]+ self[11]* other[15],
384 self[12]* other[0] + self[13]* other[4] + self[14]* other[8] + self[15]* other[12],
385 self[12]* other[1] + self[13]* other[5] + self[14]* other[9] + self[15]* other[13],
386 self[12]* other[2] + self[13]* other[6] + self[14]* other[10]+ self[15]* other[14],
387 self[12]* other[3] + self[13]* other[7] + self[14]* other[11]+ self[15]* other[15]
392 /// \brief Pre-multiplies \p self by \p other in-place.
393 inline void matrix4_premultiply_by_matrix4(Matrix4& self, const Matrix4& other)
395 self = matrix4_premultiplied_by_matrix4(self, other);
398 /// \brief returns true if \p transform is affine.
399 inline bool matrix4_is_affine(const Matrix4& transform)
401 return transform[3] == 0 && transform[7] == 0 && transform[11] == 0 && transform[15] == 1;
404 /// \brief Returns \p self post-multiplied by \p other.
405 /// \p self and \p other must be affine.
406 inline Matrix4 matrix4_affine_multiplied_by_matrix4(const Matrix4& self, const Matrix4& other)
409 other[0] * self[0] + other[1] * self[4] + other[2] * self[8],
410 other[0] * self[1] + other[1] * self[5] + other[2] * self[9],
411 other[0] * self[2] + other[1] * self[6] + other[2] * self[10],
413 other[4] * self[0] + other[5] * self[4] + other[6] * self[8],
414 other[4] * self[1] + other[5] * self[5] + other[6] * self[9],
415 other[4] * self[2] + other[5] * self[6] + other[6] * self[10],
417 other[8] * self[0] + other[9] * self[4] + other[10]* self[8],
418 other[8] * self[1] + other[9] * self[5] + other[10]* self[9],
419 other[8] * self[2] + other[9] * self[6] + other[10]* self[10],
421 other[12]* self[0] + other[13]* self[4] + other[14]* self[8] + self[12],
422 other[12]* self[1] + other[13]* self[5] + other[14]* self[9] + self[13],
423 other[12]* self[2] + other[13]* self[6] + other[14]* self[10]+ self[14],
428 /// \brief Post-multiplies \p self by \p other in-place.
429 /// \p self and \p other must be affine.
430 inline void matrix4_affine_multiply_by_matrix4(Matrix4& self, const Matrix4& other)
432 self = matrix4_affine_multiplied_by_matrix4(self, other);
435 /// \brief Returns \p self pre-multiplied by \p other.
436 /// \p self and \p other must be affine.
437 inline Matrix4 matrix4_affine_premultiplied_by_matrix4(const Matrix4& self, const Matrix4& other)
440 return matrix4_affine_multiplied_by_matrix4(other, self);
443 self[0] * other[0] + self[1] * other[4] + self[2] * other[8],
444 self[0] * other[1] + self[1] * other[5] + self[2] * other[9],
445 self[0] * other[2] + self[1] * other[6] + self[2] * other[10],
447 self[4] * other[0] + self[5] * other[4] + self[6] * other[8],
448 self[4] * other[1] + self[5] * other[5] + self[6] * other[9],
449 self[4] * other[2] + self[5] * other[6] + self[6] * other[10],
451 self[8] * other[0] + self[9] * other[4] + self[10]* other[8],
452 self[8] * other[1] + self[9] * other[5] + self[10]* other[9],
453 self[8] * other[2] + self[9] * other[6] + self[10]* other[10],
455 self[12]* other[0] + self[13]* other[4] + self[14]* other[8] + other[12],
456 self[12]* other[1] + self[13]* other[5] + self[14]* other[9] + other[13],
457 self[12]* other[2] + self[13]* other[6] + self[14]* other[10]+ other[14],
464 /// \brief Pre-multiplies \p self by \p other in-place.
465 /// \p self and \p other must be affine.
466 inline void matrix4_affine_premultiply_by_matrix4(Matrix4& self, const Matrix4& other)
468 self = matrix4_affine_premultiplied_by_matrix4(self, other);
471 /// \brief Returns \p point transformed by \p self.
472 template<typename Element>
473 inline BasicVector3<Element> matrix4_transformed_point(const Matrix4& self, const BasicVector3<Element>& point)
475 return BasicVector3<Element>(
476 static_cast<Element>(self[0] * point[0] + self[4] * point[1] + self[8] * point[2] + self[12]),
477 static_cast<Element>(self[1] * point[0] + self[5] * point[1] + self[9] * point[2] + self[13]),
478 static_cast<Element>(self[2] * point[0] + self[6] * point[1] + self[10] * point[2] + self[14])
482 /// \brief Transforms \p point by \p self in-place.
483 template<typename Element>
484 inline void matrix4_transform_point(const Matrix4& self, BasicVector3<Element>& point)
486 point = matrix4_transformed_point(self, point);
489 /// \brief Returns \p direction transformed by \p self.
490 template<typename Element>
491 inline BasicVector3<Element> matrix4_transformed_direction(const Matrix4& self, const BasicVector3<Element>& direction)
493 return BasicVector3<Element>(
494 static_cast<Element>(self[0] * direction[0] + self[4] * direction[1] + self[8] * direction[2]),
495 static_cast<Element>(self[1] * direction[0] + self[5] * direction[1] + self[9] * direction[2]),
496 static_cast<Element>(self[2] * direction[0] + self[6] * direction[1] + self[10] * direction[2])
500 /// \brief Transforms \p direction by \p self in-place.
501 template<typename Element>
502 inline void matrix4_transform_direction(const Matrix4& self, BasicVector3<Element>& normal)
504 normal = matrix4_transformed_direction(self, normal);
507 /// \brief Returns \p vector4 transformed by \p self.
508 inline Vector4 matrix4_transformed_vector4(const Matrix4& self, const Vector4& vector4)
511 self[0] * vector4[0] + self[4] * vector4[1] + self[8] * vector4[2] + self[12] * vector4[3],
512 self[1] * vector4[0] + self[5] * vector4[1] + self[9] * vector4[2] + self[13] * vector4[3],
513 self[2] * vector4[0] + self[6] * vector4[1] + self[10] * vector4[2] + self[14] * vector4[3],
514 self[3] * vector4[0] + self[7] * vector4[1] + self[11] * vector4[2] + self[15] * vector4[3]
518 /// \brief Transforms \p vector4 by \p self in-place.
519 inline void matrix4_transform_vector4(const Matrix4& self, Vector4& vector4)
521 vector4 = matrix4_transformed_vector4(self, vector4);
525 /// \brief Transposes \p self in-place.
526 inline void matrix4_transpose(Matrix4& self)
528 std::swap(self.xy(), self.yx());
529 std::swap(self.xz(), self.zx());
530 std::swap(self.xw(), self.tx());
531 std::swap(self.yz(), self.zy());
532 std::swap(self.yw(), self.ty());
533 std::swap(self.zw(), self.tz());
536 /// \brief Returns \p self transposed.
537 inline Matrix4 matrix4_transposed(const Matrix4& self)
560 /// \brief Inverts an affine transform in-place.
561 /// Adapted from Graphics Gems 2.
562 inline Matrix4 matrix4_affine_inverse(const Matrix4& self)
566 // determinant of rotation submatrix
568 = self[0] * ( self[5]*self[10] - self[9]*self[6] )
569 - self[1] * ( self[4]*self[10] - self[8]*self[6] )
570 + self[2] * ( self[4]*self[9] - self[8]*self[5] );
572 // throw exception here if (det*det < 1e-25)
574 // invert rotation submatrix
577 result[0] = static_cast<float>( (self[5]*self[10]- self[6]*self[9] )*det);
578 result[1] = static_cast<float>(- (self[1]*self[10]- self[2]*self[9] )*det);
579 result[2] = static_cast<float>( (self[1]*self[6] - self[2]*self[5] )*det);
581 result[4] = static_cast<float>(- (self[4]*self[10]- self[6]*self[8] )*det);
582 result[5] = static_cast<float>( (self[0]*self[10]- self[2]*self[8] )*det);
583 result[6] = static_cast<float>(- (self[0]*self[6] - self[2]*self[4] )*det);
585 result[8] = static_cast<float>( (self[4]*self[9] - self[5]*self[8] )*det);
586 result[9] = static_cast<float>(- (self[0]*self[9] - self[1]*self[8] )*det);
587 result[10]= static_cast<float>( (self[0]*self[5] - self[1]*self[4] )*det);
590 // multiply translation part by rotation
591 result[12] = - (self[12] * result[0] +
592 self[13] * result[4] +
593 self[14] * result[8]);
594 result[13] = - (self[12] * result[1] +
595 self[13] * result[5] +
596 self[14] * result[9]);
597 result[14] = - (self[12] * result[2] +
598 self[13] * result[6] +
599 self[14] * result[10]);
605 inline void matrix4_affine_invert(Matrix4& self)
607 self = matrix4_affine_inverse(self);
610 /// \brief A compile-time-constant integer.
612 struct IntegralConstant
614 enum unnamed_{ VALUE = VALUE_ };
617 /// \brief A compile-time-constant row/column index into a 4x4 matrix.
618 template<typename Row, typename Col>
622 typedef IntegralConstant<Row::VALUE> r;
623 typedef IntegralConstant<Col::VALUE> c;
624 typedef IntegralConstant<(r::VALUE * 4) + c::VALUE> i;
627 /// \brief A functor which returns the cofactor of a 3x3 submatrix obtained by ignoring a given row and column of a 4x4 matrix.
628 /// \param Row Defines the compile-time-constant integers x, y and z with values corresponding to the indices of the three rows to use.
629 /// \param Col Defines the compile-time-constant integers x, y and z with values corresponding to the indices of the three columns to use.
630 template<typename Row, typename Col>
631 class Matrix4Cofactor
634 typedef typename Matrix4Index<typename Row::x, typename Col::x>::i xx;
635 typedef typename Matrix4Index<typename Row::x, typename Col::y>::i xy;
636 typedef typename Matrix4Index<typename Row::x, typename Col::z>::i xz;
637 typedef typename Matrix4Index<typename Row::y, typename Col::x>::i yx;
638 typedef typename Matrix4Index<typename Row::y, typename Col::y>::i yy;
639 typedef typename Matrix4Index<typename Row::y, typename Col::z>::i yz;
640 typedef typename Matrix4Index<typename Row::z, typename Col::x>::i zx;
641 typedef typename Matrix4Index<typename Row::z, typename Col::y>::i zy;
642 typedef typename Matrix4Index<typename Row::z, typename Col::z>::i zz;
643 static double apply(const Matrix4& self)
645 return self[xx::VALUE] * ( self[yy::VALUE]*self[zz::VALUE] - self[zy::VALUE]*self[yz::VALUE] )
646 - self[xy::VALUE] * ( self[yx::VALUE]*self[zz::VALUE] - self[zx::VALUE]*self[yz::VALUE] )
647 + self[xz::VALUE] * ( self[yx::VALUE]*self[zy::VALUE] - self[zx::VALUE]*self[yy::VALUE] );
651 /// \brief The cofactor element indices for a 4x4 matrix row or column.
652 /// \param Element The index of the element to ignore.
653 template<int Element>
657 typedef IntegralConstant<(Element <= 0) ? 1 : 0> x;
658 typedef IntegralConstant<(Element <= 1) ? 2 : 1> y;
659 typedef IntegralConstant<(Element <= 2) ? 3 : 2> z;
662 /// \brief Returns the determinant of \p self.
663 inline double matrix4_determinant(const Matrix4& self)
665 return self.xx() * Matrix4Cofactor< Cofactor4<0>, Cofactor4<0> >::apply(self)
666 - self.xy() * Matrix4Cofactor< Cofactor4<0>, Cofactor4<1> >::apply(self)
667 + self.xz() * Matrix4Cofactor< Cofactor4<0>, Cofactor4<2> >::apply(self)
668 - self.xw() * Matrix4Cofactor< Cofactor4<0>, Cofactor4<3> >::apply(self);
671 /// \brief Returns the inverse of \p self using the Adjoint method.
672 /// \todo Throw an exception if the determinant is zero.
673 inline Matrix4 matrix4_full_inverse(const Matrix4& self)
675 double determinant = 1.0 / matrix4_determinant(self);
678 static_cast<float>( Matrix4Cofactor< Cofactor4<0>, Cofactor4<0> >::apply(self) * determinant),
679 static_cast<float>(-Matrix4Cofactor< Cofactor4<1>, Cofactor4<0> >::apply(self) * determinant),
680 static_cast<float>( Matrix4Cofactor< Cofactor4<2>, Cofactor4<0> >::apply(self) * determinant),
681 static_cast<float>(-Matrix4Cofactor< Cofactor4<3>, Cofactor4<0> >::apply(self) * determinant),
682 static_cast<float>(-Matrix4Cofactor< Cofactor4<0>, Cofactor4<1> >::apply(self) * determinant),
683 static_cast<float>( Matrix4Cofactor< Cofactor4<1>, Cofactor4<1> >::apply(self) * determinant),
684 static_cast<float>(-Matrix4Cofactor< Cofactor4<2>, Cofactor4<1> >::apply(self) * determinant),
685 static_cast<float>( Matrix4Cofactor< Cofactor4<3>, Cofactor4<1> >::apply(self) * determinant),
686 static_cast<float>( Matrix4Cofactor< Cofactor4<0>, Cofactor4<2> >::apply(self) * determinant),
687 static_cast<float>(-Matrix4Cofactor< Cofactor4<1>, Cofactor4<2> >::apply(self) * determinant),
688 static_cast<float>( Matrix4Cofactor< Cofactor4<2>, Cofactor4<2> >::apply(self) * determinant),
689 static_cast<float>(-Matrix4Cofactor< Cofactor4<3>, Cofactor4<2> >::apply(self) * determinant),
690 static_cast<float>(-Matrix4Cofactor< Cofactor4<0>, Cofactor4<3> >::apply(self) * determinant),
691 static_cast<float>( Matrix4Cofactor< Cofactor4<1>, Cofactor4<3> >::apply(self) * determinant),
692 static_cast<float>(-Matrix4Cofactor< Cofactor4<2>, Cofactor4<3> >::apply(self) * determinant),
693 static_cast<float>( Matrix4Cofactor< Cofactor4<3>, Cofactor4<3> >::apply(self) * determinant)
697 /// \brief Inverts \p self in-place using the Adjoint method.
698 inline void matrix4_full_invert(Matrix4& self)
700 self = matrix4_full_inverse(self);
704 /// \brief Constructs a pure-translation matrix from \p translation.
705 inline Matrix4 matrix4_translation_for_vec3(const Vector3& translation)
711 translation[0], translation[1], translation[2], 1
715 /// \brief Returns the translation part of \p self.
716 inline Vector3 matrix4_get_translation_vec3(const Matrix4& self)
718 return vector4_to_vector3(self.t());
721 /// \brief Concatenates \p self with \p translation.
722 /// The concatenated \p translation occurs before \p self.
723 inline void matrix4_translate_by_vec3(Matrix4& self, const Vector3& translation)
725 matrix4_multiply_by_matrix4(self, matrix4_translation_for_vec3(translation));
728 /// \brief Returns \p self Concatenated with \p translation.
729 /// The concatenated translation occurs before \p self.
730 inline Matrix4 matrix4_translated_by_vec3(const Matrix4& self, const Vector3& translation)
732 return matrix4_multiplied_by_matrix4(self, matrix4_translation_for_vec3(translation));
738 /// \brief Returns \p angle modulated by the range [0, 360).
739 /// \p angle must be in the range [-360, 360).
740 inline float angle_modulate_degrees_range(float angle)
742 return static_cast<float>(float_mod_range(angle, 360.0));
745 /// \brief Returns \p euler angles converted from radians to degrees.
746 inline Vector3 euler_radians_to_degrees(const Vector3& euler)
749 static_cast<float>(radians_to_degrees(euler.x())),
750 static_cast<float>(radians_to_degrees(euler.y())),
751 static_cast<float>(radians_to_degrees(euler.z()))
755 /// \brief Returns \p euler angles converted from degrees to radians.
756 inline Vector3 euler_degrees_to_radians(const Vector3& euler)
759 static_cast<float>(degrees_to_radians(euler.x())),
760 static_cast<float>(degrees_to_radians(euler.y())),
761 static_cast<float>(degrees_to_radians(euler.z()))
767 /// \brief Constructs a pure-rotation matrix about the x axis from sin \p s and cosine \p c of an angle.
768 inline Matrix4 matrix4_rotation_for_sincos_x(float s, float c)
778 /// \brief Constructs a pure-rotation matrix about the x axis from an angle in radians.
779 inline Matrix4 matrix4_rotation_for_x(double x)
781 return matrix4_rotation_for_sincos_x(static_cast<float>(sin(x)), static_cast<float>(cos(x)));
784 /// \brief Constructs a pure-rotation matrix about the x axis from an angle in degrees.
785 inline Matrix4 matrix4_rotation_for_x_degrees(float x)
787 return matrix4_rotation_for_x(degrees_to_radians(x));
790 /// \brief Constructs a pure-rotation matrix about the y axis from sin \p s and cosine \p c of an angle.
791 inline Matrix4 matrix4_rotation_for_sincos_y(float s, float c)
801 /// \brief Constructs a pure-rotation matrix about the y axis from an angle in radians.
802 inline Matrix4 matrix4_rotation_for_y(double y)
804 return matrix4_rotation_for_sincos_y(static_cast<float>(sin(y)), static_cast<float>(cos(y)));
807 /// \brief Constructs a pure-rotation matrix about the y axis from an angle in degrees.
808 inline Matrix4 matrix4_rotation_for_y_degrees(float y)
810 return matrix4_rotation_for_y(degrees_to_radians(y));
813 /// \brief Constructs a pure-rotation matrix about the z axis from sin \p s and cosine \p c of an angle.
814 inline Matrix4 matrix4_rotation_for_sincos_z(float s, float c)
824 /// \brief Constructs a pure-rotation matrix about the z axis from an angle in radians.
825 inline Matrix4 matrix4_rotation_for_z(double z)
827 return matrix4_rotation_for_sincos_z(static_cast<float>(sin(z)), static_cast<float>(cos(z)));
830 /// \brief Constructs a pure-rotation matrix about the z axis from an angle in degrees.
831 inline Matrix4 matrix4_rotation_for_z_degrees(float z)
833 return matrix4_rotation_for_z(degrees_to_radians(z));
836 /// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (x, y, z).
838 clockwise rotation around X, Y, Z, facing along axis
839 1 0 0 cy 0 -sy cz sz 0
840 0 cx sx 0 1 0 -sz cz 0
841 0 -sx cx sy 0 cy 0 0 1
843 rows of Z by cols of Y
844 cy*cz -sy*cz+sz -sy*sz+cz
847 .. or something like that..
849 final rotation is Z * Y * X
850 cy*cz -sx*-sy*cz+cx*sz cx*-sy*sz+sx*cz
851 -cy*sz sx*sy*sz+cx*cz -cx*-sy*sz+sx*cz
855 cy.cz + 0.sz + sy.0 cy.-sz + 0 .cz + sy.0 cy.0 + 0 .0 + sy.1 |
856 sx.sy.cz + cx.sz + -sx.cy.0 sx.sy.-sz + cx.cz + -sx.cy.0 sx.sy.0 + cx.0 + -sx.cy.1 |
857 -cx.sy.cz + sx.sz + cx.cy.0 -cx.sy.-sz + sx.cz + cx.cy.0 -cx.sy.0 + 0 .0 + cx.cy.1 |
859 inline Matrix4 matrix4_rotation_for_euler_xyz(const Vector3& euler)
863 double cx = cos(euler[0]);
864 double sx = sin(euler[0]);
865 double cy = cos(euler[1]);
866 double sy = sin(euler[1]);
867 double cz = cos(euler[2]);
868 double sz = sin(euler[2]);
871 static_cast<float>(cy*cz),
872 static_cast<float>(cy*sz),
873 static_cast<float>(-sy),
875 static_cast<float>(sx*sy*cz + cx*-sz),
876 static_cast<float>(sx*sy*sz + cx*cz),
877 static_cast<float>(sx*cy),
879 static_cast<float>(cx*sy*cz + sx*sz),
880 static_cast<float>(cx*sy*sz + -sx*cz),
881 static_cast<float>(cx*cy),
891 return matrix4_premultiply_by_matrix4(
892 matrix4_premultiply_by_matrix4(
893 matrix4_rotation_for_x(euler[0]),
894 matrix4_rotation_for_y(euler[1])
896 matrix4_rotation_for_z(euler[2])
902 /// \brief Constructs a pure-rotation matrix from a set of euler angles (degrees) in the order (x, y, z).
903 inline Matrix4 matrix4_rotation_for_euler_xyz_degrees(const Vector3& euler)
905 return matrix4_rotation_for_euler_xyz(euler_degrees_to_radians(euler));
908 /// \brief Concatenates \p self with the rotation transform produced by \p euler angles (degrees) in the order (x, y, z).
909 /// The concatenated rotation occurs before \p self.
910 inline void matrix4_rotate_by_euler_xyz_degrees(Matrix4& self, const Vector3& euler)
912 matrix4_multiply_by_matrix4(self, matrix4_rotation_for_euler_xyz_degrees(euler));
916 /// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (y, z, x).
917 inline Matrix4 matrix4_rotation_for_euler_yzx(const Vector3& euler)
919 return matrix4_premultiplied_by_matrix4(
920 matrix4_premultiplied_by_matrix4(
921 matrix4_rotation_for_y(euler[1]),
922 matrix4_rotation_for_z(euler[2])
924 matrix4_rotation_for_x(euler[0])
928 /// \brief Constructs a pure-rotation matrix from a set of euler angles (degrees) in the order (y, z, x).
929 inline Matrix4 matrix4_rotation_for_euler_yzx_degrees(const Vector3& euler)
931 return matrix4_rotation_for_euler_yzx(euler_degrees_to_radians(euler));
934 /// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (x, z, y).
935 inline Matrix4 matrix4_rotation_for_euler_xzy(const Vector3& euler)
937 return matrix4_premultiplied_by_matrix4(
938 matrix4_premultiplied_by_matrix4(
939 matrix4_rotation_for_x(euler[0]),
940 matrix4_rotation_for_z(euler[2])
942 matrix4_rotation_for_y(euler[1])
946 /// \brief Constructs a pure-rotation matrix from a set of euler angles (degrees) in the order (x, z, y).
947 inline Matrix4 matrix4_rotation_for_euler_xzy_degrees(const Vector3& euler)
949 return matrix4_rotation_for_euler_xzy(euler_degrees_to_radians(euler));
952 /// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (y, x, z).
954 | cy.cz + sx.sy.-sz + -cx.sy.0 0.cz + cx.-sz + sx.0 sy.cz + -sx.cy.-sz + cx.cy.0 |
955 | cy.sz + sx.sy.cz + -cx.sy.0 0.sz + cx.cz + sx.0 sy.sz + -sx.cy.cz + cx.cy.0 |
956 | cy.0 + sx.sy.0 + -cx.sy.1 0.0 + cx.0 + sx.1 sy.0 + -sx.cy.0 + cx.cy.1 |
958 inline Matrix4 matrix4_rotation_for_euler_yxz(const Vector3& euler)
962 double cx = cos(euler[0]);
963 double sx = sin(euler[0]);
964 double cy = cos(euler[1]);
965 double sy = sin(euler[1]);
966 double cz = cos(euler[2]);
967 double sz = sin(euler[2]);
970 static_cast<float>(cy*cz + sx*sy*-sz),
971 static_cast<float>(cy*sz + sx*sy*cz),
972 static_cast<float>(-cx*sy),
974 static_cast<float>(cx*-sz),
975 static_cast<float>(cx*cz),
976 static_cast<float>(sx),
978 static_cast<float>(sy*cz + -sx*cy*-sz),
979 static_cast<float>(sy*sz + -sx*cy*cz),
980 static_cast<float>(cx*cy),
990 return matrix4_premultiply_by_matrix4(
991 matrix4_premultiply_by_matrix4(
992 matrix4_rotation_for_y(euler[1]),
993 matrix4_rotation_for_x(euler[0])
995 matrix4_rotation_for_z(euler[2])
1001 /// \brief Constructs a pure-rotation matrix from a set of euler angles (degrees) in the order (y, x, z).
1002 inline Matrix4 matrix4_rotation_for_euler_yxz_degrees(const Vector3& euler)
1004 return matrix4_rotation_for_euler_yxz(euler_degrees_to_radians(euler));
1007 /// \brief Returns \p self concatenated with the rotation transform produced by \p euler angles (degrees) in the order (y, x, z).
1008 /// The concatenated rotation occurs before \p self.
1009 inline Matrix4 matrix4_rotated_by_euler_yxz_degrees(const Matrix4& self, const Vector3& euler)
1011 return matrix4_multiplied_by_matrix4(self, matrix4_rotation_for_euler_yxz_degrees(euler));
1014 /// \brief Concatenates \p self with the rotation transform produced by \p euler angles (degrees) in the order (y, x, z).
1015 /// The concatenated rotation occurs before \p self.
1016 inline void matrix4_rotate_by_euler_yxz_degrees(Matrix4& self, const Vector3& euler)
1018 self = matrix4_rotated_by_euler_yxz_degrees(self, euler);
1021 /// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (z, x, y).
1022 inline Matrix4 matrix4_rotation_for_euler_zxy(const Vector3& euler)
1025 return matrix4_premultiplied_by_matrix4(
1026 matrix4_premultiplied_by_matrix4(
1027 matrix4_rotation_for_z(euler[2]),
1028 matrix4_rotation_for_x(euler[0])
1030 matrix4_rotation_for_y(euler[1])
1033 double cx = cos(euler[0]);
1034 double sx = sin(euler[0]);
1035 double cy = cos(euler[1]);
1036 double sy = sin(euler[1]);
1037 double cz = cos(euler[2]);
1038 double sz = sin(euler[2]);
1041 static_cast<float>(cz * cy + sz * sx * sy),
1042 static_cast<float>(sz * cx),
1043 static_cast<float>(cz * -sy + sz * sx * cy),
1045 static_cast<float>(-sz * cy + cz * sx * sy),
1046 static_cast<float>(cz * cx),
1047 static_cast<float>(-sz * -sy + cz * cx * cy),
1049 static_cast<float>(cx* sy),
1050 static_cast<float>(-sx),
1051 static_cast<float>(cx* cy),
1061 /// \brief Constructs a pure-rotation matrix from a set of euler angles (degres=es) in the order (z, x, y).
1062 inline Matrix4 matrix4_rotation_for_euler_zxy_degrees(const Vector3& euler)
1064 return matrix4_rotation_for_euler_zxy(euler_degrees_to_radians(euler));
1067 /// \brief Returns \p self concatenated with the rotation transform produced by \p euler angles (degrees) in the order (z, x, y).
1068 /// The concatenated rotation occurs before \p self.
1069 inline Matrix4 matrix4_rotated_by_euler_zxy_degrees(const Matrix4& self, const Vector3& euler)
1071 return matrix4_multiplied_by_matrix4(self, matrix4_rotation_for_euler_zxy_degrees(euler));
1074 /// \brief Concatenates \p self with the rotation transform produced by \p euler angles (degrees) in the order (z, x, y).
1075 /// The concatenated rotation occurs before \p self.
1076 inline void matrix4_rotate_by_euler_zxy_degrees(Matrix4& self, const Vector3& euler)
1078 self = matrix4_rotated_by_euler_zxy_degrees(self, euler);
1081 /// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (z, y, x).
1082 inline Matrix4 matrix4_rotation_for_euler_zyx(const Vector3& euler)
1086 double cx = cos(euler[0]);
1087 double sx = sin(euler[0]);
1088 double cy = cos(euler[1]);
1089 double sy = sin(euler[1]);
1090 double cz = cos(euler[2]);
1091 double sz = sin(euler[2]);
1094 static_cast<float>(cy*cz),
1095 static_cast<float>(sx*sy*cz + cx*sz),
1096 static_cast<float>(cx*-sy*cz + sx*sz),
1098 static_cast<float>(cy*-sz),
1099 static_cast<float>(sx*sy*-sz + cx*cz),
1100 static_cast<float>(cx*-sy*-sz + sx*cz),
1102 static_cast<float>(sy),
1103 static_cast<float>(-sx*cy),
1104 static_cast<float>(cx*cy),
1114 return matrix4_premultiply_by_matrix4(
1115 matrix4_premultiply_by_matrix4(
1116 matrix4_rotation_for_z(euler[2]),
1117 matrix4_rotation_for_y(euler[1])
1119 matrix4_rotation_for_x(euler[0])
1125 /// \brief Constructs a pure-rotation matrix from a set of euler angles (degrees) in the order (z, y, x).
1126 inline Matrix4 matrix4_rotation_for_euler_zyx_degrees(const Vector3& euler)
1128 return matrix4_rotation_for_euler_zyx(euler_degrees_to_radians(euler));
1132 /// \brief Calculates and returns a set of euler angles that produce the rotation component of \p self when applied in the order (x, y, z).
1133 /// \p self must be affine and orthonormal (unscaled) to produce a meaningful result.
1134 inline Vector3 matrix4_get_rotation_euler_xyz(const Matrix4& self)
1136 double a = asin(-self[2]);
1139 if (fabs(ca) > 0.005) // Gimbal lock?
1142 static_cast<float>(atan2(self[6] / ca, self[10] / ca)),
1143 static_cast<float>(a),
1144 static_cast<float>(atan2(self[1] / ca, self[0]/ ca))
1147 else // Gimbal lock has occurred
1150 static_cast<float>(atan2(-self[9], self[5])),
1151 static_cast<float>(a),
1157 /// \brief \copydoc matrix4_get_rotation_euler_xyz(const Matrix4&)
1158 inline Vector3 matrix4_get_rotation_euler_xyz_degrees(const Matrix4& self)
1160 return euler_radians_to_degrees(matrix4_get_rotation_euler_xyz(self));
1163 /// \brief Calculates and returns a set of euler angles that produce the rotation component of \p self when applied in the order (y, x, z).
1164 /// \p self must be affine and orthonormal (unscaled) to produce a meaningful result.
1165 inline Vector3 matrix4_get_rotation_euler_yxz(const Matrix4& self)
1167 double a = asin(self[6]);
1170 if (fabs(ca) > 0.005) // Gimbal lock?
1173 static_cast<float>(a),
1174 static_cast<float>(atan2(-self[2] / ca, self[10]/ ca)),
1175 static_cast<float>(atan2(-self[4] / ca, self[5] / ca))
1178 else // Gimbal lock has occurred
1181 static_cast<float>(a),
1182 static_cast<float>(atan2(self[8], self[0])),
1188 /// \brief \copydoc matrix4_get_rotation_euler_yxz(const Matrix4&)
1189 inline Vector3 matrix4_get_rotation_euler_yxz_degrees(const Matrix4& self)
1191 return euler_radians_to_degrees(matrix4_get_rotation_euler_yxz(self));
1194 /// \brief Calculates and returns a set of euler angles that produce the rotation component of \p self when applied in the order (z, x, y).
1195 /// \p self must be affine and orthonormal (unscaled) to produce a meaningful result.
1196 inline Vector3 matrix4_get_rotation_euler_zxy(const Matrix4& self)
1198 double a = asin(-self[9]);
1201 if (fabs(ca) > 0.005) // Gimbal lock?
1204 static_cast<float>(a),
1205 static_cast<float>(atan2(self[8] / ca, self[10] / ca)),
1206 static_cast<float>(atan2(self[1] / ca, self[5]/ ca))
1209 else // Gimbal lock has occurred
1212 static_cast<float>(a),
1214 static_cast<float>(atan2(-self[4], self[0]))
1219 /// \brief \copydoc matrix4_get_rotation_euler_zxy(const Matrix4&)
1220 inline Vector3 matrix4_get_rotation_euler_zxy_degrees(const Matrix4& self)
1222 return euler_radians_to_degrees(matrix4_get_rotation_euler_zxy(self));
1225 /// \brief Calculates and returns a set of euler angles that produce the rotation component of \p self when applied in the order (z, y, x).
1226 /// \p self must be affine and orthonormal (unscaled) to produce a meaningful result.
1227 inline Vector3 matrix4_get_rotation_euler_zyx(const Matrix4& self)
1229 double a = asin(self[8]);
1232 if (fabs(ca) > 0.005) // Gimbal lock?
1235 static_cast<float>(atan2(-self[9] / ca, self[10]/ ca)),
1236 static_cast<float>(a),
1237 static_cast<float>(atan2(-self[4] / ca, self[0] / ca))
1240 else // Gimbal lock has occurred
1244 static_cast<float>(a),
1245 static_cast<float>(atan2(self[1], self[5]))
1250 /// \brief \copydoc matrix4_get_rotation_euler_zyx(const Matrix4&)
1251 inline Vector3 matrix4_get_rotation_euler_zyx_degrees(const Matrix4& self)
1253 return euler_radians_to_degrees(matrix4_get_rotation_euler_zyx(self));
1257 /// \brief Rotate \p self by \p euler angles (degrees) applied in the order (x, y, z), using \p pivotpoint.
1258 inline void matrix4_pivoted_rotate_by_euler_xyz_degrees(Matrix4& self, const Vector3& euler, const Vector3& pivotpoint)
1260 matrix4_translate_by_vec3(self, pivotpoint);
1261 matrix4_rotate_by_euler_xyz_degrees(self, euler);
1262 matrix4_translate_by_vec3(self, vector3_negated(pivotpoint));
1266 /// \brief Constructs a pure-scale matrix from \p scale.
1267 inline Matrix4 matrix4_scale_for_vec3(const Vector3& scale)
1277 /// \brief Calculates and returns the (x, y, z) scale values that produce the scale component of \p self.
1278 /// \p self must be affine and orthogonal to produce a meaningful result.
1279 inline Vector3 matrix4_get_scale_vec3(const Matrix4& self)
1282 static_cast<float>(vector3_length(vector4_to_vector3(self.x()))),
1283 static_cast<float>(vector3_length(vector4_to_vector3(self.y()))),
1284 static_cast<float>(vector3_length(vector4_to_vector3(self.z())))
1288 /// \brief Scales \p self by \p scale.
1289 inline void matrix4_scale_by_vec3(Matrix4& self, const Vector3& scale)
1291 matrix4_multiply_by_matrix4(self, matrix4_scale_for_vec3(scale));
1294 /// \brief Scales \p self by \p scale, using \p pivotpoint.
1295 inline void matrix4_pivoted_scale_by_vec3(Matrix4& self, const Vector3& scale, const Vector3& pivotpoint)
1297 matrix4_translate_by_vec3(self, pivotpoint);
1298 matrix4_scale_by_vec3(self, scale);
1299 matrix4_translate_by_vec3(self, vector3_negated(pivotpoint));
1303 /// \brief Transforms \p self by \p translation, \p euler and \p scale.
1304 /// The transforms are combined in the order: scale, rotate-z, rotate-y, rotate-x, translate.
1305 inline void matrix4_transform_by_euler_xyz_degrees(Matrix4& self, const Vector3& translation, const Vector3& euler, const Vector3& scale)
1307 matrix4_translate_by_vec3(self, translation);
1308 matrix4_rotate_by_euler_xyz_degrees(self, euler);
1309 matrix4_scale_by_vec3(self, scale);
1312 /// \brief Transforms \p self by \p translation, \p euler and \p scale, using \p pivotpoint.
1313 inline void matrix4_pivoted_transform_by_euler_xyz_degrees(Matrix4& self, const Vector3& translation, const Vector3& euler, const Vector3& scale, const Vector3& pivotpoint)
1315 matrix4_translate_by_vec3(self, pivotpoint + translation);
1316 matrix4_rotate_by_euler_xyz_degrees(self, euler);
1317 matrix4_scale_by_vec3(self, scale);
1318 matrix4_translate_by_vec3(self, vector3_negated(pivotpoint));