diff options
author | Mathias Agopian <mathias@google.com> | 2013-09-01 21:35:36 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2013-09-03 16:38:49 -0700 |
commit | 1d4d8f94e2989b7c8667602304df9059d2701653 (patch) | |
tree | a0a7ab12d583a454f08af3f21a01b7bd7dabc07a /include/ui | |
parent | 9b5534b0e5e1510f56e6a2c58ad0816167603ebd (diff) | |
download | frameworks_native-1d4d8f94e2989b7c8667602304df9059d2701653.zip frameworks_native-1d4d8f94e2989b7c8667602304df9059d2701653.tar.gz frameworks_native-1d4d8f94e2989b7c8667602304df9059d2701653.tar.bz2 |
improve mat44 implementation
this will make it easier to create matrices of different sizes
Change-Id: I2c1771ba0823c42d737762e2dfc2cd47eb302767
Diffstat (limited to 'include/ui')
-rw-r--r-- | include/ui/TMatHelpers.h | 78 | ||||
-rw-r--r-- | include/ui/TVecHelpers.h | 103 | ||||
-rw-r--r-- | include/ui/mat4.h | 155 | ||||
-rw-r--r-- | include/ui/vec2.h | 8 | ||||
-rw-r--r-- | include/ui/vec3.h | 9 | ||||
-rw-r--r-- | include/ui/vec4.h | 10 |
6 files changed, 208 insertions, 155 deletions
diff --git a/include/ui/TMatHelpers.h b/include/ui/TMatHelpers.h index b778af0..cead10a 100644 --- a/include/ui/TMatHelpers.h +++ b/include/ui/TMatHelpers.h @@ -26,6 +26,7 @@ #include <stdint.h> #include <sys/types.h> +#include <math.h> #include <utils/Debug.h> #include <utils/String8.h> @@ -172,6 +173,83 @@ String8 asString(const MATRIX& m) { }; // namespace matrix // ------------------------------------------------------------------------------------- + +/* + * TMatProductOperators implements basic arithmetic and basic compound assignments + * operators on a vector of type BASE<T>. + * + * BASE only needs to implement operator[] and size(). + * By simply inheriting from TMatProductOperators<BASE, T> BASE will automatically + * get all the functionality here. + */ + +template <template<typename T> class BASE, typename T> +class TMatProductOperators { +public: + // multiply by a scalar + BASE<T>& operator *= (T v) { + BASE<T>& lhs(static_cast< BASE<T>& >(*this)); + for (size_t r=0 ; r<lhs.row_size() ; r++) { + lhs[r] *= v; + } + return lhs; + } + + // divide by a scalar + BASE<T>& operator /= (T v) { + BASE<T>& lhs(static_cast< BASE<T>& >(*this)); + for (size_t r=0 ; r<lhs.row_size() ; r++) { + lhs[r] /= v; + } + return lhs; + } + + // matrix * matrix, result is a matrix of the same type than the lhs matrix + template<typename U> + friend BASE<T> PURE operator *(const BASE<T>& lhs, const BASE<U>& rhs) { + return matrix::multiply<BASE<T> >(lhs, rhs); + } +}; + + +/* + * TMatSquareFunctions implements functions on a matrix of type BASE<T>. + * + * BASE only needs to implement: + * - operator[] + * - col_type + * - row_type + * - COL_SIZE + * - ROW_SIZE + * + * By simply inheriting from TMatSquareFunctions<BASE, T> BASE will automatically + * get all the functionality here. + */ + +template<template<typename U> class BASE, typename T> +class TMatSquareFunctions { +public: + /* + * NOTE: the functions below ARE NOT member methods. They are friend functions + * with they definition inlined with their declaration. This makes these + * template functions available to the compiler when (and only when) this class + * is instantiated, at which point they're only templated on the 2nd parameter + * (the first one, BASE<T> being known). + */ + friend BASE<T> PURE inverse(const BASE<T>& m) { return matrix::inverse(m); } + friend BASE<T> PURE transpose(const BASE<T>& m) { return matrix::transpose(m); } + friend T PURE trace(const BASE<T>& m) { return matrix::trace(m); } +}; + +template <template<typename T> class BASE, typename T> +class TMatDebug { +public: + String8 asString() const { + return matrix::asString(*this); + } +}; + +// ------------------------------------------------------------------------------------- }; // namespace android #undef PURE diff --git a/include/ui/TVecHelpers.h b/include/ui/TVecHelpers.h index 081c69c..bb7dbfc 100644 --- a/include/ui/TVecHelpers.h +++ b/include/ui/TVecHelpers.h @@ -57,16 +57,16 @@ struct Impersonator { }; /* - * TVecArithmeticOperators implements basic arithmetic and basic compound assignments + * TVec{Add|Product}Operators implements basic arithmetic and basic compound assignments * operators on a vector of type BASE<T>. * * BASE only needs to implement operator[] and size(). - * By simply inheriting from TVecArithmeticOperators<BASE, T> BASE will automatically + * By simply inheriting from TVec{Add|Product}Operators<BASE, T> BASE will automatically * get all the functionality here. */ template <template<typename T> class BASE, typename T> -class TVecArithmeticOperators { +class TVecAddOperators { public: /* compound assignment from a another vector of the same size but different * element type. @@ -87,42 +87,93 @@ public: } return rhs; } - template <typename OTHER> - BASE<T>& operator *= (const BASE<OTHER>& v) { + + /* compound assignment from a another vector of the same type. + * These operators can be used for implicit conversion and handle operations + * like "vector *= scalar" by letting the compiler implicitly convert a scalar + * to a vector (assuming the BASE<T> allows it). + */ + BASE<T>& operator += (const BASE<T>& v) { BASE<T>& rhs = static_cast<BASE<T>&>(*this); for (size_t i=0 ; i<BASE<T>::size() ; i++) { - rhs[i] *= v[i]; + rhs[i] += v[i]; } return rhs; } - template <typename OTHER> - BASE<T>& operator /= (const BASE<OTHER>& v) { + BASE<T>& operator -= (const BASE<T>& v) { BASE<T>& rhs = static_cast<BASE<T>&>(*this); for (size_t i=0 ; i<BASE<T>::size() ; i++) { - rhs[i] /= v[i]; + rhs[i] -= v[i]; } return rhs; } - /* compound assignment from a another vector of the same type. - * These operators can be used for implicit conversion and handle operations - * like "vector *= scalar" by letting the compiler implicitly convert a scalar - * to a vector (assuming the BASE<T> allows it). + /* + * NOTE: the functions below ARE NOT member methods. They are friend functions + * with they definition inlined with their declaration. This makes these + * template functions available to the compiler when (and only when) this class + * is instantiated, at which point they're only templated on the 2nd parameter + * (the first one, BASE<T> being known). */ - BASE<T>& operator += (const BASE<T>& v) { + + /* The operators below handle operation between vectors of the same side + * but of a different element type. + */ + template<typename RT> + friend inline + BASE<T> PURE operator +(const BASE<T>& lv, const BASE<RT>& rv) { + return BASE<T>(lv) += rv; + } + template<typename RT> + friend inline + BASE<T> PURE operator -(const BASE<T>& lv, const BASE<RT>& rv) { + return BASE<T>(lv) -= rv; + } + + /* The operators below (which are not templates once this class is instanced, + * i.e.: BASE<T> is known) can be used for implicit conversion on both sides. + * These handle operations like "vector * scalar" and "scalar * vector" by + * letting the compiler implicitly convert a scalar to a vector (assuming + * the BASE<T> allows it). + */ + friend inline + BASE<T> PURE operator +(const BASE<T>& lv, const BASE<T>& rv) { + return BASE<T>(lv) += rv; + } + friend inline + BASE<T> PURE operator -(const BASE<T>& lv, const BASE<T>& rv) { + return BASE<T>(lv) -= rv; + } +}; + +template <template<typename T> class BASE, typename T> +class TVecProductOperators { +public: + /* compound assignment from a another vector of the same size but different + * element type. + */ + template <typename OTHER> + BASE<T>& operator *= (const BASE<OTHER>& v) { BASE<T>& rhs = static_cast<BASE<T>&>(*this); for (size_t i=0 ; i<BASE<T>::size() ; i++) { - rhs[i] += v[i]; + rhs[i] *= v[i]; } return rhs; } - BASE<T>& operator -= (const BASE<T>& v) { + template <typename OTHER> + BASE<T>& operator /= (const BASE<OTHER>& v) { BASE<T>& rhs = static_cast<BASE<T>&>(*this); for (size_t i=0 ; i<BASE<T>::size() ; i++) { - rhs[i] -= v[i]; + rhs[i] /= v[i]; } return rhs; } + + /* compound assignment from a another vector of the same type. + * These operators can be used for implicit conversion and handle operations + * like "vector *= scalar" by letting the compiler implicitly convert a scalar + * to a vector (assuming the BASE<T> allows it). + */ BASE<T>& operator *= (const BASE<T>& v) { BASE<T>& rhs = static_cast<BASE<T>&>(*this); for (size_t i=0 ; i<BASE<T>::size() ; i++) { @@ -151,16 +202,6 @@ public: */ template<typename RT> friend inline - BASE<T> PURE operator +(const BASE<T>& lv, const BASE<RT>& rv) { - return BASE<T>(lv) += rv; - } - template<typename RT> - friend inline - BASE<T> PURE operator -(const BASE<T>& lv, const BASE<RT>& rv) { - return BASE<T>(lv) -= rv; - } - template<typename RT> - friend inline BASE<T> PURE operator *(const BASE<T>& lv, const BASE<RT>& rv) { return BASE<T>(lv) *= rv; } @@ -177,14 +218,6 @@ public: * the BASE<T> allows it). */ friend inline - BASE<T> PURE operator +(const BASE<T>& lv, const BASE<T>& rv) { - return BASE<T>(lv) += rv; - } - friend inline - BASE<T> PURE operator -(const BASE<T>& lv, const BASE<T>& rv) { - return BASE<T>(lv) -= rv; - } - friend inline BASE<T> PURE operator *(const BASE<T>& lv, const BASE<T>& rv) { return BASE<T>(lv) *= rv; } diff --git a/include/ui/mat4.h b/include/ui/mat4.h index 08a67c7..d9647cc 100644 --- a/include/ui/mat4.h +++ b/include/ui/mat4.h @@ -33,7 +33,11 @@ namespace android { template <typename T> class tmat44 : public TVecUnaryOperators<tmat44, T>, - public TVecComparisonOperators<tmat44, T> + public TVecComparisonOperators<tmat44, T>, + public TVecAddOperators<tmat44, T>, + public TMatProductOperators<tmat44, T>, + public TMatSquareFunctions<tmat44, T>, + public TMatDebug<tmat44, T> { public: enum no_init { NO_INIT }; @@ -108,6 +112,17 @@ public: template <typename A, typename B, typename C, typename D> tmat44(const tvec4<A>& v0, const tvec4<B>& v1, const tvec4<C>& v2, const tvec4<D>& v3); + // construct from 16 scalars + template < + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, + typename I, typename J, typename K, typename L, + typename M, typename N, typename O, typename P> + tmat44( A m00, B m01, C m02, D m03, + E m10, F m11, G m12, H m13, + I m20, J m21, K m22, L m23, + M m30, N m31, O m32, P m33); + // construct from a C array template <typename U> explicit tmat44(U const* rawArray); @@ -131,33 +146,6 @@ public: template <typename A, typename B> static tmat44 rotate(A radian, const tvec3<B>& about); - - - /* - * Compound assignment arithmetic operators - */ - - // add another matrix of the same size - template <typename U> - tmat44& operator += (const tmat44<U>& v); - - // subtract another matrix of the same size - template <typename U> - tmat44& operator -= (const tmat44<U>& v); - - // multiply by a scalar - template <typename U> - tmat44& operator *= (U v); - - // divide by a scalar - template <typename U> - tmat44& operator /= (U v); - - /* - * debugging - */ - - String8 asString() const; }; // ---------------------------------------------------------------------------------------- @@ -195,6 +183,23 @@ tmat44<T>::tmat44(const tvec4<U>& v) { mValue[3] = col_type(0,0,0,v.w); } +// construct from 16 scalars +template<typename T> +template < + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, + typename I, typename J, typename K, typename L, + typename M, typename N, typename O, typename P> +tmat44<T>::tmat44( A m00, B m01, C m02, D m03, + E m10, F m11, G m12, H m13, + I m20, J m21, K m22, L m23, + M m30, N m31, O m32, P m33) { + mValue[0] = col_type(m00, m01, m02, m03); + mValue[1] = col_type(m10, m11, m12, m13); + mValue[2] = col_type(m20, m21, m22, m23); + mValue[3] = col_type(m30, m31, m32, m33); +} + template <typename T> template <typename U> tmat44<T>::tmat44(const tmat44<U>& rhs) { @@ -320,42 +325,6 @@ tmat44<T> tmat44<T>::rotate(A radian, const tvec3<B>& about) { } // ---------------------------------------------------------------------------------------- -// Compound assignment arithmetic operators -// ---------------------------------------------------------------------------------------- - -template <typename T> -template <typename U> -tmat44<T>& tmat44<T>::operator += (const tmat44<U>& v) { - for (size_t r=0 ; r<row_size() ; r++) - mValue[r] += v[r]; - return *this; -} - -template <typename T> -template <typename U> -tmat44<T>& tmat44<T>::operator -= (const tmat44<U>& v) { - for (size_t r=0 ; r<row_size() ; r++) - mValue[r] -= v[r]; - return *this; -} - -template <typename T> -template <typename U> -tmat44<T>& tmat44<T>::operator *= (U v) { - for (size_t r=0 ; r<row_size() ; r++) - mValue[r] *= v; - return *this; -} - -template <typename T> -template <typename U> -tmat44<T>& tmat44<T>::operator /= (U v) { - for (size_t r=0 ; r<row_size() ; r++) - mValue[r] /= v; - return *this; -} - -// ---------------------------------------------------------------------------------------- // Arithmetic operators outside of class // ---------------------------------------------------------------------------------------- @@ -367,24 +336,6 @@ tmat44<T>& tmat44<T>::operator /= (U v) { * it determines the output type (only relevant when T != U). */ -// matrix + matrix, result is a matrix of the same type than the lhs matrix -template <typename T, typename U> -tmat44<T> PURE operator +(const tmat44<T>& lhs, const tmat44<U>& rhs) { - tmat44<T> result(tmat44<T>::NO_INIT); - for (size_t r=0 ; r<tmat44<T>::row_size() ; r++) - result[r] = lhs[r] + rhs[r]; - return result; -} - -// matrix - matrix, result is a matrix of the same type than the lhs matrix -template <typename T, typename U> -tmat44<T> PURE operator -(const tmat44<T>& lhs, const tmat44<U>& rhs) { - tmat44<T> result(tmat44<T>::NO_INIT); - for (size_t r=0 ; r<tmat44<T>::row_size() ; r++) - result[r] = lhs[r] - rhs[r]; - return result; -} - // matrix * vector, result is a vector of the same type than the input vector template <typename T, typename U> typename tmat44<U>::col_type PURE operator *(const tmat44<T>& lv, const tvec4<U>& rv) { @@ -421,47 +372,17 @@ tmat44<T> PURE operator *(U rv, const tmat44<T>& lv) { return result; } -// matrix * matrix, result is a matrix of the same type than the lhs matrix -template <typename T, typename U> -tmat44<T> PURE operator *(const tmat44<T>& lhs, const tmat44<U>& rhs) { - return matrix::multiply< tmat44<T> >(lhs, rhs); -} - // ---------------------------------------------------------------------------------------- -// Functions -// ---------------------------------------------------------------------------------------- - -// inverse a matrix -template <typename T> -tmat44<T> PURE inverse(const tmat44<T>& m) { - return matrix::inverse(m); -} - -template <typename T> -tmat44<T> PURE transpose(const tmat44<T>& m) { - return matrix::transpose(m); -} - -template <typename T> -T PURE trace(const tmat44<T>& m) { - return matrix::trace(m); -} -template <typename T> -tvec4<T> PURE diag(const tmat44<T>& m) { +/* FIXME: this should go into TMatSquareFunctions<> but for some reason + * BASE<T>::col_type is not accessible from there (???) + */ +template<typename T> +typename tmat44<T>::col_type PURE diag(const tmat44<T>& m) { return matrix::diag(m); } // ---------------------------------------------------------------------------------------- -// Debugging -// ---------------------------------------------------------------------------------------- - -template <typename T> -String8 tmat44<T>::asString() const { - return matrix::asString(*this); -} - -// ---------------------------------------------------------------------------------------- typedef tmat44<float> mat4; diff --git a/include/ui/vec2.h b/include/ui/vec2.h index b4edfc6..c31d0e4 100644 --- a/include/ui/vec2.h +++ b/include/ui/vec2.h @@ -27,7 +27,8 @@ namespace android { // ------------------------------------------------------------------------------------- template <typename T> -class tvec2 : public TVecArithmeticOperators<tvec2, T>, +class tvec2 : public TVecProductOperators<tvec2, T>, + public TVecAddOperators<tvec2, T>, public TVecUnaryOperators<tvec2, T>, public TVecComparisonOperators<tvec2, T>, public TVecFunctions<tvec2, T> @@ -73,6 +74,11 @@ public: template<typename A> explicit tvec2(const tvec2<A>& v) : x(v.x), y(v.y) { } + + template<typename A> + tvec2(const Impersonator< tvec2<A> >& v) + : x(((const tvec2<A>&)v).x), + y(((const tvec2<A>&)v).y) { } }; // ---------------------------------------------------------------------------------------- diff --git a/include/ui/vec3.h b/include/ui/vec3.h index 591b8b2..dde59a9 100644 --- a/include/ui/vec3.h +++ b/include/ui/vec3.h @@ -26,7 +26,8 @@ namespace android { // ------------------------------------------------------------------------------------- template <typename T> -class tvec3 : public TVecArithmeticOperators<tvec3, T>, +class tvec3 : public TVecProductOperators<tvec3, T>, + public TVecAddOperators<tvec3, T>, public TVecUnaryOperators<tvec3, T>, public TVecComparisonOperators<tvec3, T>, public TVecFunctions<tvec3, T> @@ -78,6 +79,12 @@ public: template<typename A> explicit tvec3(const tvec3<A>& v) : x(v.x), y(v.y), z(v.z) { } + template<typename A> + tvec3(const Impersonator< tvec3<A> >& v) + : x(((const tvec3<A>&)v).x), + y(((const tvec3<A>&)v).y), + z(((const tvec3<A>&)v).z) { } + template<typename A, typename B> tvec3(const Impersonator< tvec2<A> >& v, B z) : x(((const tvec2<A>&)v).x), diff --git a/include/ui/vec4.h b/include/ui/vec4.h index 798382d..e03d331 100644 --- a/include/ui/vec4.h +++ b/include/ui/vec4.h @@ -26,7 +26,8 @@ namespace android { // ------------------------------------------------------------------------------------- template <typename T> -class tvec4 : public TVecArithmeticOperators<tvec4, T>, +class tvec4 : public TVecProductOperators<tvec4, T>, + public TVecAddOperators<tvec4, T>, public TVecUnaryOperators<tvec4, T>, public TVecComparisonOperators<tvec4, T>, public TVecFunctions<tvec4, T> @@ -85,6 +86,13 @@ public: template<typename A> explicit tvec4(const tvec4<A>& v) : x(v.x), y(v.y), z(v.z), w(v.w) { } + template<typename A> + tvec4(const Impersonator< tvec4<A> >& v) + : x(((const tvec4<A>&)v).x), + y(((const tvec4<A>&)v).y), + z(((const tvec4<A>&)v).z), + w(((const tvec4<A>&)v).w) { } + template<typename A, typename B> tvec4(const Impersonator< tvec3<A> >& v, B w) : x(((const tvec3<A>&)v).x), |