OptiX  3.9
NVIDIA OptiX Acceleration Engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
optixu_matrix_namespace.h
Go to the documentation of this file.
1 
2 /*
3  * Copyright (c) 2008 - 2010 NVIDIA Corporation. All rights reserved.
4  *
5  * NVIDIA Corporation and its licensors retain all intellectual property and proprietary
6  * rights in and to this software, related documentation and any modifications thereto.
7  * Any use, reproduction, disclosure or distribution of this software and related
8  * documentation without an express license agreement from NVIDIA Corporation is strictly
9  * prohibited.
10  *
11  * TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS*
12  * AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
13  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14  * PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
15  * SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT
16  * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF
17  * BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
18  * INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF
19  * SUCH DAMAGES
20  */
21 
30 #ifndef __optixu_optixu_matrix_namespace_h__
31 #define __optixu_optixu_matrix_namespace_h__
32 
33 #include "optixu_math_namespace.h"
34 #include <assert.h>
35 
36 // __forceinline__ works in CUDA, VS, and with gcc. Leave it as a macro in case
37 // we need to make this per-platform or we want to switch off inlining globally.
38 #ifndef OPTIXU_INLINE
39 # define OPTIXU_INLINE_DEFINED 1
40 # define OPTIXU_INLINE __forceinline__
41 #endif // OPTIXU_INLINE
42 
43 #define RT_MATRIX_ACCESS(m,i,j) m[i*N+j]
44 #define RT_MAT_DECL template <unsigned int M, unsigned int N>
45 
46 namespace optix {
47 
48  template <int DIM> struct VectorDim { };
49  template <> struct VectorDim<2> { typedef float2 VectorType; };
50  template <> struct VectorDim<3> { typedef float3 VectorType; };
51  template <> struct VectorDim<4> { typedef float4 VectorType; };
52 
53 
54  template <unsigned int M, unsigned int N> class Matrix;
55 
56  template <unsigned int M> OPTIXU_INLINE RT_HOSTDEVICE Matrix<M,M>& operator*=(Matrix<M,M>& m1, const Matrix<M,M>& m2);
57  RT_MAT_DECL OPTIXU_INLINE RT_HOSTDEVICE Matrix<M,N>& operator-=(Matrix<M,N>& m1, const Matrix<M,N>& m2);
58  RT_MAT_DECL OPTIXU_INLINE RT_HOSTDEVICE Matrix<M,N>& operator+=(Matrix<M,N>& m1, const Matrix<M,N>& m2);
59  RT_MAT_DECL OPTIXU_INLINE RT_HOSTDEVICE Matrix<M,N>& operator*=(Matrix<M,N>& m1, float f);
60  RT_MAT_DECL OPTIXU_INLINE RT_HOSTDEVICE Matrix<M,N>&operator/=(Matrix<M,N>& m1, float f);
61  RT_MAT_DECL OPTIXU_INLINE RT_HOSTDEVICE Matrix<M,N> operator-(const Matrix<M,N>& m1, const Matrix<M,N>& m2);
62  RT_MAT_DECL OPTIXU_INLINE RT_HOSTDEVICE Matrix<M,N> operator+(const Matrix<M,N>& m1, const Matrix<M,N>& m2);
63  RT_MAT_DECL OPTIXU_INLINE RT_HOSTDEVICE Matrix<M,N> operator/(const Matrix<M,N>& m, float f);
64  RT_MAT_DECL OPTIXU_INLINE RT_HOSTDEVICE Matrix<M,N> operator*(const Matrix<M,N>& m, float f);
65  RT_MAT_DECL OPTIXU_INLINE RT_HOSTDEVICE Matrix<M,N> operator*(float f, const Matrix<M,N>& m);
66  RT_MAT_DECL OPTIXU_INLINE RT_HOSTDEVICE typename Matrix<M,N>::floatM operator*(const Matrix<M,N>& m, const typename Matrix<M,N>::floatN& v );
67  RT_MAT_DECL OPTIXU_INLINE RT_HOSTDEVICE typename Matrix<M,N>::floatN operator*(const typename Matrix<M,N>::floatM& v, const Matrix<M,N>& m);
68  template<unsigned int M, unsigned int N, unsigned int R> OPTIXU_INLINE RT_HOSTDEVICE Matrix<M,R> operator*(const Matrix<M,N>& m1, const Matrix<N,R>& m2);
69 
70 
71  // Partial specializations to make matrix vector multiplication more efficient
72  template <unsigned int N>
73  OPTIXU_INLINE RT_HOSTDEVICE float2 operator*(const Matrix<2,N>& m, const typename Matrix<2,N>::floatN& vec );
74  template <unsigned int N>
75  OPTIXU_INLINE RT_HOSTDEVICE float3 operator*(const Matrix<3,N>& m, const typename Matrix<3,N>::floatN& vec );
76  template <unsigned int N>
77  OPTIXU_INLINE RT_HOSTDEVICE float4 operator*(const Matrix<4,N>& m, const typename Matrix<4,N>::floatN& vec );
78  OPTIXU_INLINE RT_HOSTDEVICE float4 operator*(const Matrix<4,4>& m, const float4& vec );
79 
100  template <unsigned int M, unsigned int N>
101  class Matrix
102  {
103  public:
104  typedef typename VectorDim<N>::VectorType floatN;
105  typedef typename VectorDim<M>::VectorType floatM;
106 
108  RT_HOSTDEVICE Matrix();
109 
111  RT_HOSTDEVICE explicit Matrix( const float data[M*N] ) { for(unsigned int i = 0; i < M*N; ++i) m_data[i] = data[i]; }
112 
114  RT_HOSTDEVICE Matrix( const Matrix& m );
115 
117  RT_HOSTDEVICE Matrix& operator=( const Matrix& b );
118 
120  RT_HOSTDEVICE float operator[]( unsigned int i )const { return m_data[i]; }
121 
123  RT_HOSTDEVICE float& operator[]( unsigned int i ) { return m_data[i]; }
124 
126  RT_HOSTDEVICE floatN getRow( unsigned int m )const;
127 
129  RT_HOSTDEVICE floatM getCol( unsigned int n )const;
130 
132  RT_HOSTDEVICE float* getData();
133 
135  RT_HOSTDEVICE const float* getData()const;
136 
138  RT_HOSTDEVICE void setRow( unsigned int m, const floatN &r );
139 
141  RT_HOSTDEVICE void setCol( unsigned int n, const floatM &c );
142 
144  RT_HOSTDEVICE Matrix<N,M> transpose() const;
145 
147  RT_HOSTDEVICE Matrix<4,4> inverse() const;
148 
150  RT_HOSTDEVICE float det() const;
151 
153  RT_HOSTDEVICE static Matrix<4,4> rotate(const float radians, const float3& axis);
154 
156  RT_HOSTDEVICE static Matrix<4,4> translate(const float3& vec);
157 
159  RT_HOSTDEVICE static Matrix<4,4> scale(const float3& vec);
160 
162  RT_HOSTDEVICE static Matrix<N,N> identity();
163 
165  RT_HOSTDEVICE bool operator<( const Matrix<M, N>& rhs ) const;
166  private:
168  float m_data[M*N];
169  };
170 
171 
172 
173  template<unsigned int M, unsigned int N>
174  OPTIXU_INLINE RT_HOSTDEVICE Matrix<M,N>::Matrix()
175  {
176  }
177 
178  template<unsigned int M, unsigned int N>
179  OPTIXU_INLINE RT_HOSTDEVICE Matrix<M,N>::Matrix( const Matrix<M,N>& m )
180  {
181  for(unsigned int i = 0; i < M*N; ++i)
182  m_data[i] = m[i];
183  }
184 
185  template<unsigned int M, unsigned int N>
186  OPTIXU_INLINE RT_HOSTDEVICE Matrix<M,N>& Matrix<M,N>::operator=( const Matrix& b )
187  {
188  for(unsigned int i = 0; i < M*N; ++i)
189  m_data[i] = b[i];
190  return *this;
191  }
192 
193 
194  /*
195  template<unsigned int M, unsigned int N>
196  OPTIXU_INLINE RT_HOSTDEVICE float Matrix<M,N>::operator[]( unsigned int i )const
197  {
198  assert( i < M*N );
199  return m_data[i];
200  }
201 
202 
203  template<unsigned int M, unsigned int N>
204  OPTIXU_INLINE RT_HOSTDEVICE float& Matrix<M,N>::operator[]( unsigned int i )
205  {
206  return m_data[i];
207  }
208  */
209 
210  template<unsigned int M, unsigned int N>
211  OPTIXU_INLINE RT_HOSTDEVICE typename Matrix<M,N>::floatN Matrix<M,N>::getRow( unsigned int m )const
212  {
213  typename Matrix<M,N>::floatN temp;
214  float* v = reinterpret_cast<float*>( &temp );
215  const float* row = &( m_data[m*N] );
216  for(unsigned int i = 0; i < N; ++i)
217  v[i] = row[i];
218 
219  return temp;
220  }
221 
222 
223  template<unsigned int M, unsigned int N>
224  OPTIXU_INLINE RT_HOSTDEVICE typename Matrix<M,N>::floatM Matrix<M,N>::getCol( unsigned int n )const
225  {
226  typename Matrix<M,N>::floatM temp;
227  float* v = reinterpret_cast<float*>( &temp );
228  for ( unsigned int i = 0; i < M; ++i )
229  v[i] = RT_MATRIX_ACCESS( m_data, i, n );
230 
231  return temp;
232  }
233 
234 
235  template<unsigned int M, unsigned int N>
236  OPTIXU_INLINE RT_HOSTDEVICE float* Matrix<M,N>::getData()
237  {
238  return m_data;
239  }
240 
241 
242  template<unsigned int M, unsigned int N>
243  OPTIXU_INLINE RT_HOSTDEVICE const float* Matrix<M,N>::getData() const
244  {
245  return m_data;
246  }
247 
248 
249  template<unsigned int M, unsigned int N>
250  OPTIXU_INLINE RT_HOSTDEVICE void Matrix<M,N>::setRow( unsigned int m, const typename Matrix<M,N>::floatN &r )
251  {
252  const float* v = reinterpret_cast<const float*>( &r );
253  float* row = &( m_data[m*N] );
254  for(unsigned int i = 0; i < N; ++i)
255  row[i] = v[i];
256  }
257 
258 
259  template<unsigned int M, unsigned int N>
260  OPTIXU_INLINE RT_HOSTDEVICE void Matrix<M,N>::setCol( unsigned int n, const typename Matrix<M,N>::floatM &c )
261  {
262  const float* v = reinterpret_cast<const float*>( &c );
263  for ( unsigned int i = 0; i < M; ++i )
264  RT_MATRIX_ACCESS( m_data, i, n ) = v[i];
265  }
266 
267 
268  // Subtract two matrices of the same size.
269  template<unsigned int M, unsigned int N>
270  RT_HOSTDEVICE Matrix<M,N> operator-(const Matrix<M,N>& m1, const Matrix<M,N>& m2)
271  {
272  Matrix<M,N> temp( m1 );
273  temp -= m2;
274  return temp;
275  }
276 
277 
278  // Subtract two matrices of the same size.
279  template<unsigned int M, unsigned int N>
280  RT_HOSTDEVICE Matrix<M,N>& operator-=(Matrix<M,N>& m1, const Matrix<M,N>& m2)
281  {
282  for ( unsigned int i = 0; i < M*N; ++i )
283  m1[i] -= m2[i];
284  return m1;
285  }
286 
287 
288  // Add two matrices of the same size.
289  template<unsigned int M, unsigned int N>
290  RT_HOSTDEVICE Matrix<M,N> operator+(const Matrix<M,N>& m1, const Matrix<M,N>& m2)
291  {
292  Matrix<M,N> temp( m1 );
293  temp += m2;
294  return temp;
295  }
296 
297 
298  // Add two matrices of the same size.
299  template<unsigned int M, unsigned int N>
300  RT_HOSTDEVICE Matrix<M,N>& operator+=(Matrix<M,N>& m1, const Matrix<M,N>& m2)
301  {
302  for ( unsigned int i = 0; i < M*N; ++i )
303  m1[i] += m2[i];
304  return m1;
305  }
306 
307 
308  // Multiply two compatible matrices.
309  template<unsigned int M, unsigned int N, unsigned int R>
310  RT_HOSTDEVICE Matrix<M,R> operator*( const Matrix<M,N>& m1, const Matrix<N,R>& m2)
311  {
312  Matrix<M,R> temp;
313 
314  for ( unsigned int i = 0; i < M; ++i ) {
315  for ( unsigned int j = 0; j < R; ++j ) {
316  float sum = 0.0f;
317  for ( unsigned int k = 0; k < N; ++k ) {
318  float ik = m1[ i*N+k ];
319  float kj = m2[ k*R+j ];
320  sum += ik * kj;
321  }
322  temp[i*R+j] = sum;
323  }
324  }
325  return temp;
326  }
327 
328 
329  // Multiply two compatible matrices.
330  template<unsigned int M>
331  RT_HOSTDEVICE Matrix<M,M>& operator*=(Matrix<M,M>& m1, const Matrix<M,M>& m2)
332  {
333  m1 = m1*m2;
334  return m1;
335  }
336 
337 
338  // Multiply matrix by vector
339  template<unsigned int M, unsigned int N>
340  RT_HOSTDEVICE typename Matrix<M,N>::floatM operator*(const Matrix<M,N>& m, const typename Matrix<M,N>::floatN& vec )
341  {
342  typename Matrix<M,N>::floatM temp;
343  float* t = reinterpret_cast<float*>( &temp );
344  const float* v = reinterpret_cast<const float*>( &vec );
345 
346  for (unsigned int i = 0; i < M; ++i) {
347  float sum = 0.0f;
348  for (unsigned int j = 0; j < N; ++j) {
349  sum += RT_MATRIX_ACCESS( m, i, j ) * v[j];
350  }
351  t[i] = sum;
352  }
353 
354  return temp;
355  }
356 
357  // Multiply matrix2xN by floatN
358  template<unsigned int N>
359  OPTIXU_INLINE RT_HOSTDEVICE float2 operator*(const Matrix<2,N>& m, const typename Matrix<2,N>::floatN& vec )
360  {
361  float2 temp = { 0.0f, 0.0f };
362  const float* v = reinterpret_cast<const float*>( &vec );
363 
364  int index = 0;
365  for (unsigned int j = 0; j < N; ++j)
366  temp.x += m[index++] * v[j];
367 
368  for (unsigned int j = 0; j < N; ++j)
369  temp.y += m[index++] * v[j];
370 
371  return temp;
372  }
373 
374  // Multiply matrix3xN by floatN
375  template<unsigned int N>
376  OPTIXU_INLINE RT_HOSTDEVICE float3 operator*(const Matrix<3,N>& m, const typename Matrix<3,N>::floatN& vec )
377  {
378  float3 temp = { 0.0f, 0.0f, 0.0f };
379  const float* v = reinterpret_cast<const float*>( &vec );
380 
381  int index = 0;
382  for (unsigned int j = 0; j < N; ++j)
383  temp.x += m[index++] * v[j];
384 
385  for (unsigned int j = 0; j < N; ++j)
386  temp.y += m[index++] * v[j];
387 
388  for (unsigned int j = 0; j < N; ++j)
389  temp.z += m[index++] * v[j];
390 
391  return temp;
392  }
393 
394  // Multiply matrix4xN by floatN
395  template<unsigned int N>
396  OPTIXU_INLINE RT_HOSTDEVICE float4 operator*(const Matrix<4,N>& m, const typename Matrix<4,N>::floatN& vec )
397  {
398  float4 temp = { 0.0f, 0.0f, 0.0f, 0.0f };
399 
400  const float* v = reinterpret_cast<const float*>( &vec );
401 
402  int index = 0;
403  for (unsigned int j = 0; j < N; ++j)
404  temp.x += m[index++] * v[j];
405 
406  for (unsigned int j = 0; j < N; ++j)
407  temp.y += m[index++] * v[j];
408 
409  for (unsigned int j = 0; j < N; ++j)
410  temp.z += m[index++] * v[j];
411 
412  for (unsigned int j = 0; j < N; ++j)
413  temp.w += m[index++] * v[j];
414 
415  return temp;
416  }
417 
418  // Multiply matrix4x4 by float4
419  OPTIXU_INLINE RT_HOSTDEVICE float4 operator*(const Matrix<4,4>& m, const float4& vec )
420  {
421  float4 temp;
422  temp.x = m[ 0] * vec.x +
423  m[ 1] * vec.y +
424  m[ 2] * vec.z +
425  m[ 3] * vec.w;
426  temp.y = m[ 4] * vec.x +
427  m[ 5] * vec.y +
428  m[ 6] * vec.z +
429  m[ 7] * vec.w;
430  temp.z = m[ 8] * vec.x +
431  m[ 9] * vec.y +
432  m[10] * vec.z +
433  m[11] * vec.w;
434  temp.w = m[12] * vec.x +
435  m[13] * vec.y +
436  m[14] * vec.z +
437  m[15] * vec.w;
438 
439  return temp;
440  }
441 
442  // Multiply vector by matrix
443  template<unsigned int M, unsigned int N>
444  RT_HOSTDEVICE typename Matrix<M,N>::floatN operator*(const typename Matrix<M,N>::floatM& vec, const Matrix<M,N>& m)
445  {
446  typename Matrix<M,N>::floatN temp;
447  float* t = reinterpret_cast<float*>( &temp );
448  const float* v = reinterpret_cast<const float*>( &vec);
449 
450  for (unsigned int i = 0; i < N; ++i) {
451  float sum = 0.0f;
452  for (unsigned int j = 0; j < M; ++j) {
453  sum += v[j] * RT_MATRIX_ACCESS( m, j, i ) ;
454  }
455  t[i] = sum;
456  }
457 
458  return temp;
459  }
460 
461 
462  // Multply matrix by a scalar.
463  template<unsigned int M, unsigned int N>
464  RT_HOSTDEVICE Matrix<M,N> operator*(const Matrix<M,N>& m, float f)
465  {
466  Matrix<M,N> temp( m );
467  temp *= f;
468  return temp;
469  }
470 
471 
472  // Multply matrix by a scalar.
473  template<unsigned int M, unsigned int N>
474  RT_HOSTDEVICE Matrix<M,N>& operator*=(Matrix<M,N>& m, float f)
475  {
476  for ( unsigned int i = 0; i < M*N; ++i )
477  m[i] *= f;
478  return m;
479  }
480 
481 
482  // Multply matrix by a scalar.
483  template<unsigned int M, unsigned int N>
484  RT_HOSTDEVICE Matrix<M,N> operator*(float f, const Matrix<M,N>& m)
485  {
486  Matrix<M,N> temp;
487 
488  for ( unsigned int i = 0; i < M*N; ++i )
489  temp[i] = m[i]*f;
490 
491  return temp;
492  }
493 
494 
495  // Divide matrix by a scalar.
496  template<unsigned int M, unsigned int N>
497  RT_HOSTDEVICE Matrix<M,N> operator/(const Matrix<M,N>& m, float f)
498  {
499  Matrix<M,N> temp( m );
500  temp /= f;
501  return temp;
502  }
503 
504 
505  // Divide matrix by a scalar.
506  template<unsigned int M, unsigned int N>
507  RT_HOSTDEVICE Matrix<M,N>& operator/=(Matrix<M,N>& m, float f)
508  {
509  float inv_f = 1.0f / f;
510  for ( unsigned int i = 0; i < M*N; ++i )
511  m[i] *= inv_f;
512  return m;
513  }
514 
515  // Returns the transpose of the matrix.
516  template<unsigned int M, unsigned int N>
517  OPTIXU_INLINE RT_HOSTDEVICE Matrix<N,M> Matrix<M,N>::transpose() const
518  {
519  Matrix<N,M> ret;
520  for( unsigned int row = 0; row < M; ++row )
521  for( unsigned int col = 0; col < N; ++col )
522  ret[col*M+row] = m_data[row*N+col];
523  return ret;
524  }
525 
526  // Returns the determinant of the matrix.
527  template<>
528  OPTIXU_INLINE RT_HOSTDEVICE float Matrix<3,3>::det() const
529  {
530  const float* m = m_data;
531  float d = m[0]*m[4]*m[8] + m[1]*m[5]*m[6] + m[2]*m[3]*m[7]
532  - m[0]*m[5]*m[7] - m[1]*m[3]*m[8] - m[2]*m[4]*m[6];
533  return d;
534  }
535 
536  // Returns the determinant of the matrix.
537  template<>
538  OPTIXU_INLINE RT_HOSTDEVICE float Matrix<4,4>::det() const
539  {
540  const float* m = m_data;
541  float d =
542  m[0]*m[5]*m[10]*m[15]-
543  m[0]*m[5]*m[11]*m[14]+m[0]*m[9]*m[14]*m[7]-
544  m[0]*m[9]*m[6]*m[15]+m[0]*m[13]*m[6]*m[11]-
545  m[0]*m[13]*m[10]*m[7]-m[4]*m[1]*m[10]*m[15]+m[4]*m[1]*m[11]*m[14]-
546  m[4]*m[9]*m[14]*m[3]+m[4]*m[9]*m[2]*m[15]-
547  m[4]*m[13]*m[2]*m[11]+m[4]*m[13]*m[10]*m[3]+m[8]*m[1]*m[6]*m[15]-
548  m[8]*m[1]*m[14]*m[7]+m[8]*m[5]*m[14]*m[3]-
549  m[8]*m[5]*m[2]*m[15]+m[8]*m[13]*m[2]*m[7]-
550  m[8]*m[13]*m[6]*m[3]-
551  m[12]*m[1]*m[6]*m[11]+m[12]*m[1]*m[10]*m[7]-
552  m[12]*m[5]*m[10]*m[3]+m[12]*m[5]*m[2]*m[11]-
553  m[12]*m[9]*m[2]*m[7]+m[12]*m[9]*m[6]*m[3];
554  return d;
555  }
556 
557  // Returns the inverse of the matrix.
558  template<>
559  OPTIXU_INLINE RT_HOSTDEVICE Matrix<4,4> Matrix<4,4>::inverse() const
560  {
561  Matrix<4,4> dst;
562  const float* m = m_data;
563  const float d = 1.0f / det();
564 
565  dst[0] = d * (m[5] * (m[10] * m[15] - m[14] * m[11]) + m[9] * (m[14] * m[7] - m[6] * m[15]) + m[13] * (m[6] * m[11] - m[10] * m[7]));
566  dst[4] = d * (m[6] * (m[8] * m[15] - m[12] * m[11]) + m[10] * (m[12] * m[7] - m[4] * m[15]) + m[14] * (m[4] * m[11] - m[8] * m[7]));
567  dst[8] = d * (m[7] * (m[8] * m[13] - m[12] * m[9]) + m[11] * (m[12] * m[5] - m[4] * m[13]) + m[15] * (m[4] * m[9] - m[8] * m[5]));
568  dst[12] = d * (m[4] * (m[13] * m[10] - m[9] * m[14]) + m[8] * (m[5] * m[14] - m[13] * m[6]) + m[12] * (m[9] * m[6] - m[5] * m[10]));
569  dst[1] = d * (m[9] * (m[2] * m[15] - m[14] * m[3]) + m[13] * (m[10] * m[3] - m[2] * m[11]) + m[1] * (m[14] * m[11] - m[10] * m[15]));
570  dst[5] = d * (m[10] * (m[0] * m[15] - m[12] * m[3]) + m[14] * (m[8] * m[3] - m[0] * m[11]) + m[2] * (m[12] * m[11] - m[8] * m[15]));
571  dst[9] = d * (m[11] * (m[0] * m[13] - m[12] * m[1]) + m[15] * (m[8] * m[1] - m[0] * m[9]) + m[3] * (m[12] * m[9] - m[8] * m[13]));
572  dst[13] = d * (m[8] * (m[13] * m[2] - m[1] * m[14]) + m[12] * (m[1] * m[10] - m[9] * m[2]) + m[0] * (m[9] * m[14] - m[13] * m[10]));
573  dst[2] = d * (m[13] * (m[2] * m[7] - m[6] * m[3]) + m[1] * (m[6] * m[15] - m[14] * m[7]) + m[5] * (m[14] * m[3] - m[2] * m[15]));
574  dst[6] = d * (m[14] * (m[0] * m[7] - m[4] * m[3]) + m[2] * (m[4] * m[15] - m[12] * m[7]) + m[6] * (m[12] * m[3] - m[0] * m[15]));
575  dst[10] = d * (m[15] * (m[0] * m[5] - m[4] * m[1]) + m[3] * (m[4] * m[13] - m[12] * m[5]) + m[7] * (m[12] * m[1] - m[0] * m[13]));
576  dst[14] = d * (m[12] * (m[5] * m[2] - m[1] * m[6]) + m[0] * (m[13] * m[6] - m[5] * m[14]) + m[4] * (m[1] * m[14] - m[13] * m[2]));
577  dst[3] = d * (m[1] * (m[10] * m[7] - m[6] * m[11]) + m[5] * (m[2] * m[11] - m[10] * m[3]) + m[9] * (m[6] * m[3] - m[2] * m[7]));
578  dst[7] = d * (m[2] * (m[8] * m[7] - m[4] * m[11]) + m[6] * (m[0] * m[11] - m[8] * m[3]) + m[10] * (m[4] * m[3] - m[0] * m[7]));
579  dst[11] = d * (m[3] * (m[8] * m[5] - m[4] * m[9]) + m[7] * (m[0] * m[9] - m[8] * m[1]) + m[11] * (m[4] * m[1] - m[0] * m[5]));
580  dst[15] = d * (m[0] * (m[5] * m[10] - m[9] * m[6]) + m[4] * (m[9] * m[2] - m[1] * m[10]) + m[8] * (m[1] * m[6] - m[5] * m[2]));
581  return dst;
582  }
583 
584  // Returns a rotation matrix.
585  // This is a static member.
586  template<>
587  OPTIXU_INLINE RT_HOSTDEVICE Matrix<4,4> Matrix<4,4>::rotate(const float radians, const float3& axis)
588  {
589  Matrix<4,4> Mat = Matrix<4,4>::identity();
590  float *m = Mat.getData();
591 
592  // NOTE: Element 0,1 is wrong in Foley and Van Dam, Pg 227!
593  float sintheta=sinf(radians);
594  float costheta=cosf(radians);
595  float ux=axis.x;
596  float uy=axis.y;
597  float uz=axis.z;
598  m[0*4+0]=ux*ux+costheta*(1-ux*ux);
599  m[0*4+1]=ux*uy*(1-costheta)-uz*sintheta;
600  m[0*4+2]=uz*ux*(1-costheta)+uy*sintheta;
601  m[0*4+3]=0;
602 
603  m[1*4+0]=ux*uy*(1-costheta)+uz*sintheta;
604  m[1*4+1]=uy*uy+costheta*(1-uy*uy);
605  m[1*4+2]=uy*uz*(1-costheta)-ux*sintheta;
606  m[1*4+3]=0;
607 
608  m[2*4+0]=uz*ux*(1-costheta)-uy*sintheta;
609  m[2*4+1]=uy*uz*(1-costheta)+ux*sintheta;
610  m[2*4+2]=uz*uz+costheta*(1-uz*uz);
611  m[2*4+3]=0;
612 
613  m[3*4+0]=0;
614  m[3*4+1]=0;
615  m[3*4+2]=0;
616  m[3*4+3]=1;
617 
618  return Matrix<4,4>( m );
619  }
620 
621  // Returns a translation matrix.
622  // This is a static member.
623  template<>
624  OPTIXU_INLINE RT_HOSTDEVICE Matrix<4,4> Matrix<4,4>::translate(const float3& vec)
625  {
626  Matrix<4,4> Mat = Matrix<4,4>::identity();
627  float *m = Mat.getData();
628 
629  m[3] = vec.x;
630  m[7] = vec.y;
631  m[11]= vec.z;
632 
633  return Matrix<4,4>( m );
634  }
635 
636  // Returns a scale matrix.
637  // This is a static member.
638  template<>
639  OPTIXU_INLINE RT_HOSTDEVICE Matrix<4,4> Matrix<4,4>::scale(const float3& vec)
640  {
641  Matrix<4,4> Mat = Matrix<4,4>::identity();
642  float *m = Mat.getData();
643 
644  m[0] = vec.x;
645  m[5] = vec.y;
646  m[10]= vec.z;
647 
648  return Matrix<4,4>( m );
649  }
650 
651  // Returns the identity matrix.
652  // This is a static member.
653  template<unsigned int M, unsigned int N>
654  OPTIXU_INLINE RT_HOSTDEVICE Matrix<N,N> Matrix<M,N>::identity()
655  {
656  float temp[N*N];
657  for(unsigned int i = 0; i < N*N; ++i)
658  temp[i] = 0;
659  for( unsigned int i = 0; i < N; ++i )
660  RT_MATRIX_ACCESS( temp,i,i ) = 1.0f;
661  return Matrix<N,N>( temp );
662  }
663 
664  // Ordered comparison operator so that the matrix can be used in an STL container.
665  template<unsigned int M, unsigned int N>
666  OPTIXU_INLINE RT_HOSTDEVICE bool Matrix<M,N>::operator<( const Matrix<M, N>& rhs ) const
667  {
668  for( unsigned int i = 0; i < N*M; ++i ) {
669  if( m_data[i] < rhs[i] )
670  return true;
671  else if( m_data[i] > rhs[i] )
672  return false;
673  }
674  return false;
675  }
676 
677  typedef Matrix<2, 2> Matrix2x2;
678  typedef Matrix<2, 3> Matrix2x3;
679  typedef Matrix<2, 4> Matrix2x4;
680  typedef Matrix<3, 2> Matrix3x2;
681  typedef Matrix<3, 3> Matrix3x3;
682  typedef Matrix<3, 4> Matrix3x4;
683  typedef Matrix<4, 2> Matrix4x2;
684  typedef Matrix<4, 3> Matrix4x3;
685  typedef Matrix<4, 4> Matrix4x4;
686 
687 
688  OPTIXU_INLINE RT_HOSTDEVICE Matrix<3,3> make_matrix3x3(const Matrix<4,4> &matrix)
689  {
690  Matrix<3,3> Mat;
691  float *m = Mat.getData();
692  const float *m4x4 = matrix.getData();
693 
694  m[0*3+0]=m4x4[0*4+0];
695  m[0*3+1]=m4x4[0*4+1];
696  m[0*3+2]=m4x4[0*4+2];
697 
698  m[1*3+0]=m4x4[1*4+0];
699  m[1*3+1]=m4x4[1*4+1];
700  m[1*3+2]=m4x4[1*4+2];
701 
702  m[2*3+0]=m4x4[2*4+0];
703  m[2*3+1]=m4x4[2*4+1];
704  m[2*3+2]=m4x4[2*4+2];
705 
706  return Mat;
707  }
708 
709 } // end namespace optix
710 
711 #undef RT_MATRIX_ACCESS
712 #undef RT_MAT_DECL
713 
714 #ifdef OPTIXU_INLINE_DEFINED
715 # undef OPTIXU_INLINE_DEFINED
716 # undef OPTIXU_INLINE
717 #endif
718 
719 #endif // __optixu_optixu_matrix_namespace_h__
static RT_HOSTDEVICE Matrix< 4, 4 > translate(const float3 &vec)
RT_HOSTDEVICE Matrix< 4, 4 > inverse() const
RT_HOSTDEVICE float operator[](unsigned int i) const
Definition: optixu_matrix_namespace.h:120
RT_HOSTDEVICE Matrix(const float data[M *N])
Definition: optixu_matrix_namespace.h:111
RT_HOSTDEVICE Matrix & operator=(const Matrix &b)
Definition: optixu_matrix_namespace.h:186
RT_HOSTDEVICE floatN getRow(unsigned int m) const
Definition: optixu_matrix_namespace.h:211
A matrix with M rows and N columns.
Definition: optixu_matrix_namespace.h:54
static RT_HOSTDEVICE Matrix< 4, 4 > rotate(const float radians, const float3 &axis)
Definition: optixu_matrix_namespace.h:48
static RT_HOSTDEVICE Matrix< 4, 4 > scale(const float3 &vec)
static RT_HOSTDEVICE Matrix< N, N > identity()
Definition: optixu_matrix_namespace.h:654
RT_HOSTDEVICE Matrix()
A column of the matrix.
Definition: optixu_matrix_namespace.h:174
RT_HOSTDEVICE float & operator[](unsigned int i)
Definition: optixu_matrix_namespace.h:123
RT_HOSTDEVICE floatM getCol(unsigned int n) const
Definition: optixu_matrix_namespace.h:224
OptiX public API.
RT_HOSTDEVICE void setRow(unsigned int m, const floatN &r)
Definition: optixu_matrix_namespace.h:250
RT_HOSTDEVICE Matrix< N, M > transpose() const
Definition: optixu_matrix_namespace.h:517
RT_HOSTDEVICE bool operator<(const Matrix< M, N > &rhs) const
Definition: optixu_matrix_namespace.h:666
VectorDim< M >::VectorType floatM
A row of the matrix.
Definition: optixu_matrix_namespace.h:105
RT_HOSTDEVICE float * getData()
Definition: optixu_matrix_namespace.h:236
RT_HOSTDEVICE float det() const
RT_HOSTDEVICE void setCol(unsigned int n, const floatM &c)
Definition: optixu_matrix_namespace.h:260