From 73eabe3b11ced43baea0551f025d5b36c8426cda Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Mon, 19 Sep 2016 22:55:42 +0200 Subject: [PATCH] Upgraded SimpleMath, added basic camera controls to the testmodule --- src/Globals.h | 7 + src/SimpleMath/README | 10 + src/SimpleMath/SimpleMath.h | 4 + src/SimpleMath/SimpleMath.h.orig | 24 + src/SimpleMath/SimpleMathBlock.h.orig | 220 +++++++++ src/SimpleMath/SimpleMathDynamic.h | 98 ++++ src/SimpleMath/SimpleMathDynamic.h.orig | 619 ++++++++++++++++++++++++ src/SimpleMath/SimpleMathFixed.h | 55 ++- src/SimpleMath/SimpleMathQR.h | 2 +- src/TestModule.cc | 63 ++- src/main.cc | 95 +--- 11 files changed, 1110 insertions(+), 87 deletions(-) create mode 100644 src/Globals.h create mode 100644 src/SimpleMath/README create mode 100644 src/SimpleMath/SimpleMath.h.orig create mode 100644 src/SimpleMath/SimpleMathBlock.h.orig create mode 100644 src/SimpleMath/SimpleMathDynamic.h.orig diff --git a/src/Globals.h b/src/Globals.h new file mode 100644 index 0000000..6559a1a --- /dev/null +++ b/src/Globals.h @@ -0,0 +1,7 @@ +#pragma once + +struct Renderer; +extern Renderer* gRenderer; + +struct GLFWwindow; +extern GLFWwindow* gWindow; diff --git a/src/SimpleMath/README b/src/SimpleMath/README new file mode 100644 index 0000000..e49e343 --- /dev/null +++ b/src/SimpleMath/README @@ -0,0 +1,10 @@ +This is a highly inefficient math library. It was conceived by Martin +Felis while he was waiting for code to +compile which used a highly efficient math library. + +It is intended to be used as a fast compiling substitute for the +blazingly fast Eigen3 http://eigen.tuxfamily.org/index.php?title=Main_Page +library and tries to mimic its API to a certain extent. + +Feel free to use it wherever you like. However, no guarantees are given +that this code does what it says it would. diff --git a/src/SimpleMath/SimpleMath.h b/src/SimpleMath/SimpleMath.h index 568dc66..2e36ff2 100644 --- a/src/SimpleMath/SimpleMath.h +++ b/src/SimpleMath/SimpleMath.h @@ -22,6 +22,10 @@ typedef SimpleMath::Fixed::Matrix Matrix33f; typedef SimpleMath::Fixed::Matrix Matrix44f; typedef SimpleMath::Dynamic::Matrix VectorNd; +typedef SimpleMath::Dynamic::Matrix MatrixNd; + +typedef SimpleMath::Dynamic::Matrix VectorNf; +typedef SimpleMath::Dynamic::Matrix MatrixNNf; } diff --git a/src/SimpleMath/SimpleMath.h.orig b/src/SimpleMath/SimpleMath.h.orig new file mode 100644 index 0000000..4fd753f --- /dev/null +++ b/src/SimpleMath/SimpleMath.h.orig @@ -0,0 +1,24 @@ +#ifndef _SIMPLEMATH_H +#define _SIMPLEMATH_H + +#include "SimpleMathFixed.h" +#include "SimpleMathDynamic.h" +#include "SimpleMathMixed.h" +#include "SimpleMathQR.h" +#include "SimpleMathCommaInitializer.h" + +typedef SimpleMath::Fixed::Matrix Vector3i; + +typedef SimpleMath::Fixed::Matrix Vector3d; +typedef SimpleMath::Fixed::Matrix Matrix33d; + +typedef SimpleMath::Fixed::Matrix Vector4d; + +typedef SimpleMath::Fixed::Matrix Vector3f; +typedef SimpleMath::Fixed::Matrix Vector4f; +typedef SimpleMath::Fixed::Matrix Matrix33f; +typedef SimpleMath::Fixed::Matrix Matrix44f; + +typedef SimpleMath::Dynamic::Matrix VectorNd; + +#endif /* _SIMPLEMATH_H */ diff --git a/src/SimpleMath/SimpleMathBlock.h.orig b/src/SimpleMath/SimpleMathBlock.h.orig new file mode 100644 index 0000000..93753a1 --- /dev/null +++ b/src/SimpleMath/SimpleMathBlock.h.orig @@ -0,0 +1,220 @@ +/** + * This is a highly inefficient math library. It was conceived by Martin + * Felis while he was compiling code + * that uses a highly efficient math library. + * + * It is intended to be used as a fast compiling substitute for the + * blazingly fast Eigen3 library and tries to mimic its API to a certain + * extend. + * + * Feel free to use it wherever you like. However, no guarantees are given + * that this code does what it says it would. + */ + +#ifndef SIMPLEMATHBLOCK_H +#define SIMPLEMATHBLOCK_H + +#include +#include +#include +#include + +#include "compileassert.h" + +// #include "SimpleMathQR.h" + +/** \brief Namespace for a highly inefficient math library + * + */ +namespace SimpleMath { + +/** \brief Namespace for fixed size elements + */ +// forward declaration +template +class Matrix; + +template +class Block { + public: + typedef val_type value_type; + + Block() : + mParentRows(0), + mParentCols(0), + mParentRowStart(0), + mParentColStart(0) + { } + Block (const matrix_type &matrix, const unsigned int row_start, const unsigned int col_start, const unsigned int row_count, const unsigned int col_count) : + mParentRows (matrix.rows()), + mParentCols (matrix.cols()), + mParentRowStart (row_start), + mParentColStart (col_start), + mRowCount (row_count), + mColCount (col_count), + mTransposed (false) { + assert (mParentRows >= mParentRowStart + mRowCount); + assert (mParentCols >= mParentColStart + mColCount); + + // without the following line we could not create blocks from const + // matrices + mParentMatrix = const_cast(&matrix); + } + + // copy data from the other block into this + Block& operator=(const Block &other) { + if (this != &other) { + if (mRowCount != other.rows() || mColCount != other.cols()) { + std::cerr << "Error: cannot assign blocks of different size (left is " << mRowCount << "x" << mColCount << " right is " << other.rows() << "x" << other.cols() << ")!" << std::endl; + abort(); + } + + value_type* temp_values = new value_type [mRowCount * mColCount]; + + for (unsigned int i = 0; i < mRowCount; i++) { + for (unsigned int j = 0; j < mColCount; j++) { + temp_values[i * mColCount + j] = static_cast(other(i,j)); + } + } + + for (unsigned int i = 0; i < mRowCount; i++) { + for (unsigned int j = 0; j < mColCount; j++) { + (*this)(i,j) = temp_values[i * mColCount + j]; + } + } + + delete[] temp_values; + } + + return *this; + } + + template + // copy data from the other block into this + Block& operator=(const other_matrix_type &other) { + if (mRowCount != other.rows() || mColCount != other.cols()) { + std::cerr << "Error: cannot assign blocks of different size (left is " << mRowCount << "x" << mColCount << " right is " << other.rows() << "x" << other.cols() << ")!" << std::endl; + abort(); + } + + value_type *temp_values = new value_type[mRowCount * mColCount]; + + for (unsigned int i = 0; i < mRowCount; i++) { + for (unsigned int j = 0; j < mColCount; j++) { + temp_values[i * mColCount + j] = static_cast(other(i,j)); + } + } + + for (unsigned int i = 0; i < mRowCount; i++) { + for (unsigned int j = 0; j < mColCount; j++) { + (*this)(i,j) = temp_values[i * mColCount + j]; + } + } + + delete[] temp_values; + + return *this; + } + + template + other_matrix_type operator+(const other_matrix_type& other) { + other_matrix_type result (this); + + for (unsigned int i = 0; i < mRowCount; i++) { + for (unsigned int j = 0; j < mColCount; j++) { + result += other(i,j); + } + } + + return result; + } + + template + other_matrix_type operator-(const other_matrix_type& other) { + other_matrix_type result (this); + + for (unsigned int i = 0; i < mRowCount; i++) { + for (unsigned int j = 0; j < mColCount; j++) { + result -= other(i,j); + } + } + + return result; + } + + unsigned int rows() const { + if (!mTransposed) + return mRowCount; + + return mColCount; + } + unsigned int cols() const { + if (!mTransposed) + return mColCount; + + return mRowCount; + } + const val_type& operator() (const unsigned int i, const unsigned int j) const { + + if (!mTransposed) { + assert (i < mRowCount); + assert (j < mColCount); + return (*mParentMatrix) (i + mParentRowStart, j + mParentColStart); + } + + return (*mParentMatrix) (j + mParentRowStart, i + mParentColStart); + } + + val_type& operator() (const unsigned int i, const unsigned int j) { + if (!mTransposed) { + assert (i < mRowCount); + assert (j < mColCount); + return (*mParentMatrix) (i + mParentRowStart, j + mParentColStart); + } + + assert (j < mRowCount); + assert (i < mColCount); + return (*mParentMatrix) (j + mParentRowStart, i + mParentColStart); + } + + Block transpose() const { + Block result (*this); + result.mTransposed = mTransposed ^ true; + return result; + } + + private: + matrix_type *mParentMatrix; + const unsigned int mParentRows; + const unsigned int mParentCols; + const unsigned int mParentRowStart; + const unsigned int mParentColStart; + const unsigned int mRowCount; + const unsigned int mColCount; + bool mTransposed; +}; + +template +inline std::ostream& operator<<(std::ostream& output, const Block &block) { + unsigned int i,j; + for (i = 0; i < block.rows(); i++) { + output << "[ "; + for (j = 0; j < block.cols(); j++) { + output << block(i,j); + + if (j < block.cols() - 1) + output << ", "; + } + output << " ]"; + + if (block.rows() > 1 && i < block.rows() - 1) + output << std::endl; + } + + return output; +} + + +} + +#endif /* SIMPLEMATHBLOCK_H */ diff --git a/src/SimpleMath/SimpleMathDynamic.h b/src/SimpleMath/SimpleMathDynamic.h index fc9fbd9..62975e8 100644 --- a/src/SimpleMath/SimpleMathDynamic.h +++ b/src/SimpleMath/SimpleMathDynamic.h @@ -303,6 +303,28 @@ class Matrix { return result; } + val_type trace() const { + assert (rows() == cols()); + val_type result = 0.; + + for (unsigned int i = 0; i < rows(); i++) { + result += operator()(i,i); + } + + return result; + } + + val_type mean() const { + assert (rows() == 1 || cols() == 1); + + val_type result = 0.; + for (unsigned int i = 0; i < rows() * cols(); i++) { + result += operator[](i); + } + + return result / static_cast(rows() * cols()); + } + static matrix_type Zero() { matrix_type result; result.setZero(); @@ -387,6 +409,38 @@ class Matrix { return Block(*this, row_start, col_start, row_count, col_count); } + Block + block (unsigned int row_start, unsigned int col_start, unsigned int row_count, unsigned int col_count) const { + return Block(*this, row_start, col_start, row_count, col_count); + } + + template + Block + block (unsigned int row_start, unsigned int col_start) const { + return Block(*this, row_start, col_start, row_count, col_count); + } + + // row and col accessors + Block + col(unsigned int index) const { + return Block(*this, 0, index, rows(), 1); + } + + Block + col(unsigned int index) { + return Block(*this, 0, index, rows(), 1); + } + + Block + row(unsigned int index) const { + return Block(*this, index, 0, 1, cols()); + } + + Block + row(unsigned int index) { + return Block(*this, index, 0, 1, cols()); + } + // Operators with scalars void operator*=(const val_type &scalar) { for (unsigned int i = 0; i < nrows * ncols; i++) @@ -450,6 +504,45 @@ class Matrix { return result; } + template + Matrix operator*(const Fixed::Matrix &other_matrix) const { + assert (ncols == other_matrix.rows()); + + Matrix result(nrows, other_matrix.cols()); + + result.setZero(); + + unsigned int i,j, k; + for (i = 0; i < nrows; i++) { + for (j = 0; j < other_matrix.cols(); j++) { + for (k = 0; k < other_matrix.rows(); k++) { + result(i,j) += mData[i * ncols + k] * other_matrix(k,j); + } + } + } + + return result; + } + + Matrix operator*(const Block &other_matrix) const { + assert (ncols == other_matrix.rows()); + + Matrix result(nrows, other_matrix.cols()); + + result.setZero(); + + unsigned int i,j, k; + for (i = 0; i < nrows; i++) { + for (j = 0; j < other_matrix.cols(); j++) { + for (k = 0; k < other_matrix.rows(); k++) { + result(i,j) += mData[i * ncols + k] * other_matrix(k,j); + } + } + } + + return result; + } + void operator*=(const Matrix &matrix) { matrix_type temp (*this); *this = temp * matrix; @@ -474,12 +567,17 @@ class Matrix { } operator val_type() { + assert (nrows == 1); assert (nrows == 1); return mData[0]; } + Matrix operator-() const { + return *this * -1.0; + }; + Matrix inverse() const { return colPivHouseholderQr().inverse(); } diff --git a/src/SimpleMath/SimpleMathDynamic.h.orig b/src/SimpleMath/SimpleMathDynamic.h.orig new file mode 100644 index 0000000..b86108b --- /dev/null +++ b/src/SimpleMath/SimpleMathDynamic.h.orig @@ -0,0 +1,619 @@ +/** + * This is a highly inefficient math library. It was conceived by Martin + * Felis while he was compiling code + * that uses a highly efficient math library. + * + * It is intended to be used as a fast compiling substitute for the + * blazingly fast Eigen3 library and tries to mimic its API to a certain + * extend. + * + * Feel free to use it wherever you like. However, no guarantees are given + * that this code does what it says it would. + */ + +#ifndef SIMPLEMATHDYNAMIC_H +#define SIMPLEMATHDYNAMIC_H + +#include +#include +#include +#include + +#include "compileassert.h" +#include "SimpleMathBlock.h" + +/** \brief Namespace for a highly inefficient math library + * + */ +namespace SimpleMath { + +template +class LLT; + +template +class HouseholderQR; + +template +class ColPivHouseholderQR; + +template +class CommaInitializer; + +namespace Fixed { + template class Matrix; +} + + +/** \brief Namespace for elements of varying size. + */ +namespace Dynamic { + +// forward declaration +template +class Matrix; + +/** \brief Class for both matrices and vectors. + */ +template +class Matrix { + public: + typedef Matrix matrix_type; + typedef val_type value_type; + + Matrix() : + nrows (0), + ncols (0), + mapped_data (false), + mData (NULL) {}; + Matrix(unsigned int rows) : + nrows (rows), + ncols (1), + mapped_data (false) { + mData = new val_type[rows]; + } + Matrix(unsigned int rows, unsigned int cols) : + nrows (rows), + ncols (cols), + mapped_data (false) { + mData = new val_type[rows * cols]; + } + Matrix(unsigned int rows, unsigned int cols, val_type *data_ptr) : + nrows (rows), + ncols (cols), + mapped_data (true) { + mData = data_ptr; + } + + unsigned int rows() const { + return nrows; + } + + unsigned int cols() const { + return ncols; + } + + unsigned int size() const { + return nrows * ncols; + } + void resize (unsigned int rows, unsigned int cols=1) { + if (nrows * ncols > 0 && mData != NULL && mapped_data == false) { + delete[] mData; + } + + nrows = rows; + ncols = cols; + + mData = new val_type[nrows * ncols]; + } + + void conservativeResize (unsigned int rows, unsigned int cols = 1) { + Matrix result = Matrix::Zero(rows, cols); + + unsigned int arows = std::min (rows, nrows); + unsigned int acols = std::min (cols, ncols); + + for (unsigned int i = 0; i < arows; i++) { + for (unsigned int j = 0; j < acols; j++) { + result(i,j) = (*this)(i,j); + } + } + + *this = result; + } + + Matrix(const Matrix &matrix) : + nrows (matrix.nrows), + ncols (matrix.ncols), + mapped_data (false) { + unsigned int i; + + mData = new val_type[nrows * ncols]; + + for (i = 0; i < nrows * ncols; i++) + mData[i] = matrix.mData[i]; + } + Matrix& operator=(const Matrix &matrix) { + if (this != &matrix) { + if (!mapped_data) { + delete[] mData; + + nrows = matrix.nrows; + ncols = matrix.ncols; + mapped_data = false; + + mData = new val_type[nrows * ncols]; + + unsigned int i; + for (i = 0; i < nrows * ncols; i++) + mData[i] = matrix.mData[i]; + } else { + // we overwrite any existing data + nrows = matrix.nrows; + ncols = matrix.ncols; + mapped_data = true; + + unsigned int i; + for (i = 0; i < nrows * ncols; i++) + mData[i] = matrix.mData[i]; + } + } + return *this; + } + + CommaInitializer operator<< (const val_type& value) { + return CommaInitializer (*this, value); + } + + // conversion different val_types + template + Matrix (const Matrix &matrix) : + nrows (matrix.rows()), + ncols (matrix.cols()), + mapped_data(false) { + + mData = new val_type[nrows * ncols]; + + for (unsigned int i = 0; i < nrows; i++) { + for (unsigned int j = 0; j < ncols; j++) { + (*this)(i,j) = static_cast(matrix(i,j)); + } + } + } + + // conversion from a fixed size matrix + template + Matrix (const Fixed::Matrix &fixed_matrix) : + nrows (fnrows), + ncols (fncols), + mapped_data (false), + mData (NULL) { + mData = new val_type[nrows * ncols]; + + for (unsigned int i = 0; i < nrows; i++) { + for (unsigned int j = 0; j < ncols; j++) { + (*this)(i,j) = static_cast(fixed_matrix(i,j)); + } + } + } + + template + explicit Matrix (const Block &block) : + nrows(block.rows()), + ncols(block.cols()), + mapped_data (false) { + mData = new val_type[nrows * ncols]; + + for (unsigned int i = 0; i < nrows; i++) { + for (unsigned int j = 0; j < ncols; j++) { + (*this)(i,j) = static_cast(block(i,j)); + } + } + + } + + ~Matrix() { + if (nrows * ncols > 0 && mData != NULL && mapped_data == false) { + delete[] mData; + mData = NULL; + } + + nrows = 0; + ncols = 0; + }; + + // comparison + bool operator==(const Matrix &matrix) const { + if (nrows != matrix.nrows || ncols != matrix.ncols) + return false; + + for (unsigned int i = 0; i < nrows * ncols; i++) { + if (mData[i] != matrix.mData[i]) + return false; + } + return true; + } + bool operator!=(const Matrix &matrix) const { + if (nrows != matrix.nrows || ncols != matrix.ncols) + return true; + + for (unsigned int i = 0; i < nrows * ncols; i++) { + if (mData[i] != matrix.mData[i]) + return true; + } + return false; + } + + // access operators + const val_type& operator[](const unsigned int &index) const { + assert (index >= 0); + assert (index < nrows * ncols); + return mData[index]; + }; + val_type& operator[](const unsigned int &index) { + assert (index >= 0 && index < nrows * ncols); + return mData[index]; + } + + const val_type& operator()(const unsigned int &row, const unsigned int &col) const { + if (!(row >= 0 && row < nrows && col >= 0 && col < ncols)) { + std::cout << "row = " << row << " col = " << col << std::endl; + std::cout << "nrows = " << nrows << " ncols = " << ncols << std::endl; + std::cout << "invalid read = " << mData[100000] << std::endl; + } + assert (row >= 0 && row < nrows && col >= 0 && col < ncols); + return mData[row*ncols + col]; + }; + val_type& operator()(const unsigned int &row, const unsigned int &col) { + assert (row >= 0 && row < nrows && col >= 0 && col < ncols); + return mData[row*ncols + col]; + }; + + void zero() { + for (unsigned int i = 0; i < ncols * nrows; i++) + mData[i] = 0.; + } + void setZero() { + zero(); + } + + val_type norm() const { + return sqrt(this->squaredNorm()); + } + + void normalize() { + val_type length = this->norm(); + + for (unsigned int i = 0; i < ncols * nrows; i++) + mData[i] /= length; + } + + Matrix normalized() const { + return Matrix (*this) / this->norm(); + } + + Matrix cross(const Matrix &other_vector) { + assert (nrows * ncols == 3); + assert (other_vector.nrows * other_vector.ncols == 3); + + Matrix result (3, 1); + result[0] = mData[1] * other_vector[2] - mData[2] * other_vector[1]; + result[1] = mData[2] * other_vector[0] - mData[0] * other_vector[2]; + result[2] = mData[0] * other_vector[1] - mData[1] * other_vector[0]; + + return result; + } + + static matrix_type Zero() { + matrix_type result; + result.setZero(); + return result; + } + + static matrix_type Zero(int rows, int cols = 1) { + matrix_type result (rows, cols); + result.setZero(); + return result; + } + + static matrix_type Constant (int rows, val_type value) { + matrix_type result (rows, 1); + unsigned int i; + for (i = 0; i < result.size(); i++) + result[i] = value; + + return result; + } + + static matrix_type Constant (int rows, int cols, val_type value) { + matrix_type result (rows, cols); + unsigned int i; + for (i = 0; i < result.size(); i++) + result[i] = value; + + return result; + } + + static matrix_type Identity (int rows, int cols = 1) { + assert (rows == cols); + + matrix_type result (rows, cols); + result.identity(); + + return result; + } + + void identity() { + assert (nrows == ncols); + + setZero(); + for (unsigned int i = 0; i < ncols; i++) + mData[i * ncols + i] = 1.; + } + + void random() { + for (unsigned int i = 0; i < nrows * ncols; i++) + mData[i] = static_cast (rand()) / static_cast (RAND_MAX); + } + + val_type squaredNorm() const { + assert (ncols == 1 || nrows == 1); + val_type result = 0; + + for (unsigned int i = 0; i < nrows * ncols; i++) + result += mData[i] * mData[i]; + + return result; + } + + val_type dot(const matrix_type &matrix) const { + assert (ncols == 1 || nrows == 1); + val_type result = 0; + + for (unsigned int i = 0; i < nrows * ncols; i++) + result += mData[i] * matrix[i]; + + return result; + } + + // Blocks + Block + block (unsigned int row_start, unsigned int col_start, unsigned int row_count, unsigned int col_count) { + return Block(*this, row_start, col_start, row_count, col_count); + } + + template + Block + block (unsigned int row_start, unsigned int col_start) { + return Block(*this, row_start, col_start, row_count, col_count); + } + + Block + block (unsigned int row_start, unsigned int col_start, unsigned int row_count, unsigned int col_count) const { + return Block(*this, row_start, col_start, row_count, col_count); + } + + template + Block + block (unsigned int row_start, unsigned int col_start) const { + return Block(*this, row_start, col_start, row_count, col_count); + } + + // Operators with scalars + void operator*=(const val_type &scalar) { + for (unsigned int i = 0; i < nrows * ncols; i++) + mData[i] *= scalar; + }; + void operator/=(const val_type &scalar) { + for (unsigned int i = 0; i < nrows * ncols; i++) + mData[i] /= scalar; + } + Matrix operator/(const val_type& scalar) const { + matrix_type result (*this); + + for (unsigned int i = 0; i < nrows * ncols; i++) + result[i] /= scalar; + + return result; + } + + // Operators with other matrices + Matrix operator+(const Matrix &matrix) const { + matrix_type result (*this); + + for (unsigned int i = 0; i < nrows * ncols; i++) + result[i] += matrix[i]; + + return result; + } + void operator+=(const matrix_type &matrix) { + for (unsigned int i = 0; i < nrows * ncols; i++) + mData[i] += matrix.mData[i]; + } + Matrix operator-(const Matrix &matrix) const { + matrix_type result (*this); + + for (unsigned int i = 0; i < nrows * ncols; i++) + result[i] -= matrix[i]; + + return result; + } + void operator-=(const Matrix &matrix) { + for (unsigned int i = 0; i < nrows * ncols; i++) + mData[i] -= matrix.mData[i]; + } + + Matrix operator*(const Matrix &other_matrix) const { + assert (ncols == other_matrix.nrows); + + Matrix result(nrows, other_matrix.ncols); + + result.setZero(); + + unsigned int i,j, k; + for (i = 0; i < nrows; i++) { + for (j = 0; j < other_matrix.cols(); j++) { + for (k = 0; k < other_matrix.rows(); k++) { + result(i,j) += mData[i * ncols + k] * other_matrix(k,j); + } + } + } + + return result; + } + + template + Matrix operator*(const Fixed::Matrix &other_matrix) const { + assert (ncols == other_matrix.rows()); + + Matrix result(nrows, other_matrix.cols()); + + result.setZero(); + + unsigned int i,j, k; + for (i = 0; i < nrows; i++) { + for (j = 0; j < other_matrix.cols(); j++) { + for (k = 0; k < other_matrix.rows(); k++) { + result(i,j) += mData[i * ncols + k] * other_matrix(k,j); + } + } + } + + return result; + } + + Matrix operator*(const Block &other_matrix) const { + assert (ncols == other_matrix.rows()); + + Matrix result(nrows, other_matrix.cols()); + + result.setZero(); + + unsigned int i,j, k; + for (i = 0; i < nrows; i++) { + for (j = 0; j < other_matrix.cols(); j++) { + for (k = 0; k < other_matrix.rows(); k++) { + result(i,j) += mData[i * ncols + k] * other_matrix(k,j); + } + } + } + + return result; + } + + void operator*=(const Matrix &matrix) { + matrix_type temp (*this); + *this = temp * matrix; + } + + // Special operators + val_type *data(){ + return mData; + } + + // regular transpose of a 6 dimensional matrix + Matrix transpose() const { + Matrix result(ncols, nrows); + + for (unsigned int i = 0; i < nrows; i++) { + for (unsigned int j = 0; j < ncols; j++) { + result(j,i) = mData[i * ncols + j]; + } + } + + return result; + } + + operator val_type() { + assert (nrows == 1); + assert (nrows == 1); + + return mData[0]; + } + + Matrix inverse() const { + return colPivHouseholderQr().inverse(); + } + + const LLT llt() const { + return LLT(*this); + } + + const HouseholderQR householderQr() const { + return HouseholderQR(*this); + } + const ColPivHouseholderQR colPivHouseholderQr() const { + return ColPivHouseholderQR(*this); + } + + private: + unsigned int nrows; + unsigned int ncols; + bool mapped_data; + + val_type* mData; +}; + +template +inline Matrix operator*(val_type scalar, const Matrix &matrix) { + Matrix result (matrix); + + for (unsigned int i = 0; i < matrix.rows() * matrix.cols(); i++) + result.data()[i] *= scalar; + + return result; +} + +template +inline Matrix operator*(const Matrix &matrix, other_type scalar) { + Matrix result (matrix); + + for (unsigned int i = 0; i < matrix.rows() * matrix.cols(); i++) + result.data()[i] *= static_cast(scalar); + + return result; +} + +template +inline std::ostream& operator<<(std::ostream& output, const Matrix &matrix) { + size_t max_width = 0; + size_t out_width = output.width(); + + // get the widest number + for (size_t i = 0; i < matrix.rows(); i++) { + for (size_t j = 0; j < matrix.cols(); j++) { + std::stringstream out_stream; + out_stream << matrix(i,j); + max_width = std::max (out_stream.str().size(),max_width); + } + } + + // overwrite width if it was explicitly prescribed + if (out_width != 0) { + max_width = out_width; + } + + for (unsigned int i = 0; i < matrix.rows(); i++) { + output.width(0); + output << "[ "; + output.width(out_width); + for (unsigned int j = 0; j < matrix.cols(); j++) { + std::stringstream out_stream; + out_stream.width (max_width); + out_stream << matrix(i,j); + output << out_stream.str(); + + if (j < matrix.cols() - 1) + output << ", "; + } + output << " ]"; + + if (matrix.rows() > 1 && i < matrix.rows() - 1) + output << std::endl; + } + return output;} + +} + +} + +#endif /* SIMPLEMATHDYNAMIC_H */ diff --git a/src/SimpleMath/SimpleMathFixed.h b/src/SimpleMath/SimpleMathFixed.h index 8942ab6..9c51ff1 100644 --- a/src/SimpleMath/SimpleMathFixed.h +++ b/src/SimpleMath/SimpleMathFixed.h @@ -78,13 +78,10 @@ class Matrix { for (i = 0; i < nrows * ncols; i++) mData[i] = matrix.mData[i]; } - Matrix(unsigned int rows, unsigned int cols, val_type *data_ptr) { - assert (rows == nrows); - assert (cols == ncols); - - for (int i = 0; i < 16; i++) { - mData[i] = data_ptr[i]; - } + Matrix(unsigned int _nrows, unsigned int _ncols, const value_type* values) { + assert(nrows == _nrows); + assert(ncols == _ncols); + memcpy (mData, values, sizeof(value_type) * nrows * ncols); } Matrix& operator=(const Matrix &matrix) { @@ -529,6 +526,28 @@ class Matrix { return result; } + val_type trace() const { + COMPILE_ASSERT(nrows == ncols); + val_type result = 0.; + + for (unsigned int i = 0; i < rows(); i++) { + result += operator()(i,i); + } + + return result; + } + + val_type mean() const { + COMPILE_ASSERT(nrows == 1 || ncols == 1); + + val_type result = 0.; + for (unsigned int i = 0; i < rows() * cols(); i++) { + result += operator[](i); + } + + return result / static_cast(nrows * ncols); + } + static matrix_type Zero() { matrix_type result; result.setZero(); @@ -616,6 +635,27 @@ class Matrix { return Block(*this, row_start, col_start, block_row_count, block_col_count); } + // row and col accessors + Block + col(unsigned int index) const { + return Block(*this, 0, index, rows(), 1); + } + + Block + col(unsigned int index) { + return Block(*this, 0, index, rows(), 1); + } + + Block + row(unsigned int index) const { + return Block(*this, index, 0, 1, cols()); + } + + Block + row(unsigned int index) { + return Block(*this, index, 0, 1, cols()); + } + // Operators with scalars void operator*=(const val_type &scalar) { for (unsigned int i = 0; i < nrows * ncols; i++) @@ -701,7 +741,6 @@ class Matrix { return result; } - void operator*=(const Matrix &matrix) { matrix_type temp (*this); *this = temp * matrix; diff --git a/src/SimpleMath/SimpleMathQR.h b/src/SimpleMath/SimpleMathQR.h index 91832f2..a1bb3b8 100644 --- a/src/SimpleMath/SimpleMathQR.h +++ b/src/SimpleMath/SimpleMathQR.h @@ -233,7 +233,7 @@ namespace SimpleMath { MatrixXXd Q (MatrixXXd::Identity(mR.rows(), mR.rows())); Q.block(i, i, block_rows, block_rows) = MatrixXXd (Q.block(i, i, block_rows, block_rows)) - - MatrixXXd(v * v.transpose() / (v.squaredNorm() * 0.5)); + - MatrixXXd(v * v.transpose() / (v.squaredNorm() * static_cast(0.5))); mR = Q * mR; diff --git a/src/TestModule.cc b/src/TestModule.cc index b51c9c9..62654c0 100644 --- a/src/TestModule.cc +++ b/src/TestModule.cc @@ -1,11 +1,63 @@ #include "RuntimeModule.h" +#include "Globals.h" #include "Renderer.h" #include "3rdparty/ocornut-imgui/imgui.h" #include "imgui/imgui.h" +#include +#include "SimpleMath/SimpleMath.h" +#include "SimpleMath/SimpleMathMap.h" #include #include +typedef SimpleMath::Matrix44f Matrix44f; +typedef SimpleMath::Vector4f Vector4f; +typedef SimpleMath::Matrix33f Matrix33f; +typedef SimpleMath::Vector3f Vector3f; +typedef SimpleMath::MatrixNNf MatrixNNf; +typedef SimpleMath::VectorNf VectorNf; + + +void handle_keyboard () { + Camera *active_camera = &gRenderer->cameras[gRenderer->activeCameraIndex]; + assert (active_camera != nullptr); + Matrix44f camera_view_matrix = SimpleMath::Map(active_camera->mtxView, 4, 4); + Matrix33f camera_rot_inv = camera_view_matrix.block<3,3>(0,0).transpose(); + + Vector3f forward = camera_rot_inv.transpose() * Vector3f (0.f, 0.f, 1.f); + Vector3f right = camera_rot_inv.transpose() * Vector3f (1.f, 0.f, 0.f); + + Vector3f eye = SimpleMath::Map(active_camera->eye, 3, 1); + Vector3f poi= SimpleMath::Map(active_camera->poi, 3, 1); + + Vector3f direction (0.f, 0.f, 0.f); + + if (glfwGetKey(gWindow, GLFW_KEY_W) == GLFW_PRESS) { + direction += forward; + } + + if (glfwGetKey(gWindow, GLFW_KEY_S) == GLFW_PRESS) { + direction -= forward; + } + + if (glfwGetKey(gWindow, GLFW_KEY_D) == GLFW_PRESS) { + direction += right; + } + + if (glfwGetKey(gWindow, GLFW_KEY_A) == GLFW_PRESS) { + direction -= right; + } + + float step = 0.1f; + eye += direction * step; + poi += direction * step; + + memcpy (active_camera->eye, eye.data(), sizeof(float) * 3); + memcpy (active_camera->poi, poi.data(), sizeof(float) * 3); +} + +// Boilerplate for the module reload stuff + struct module_state { int width, height; int select; @@ -33,8 +85,13 @@ static void module_unload(struct module_state *state) { static bool module_step(struct module_state *state) { bool enabled = true; - ImGui::Begin("yoyoyo"); - if (ImGui::Button("Baem Yahoo")) { + ImGui::Begin("yoyoyoxi2"); + if (ImGui::Button("Hallo Katrina")) { + if (gRenderer->drawDebug) { + gRenderer->drawDebug = false; + } else { + gRenderer->drawDebug = true; + } std::cout << "Clicked on Baem!" << std::endl; } ImGui::End(); @@ -43,6 +100,8 @@ static bool module_step(struct module_state *state) { std::ostringstream s; s << "TestModule: 2 Runtime Object 4 " << deltaTime << " update called!"; + handle_keyboard(); + bgfx::dbgTextPrintf(1, 20, 0x6f, s.str().c_str()); return true; diff --git a/src/main.cc b/src/main.cc index 20777de..9f2614b 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,39 +1,3 @@ -//======================================================================== -// Simple GLFW example -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -//! [code] - -//#define USE_GLAD - -#ifdef USE_GLEW -#include -#endif - -#ifdef USE_GLAD -#include -#endif - #define GLFW_EXPOSE_NATIVE_GLX #define GLFW_EXPOSE_NATIVE_X11 #include @@ -51,37 +15,12 @@ #include "Renderer.h" #include "RuntimeModuleManager.h" +#include "Globals.h" +Renderer* gRenderer = nullptr; +GLFWwindow* gWindow = nullptr; + using namespace std; -static const struct -{ - float x, y; - float r, g, b; -} vertices[3] = -{ - { -0.6f, -0.4f, 1.f, 0.f, 0.f }, - { 0.6f, -0.4f, 0.f, 1.f, 0.f }, - { 0.f, 0.6f, 0.f, 0.f, 1.f } -}; - -static const char* vertex_shader_text = -"uniform mat4 MVP;\n" -"attribute vec3 vCol;\n" -"attribute vec2 vPos;\n" -"varying vec3 color;\n" -"void main()\n" -"{\n" -" gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n" -" color = vCol;\n" -"}\n"; - -static const char* fragment_shader_text = -"varying vec3 color;\n" -"void main()\n" -"{\n" -" gl_FragColor = vec4(color, 1.0);\n" -"}\n"; - namespace bgfx { inline void glfwSetWindow(GLFWwindow* _window) { @@ -127,17 +66,19 @@ int main(void) glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE); - GLFWwindow* win = glfwCreateWindow(800, 600, "ProtoT", NULL, NULL); - glfwMakeContextCurrent(win); + gWindow = glfwCreateWindow(800, 600, "ProtoT", NULL, NULL); + glfwMakeContextCurrent(gWindow); int width, height; - glfwGetWindowSize(win, &width, &height); + glfwGetWindowSize(gWindow, &width, &height); Renderer renderer; - bgfx::glfwSetWindow(win); + bgfx::glfwSetWindow(gWindow); bgfx::renderFrame(); renderer.initialize(width, height); + gRenderer = &renderer; + // bgfx::init(); // bgfx::reset(width, height, BGFX_RESET_VSYNC); @@ -154,10 +95,10 @@ int main(void) module_manager.RegisterModule("libTestModule.so"); printf("Starting main loop...\n"); - glfwSetKeyCallback(win, key_callback); + glfwSetKeyCallback(gWindow, key_callback); int64_t time_offset = bx::getHPCounter(); - while(!glfwWindowShouldClose(win)) { + while(!glfwWindowShouldClose(gWindow)) { int64_t now = bx::getHPCounter(); static int64_t last = now; const int64_t frameTime = now - last; @@ -168,7 +109,7 @@ int main(void) float time = (float)( (now-time_offset)/double(bx::getHPFrequency() ) ); int width, height; - glfwGetWindowSize(win, &width, &height); + glfwGetWindowSize(gWindow, &width, &height); if (width != renderer.width || height != renderer.height) { renderer.resize(width, height); } @@ -192,18 +133,20 @@ int main(void) // send inputs to the input state of the renderer double mouse_x, mouse_y; - glfwGetCursorPos(win, &mouse_x, &mouse_y); + glfwGetCursorPos(gWindow, &mouse_x, &mouse_y); renderer.inputState.mouseX = mouse_x; renderer.inputState.mouseY = mouse_y; renderer.inputState.mouseButton = - glfwGetMouseButton(win, 0) - + (glfwGetMouseButton(win, 1) << 1) - + (glfwGetMouseButton(win, 2) << 2); + glfwGetMouseButton(gWindow, 0) + + (glfwGetMouseButton(gWindow, 1) << 1) + + (glfwGetMouseButton(gWindow, 2) << 2); usleep(16000); } module_manager.UnloadModules(); + + gRenderer = nullptr; } //! [code]