source: trunk/nv/stl/math/mat4.hh @ 534

Last change on this file since 534 was 534, checked in by epyon, 8 years ago

CONTINUED:

  • getting rid of size_t
  • datatypes now restricted to uint32 size
  • 64-bit compatibility
  • copyright updates where modified
File size: 12.3 KB
Line 
1// Copyright (C) 2015-2015 ChaosForge Ltd
2// http://chaosforge.org/
3//
4// This file is part of Nova libraries.
5// For conditions of distribution and use, see copying.txt file in root folder.
6
7/**
8 * @file mat4.hh
9 * @author Kornel Kisielewicz epyon@chaosforge.org
10 * @brief matrix 4x4
11 */
12
13#ifndef NV_STL_MATH_MAT4_HH
14#define NV_STL_MATH_MAT4_HH
15
16#include <nv/stl/math/common.hh>
17
18namespace nv
19{
20
21        namespace math
22        {
23
24                template <typename T>
25                struct tmat4
26                {
27                        typedef tvec4<T> column_type;
28                        typedef tvec4<T> row_type;
29                        typedef tmat4<T> this_type;
30                        typedef uint32   size_type;
31                        typedef T        value_type;
32
33                        static constexpr size_type SIZE = 4;
34                        inline constexpr size_type size() const { return 4; }
35
36                private:
37                        column_type value[4];
38
39                public:
40                        inline tmat4()
41                                : value{
42                                        column_type( static_cast<T>( 1 ), static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) ),
43                                        column_type( static_cast<T>( 0 ), static_cast<T>( 1 ), static_cast<T>( 0 ), static_cast<T>( 0 ) ),
44                                        column_type( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 1 ), static_cast<T>( 0 ) ),
45                                        column_type( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 1 ) )
46                                }
47                        {}
48
49                        inline tmat4( const tmat4<T> & m ) = default;
50                        inline tmat4( tmat4<T> && m ) = default;
51                        inline tmat4<T> & operator=( const tmat4<T> & m ) = default;
52                        inline tmat4<T> & operator=( tmat4<T> && m ) = default;
53
54                        inline explicit tmat4( T s )
55                                : value{
56                                        column_type( static_cast<T>( s ), static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) ),
57                                        column_type( static_cast<T>( 0 ), static_cast<T>( s ), static_cast<T>( 0 ), static_cast<T>( 0 ) ),
58                                        column_type( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( s ), static_cast<T>( 0 ) ),
59                                        column_type( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( s ) )
60                                }
61                        {}
62
63                        inline explicit tmat4( no_init_t )
64                                : value{
65                                        column_type( no_init ),
66                                        column_type( no_init ),
67                                        column_type( no_init ),
68                                        column_type( no_init )
69                                }
70                        {}
71
72                        inline tmat4(
73                                T x0, T y0, T z0, T w0,
74                                T x1, T y1, T z1, T w1,
75                                T x2, T y2, T z2, T w2,
76                                T x3, T y3, T z3, T w3
77                        ) : value{
78                                column_type( x0, y0, z0, w0 ),
79                                column_type( x1, y1, z1, w1 ),
80                                column_type( x2, y2, z2, w2 ),
81                                column_type( x3, y3, z3, w3 )
82                        }
83                        {}
84
85                        inline tmat4(
86                                const column_type & v0,
87                                const column_type & v1,
88                                const column_type & v2,
89                                const column_type & v3
90                        ) : value{ v0, v1, v2, v3 }
91                        {}
92
93                        template <typename U>
94                        inline explicit tmat4( const tmat4<U> & m )
95                                : value{
96                                        column_type( m[0] ),
97                                        column_type( m[1] ),
98                                        column_type( m[2] ),
99                                        column_type( m[3] )
100                                }
101                        {}
102
103                        inline explicit tmat4( const tmat2<T> & m )
104                                : value{
105                                        column_type( m[0], static_cast<T>( 0 ), static_cast<T>( 0 ) ),
106                                        column_type( m[1], static_cast<T>( 0 ), static_cast<T>( 0 ) ),
107                                        column_type( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 1 ), static_cast<T>( 0 ) ),
108                                        column_type( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 1 ) )
109                                }
110                        {}
111
112                        inline explicit tmat4( const tmat3<T> & m )
113                                : value{
114                                        column_type( m[0], static_cast<T>( 0 ) ),
115                                        column_type( m[1], static_cast<T>( 0 ) ),
116                                        column_type( m[2], static_cast<T>( 0 ) ),
117                                        column_type( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 1 ) )
118                                }
119                        {}
120
121                        inline column_type & operator[]( size_type i )
122                        {
123                                NV_ASSERT_DEBUG( i >= 0 && i < this->size(), "index out of range!" );
124                                return this->value[i];
125                        }
126
127                        inline const column_type& operator[]( size_type i ) const
128                        {
129                                NV_ASSERT_DEBUG( i >= 0 && i < this->size(), "index out of range!" );
130                                return this->value[i];
131                        }
132
133                        inline tmat4<T>& operator+=( T s )
134                        {
135                                this->value[0] += s;
136                                this->value[1] += s;
137                                this->value[2] += s;
138                                this->value[3] += s;
139                                return *this;
140                        }
141
142                        inline tmat4<T>& operator+=( const tmat4<T> & m )
143                        {
144                                this->value[0] += m[0];
145                                this->value[1] += m[1];
146                                this->value[2] += m[2];
147                                this->value[3] += m[3];
148                                return *this;
149                        }
150
151                        inline tmat4<T> & operator-=( T s )
152                        {
153                                this->value[0] -= s;
154                                this->value[1] -= s;
155                                this->value[2] -= s;
156                                this->value[3] -= s;
157                                return *this;
158                        }
159
160                        inline tmat4<T> & operator-=( const tmat4<T> & m )
161                        {
162                                this->value[0] -= m[0];
163                                this->value[1] -= m[1];
164                                this->value[2] -= m[2];
165                                this->value[3] -= m[3];
166                                return *this;
167                        }
168
169                        inline tmat4<T> & operator*=( T s )
170                        {
171                                this->value[0] *= s;
172                                this->value[1] *= s;
173                                this->value[2] *= s;
174                                this->value[3] *= s;
175                                return *this;
176                        }
177
178                        inline tmat4<T> & operator*=( const tmat4<T> & m )
179                        {
180                                return ( *this = *this * m );
181                        }
182
183                        inline tmat4<T> & operator/=( T s )
184                        {
185                                this->value[0] /= s;
186                                this->value[1] /= s;
187                                this->value[2] /= s;
188                                this->value[3] /= s;
189                                return *this;
190                        }
191
192                        inline tmat4<T> & operator/=( const tmat4<T> & m )
193                        {
194                                return ( *this = *this * detail::compute_inverse<T>( m ) );
195                        }
196
197                        inline tmat4<T> & operator++()
198                        {
199                                ++this->value[0];
200                                ++this->value[1];
201                                ++this->value[2];
202                                ++this->value[3];
203                                return *this;
204                        }
205
206                        inline tmat4<T> & operator--()
207                        {
208                                --this->value[0];
209                                --this->value[1];
210                                --this->value[2];
211                                --this->value[3];
212                                return *this;
213                        }
214
215                        inline tmat4<T> operator++( int )
216                        {
217                                tmat4<T> result( *this );
218                                ++*this;
219                                return result;
220                        }
221
222                        inline tmat4<T> operator--( int )
223                        {
224                                tmat4<T> result( *this );
225                                --*this;
226                                return result;
227                        }
228
229                };
230
231                namespace detail
232                {
233                        template <typename T>
234                        inline tmat4<T> compute_inverse( const tmat4<T> & m )
235                        {
236                                T cf00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
237                                T cf02 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
238                                T cf03 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
239
240                                T cf04 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
241                                T cf06 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
242                                T cf07 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
243
244                                T cf08 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
245                                T cf10 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
246                                T cf11 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
247
248                                T cf12 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
249                                T cf14 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
250                                T cf15 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
251
252                                T cf16 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
253                                T cf18 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
254                                T cf19 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
255
256                                T cf20 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
257                                T cf22 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
258                                T cf23 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
259
260                                tvec4<T> f0( cf00, cf00, cf02, cf03 );
261                                tvec4<T> f1( cf04, cf04, cf06, cf07 );
262                                tvec4<T> f2( cf08, cf08, cf10, cf11 );
263                                tvec4<T> f3( cf12, cf12, cf14, cf15 );
264                                tvec4<T> f4( cf16, cf16, cf18, cf19 );
265                                tvec4<T> f5( cf20, cf20, cf22, cf23 );
266
267                                tvec4<T> v0( m[1][0], m[0][0], m[0][0], m[0][0] );
268                                tvec4<T> v1( m[1][1], m[0][1], m[0][1], m[0][1] );
269                                tvec4<T> v2( m[1][2], m[0][2], m[0][2], m[0][2] );
270                                tvec4<T> v3( m[1][3], m[0][3], m[0][3], m[0][3] );
271
272                                tvec4<T> i0( v1 * f0 - v2 * f1 + v3 * f2 );
273                                tvec4<T> i1( v0 * f0 - v2 * f3 + v3 * f4 );
274                                tvec4<T> i2( v0 * f1 - v1 * f3 + v3 * f5 );
275                                tvec4<T> i3( v0 * f2 - v1 * f4 + v2 * f5 );
276
277                                tvec4<T> sgn_a( +1, -1, +1, -1 );
278                                tvec4<T> sgn_b( -1, +1, -1, +1 );
279                                tmat4<T> inv( i0 * sgn_a, i1 * sgn_b, i2 * sgn_a, i3 * sgn_b );
280
281                                tvec4<T> rz( inv[0][0], inv[1][0], inv[2][0], inv[3][0] );
282                                tvec4<T> d0( m[0] * rz );
283                                T d1 = ( d0.x + d0.y ) + ( d0.z + d0.w );
284                                T one_over_det = static_cast<T>( 1 ) / d1;
285
286                                return inv * one_over_det;
287                        }
288
289                }
290
291
292                template <typename T>
293                inline tmat4<T> const operator-( const tmat4<T> & m )
294                {
295                        return tmat4<T>(
296                                -m[0],
297                                -m[1],
298                                -m[2],
299                                -m[3] );
300                }
301
302                template <typename T>
303                inline tmat4<T> operator+( const tmat4<T> & m, T s )
304                {
305                        return tmat4<T>(
306                                m[0] + s,
307                                m[1] + s,
308                                m[2] + s,
309                                m[3] + s );
310                }
311
312                template <typename T>
313                inline tmat4<T> operator+( T s, const tmat4<T> & m )
314                {
315                        return tmat4<T>(
316                                m[0] + s,
317                                m[1] + s,
318                                m[2] + s,
319                                m[3] + s );
320                }
321
322                template <typename T>
323                inline tmat4<T> operator+( const tmat4<T> & m1, const tmat4<T> & m2 )
324                {
325                        return tmat4<T>(
326                                m1[0] + m2[0],
327                                m1[1] + m2[1],
328                                m1[2] + m2[2],
329                                m1[3] + m2[3] );
330                }
331
332                template <typename T>
333                inline tmat4<T> operator-( const tmat4<T> & m, T s )
334                {
335                        return tmat4<T>(
336                                m[0] - s,
337                                m[1] - s,
338                                m[2] - s,
339                                m[3] - s );
340                }
341
342                template <typename T>
343                inline tmat4<T> operator-( T s, const tmat4<T> & m )
344                {
345                        return tmat4<T>(
346                                s - m[0],
347                                s - m[1],
348                                s - m[2],
349                                s - m[3] );
350                }
351
352                template <typename T>
353                inline tmat4<T> operator-( const tmat4<T> & m1, const tmat4<T> & m2 )
354                {
355                        return tmat4<T>(
356                                m1[0] - m2[0],
357                                m1[1] - m2[1],
358                                m1[2] - m2[2],
359                                m1[3] - m2[3] );
360                }
361
362                template <typename T>
363                inline tmat4<T> operator*( const tmat4<T> & m, T s )
364                {
365                        return tmat4<T>(
366                                m[0] * s,
367                                m[1] * s,
368                                m[2] * s,
369                                m[3] * s );
370                }
371
372                template <typename T>
373                inline tmat4<T> operator*( T s, const tmat4<T> & m )
374                {
375                        return tmat4<T>(
376                                m[0] * s,
377                                m[1] * s,
378                                m[2] * s,
379                                m[3] * s );
380                }
381
382                template <typename T>
383                inline typename tmat4<T>::column_type operator*( const tmat4<T> & m, const typename tmat4<T>::row_type & v )
384                {
385                        typedef typename tmat4<T>::column_type column_type;
386                        column_type u0 = m[0] * column_type( v[0] );
387                        column_type u1 = m[1] * column_type( v[1] );
388                        column_type u2 = m[2] * column_type( v[2] );
389                        column_type u3 = m[3] * column_type( v[3] );
390                        return ( u0 + u1 ) + ( u2 + u3 );
391                }
392
393                template <typename T>
394                inline typename tmat4<T>::row_type operator* ( const typename tmat4<T>::column_type & v, const tmat4<T> & m )
395                {
396                        return typename tmat4<T>::row_type(
397                                m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2] + m[0][3] * v[3],
398                                m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2] + m[1][3] * v[3],
399                                m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2] + m[2][3] * v[3],
400                                m[3][0] * v[0] + m[3][1] * v[1] + m[3][2] * v[2] + m[3][3] * v[3]
401                        );
402                }
403
404                template <typename T>
405                inline tmat4<T> operator*( const tmat4<T> & m1, const tmat4<T> & m2 )
406                {
407                        typedef typename tmat4<T>::column_type column_type;
408                        column_type m2_0 = m2[0];
409                        column_type m2_1 = m2[1];
410                        column_type m2_2 = m2[2];
411                        column_type m2_3 = m2[3];
412
413                        tmat4<T> result( no_init );
414                        result[0] = m1[0] * m2_0[0] + m1[1] * m2_0[1] + m1[2] * m2_0[2] + m1[3] * m2_0[3];
415                        result[1] = m1[0] * m2_1[0] + m1[1] * m2_1[1] + m1[2] * m2_1[2] + m1[3] * m2_1[3];
416                        result[2] = m1[0] * m2_2[0] + m1[1] * m2_2[1] + m1[2] * m2_2[2] + m1[3] * m2_2[3];
417                        result[3] = m1[0] * m2_3[0] + m1[1] * m2_3[1] + m1[2] * m2_3[2] + m1[3] * m2_3[3];
418                        return result;
419                }
420
421                template <typename T>
422                inline tmat4<T> operator/( const tmat4<T> & m, T s )
423                {
424                        return tmat4<T>(
425                                m[0] / s,
426                                m[1] / s,
427                                m[2] / s,
428                                m[3] / s );
429                }
430
431                template <typename T>
432                inline tmat4<T> operator/( T s, const tmat4<T> & m )
433                {
434                        return tmat4<T>(
435                                s / m[0],
436                                s / m[1],
437                                s / m[2],
438                                s / m[3] );
439                }
440
441                template <typename T>
442                inline typename tmat4<T>::column_type operator/( const tmat4<T> & m, typename tmat4<T>::row_type const & v )
443                {
444                        return detail::compute_inverse<T>( m ) * v;
445                }
446
447                template <typename T>
448                inline typename tmat4<T>::row_type operator/( typename tmat4<T>::column_type const & v, const tmat4<T> & m )
449                {
450                        return v * detail::compute_inverse<T>( m );
451                }
452
453                template <typename T>
454                inline tmat4<T> operator/( const tmat4<T> & m1, const tmat4<T> & m2 )
455                {
456                        tmat4<T> m1_copy( m1 );
457                        return m1_copy /= m2;
458                }
459
460                template <typename T>
461                inline bool operator==( const tmat4<T> & m1, const tmat4<T> & m2 )
462                {
463                        return ( m1[0] == m2[0] ) && ( m1[1] == m2[1] ) && ( m1[2] == m2[2] ) && ( m1[3] == m2[3] );
464                }
465
466                template <typename T>
467                inline bool operator!=( const tmat4<T> & m1, const tmat4<T> & m2 )
468                {
469                        return ( m1[0] != m2[0] ) || ( m1[1] != m2[1] ) || ( m1[2] != m2[2] ) || ( m1[3] != m2[3] );
470                }
471        }
472
473}
474
475#endif // NV_STL_MATH_MAT4_HH
Note: See TracBrowser for help on using the repository browser.