15d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy/* 25d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Copyright 2013 The Android Open Source Project 35d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 45d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 55d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * you may not use this file except in compliance with the License. 65d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * You may obtain a copy of the License at 75d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 85d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 95d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 105d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Unless required by applicable law or agreed to in writing, software 115d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 125d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * See the License for the specific language governing permissions and 145d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * limitations under the License. 155d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 165d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 171d77b719d51a01cbd6954a048fb64e79d50a950eMathias Agopian#pragma once 185d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 191d77b719d51a01cbd6954a048fb64e79d50a950eMathias Agopian#include <math/TMatHelpers.h> 201d77b719d51a01cbd6954a048fb64e79d50a950eMathias Agopian#include <math/vec2.h> 215d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <stdint.h> 225d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <sys/types.h> 235d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 245d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#define PURE __attribute__((pure)) 255d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 26caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#if __cplusplus >= 201402L 27caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#define CONSTEXPR constexpr 28caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#else 29caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#define CONSTEXPR 30caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#endif 31caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy 325d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guynamespace android { 335d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// ------------------------------------------------------------------------------------- 345d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guynamespace details { 355d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 365d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy/** 375d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * A 2x2 column-major matrix class. 385d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 395d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Conceptually a 2x2 matrix is a an array of 2 column vec2: 405d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 415d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * mat2 m = 425d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 435d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \left( 445d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \begin{array}{cc} 455d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * m[0] & m[1] \\ 465d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \end{array} 475d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \right) 485d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 495d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * = 505d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 515d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \left( 525d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \begin{array}{cc} 535d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * m[0][0] & m[1][0] \\ 545d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * m[0][1] & m[1][1] \\ 555d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \end{array} 565d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \right) 575d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 585d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * = 595d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 605d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \left( 615d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \begin{array}{cc} 625d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * m(0,0) & m(0,1) \\ 635d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * m(1,0) & m(1,1) \\ 645d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \end{array} 655d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \right) 665d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 675d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 685d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * m[n] is the \f$ n^{th} \f$ column of the matrix and is a vec2. 695d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 705d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 715d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate <typename T> 725d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyclass TMat22 : public TVecUnaryOperators<TMat22, T>, 735d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy public TVecComparisonOperators<TMat22, T>, 745d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy public TVecAddOperators<TMat22, T>, 755d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy public TMatProductOperators<TMat22, T>, 765d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy public TMatSquareFunctions<TMat22, T>, 775d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy public TMatHelpers<TMat22, T>, 785d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy public TMatDebug<TMat22, T> { 795d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guypublic: 805d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy enum no_init { NO_INIT }; 815d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typedef T value_type; 825d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typedef T& reference; 835d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typedef T const& const_reference; 845d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typedef size_t size_type; 855d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typedef TVec2<T> col_type; 865d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typedef TVec2<T> row_type; 875d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 885d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr size_t COL_SIZE = col_type::SIZE; // size of a column (i.e.: number of rows) 895d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr size_t ROW_SIZE = row_type::SIZE; // size of a row (i.e.: number of columns) 905d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr size_t NUM_ROWS = COL_SIZE; 915d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr size_t NUM_COLS = ROW_SIZE; 925d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 935d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyprivate: 945d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy /* 955d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * <-- N columns --> 965d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 975d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * a[0][0] a[1][0] a[2][0] ... a[N][0] ^ 985d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * a[0][1] a[1][1] a[2][1] ... a[N][1] | 995d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * a[0][2] a[1][2] a[2][2] ... a[N][2] M rows 1005d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * ... | 1015d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * a[0][M] a[1][M] a[2][M] ... a[N][M] v 1025d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 1035d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * COL_SIZE = M 1045d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * ROW_SIZE = N 1055d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * m[0] = [ a[0][0] a[0][1] a[0][2] ... a[0][M] ] 1065d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 1075d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1085d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy col_type m_value[NUM_COLS]; 1095d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1105d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guypublic: 1115d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // array access 1125d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy inline constexpr col_type const& operator[](size_t column) const { 1135d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#if __cplusplus >= 201402L 1145d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // only possible in C++0x14 with constexpr 1155d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy assert(column < NUM_COLS); 1165d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#endif 1175d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return m_value[column]; 1185d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 1195d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1205d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy inline col_type& operator[](size_t column) { 1215d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy assert(column < NUM_COLS); 1225d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return m_value[column]; 1235d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 1245d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1255d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // ----------------------------------------------------------------------- 1265d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // we want the compiler generated versions for these... 1275d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy TMat22(const TMat22&) = default; 1285d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy ~TMat22() = default; 1295d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy TMat22& operator = (const TMat22&) = default; 1305d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1315d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy /** 1325d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * constructors 1335d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 1345d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1355d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy /** 1365d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * leaves object uninitialized. use with caution. 1375d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 138caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy explicit constexpr TMat22(no_init) 1395d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy : m_value{ col_type(col_type::NO_INIT), 1405d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy col_type(col_type::NO_INIT) } {} 1415d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1425d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1435d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy /** 1445d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * initialize to identity. 1455d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 1465d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 1475d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \left( 1485d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \begin{array}{cc} 1495d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 1 & 0 \\ 1505d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 0 & 1 \\ 1515d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \end{array} 1525d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \right) 1535d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 1545d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 155caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy CONSTEXPR TMat22(); 1565d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1575d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy /** 1585d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * initialize to Identity*scalar. 1595d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 1605d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 1615d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \left( 1625d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \begin{array}{cc} 1635d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * v & 0 \\ 1645d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 0 & v \\ 1655d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \end{array} 1665d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \right) 1675d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 1685d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 1695d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template<typename U> 170caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy explicit CONSTEXPR TMat22(U v); 1715d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1725d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy /** 1735d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * sets the diagonal to a vector. 1745d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 1755d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 1765d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \left( 1775d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \begin{array}{cc} 1785d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * v[0] & 0 \\ 1795d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 0 & v[1] \\ 1805d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \end{array} 1815d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \right) 1825d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 1835d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 1845d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template <typename U> 185caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy explicit CONSTEXPR TMat22(const TVec2<U>& v); 1865d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1875d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy /** 1885d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * construct from another matrix of the same size 1895d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 1905d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template <typename U> 191caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy explicit CONSTEXPR TMat22(const TMat22<U>& rhs); 1925d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1935d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy /** 1945d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * construct from 2 column vectors. 1955d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 1965d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 1975d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \left( 1985d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \begin{array}{cc} 1995d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * v0 & v1 \\ 2005d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \end{array} 2015d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \right) 2025d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 2035d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 2045d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template <typename A, typename B> 205caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy CONSTEXPR TMat22(const TVec2<A>& v0, const TVec2<B>& v1); 2065d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 2075d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy /** construct from 4 elements in column-major form. 2085d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 2095d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 2105d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \left( 2115d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \begin{array}{cc} 2125d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * m[0][0] & m[1][0] \\ 2135d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * m[0][1] & m[1][1] \\ 2145d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \end{array} 2155d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \right) 2165d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * \f$ 2175d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 2185d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template < 2195d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typename A, typename B, 2205d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typename C, typename D> 221caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy CONSTEXPR TMat22(A m00, B m01, C m10, D m11); 2225d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 2235d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy /** 2245d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * construct from a C array in column major form. 2255d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 2265d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template <typename U> 227caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy explicit CONSTEXPR TMat22(U const* rawArray); 2285d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 2295d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy /** 2305d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Rotate by radians in the 2D plane 2315d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 232caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy static CONSTEXPR TMat22<T> rotate(T radian) { 2335d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy TMat22<T> r(TMat22<T>::NO_INIT); 2345d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy T c = std::cos(radian); 2355d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy T s = std::sin(radian); 2365d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy r[0][0] = c; r[1][1] = c; 2375d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy r[0][1] = s; r[1][0] = -s; 2385d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return r; 2395d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 2405d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy}; 2415d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 2425d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// ---------------------------------------------------------------------------------------- 2435d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// Constructors 2445d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// ---------------------------------------------------------------------------------------- 2455d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 2465d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// Since the matrix code could become pretty big quickly, we don't inline most 2475d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// operations. 2485d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 2495d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate <typename T> 250caf2ca414f69d460c516e2370cf42bcf49178d95Romain GuyCONSTEXPR TMat22<T>::TMat22() { 2515d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy m_value[0] = col_type(1, 0); 2525d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy m_value[1] = col_type(0, 1); 2535d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 2545d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 2555d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate <typename T> 2565d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate <typename U> 257caf2ca414f69d460c516e2370cf42bcf49178d95Romain GuyCONSTEXPR TMat22<T>::TMat22(U v) { 2585d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy m_value[0] = col_type(v, 0); 2595d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy m_value[1] = col_type(0, v); 2605d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 2615d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 2625d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate<typename T> 2635d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate<typename U> 264caf2ca414f69d460c516e2370cf42bcf49178d95Romain GuyCONSTEXPR TMat22<T>::TMat22(const TVec2<U>& v) { 2655d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy m_value[0] = col_type(v.x, 0); 2665d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy m_value[1] = col_type(0, v.y); 2675d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 2685d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 2695d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// construct from 4 scalars. Note that the arrangement 2705d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// of values in the constructor is the transpose of the matrix 2715d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// notation. 2725d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate<typename T> 2735d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate < 2745d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typename A, typename B, 2755d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typename C, typename D> 276caf2ca414f69d460c516e2370cf42bcf49178d95Romain GuyCONSTEXPR TMat22<T>::TMat22( A m00, B m01, C m10, D m11) { 2775d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy m_value[0] = col_type(m00, m01); 2785d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy m_value[1] = col_type(m10, m11); 2795d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 2805d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 2815d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate <typename T> 2825d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate <typename U> 283caf2ca414f69d460c516e2370cf42bcf49178d95Romain GuyCONSTEXPR TMat22<T>::TMat22(const TMat22<U>& rhs) { 2845d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t col = 0; col < NUM_COLS; ++col) { 2855d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy m_value[col] = col_type(rhs[col]); 2865d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 2875d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 2885d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 2895d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// Construct from 2 column vectors. 2905d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate <typename T> 2915d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate <typename A, typename B> 292caf2ca414f69d460c516e2370cf42bcf49178d95Romain GuyCONSTEXPR TMat22<T>::TMat22(const TVec2<A>& v0, const TVec2<B>& v1) { 2935d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy m_value[0] = v0; 2945d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy m_value[1] = v1; 2955d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 2965d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 2975d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// Construct from raw array, in column-major form. 2985d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate <typename T> 2995d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate <typename U> 300caf2ca414f69d460c516e2370cf42bcf49178d95Romain GuyCONSTEXPR TMat22<T>::TMat22(U const* rawArray) { 3015d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t col = 0; col < NUM_COLS; ++col) { 3025d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t row = 0; row < NUM_ROWS; ++row) { 3035d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy m_value[col][row] = *rawArray++; 3045d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 3055d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 3065d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 3075d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 3085d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// ---------------------------------------------------------------------------------------- 3095d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// Arithmetic operators outside of class 3105d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// ---------------------------------------------------------------------------------------- 3115d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 3125d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy/* We use non-friend functions here to prevent the compiler from using 3135d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * implicit conversions, for instance of a scalar to a vector. The result would 3145d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * not be what the caller expects. 3155d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 3165d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Also note that the order of the arguments in the inner loop is important since 3175d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * it determines the output type (only relevant when T != U). 3185d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 3195d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 3205d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// matrix * column-vector, result is a vector of the same type than the input vector 3215d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate <typename T, typename U> 322caf2ca414f69d460c516e2370cf42bcf49178d95Romain GuyCONSTEXPR typename TMat22<U>::col_type PURE operator *(const TMat22<T>& lhs, const TVec2<U>& rhs) { 3235d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // Result is initialized to zero. 3245d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typename TMat22<U>::col_type result; 3255d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t col = 0; col < TMat22<T>::NUM_COLS; ++col) { 3265d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy result += lhs[col] * rhs[col]; 3275d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 3285d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return result; 3295d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 3305d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 3315d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// row-vector * matrix, result is a vector of the same type than the input vector 3325d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate <typename T, typename U> 333caf2ca414f69d460c516e2370cf42bcf49178d95Romain GuyCONSTEXPR typename TMat22<U>::row_type PURE operator *(const TVec2<U>& lhs, const TMat22<T>& rhs) { 3345d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typename TMat22<U>::row_type result(TMat22<U>::row_type::NO_INIT); 3355d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t col = 0; col < TMat22<T>::NUM_COLS; ++col) { 3365d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy result[col] = dot(lhs, rhs[col]); 3375d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 3385d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return result; 3395d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 3405d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 3415d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// matrix * scalar, result is a matrix of the same type than the input matrix 3425d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate<typename T, typename U> 3435d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyconstexpr typename std::enable_if<std::is_arithmetic<U>::value, TMat22<T>>::type PURE 3445d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyoperator*(TMat22<T> lhs, U rhs) { 3455d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lhs *= rhs; 3465d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 3475d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 3485d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// scalar * matrix, result is a matrix of the same type than the input matrix 3495d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate<typename T, typename U> 3505d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyconstexpr typename std::enable_if<std::is_arithmetic<U>::value, TMat22<T>>::type PURE 3515d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyoperator*(U lhs, const TMat22<T>& rhs) { 3525d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return rhs * lhs; 3535d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 3545d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 3555d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// ---------------------------------------------------------------------------------------- 3565d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 3575d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy/* FIXME: this should go into TMatSquareFunctions<> but for some reason 3585d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * BASE<T>::col_type is not accessible from there (???) 3595d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 3605d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate<typename T> 361caf2ca414f69d460c516e2370cf42bcf49178d95Romain GuyCONSTEXPR typename TMat22<T>::col_type PURE diag(const TMat22<T>& m) { 3625d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return matrix::diag(m); 3635d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 3645d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 3655d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} // namespace details 3665d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 3675d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// ---------------------------------------------------------------------------------------- 3685d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 3695d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytypedef details::TMat22<double> mat2d; 3705d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytypedef details::TMat22<float> mat2; 3715d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytypedef details::TMat22<float> mat2f; 3725d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 3735d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// ---------------------------------------------------------------------------------------- 3745d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} // namespace android 3755d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 3765d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#undef PURE 377caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#undef CONSTEXPR 378