30 #include <cugar/linalg/vector.h> 42 #define _V(v, i) (((Vector<T,M>&)v).x[(i)]) 47 #define _M(m, i, j) (((Matrix<T,N,M>&)m).r[(i)].x[(j)]) 52 #define _CM(m, i, j) (((const Matrix<T,N,M>&)m).r[(i)].x[(j)]) 59 template <
typename T,
int N,
int M> Matrix<T,N,M>::Matrix() { }
61 template <
typename T,
int N,
int M> Matrix<T,N,M>::Matrix(
const T s)
63 for (
int i = 0; i < N; i++)
64 r[i] = Vector<T,M>(s);
67 template <
typename T,
int N,
int M> Matrix<T,N,M>::Matrix(
const Matrix<T,N,M>& m)
69 for (
int i = 0; i < N; i++)
73 template <
typename T,
int N,
int M> Matrix<T,N,M>::Matrix(
const Vector<T,M>& v)
75 for (
int i = 0; i < N; i++)
76 for (
int j = 0; j < M; j++)
82 for (
int i = 0; i < M; i++)
87 template <
typename T,
int N,
int M> Matrix<T,N,M>::Matrix(
const Vector<T,M> *v)
89 for (
int i = 0; i < N; i++)
93 template <
typename T,
int N,
int M> Matrix<T,N,M>::Matrix(
const T *v)
95 for (
int i = 0; i < N; i++)
96 for (
int j = 0; j < M; j++)
100 template <
typename T,
int N,
int M> Matrix<T,N,M>::Matrix(
const T **v)
102 for (
int i = 0; i < N; i++)
103 for (
int j = 0; j < M; j++)
114 template <
typename T,
int N,
int M> Matrix<T,N,M>& Matrix<T,N,M>::operator = (
const Matrix<T,N,M>& m)
116 for (
int i = 0; i < N; i++)
121 template <
typename T,
int N,
int M> Matrix<T,N,M>& Matrix<T,N,M>::operator += (
const Matrix<T,N,M>& m)
123 for (
int i = 0; i < N; i++)
128 template <
typename T,
int N,
int M> Matrix<T,N,M>& Matrix<T,N,M>::operator -= (
const Matrix<T,N,M>& m)
130 for (
int i = 0; i < N; i++)
135 template <
typename T,
int N,
int M> Matrix<T,N,M>& Matrix<T,N,M>::operator *= (T k)
137 for (
int i = 0; i < N; i++)
142 template <
typename T,
int N,
int M> Matrix<T,N,M>& Matrix<T,N,M>::operator /= (T k)
144 for (
int i = 0; i < N; i++)
149 template <
typename T,
int N,
int M>
const Vector<T,M>& Matrix<T,N,M>::operator [] (
int i)
const 153 template <
typename T,
int N,
int M> Vector<T,M>& Matrix<T,N,M>::operator [] (
int i)
158 template <
typename T,
int N,
int M>
const Vector<T,M>& Matrix<T,N,M>::get(
int i)
const 162 template <
typename T,
int N,
int M>
void Matrix<T,N,M>::set(
int i,
const Vector<T,M>& v)
167 template <
typename T,
int N,
int M>
const T& Matrix<T,N,M>::operator () (
int i,
int j)
const 171 template <
typename T,
int N,
int M> T& Matrix<T,N,M>::operator () (
int i,
int j)
176 template <
typename T,
int N,
int M> T Matrix<T,N,M>::det()
const 181 template <
typename T,
int N,
int M>
182 Matrix<T, N, M> Matrix<T,N,M>::one()
186 for (
int i = 0; i < N; i++)
187 for (
int j = 0; j < M; j++)
188 r[i][j] = (i == j) ? 1.0f : 0.0f;
194 template <
typename T,
int N,
int M,
int Q> CUGAR_HOST_DEVICE Matrix<T,N,Q>& multiply(
const Matrix<T,N,M>& a,
const Matrix<T,M,Q>& b, Matrix<T,N,Q>& r)
196 for (
int i = 0; i < N; i++)
198 for (
int j = 0; j < Q; j++)
201 for (
int k = 0; k < M; k++)
202 r[i][j] += a[i][k]*b[k][j];
209 template <
typename T,
int N,
int M> CUGAR_HOST_DEVICE Vector<T,M>& multiply(
const Vector<T,N>& v,
const Matrix<T,N,M>& m, Vector<T,M>& r)
211 for (
int i = 0; i < M; i++)
214 for (
int j = 0; j < N; j++)
220 template <
typename T,
int N,
int M> CUGAR_HOST_DEVICE Vector<T,N>& multiply(
const Matrix<T,N,M>& m,
const Vector<T,M>& v, Vector<T,N>& r)
222 for (
int i = 0; i < N; i++)
225 for (
int j = 0; j < M; j++)
231 template <
typename T,
int N,
int M> CUGAR_HOST_DEVICE Matrix<T,M,N> transpose(
const Matrix<T,N,M>& m)
235 return transpose(m, r);
238 template <
typename T,
int N,
int M> CUGAR_HOST_DEVICE Matrix<T,M,N>& transpose(
const Matrix<T,N,M>& m, Matrix<T,M,N>& r)
240 for (
int i = 0; i < N; i++)
241 for (
int j = 0; j < M; j++)
247 template <
typename T,
int N,
int M>
bool invert(
const Matrix<T,N,M>& a, Matrix<T,M,N>& r)
250 if (d < 1.0e-10f)
return false;
255 template <
typename T>
257 bool invert(
const Matrix<T,2,2>& a, Matrix<T,2,2>& r)
259 const T det = cugar::det(a);
260 if (fabsf(det) < 1.0e-10f)
return false;
262 const T invdet = T(1.0) / det;
264 r(0,0) = a(1,1) * invdet;
265 r(0,1) = -a(0,1) * invdet;
266 r(1,0) = -a(1,0) * invdet;
267 r(1,1) = a(0,0) * invdet;
271 template <
typename T>
273 bool invert(
const Matrix<T,3,3>& a, Matrix<T,3,3>& r)
275 const T det = cugar::det(a);
276 if (fabsf(det) < 1.0e-10f)
return false;
278 const T invdet = T(1.0) / det;
280 r(0,0) = (a(1,1) * a(2,2) - a(2,1) * a(1,2)) * invdet;
281 r(0,1) = (a(0,2) * a(2,1) - a(0,1) * a(2,2)) * invdet;
282 r(0,2) = (a(0,1) * a(1,2) - a(0,2) * a(1,1)) * invdet;
283 r(1,0) = (a(1,2) * a(2,0) - a(1,0) * a(2,2)) * invdet;
284 r(1,1) = (a(0,0) * a(2,2) - a(0,2) * a(2,0)) * invdet;
285 r(1,2) = (a(1,0) * a(0,2) - a(0,0) * a(1,2)) * invdet;
286 r(2,0) = (a(1,0) * a(2,1) - a(2,0) * a(1,1)) * invdet;
287 r(2,1) = (a(2,0) * a(0,1) - a(0,0) * a(2,1)) * invdet;
288 r(2,2) = (a(0,0) * a(1,1) - a(1,0) * a(0,1)) * invdet;
292 template <
typename T>
294 bool invert(
const Matrix<T,4,4>& a, Matrix<T,4,4>& r)
296 T t1, t2, t3, t4, t5, t6;
304 t1 = a(2,2)*a(3,3) - a(2,3)*a(3,2);
305 t2 = a(2,1)*a(3,3) - a(2,3)*a(3,1);
306 t3 = a(2,1)*a(3,2) - a(2,2)*a(3,1);
307 t4 = a(2,0)*a(3,3) - a(2,3)*a(3,0);
308 t5 = a(2,0)*a(3,2) - a(2,2)*a(3,0);
309 t6 = a(2,0)*a(3,1) - a(2,1)*a(3,0);
311 r[0][0] = a(1,1) * t1 - a(1,2) * t2 + a(1,3) * t3;
312 r[0][1] = -(a(0,1) * t1 - a(0,2) * t2 + a(0,3) * t3);
313 r[1][0] = -(a(1,0) * t1 - a(1,2) * t4 + a(1,3) * t5);
314 r[1][1] = a(0,0) * t1 - a(0,2) * t4 + a(0,3) * t5;
315 r[2][0] = a(1,0) * t2 - a(1,1) * t4 + a(1,3) * t6;
316 r[2][1] = -(a(0,0) * t2 - a(0,1) * t4 + a(0,3) * t6);
317 r[3][0] = -(a(1,0) * t3 - a(1,1) * t5 + a(1,2) * t6);
318 r[3][1] = a(0,0) * t3 - a(0,1) * t5 + a(0,2) * t6;
322 t1 = a(1,2)*a(3,3) - a(1,3)*a(3,2);
323 t2 = a(1,1)*a(3,3) - a(1,3)*a(3,1);
324 t3 = a(1,1)*a(3,2) - a(1,2)*a(3,1);
325 t4 = a(1,0)*a(3,3) - a(1,3)*a(3,0);
326 t5 = a(1,0)*a(3,2) - a(1,2)*a(3,0);
327 t6 = a(1,0)*a(3,1) - a(1,1)*a(3,0);
329 r[0][2] = a(0,1) * t1 - a(0,2) * t2 + a(0,3) * t3;
330 r[1][2] = -(a(0,0) * t1 - a(0,2) * t4 + a(0,3) * t5);
331 r[2][2] = a(0,0) * t2 - a(0,1) * t4 + a(0,3) * t6;
332 r[3][2] = -(a(0,0) * t3 - a(0,1) * t5 + a(0,2) * t6);
336 t1 = a(1,2)*a(2,3) - a(1,3)*a(2,2);
337 t2 = a(1,1)*a(2,3) - a(1,3)*a(2,1);
338 t3 = a(1,1)*a(2,2) - a(1,2)*a(2,1);
339 t4 = a(1,0)*a(2,3) - a(1,3)*a(2,0);
340 t5 = a(1,0)*a(2,2) - a(1,2)*a(2,0);
341 t6 = a(1,0)*a(2,1) - a(1,1)*a(2,0);
343 r[0][3] = -(a(0,1) * t1 - a(0,2) * t2 + a(0,3) * t3);
344 r[1][3] = a(0,0) * t1 - a(0,2) * t4 + a(0,3) * t5;
345 r[2][3] = -(a(0,0) * t2 - a(0,1) * t4 + a(0,3) * t6);
346 r[3][3] = a(0,0) * t3 - a(0,1) * t5 + a(0,2) * t6;
350 T d = a(0,0)*r[0][0] + a(0,1)*r[1][0] + a(0,2)*r[2][0] + a(0,3)*r[3][0];
352 if (d == T(0.0))
return false;
360 template <
typename T,
int N,
int M>
362 T det(
const Matrix<T,N,M>& m)
367 template <
typename T>
369 T det(
const Matrix<T,2,2>& m)
371 return m(0,0) * m(1,1) - m(0,1) * m(1,0);
374 template <
typename T>
376 T det(
const Matrix<T,3,3>& m)
379 return m(0,0) * (m(1,1)*m(2,2) - m(1,2)*m(2,1))
380 - m(0,1) * (m(1,0)*m(2,2) - m(1,2)*m(2,0))
381 + m(0,2) * (m(1,0)*m(2,1) - m(1,1)*m(2,0));
384 template <
typename T>
386 void cholesky(
const Matrix<T,2,2>& m, Matrix<T,2,2>& r)
388 const T a = sqrt(m(0,0));
389 const T b = m(0, 1) / a;
390 const T c = sqrt(m(1,1) - b*b);
401 template <
typename T,
int N,
int M> CUGAR_API_CS CUGAR_HOST_DEVICE
int operator == (
const Matrix<T,N,M>& a,
const Matrix<T,N,M>& b)
403 for (
int i = 0; i < N; i++)
411 template <
typename T,
int N,
int M> CUGAR_API_CS CUGAR_HOST_DEVICE
int operator != (
const Matrix<T,N,M>& a,
const Matrix<T,N,M>& b)
416 template <
typename T,
int N,
int M> CUGAR_API_CS Matrix<T,N,M> CUGAR_HOST_DEVICE operator - (
const Matrix<T,N,M>& a)
418 return (Matrix<T,N,M>(a) *= -1.0);
421 template <
typename T,
int N,
int M> CUGAR_API_CS Matrix<T,N,M> CUGAR_HOST_DEVICE operator + (
const Matrix<T,N,M>& a,
const Matrix<T,N,M>& b)
424 for (
int i = 0; i < N; i++)
425 for (
int j = 0; j < N; j++)
426 r(i,j) = a(i,j) + b(i,j);
431 template <
typename T,
int N,
int M> CUGAR_API_CS Matrix<T,N,M> CUGAR_HOST_DEVICE operator - (
const Matrix<T,N,M>& a,
const Matrix<T,N,M>& b)
434 for (
int i = 0; i < N; i++)
435 for (
int j = 0; j < N; j++)
436 r(i,j) = a(i,j) - b(i,j);
441 template <
typename T,
int N,
int M,
int Q> CUGAR_API_CS CUGAR_HOST_DEVICE Matrix<T,N,Q> operator * (
const Matrix<T,N,M>& a,
const Matrix<T,M,Q>& b)
445 return multiply(a, b, r);
448 template <
typename T,
int N,
int M> CUGAR_API_CS CUGAR_HOST_DEVICE Matrix<T,N,M> operator * (
const Matrix<T,N,M>& a, T k)
451 for (
int i = 0; i < N; i++)
452 for (
int j = 0; j < N; j++)
458 template <
typename T,
int N,
int M> CUGAR_API_CS CUGAR_HOST_DEVICE Matrix<T,N,M> operator * (T k,
const Matrix<T,N,M>& a)
461 for (
int i = 0; i < N; i++)
462 for (
int j = 0; j < N; j++)
468 template <
typename T,
int N,
int M> CUGAR_API_CS CUGAR_HOST_DEVICE Vector<T,M> operator * (
const Vector<T,N>& v,
const Matrix<T,N,M>& m)
472 return multiply(v, m, r);
474 template <
typename T,
int N,
int M> CUGAR_API_CS CUGAR_HOST_DEVICE Vector<T,N> operator * (
const Matrix<T,N,M>& m,
const Vector<T,M>& v)
478 return multiply(m, v, r);
481 template <
typename T,
int N,
int M> CUGAR_API_CS CUGAR_HOST_DEVICE Matrix<T,N,M> operator / (
const Matrix<T,N,M>& a, T k)
484 for (
int i = 0; i < N; i++)
485 for (
int j = 0; j < N; j++)
491 template <
typename T,
int N> CUGAR_API_CS CUGAR_HOST_DEVICE Matrix<T,N,N> operator + (
const Matrix<T,N,N>& a,
const Vector<T,N>& b)
493 return a + Matrix<T,N,N>(b);
496 template <
typename T,
int N> CUGAR_API_CS CUGAR_HOST_DEVICE Matrix<T,N,N> operator + (
const Vector<T,N>& a,
const Matrix<T,N,N>& b)
498 return Matrix<T,N,N>(a) + b;
501 template <
typename T, u
int32 N, u
int32 M>
502 CUGAR_API_CS CUGAR_HOST_DEVICE
506 for (uint32 i = 0; i < N; ++i)
507 for (uint32 j = 0; j < M; ++j)
508 r(i,j) = op1[i]*op2[j];
512 CUGAR_API_CS CUGAR_HOST_DEVICE
516 r(0,0) = op1.x * op2.x;
517 r(0,1) = op1.x * op2.y;
518 r(1,0) = op1.y * op2.x;
519 r(1,1) = op1.y * op2.y;
523 template <
typename T>
528 m(0,0) = m(1,1) = m(2,2) = m(3,3) = 1.0f;
538 template <
typename T>
551 template <
typename T>
556 T f = T(1) / std::tan(fovy / T(2));
560 m(2,2) = (zFar + zNear) / (zNear - zFar);
561 m(2,3) = T(2) * zFar * zNear / (zNear - zFar);
567 template <
typename T>
581 m(2,0) = (flip_sign ? -1.0f : 1.0f) * f.x;
582 m(2,1) = (flip_sign ? -1.0f : 1.0f) * f.y;
583 m(2,2) = (flip_sign ? -1.0f : 1.0f) * f.z;
591 template <
typename T>
605 m(0,2) = (flip_sign ? -1.0f : 1.0f) * f.x;
606 m(1,2) = (flip_sign ? -1.0f : 1.0f) * f.y;
607 m(2,2) = (flip_sign ? -1.0f : 1.0f) * f.z;
615 template <
typename T>
620 const float sin_q = sin(q);
621 m[1][1] = m[2][2] = cos(q);
624 m[0][0] = m[3][3] = T(1.0f);
637 template <
typename T>
642 const float sin_q = sin(q);
643 m[0][0] = m[2][2] = cos(q);
646 m[1][1] = m[3][3] = T(1.0f);
659 template <
typename T>
664 const float sin_q = sin(q);
665 m[0][0] = m[1][1] = cos(q);
668 m[2][2] = m[3][3] = T(1.0f);
682 template <
typename T>
685 const Vector3f tangent = orthogonal( axis );
686 const Vector3f binormal = cross( axis, tangent );
689 basis_change[0] =
Vector4f( tangent, 0.0f );
690 basis_change[1] =
Vector4f( binormal, 0.0f );
691 basis_change[2] =
Vector4f( axis, 0.0f );
692 basis_change[3] =
Vector4f( 0.0f, 0.0f, 0.0f, 1.0f );
694 Matrix4x4f inv_basis_change = transpose( basis_change );
699 return basis_change * rot * inv_basis_change;
704 return Vector3f( r[0], r[1], r[2] );
709 return Vector3f( r[0], r[1], r[2] );
716 const float T = m(0,0) + m(1,1);
717 const float D = m(0,0) * m(1,1) - m(1,0) * m(0,1);
718 const float S = sqrtf(T*T*0.25f - D);
719 const float l1 = T*0.5f + S;
720 const float l2 = T*0.5f - S;
728 const float a = m(0,0);
729 const float b = m(0,1);
730 const float c = m(1,0);
731 const float d = m(1,1);
734 const float S1 = a*a + b*b + c*c + d*d;
735 const float S2 = sqrtf(
sqr(a*a + b*b - c*c - d*d) + 4*
sqr(a*c + b*d) );
737 sqrtf((S1 + S2)*0.5f),
738 sqrtf((S1 - S2)*0.5f));
740 const float s00 = sqrtf(
sqr(a - d) +
sqr(b + c) );
741 const float s01 = sqrtf(
sqr(a + d) +
sqr(b - c) );
743 const float s0 = (s00 + s01) / 2;
744 const float s1 = fabsf(s0 - s00);
752 CUGAR_HOST_DEVICE
inline void svd(
758 const float a = m(0,0);
759 const float b = m(0,1);
760 const float c = m(1,0);
761 const float d = m(1,1);
765 v(1,0) = (s[0] > s[1]) ? sinf((atan2f(2 * (a*b + c*d), a*a - b*b + c*c - d*d)) / 2) : 0;
766 v(0,0) = sqrtf(1 - v(1,0) * v(1,0));
770 u(0,0) = (s[0] != 0) ? (a * v(0,0) + b * v(1,0)) / s[0] : 1;
771 u(1,1) = (s[0] != 0) ? (c * v(0,0) + d * v(1,0)) / s[0] : 0;
772 u(0,1) = (s[1] != 0) ? (a * v(0,1) + b * v(1,1)) / s[1] : -u(1,1);
773 u(1,1) = (s[1] != 0) ? (c * v(0,1) + d * v(1,1)) / s[1] : u(0,0);
CUGAR_HOST_DEVICE Vector2f eigen_values(const Matrix2x2f &m)
Definition: matrix_inline.h:714
CUGAR_HOST_DEVICE Matrix< T, 4, 4 > rotation_around_axis(const T q, const Vector3f &axis)
Definition: matrix_inline.h:683
CUGAR_HOST_DEVICE Matrix< T, 4, 4 > translate(const Vector< T, 3 > &vec)
Definition: matrix_inline.h:524
CUGAR_HOST_DEVICE Vector2f singular_values(const Matrix2x2f &m)
Definition: matrix_inline.h:726
CUGAR_HOST_DEVICE Vector3f vtrans(const Matrix4x4f &m, const Vector3f &v)
Definition: matrix_inline.h:706
Matrix< T, 4, 4 > perspective(T fovy, T aspect, T zNear, T zFar)
Definition: matrix_inline.h:552
CUGAR_HOST_DEVICE Matrix< T, 4, 4 > rotation_around_Y(const T q)
Definition: matrix_inline.h:638
CUGAR_HOST_DEVICE Vector3f ptrans(const Matrix4x4f &m, const Vector3f &v)
Definition: matrix_inline.h:701
CUGAR_HOST_DEVICE Matrix< T, 4, 4 > rotation_around_Z(const T q)
Definition: matrix_inline.h:660
CUGAR_HOST_DEVICE void svd(const Matrix2x2f &m, Matrix2x2f &u, Vector2f &s, Matrix2x2f &v)
Definition: matrix_inline.h:752
float CUGAR_HOST_DEVICE sqr(const float x)
Definition: numbers.h:610
Matrix< T, 4, 4 > look_at(const Vector< T, 3 > &eye, const Vector< T, 3 > ¢er, const Vector< T, 3 > &up, bool flip_sign=false)
Definition: matrix_inline.h:568
Define a vector_view POD type and plain_view() for std::vector.
Definition: diff.h:38
CUGAR_API_CS CUGAR_HOST_DEVICE Matrix< T, N, M > outer_product(const Vector< T, N > op1, const Vector< T, M > op2)
Definition: matrix_inline.h:503
CUGAR_HOST_DEVICE Matrix< T, 4, 4 > rotation_around_X(const T q)
Definition: matrix_inline.h:616
Matrix< T, 4, 4 > inverse_look_at(const Vector< T, 3 > &eye, const Vector< T, 3 > ¢er, const Vector< T, 3 > &up, bool flip_sign=false)
Definition: matrix_inline.h:592
CUGAR_HOST_DEVICE Matrix< T, 4, 4 > scale(const Vector< T, 3 > &vec)
build a 3d scaling matrix
Definition: matrix_inline.h:539