improve mat44 implementation
this will make it easier to create matrices of different sizes Change-Id: I2c1771ba0823c42d737762e2dfc2cd47eb302767
This commit is contained in:
parent
9b5534b0e5
commit
1d4d8f94e2
@ -26,6 +26,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <math.h>
|
||||
#include <utils/Debug.h>
|
||||
#include <utils/String8.h>
|
||||
|
||||
@ -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<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
|
||||
|
||||
|
@ -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,22 +87,6 @@ public:
|
||||
}
|
||||
return rhs;
|
||||
}
|
||||
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];
|
||||
}
|
||||
return rhs;
|
||||
}
|
||||
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];
|
||||
}
|
||||
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<T> being known).
|
||||
*/
|
||||
|
||||
/* 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];
|
||||
}
|
||||
return rhs;
|
||||
}
|
||||
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];
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -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) {
|
||||
@ -319,42 +324,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,46 +372,16 @@ 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;
|
||||
|
@ -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) { }
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user