OSDN Git Service

Add ColorSpace class
[android-x86/frameworks-native.git] / include / ui / mat3.h
1 /*
2  * Copyright 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef UI_MAT3_H_
18 #define UI_MAT3_H_
19
20 #include <ui/quat.h>
21 #include <ui/TMatHelpers.h>
22 #include <ui/vec3.h>
23 #include <stdint.h>
24 #include <sys/types.h>
25
26 #define PURE __attribute__((pure))
27
28 #if __cplusplus >= 201402L
29 #define CONSTEXPR constexpr
30 #else
31 #define CONSTEXPR
32 #endif
33
34 namespace android {
35 // -------------------------------------------------------------------------------------
36 namespace details {
37
38 template<typename T>
39 class TQuaternion;
40
41 /**
42  * A 3x3 column-major matrix class.
43  *
44  * Conceptually a 3x3 matrix is a an array of 3 column vec3:
45  *
46  * mat3 m =
47  *      \f$
48  *      \left(
49  *      \begin{array}{ccc}
50  *      m[0] & m[1] & m[2] \\
51  *      \end{array}
52  *      \right)
53  *      \f$
54  *      =
55  *      \f$
56  *      \left(
57  *      \begin{array}{ccc}
58  *      m[0][0] & m[1][0] & m[2][0] \\
59  *      m[0][1] & m[1][1] & m[2][1] \\
60  *      m[0][2] & m[1][2] & m[2][2] \\
61  *      \end{array}
62  *      \right)
63  *      \f$
64  *      =
65  *      \f$
66  *      \left(
67  *      \begin{array}{ccc}
68  *      m(0,0) & m(0,1) & m(0,2) \\
69  *      m(1,0) & m(1,1) & m(1,2) \\
70  *      m(2,0) & m(2,1) & m(2,2) \\
71  *      \end{array}
72  *      \right)
73  *      \f$
74  *
75  * m[n] is the \f$ n^{th} \f$ column of the matrix and is a vec3.
76  *
77  */
78 template <typename T>
79 class TMat33 :  public TVecUnaryOperators<TMat33, T>,
80                 public TVecComparisonOperators<TMat33, T>,
81                 public TVecAddOperators<TMat33, T>,
82                 public TMatProductOperators<TMat33, T>,
83                 public TMatSquareFunctions<TMat33, T>,
84                 public TMatTransform<TMat33, T>,
85                 public TMatHelpers<TMat33, T>,
86                 public TMatDebug<TMat33, T> {
87 public:
88     enum no_init { NO_INIT };
89     typedef T value_type;
90     typedef T& reference;
91     typedef T const& const_reference;
92     typedef size_t size_type;
93     typedef TVec3<T> col_type;
94     typedef TVec3<T> row_type;
95
96     static constexpr size_t COL_SIZE = col_type::SIZE;  // size of a column (i.e.: number of rows)
97     static constexpr size_t ROW_SIZE = row_type::SIZE;  // size of a row (i.e.: number of columns)
98     static constexpr size_t NUM_ROWS = COL_SIZE;
99     static constexpr size_t NUM_COLS = ROW_SIZE;
100
101 private:
102     /*
103      *  <--  N columns  -->
104      *
105      *  a[0][0] a[1][0] a[2][0] ... a[N][0]    ^
106      *  a[0][1] a[1][1] a[2][1] ... a[N][1]    |
107      *  a[0][2] a[1][2] a[2][2] ... a[N][2]  M rows
108      *  ...                                    |
109      *  a[0][M] a[1][M] a[2][M] ... a[N][M]    v
110      *
111      *  COL_SIZE = M
112      *  ROW_SIZE = N
113      *  m[0] = [ a[0][0] a[0][1] a[0][2] ... a[0][M] ]
114      */
115
116     col_type m_value[NUM_COLS];
117
118 public:
119     // array access
120     inline constexpr col_type const& operator[](size_t column) const {
121 #if __cplusplus >= 201402L
122         // only possible in C++0x14 with constexpr
123         assert(column < NUM_COLS);
124 #endif
125         return m_value[column];
126     }
127
128     inline col_type& operator[](size_t column) {
129         assert(column < NUM_COLS);
130         return m_value[column];
131     }
132
133     // -----------------------------------------------------------------------
134     // we want the compiler generated versions for these...
135     TMat33(const TMat33&) = default;
136     ~TMat33() = default;
137     TMat33& operator = (const TMat33&) = default;
138
139     /**
140      *  constructors
141      */
142
143     /**
144      * leaves object uninitialized. use with caution.
145      */
146     explicit constexpr TMat33(no_init)
147             : m_value{ col_type(col_type::NO_INIT),
148                        col_type(col_type::NO_INIT),
149                        col_type(col_type::NO_INIT) } {}
150
151
152     /**
153      * initialize to identity.
154      *
155      *      \f$
156      *      \left(
157      *      \begin{array}{ccc}
158      *      1 & 0 & 0 \\
159      *      0 & 1 & 0 \\
160      *      0 & 0 & 1 \\
161      *      \end{array}
162      *      \right)
163      *      \f$
164      */
165     CONSTEXPR TMat33();
166
167     /**
168      * initialize to Identity*scalar.
169      *
170      *      \f$
171      *      \left(
172      *      \begin{array}{ccc}
173      *      v & 0 & 0 \\
174      *      0 & v & 0 \\
175      *      0 & 0 & v \\
176      *      \end{array}
177      *      \right)
178      *      \f$
179      */
180     template<typename U>
181     explicit CONSTEXPR TMat33(U v);
182
183     /**
184      * sets the diagonal to a vector.
185      *
186      *      \f$
187      *      \left(
188      *      \begin{array}{ccc}
189      *      v[0] & 0 & 0 \\
190      *      0 & v[1] & 0 \\
191      *      0 & 0 & v[2] \\
192      *      \end{array}
193      *      \right)
194      *      \f$
195      */
196     template <typename U>
197     explicit CONSTEXPR TMat33(const TVec3<U>& v);
198
199     /**
200      * construct from another matrix of the same size
201      */
202     template <typename U>
203     explicit CONSTEXPR TMat33(const TMat33<U>& rhs);
204
205     /**
206      * construct from 3 column vectors.
207      *
208      *      \f$
209      *      \left(
210      *      \begin{array}{ccc}
211      *      v0 & v1 & v2 \\
212      *      \end{array}
213      *      \right)
214      *      \f$
215      */
216     template <typename A, typename B, typename C>
217     CONSTEXPR TMat33(const TVec3<A>& v0, const TVec3<B>& v1, const TVec3<C>& v2);
218
219     /** construct from 9 elements in column-major form.
220      *
221      *      \f$
222      *      \left(
223      *      \begin{array}{ccc}
224      *      m[0][0] & m[1][0] & m[2][0] \\
225      *      m[0][1] & m[1][1] & m[2][1] \\
226      *      m[0][2] & m[1][2] & m[2][2] \\
227      *      \end{array}
228      *      \right)
229      *      \f$
230      */
231     template <
232         typename A, typename B, typename C,
233         typename D, typename E, typename F,
234         typename G, typename H, typename I>
235     CONSTEXPR TMat33(
236            A m00, B m01, C m02,
237            D m10, E m11, F m12,
238            G m20, H m21, I m22);
239
240     /**
241      * construct from a quaternion
242      */
243     template <typename U>
244     explicit CONSTEXPR TMat33(const TQuaternion<U>& q);
245
246     /**
247      * construct from a C array in column major form.
248      */
249     template <typename U>
250     explicit CONSTEXPR TMat33(U const* rawArray);
251
252     /**
253      * orthogonalize only works on matrices of size 3x3
254      */
255     friend inline
256     CONSTEXPR TMat33 orthogonalize(const TMat33& m) {
257         TMat33 ret(TMat33::NO_INIT);
258         ret[0] = normalize(m[0]);
259         ret[2] = normalize(cross(ret[0], m[1]));
260         ret[1] = normalize(cross(ret[2], ret[0]));
261         return ret;
262     }
263 };
264
265 // ----------------------------------------------------------------------------------------
266 // Constructors
267 // ----------------------------------------------------------------------------------------
268
269 // Since the matrix code could become pretty big quickly, we don't inline most
270 // operations.
271
272 template <typename T>
273 CONSTEXPR TMat33<T>::TMat33() {
274     m_value[0] = col_type(1, 0, 0);
275     m_value[1] = col_type(0, 1, 0);
276     m_value[2] = col_type(0, 0, 1);
277 }
278
279 template <typename T>
280 template <typename U>
281 CONSTEXPR TMat33<T>::TMat33(U v) {
282     m_value[0] = col_type(v, 0, 0);
283     m_value[1] = col_type(0, v, 0);
284     m_value[2] = col_type(0, 0, v);
285 }
286
287 template<typename T>
288 template<typename U>
289 CONSTEXPR TMat33<T>::TMat33(const TVec3<U>& v) {
290     m_value[0] = col_type(v.x, 0, 0);
291     m_value[1] = col_type(0, v.y, 0);
292     m_value[2] = col_type(0, 0, v.z);
293 }
294
295 // construct from 16 scalars. Note that the arrangement
296 // of values in the constructor is the transpose of the matrix
297 // notation.
298 template<typename T>
299 template <
300     typename A, typename B, typename C,
301     typename D, typename E, typename F,
302     typename G, typename H, typename I>
303 CONSTEXPR TMat33<T>::TMat33(
304         A m00, B m01, C m02,
305         D m10, E m11, F m12,
306         G m20, H m21, I m22) {
307     m_value[0] = col_type(m00, m01, m02);
308     m_value[1] = col_type(m10, m11, m12);
309     m_value[2] = col_type(m20, m21, m22);
310 }
311
312 template <typename T>
313 template <typename U>
314 CONSTEXPR TMat33<T>::TMat33(const TMat33<U>& rhs) {
315     for (size_t col = 0; col < NUM_COLS; ++col) {
316         m_value[col] = col_type(rhs[col]);
317     }
318 }
319
320 // Construct from 3 column vectors.
321 template <typename T>
322 template <typename A, typename B, typename C>
323 CONSTEXPR TMat33<T>::TMat33(const TVec3<A>& v0, const TVec3<B>& v1, const TVec3<C>& v2) {
324     m_value[0] = v0;
325     m_value[1] = v1;
326     m_value[2] = v2;
327 }
328
329 // Construct from raw array, in column-major form.
330 template <typename T>
331 template <typename U>
332 CONSTEXPR TMat33<T>::TMat33(U const* rawArray) {
333     for (size_t col = 0; col < NUM_COLS; ++col) {
334         for (size_t row = 0; row < NUM_ROWS; ++row) {
335             m_value[col][row] = *rawArray++;
336         }
337     }
338 }
339
340 template <typename T>
341 template <typename U>
342 CONSTEXPR TMat33<T>::TMat33(const TQuaternion<U>& q) {
343     const U n = q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w;
344     const U s = n > 0 ? 2/n : 0;
345     const U x = s*q.x;
346     const U y = s*q.y;
347     const U z = s*q.z;
348     const U xx = x*q.x;
349     const U xy = x*q.y;
350     const U xz = x*q.z;
351     const U xw = x*q.w;
352     const U yy = y*q.y;
353     const U yz = y*q.z;
354     const U yw = y*q.w;
355     const U zz = z*q.z;
356     const U zw = z*q.w;
357     m_value[0] = col_type(1-yy-zz,    xy+zw,    xz-yw);  // NOLINT
358     m_value[1] = col_type(  xy-zw,  1-xx-zz,    yz+xw);  // NOLINT
359     m_value[2] = col_type(  xz+yw,    yz-xw,  1-xx-yy);  // NOLINT
360 }
361
362 // ----------------------------------------------------------------------------------------
363 // Arithmetic operators outside of class
364 // ----------------------------------------------------------------------------------------
365
366 /* We use non-friend functions here to prevent the compiler from using
367  * implicit conversions, for instance of a scalar to a vector. The result would
368  * not be what the caller expects.
369  *
370  * Also note that the order of the arguments in the inner loop is important since
371  * it determines the output type (only relevant when T != U).
372  */
373
374 // matrix * column-vector, result is a vector of the same type than the input vector
375 template <typename T, typename U>
376 CONSTEXPR typename TMat33<U>::col_type PURE operator *(const TMat33<T>& lhs, const TVec3<U>& rhs) {
377     // Result is initialized to zero.
378     typename TMat33<U>::col_type result;
379     for (size_t col = 0; col < TMat33<T>::NUM_COLS; ++col) {
380         result += lhs[col] * rhs[col];
381     }
382     return result;
383 }
384
385 // row-vector * matrix, result is a vector of the same type than the input vector
386 template <typename T, typename U>
387 CONSTEXPR typename TMat33<U>::row_type PURE operator *(const TVec3<U>& lhs, const TMat33<T>& rhs) {
388     typename TMat33<U>::row_type result(TMat33<U>::row_type::NO_INIT);
389     for (size_t col = 0; col < TMat33<T>::NUM_COLS; ++col) {
390         result[col] = dot(lhs, rhs[col]);
391     }
392     return result;
393 }
394
395 // matrix * scalar, result is a matrix of the same type than the input matrix
396 template<typename T, typename U>
397 constexpr typename std::enable_if<std::is_arithmetic<U>::value, TMat33<T>>::type PURE
398 operator*(TMat33<T> lhs, U rhs) {
399     return lhs *= rhs;
400 }
401
402 // scalar * matrix, result is a matrix of the same type than the input matrix
403 template<typename T, typename U>
404 constexpr typename std::enable_if<std::is_arithmetic<U>::value, TMat33<T>>::type PURE
405 operator*(U lhs, const TMat33<T>& rhs) {
406     return rhs * lhs;
407 }
408
409 //------------------------------------------------------------------------------
410 template <typename T>
411 CONSTEXPR TMat33<T> orthogonalize(const TMat33<T>& m) {
412     TMat33<T> ret(TMat33<T>::NO_INIT);
413     ret[0] = normalize(m[0]);
414     ret[2] = normalize(cross(ret[0], m[1]));
415     ret[1] = normalize(cross(ret[2], ret[0]));
416     return ret;
417 }
418
419 // ----------------------------------------------------------------------------------------
420
421 /* FIXME: this should go into TMatSquareFunctions<> but for some reason
422  * BASE<T>::col_type is not accessible from there (???)
423  */
424 template<typename T>
425 CONSTEXPR typename TMat33<T>::col_type PURE diag(const TMat33<T>& m) {
426     return matrix::diag(m);
427 }
428
429 }  // namespace details
430
431 // ----------------------------------------------------------------------------------------
432
433 typedef details::TMat33<double> mat3d;
434 typedef details::TMat33<float> mat3;
435 typedef details::TMat33<float> mat3f;
436
437 // ----------------------------------------------------------------------------------------
438 }  // namespace android
439
440 #undef PURE
441 #undef CONSTEXPR
442
443 #endif  // UI_MAT3_H_