vector and matrix classes for graphics use
- this implements vec2, vec3, vec4, which are float vectors
of size 2, 3 and 4 respectively.
the code allows easy instantiation of vectors of a different
type via the tvec{2|3|4}<T> template classes.
- this also implements mat4 which is a float 4x4 matrix. the
tmat44<T> template class allows easy instantiation of a
4x4 matrix of a different value_type.
The vector types have some minimal support for the
glsl style swizzled access; for instance:
vec4 u;
vec3 v = u.xyz;
only .x, .xy, .xyz and their .stpq / .rgba equivalent are
supported.
most operators are supported on both vector and matrices:
arithmetic, unary, compound assignment and comparison
(bit-wise operators NOT supported).
- operations available on vectors include:
dot, length, distance, normalize and cross
- operations available on matrices include:
transpose, inverse, trace
- and a few utilities to create matrices:
ortho, frustum, lookAt
Change-Id: I64add89ae90fa78d3f2f59985b63495575378635
diff --git a/include/ui/TMatHelpers.h b/include/ui/TMatHelpers.h
new file mode 100644
index 0000000..b778af0
--- /dev/null
+++ b/include/ui/TMatHelpers.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TMAT_IMPLEMENTATION
+#error "Don't include TMatHelpers.h directly. use ui/mat*.h instead"
+#else
+#undef TMAT_IMPLEMENTATION
+#endif
+
+
+#ifndef UI_TMAT_HELPERS_H
+#define UI_TMAT_HELPERS_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Debug.h>
+#include <utils/String8.h>
+
+#define PURE __attribute__((pure))
+
+namespace android {
+// -------------------------------------------------------------------------------------
+
+/*
+ * No user serviceable parts here.
+ *
+ * Don't use this file directly, instead include ui/mat*.h
+ */
+
+
+/*
+ * Matrix utilities
+ */
+
+namespace matrix {
+
+inline int PURE transpose(int v) { return v; }
+inline float PURE transpose(float v) { return v; }
+inline double PURE transpose(double v) { return v; }
+
+inline int PURE trace(int v) { return v; }
+inline float PURE trace(float v) { return v; }
+inline double PURE trace(double v) { return v; }
+
+template<typename MATRIX>
+MATRIX PURE inverse(const MATRIX& src) {
+
+ COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::COL_SIZE == MATRIX::ROW_SIZE );
+
+ typename MATRIX::value_type t;
+ const size_t N = MATRIX::col_size();
+ size_t swap;
+ MATRIX tmp(src);
+ MATRIX inverse(1);
+
+ for (size_t i=0 ; i<N ; i++) {
+ // look for largest element in column
+ swap = i;
+ for (size_t j=i+1 ; j<N ; j++) {
+ if (fabs(tmp[j][i]) > fabs(tmp[i][i])) {
+ swap = j;
+ }
+ }
+
+ if (swap != i) {
+ /* swap rows. */
+ for (size_t k=0 ; k<N ; k++) {
+ t = tmp[i][k];
+ tmp[i][k] = tmp[swap][k];
+ tmp[swap][k] = t;
+
+ t = inverse[i][k];
+ inverse[i][k] = inverse[swap][k];
+ inverse[swap][k] = t;
+ }
+ }
+
+ t = 1 / tmp[i][i];
+ for (size_t k=0 ; k<N ; k++) {
+ tmp[i][k] *= t;
+ inverse[i][k] *= t;
+ }
+ for (size_t j=0 ; j<N ; j++) {
+ if (j != i) {
+ t = tmp[j][i];
+ for (size_t k=0 ; k<N ; k++) {
+ tmp[j][k] -= tmp[i][k] * t;
+ inverse[j][k] -= inverse[i][k] * t;
+ }
+ }
+ }
+ }
+ return inverse;
+}
+
+template<typename MATRIX_R, typename MATRIX_A, typename MATRIX_B>
+MATRIX_R PURE multiply(const MATRIX_A& lhs, const MATRIX_B& rhs) {
+ // pre-requisite:
+ // lhs : D columns, R rows
+ // rhs : C columns, D rows
+ // res : C columns, R rows
+
+ COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_A::ROW_SIZE == MATRIX_B::COL_SIZE );
+ COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_R::ROW_SIZE == MATRIX_B::ROW_SIZE );
+ COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_R::COL_SIZE == MATRIX_A::COL_SIZE );
+
+ MATRIX_R res(MATRIX_R::NO_INIT);
+ for (size_t r=0 ; r<MATRIX_R::row_size() ; r++) {
+ res[r] = lhs * rhs[r];
+ }
+ return res;
+}
+
+// transpose. this handles matrices of matrices
+template <typename MATRIX>
+MATRIX PURE transpose(const MATRIX& m) {
+ // for now we only handle square matrix transpose
+ COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE );
+ MATRIX result(MATRIX::NO_INIT);
+ for (size_t r=0 ; r<MATRIX::row_size() ; r++)
+ for (size_t c=0 ; c<MATRIX::col_size() ; c++)
+ result[c][r] = transpose(m[r][c]);
+ return result;
+}
+
+// trace. this handles matrices of matrices
+template <typename MATRIX>
+typename MATRIX::value_type PURE trace(const MATRIX& m) {
+ COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE );
+ typename MATRIX::value_type result(0);
+ for (size_t r=0 ; r<MATRIX::row_size() ; r++)
+ result += trace(m[r][r]);
+ return result;
+}
+
+// trace. this handles matrices of matrices
+template <typename MATRIX>
+typename MATRIX::col_type PURE diag(const MATRIX& m) {
+ COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE );
+ typename MATRIX::col_type result(MATRIX::col_type::NO_INIT);
+ for (size_t r=0 ; r<MATRIX::row_size() ; r++)
+ result[r] = m[r][r];
+ return result;
+}
+
+template <typename MATRIX>
+String8 asString(const MATRIX& m) {
+ String8 s;
+ for (size_t c=0 ; c<MATRIX::col_size() ; c++) {
+ s.append("| ");
+ for (size_t r=0 ; r<MATRIX::row_size() ; r++) {
+ s.appendFormat("%7.2f ", m[r][c]);
+ }
+ s.append("|\n");
+ }
+ return s;
+}
+
+}; // namespace matrix
+
+// -------------------------------------------------------------------------------------
+}; // namespace android
+
+#undef PURE
+
+#endif /* UI_TMAT_HELPERS_H */