From 1d4d8f94e2989b7c8667602304df9059d2701653 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Sun, 1 Sep 2013 21:35:36 -0700 Subject: [PATCH] improve mat44 implementation this will make it easier to create matrices of different sizes Change-Id: I2c1771ba0823c42d737762e2dfc2cd47eb302767 --- include/ui/TMatHelpers.h | 78 ++++++++++++++++++++ include/ui/TVecHelpers.h | 107 +++++++++++++++++---------- include/ui/mat4.h | 155 ++++++++++----------------------------- include/ui/vec2.h | 8 +- include/ui/vec3.h | 9 ++- include/ui/vec4.h | 10 ++- 6 files changed, 210 insertions(+), 157 deletions(-) diff --git a/include/ui/TMatHelpers.h b/include/ui/TMatHelpers.h index b778af0ff..cead10a8c 100644 --- a/include/ui/TMatHelpers.h +++ b/include/ui/TMatHelpers.h @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -171,6 +172,83 @@ String8 asString(const MATRIX& m) { }; // namespace matrix +// ------------------------------------------------------------------------------------- + +/* + * TMatProductOperators implements basic arithmetic and basic compound assignments + * operators on a vector of type BASE. + * + * BASE only needs to implement operator[] and size(). + * By simply inheriting from TMatProductOperators BASE will automatically + * get all the functionality here. + */ + +template class BASE, typename T> +class TMatProductOperators { +public: + // multiply by a scalar + BASE& operator *= (T v) { + BASE& lhs(static_cast< BASE& >(*this)); + for (size_t r=0 ; r& operator /= (T v) { + BASE& lhs(static_cast< BASE& >(*this)); + for (size_t r=0 ; r + friend BASE PURE operator *(const BASE& lhs, const BASE& rhs) { + return matrix::multiply >(lhs, rhs); + } +}; + + +/* + * TMatSquareFunctions implements functions on a matrix of type BASE. + * + * BASE only needs to implement: + * - operator[] + * - col_type + * - row_type + * - COL_SIZE + * - ROW_SIZE + * + * By simply inheriting from TMatSquareFunctions BASE will automatically + * get all the functionality here. + */ + +template 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 being known). + */ + friend BASE PURE inverse(const BASE& m) { return matrix::inverse(m); } + friend BASE PURE transpose(const BASE& m) { return matrix::transpose(m); } + friend T PURE trace(const BASE& m) { return matrix::trace(m); } +}; + +template class BASE, typename T> +class TMatDebug { +public: + String8 asString() const { + return matrix::asString(*this); + } +}; + // ------------------------------------------------------------------------------------- }; // namespace android diff --git a/include/ui/TVecHelpers.h b/include/ui/TVecHelpers.h index 081c69ce4..bb7dbfc2b 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. * * BASE only needs to implement operator[] and size(). - * By simply inheriting from TVecArithmeticOperators BASE will automatically + * By simply inheriting from TVec{Add|Product}Operators BASE will automatically * get all the functionality here. */ template class BASE, typename T> -class TVecArithmeticOperators { +class TVecAddOperators { public: /* compound assignment from a another vector of the same size but different * element type. @@ -87,22 +87,6 @@ public: } return rhs; } - template - BASE& operator *= (const BASE& v) { - BASE& rhs = static_cast&>(*this); - for (size_t i=0 ; i::size() ; i++) { - rhs[i] *= v[i]; - } - return rhs; - } - template - BASE& operator /= (const BASE& v) { - BASE& rhs = static_cast&>(*this); - for (size_t i=0 ; i::size() ; 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 @@ -123,6 +107,73 @@ public: } return rhs; } + + /* + * 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 being known). + */ + + /* The operators below handle operation between vectors of the same side + * but of a different element type. + */ + template + friend inline + BASE PURE operator +(const BASE& lv, const BASE& rv) { + return BASE(lv) += rv; + } + template + friend inline + BASE PURE operator -(const BASE& lv, const BASE& rv) { + return BASE(lv) -= rv; + } + + /* The operators below (which are not templates once this class is instanced, + * i.e.: BASE 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 allows it). + */ + friend inline + BASE PURE operator +(const BASE& lv, const BASE& rv) { + return BASE(lv) += rv; + } + friend inline + BASE PURE operator -(const BASE& lv, const BASE& rv) { + return BASE(lv) -= rv; + } +}; + +template class BASE, typename T> +class TVecProductOperators { +public: + /* compound assignment from a another vector of the same size but different + * element type. + */ + template + BASE& operator *= (const BASE& v) { + BASE& rhs = static_cast&>(*this); + for (size_t i=0 ; i::size() ; i++) { + rhs[i] *= v[i]; + } + return rhs; + } + template + BASE& operator /= (const BASE& v) { + BASE& rhs = static_cast&>(*this); + for (size_t i=0 ; i::size() ; 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 allows it). + */ BASE& operator *= (const BASE& v) { BASE& rhs = static_cast&>(*this); for (size_t i=0 ; i::size() ; i++) { @@ -151,16 +202,6 @@ public: */ template friend inline - BASE PURE operator +(const BASE& lv, const BASE& rv) { - return BASE(lv) += rv; - } - template - friend inline - BASE PURE operator -(const BASE& lv, const BASE& rv) { - return BASE(lv) -= rv; - } - template - friend inline BASE PURE operator *(const BASE& lv, const BASE& rv) { return BASE(lv) *= rv; } @@ -177,14 +218,6 @@ public: * the BASE allows it). */ friend inline - BASE PURE operator +(const BASE& lv, const BASE& rv) { - return BASE(lv) += rv; - } - friend inline - BASE PURE operator -(const BASE& lv, const BASE& rv) { - return BASE(lv) -= rv; - } - friend inline BASE PURE operator *(const BASE& lv, const BASE& rv) { return BASE(lv) *= rv; } diff --git a/include/ui/mat4.h b/include/ui/mat4.h index 08a67c7a1..d9647cc1a 100644 --- a/include/ui/mat4.h +++ b/include/ui/mat4.h @@ -33,7 +33,11 @@ namespace android { template class tmat44 : public TVecUnaryOperators, - public TVecComparisonOperators + public TVecComparisonOperators, + public TVecAddOperators, + public TMatProductOperators, + public TMatSquareFunctions, + public TMatDebug { public: enum no_init { NO_INIT }; @@ -108,6 +112,17 @@ public: template tmat44(const tvec4& v0, const tvec4& v1, const tvec4& v2, const tvec4& 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 explicit tmat44(U const* rawArray); @@ -131,33 +146,6 @@ public: template static tmat44 rotate(A radian, const tvec3& about); - - - /* - * Compound assignment arithmetic operators - */ - - // add another matrix of the same size - template - tmat44& operator += (const tmat44& v); - - // subtract another matrix of the same size - template - tmat44& operator -= (const tmat44& v); - - // multiply by a scalar - template - tmat44& operator *= (U v); - - // divide by a scalar - template - tmat44& operator /= (U v); - - /* - * debugging - */ - - String8 asString() const; }; // ---------------------------------------------------------------------------------------- @@ -195,6 +183,23 @@ tmat44::tmat44(const tvec4& v) { mValue[3] = col_type(0,0,0,v.w); } +// construct from 16 scalars +template +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::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 template tmat44::tmat44(const tmat44& rhs) { @@ -319,42 +324,6 @@ tmat44 tmat44::rotate(A radian, const tvec3& about) { } } -// ---------------------------------------------------------------------------------------- -// Compound assignment arithmetic operators -// ---------------------------------------------------------------------------------------- - -template -template -tmat44& tmat44::operator += (const tmat44& v) { - for (size_t r=0 ; r -template -tmat44& tmat44::operator -= (const tmat44& v) { - for (size_t r=0 ; r -template -tmat44& tmat44::operator *= (U v) { - for (size_t r=0 ; r -template -tmat44& tmat44::operator /= (U v) { - for (size_t r=0 ; r& tmat44::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 -tmat44 PURE operator +(const tmat44& lhs, const tmat44& rhs) { - tmat44 result(tmat44::NO_INIT); - for (size_t r=0 ; r::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 -tmat44 PURE operator -(const tmat44& lhs, const tmat44& rhs) { - tmat44 result(tmat44::NO_INIT); - for (size_t r=0 ; r::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 tmat44::col_type PURE operator *(const tmat44& lv, const tvec4& rv) { @@ -421,46 +372,16 @@ tmat44 PURE operator *(U rv, const tmat44& lv) { return result; } -// matrix * matrix, result is a matrix of the same type than the lhs matrix -template -tmat44 PURE operator *(const tmat44& lhs, const tmat44& rhs) { - return matrix::multiply< tmat44 >(lhs, rhs); -} - -// ---------------------------------------------------------------------------------------- -// Functions // ---------------------------------------------------------------------------------------- -// inverse a matrix -template -tmat44 PURE inverse(const tmat44& m) { - return matrix::inverse(m); -} - -template -tmat44 PURE transpose(const tmat44& m) { - return matrix::transpose(m); -} - -template -T PURE trace(const tmat44& m) { - return matrix::trace(m); -} - -template -tvec4 PURE diag(const tmat44& m) { +/* FIXME: this should go into TMatSquareFunctions<> but for some reason + * BASE::col_type is not accessible from there (???) + */ +template +typename tmat44::col_type PURE diag(const tmat44& m) { return matrix::diag(m); } -// ---------------------------------------------------------------------------------------- -// Debugging -// ---------------------------------------------------------------------------------------- - -template -String8 tmat44::asString() const { - return matrix::asString(*this); -} - // ---------------------------------------------------------------------------------------- typedef tmat44 mat4; diff --git a/include/ui/vec2.h b/include/ui/vec2.h index b4edfc67d..c31d0e43e 100644 --- a/include/ui/vec2.h +++ b/include/ui/vec2.h @@ -27,7 +27,8 @@ namespace android { // ------------------------------------------------------------------------------------- template -class tvec2 : public TVecArithmeticOperators, +class tvec2 : public TVecProductOperators, + public TVecAddOperators, public TVecUnaryOperators, public TVecComparisonOperators, public TVecFunctions @@ -73,6 +74,11 @@ public: template explicit tvec2(const tvec2& v) : x(v.x), y(v.y) { } + + template + tvec2(const Impersonator< tvec2 >& v) + : x(((const tvec2&)v).x), + y(((const tvec2&)v).y) { } }; // ---------------------------------------------------------------------------------------- diff --git a/include/ui/vec3.h b/include/ui/vec3.h index 591b8b284..dde59a96f 100644 --- a/include/ui/vec3.h +++ b/include/ui/vec3.h @@ -26,7 +26,8 @@ namespace android { // ------------------------------------------------------------------------------------- template -class tvec3 : public TVecArithmeticOperators, +class tvec3 : public TVecProductOperators, + public TVecAddOperators, public TVecUnaryOperators, public TVecComparisonOperators, public TVecFunctions @@ -78,6 +79,12 @@ public: template explicit tvec3(const tvec3& v) : x(v.x), y(v.y), z(v.z) { } + template + tvec3(const Impersonator< tvec3 >& v) + : x(((const tvec3&)v).x), + y(((const tvec3&)v).y), + z(((const tvec3&)v).z) { } + template tvec3(const Impersonator< tvec2 >& v, B z) : x(((const tvec2&)v).x), diff --git a/include/ui/vec4.h b/include/ui/vec4.h index 798382d2b..e03d331fb 100644 --- a/include/ui/vec4.h +++ b/include/ui/vec4.h @@ -26,7 +26,8 @@ namespace android { // ------------------------------------------------------------------------------------- template -class tvec4 : public TVecArithmeticOperators, +class tvec4 : public TVecProductOperators, + public TVecAddOperators, public TVecUnaryOperators, public TVecComparisonOperators, public TVecFunctions @@ -85,6 +86,13 @@ public: template explicit tvec4(const tvec4& v) : x(v.x), y(v.y), z(v.z), w(v.w) { } + template + tvec4(const Impersonator< tvec4 >& v) + : x(((const tvec4&)v).x), + y(((const tvec4&)v).y), + z(((const tvec4&)v).z), + w(((const tvec4&)v).w) { } + template tvec4(const Impersonator< tvec3 >& v, B w) : x(((const tvec3&)v).x),