Wed, 22 Jan 2020 22:41:17 +0200
modelview matrix set up
/* * LDForge: LDraw parts authoring CAD * Copyright (C) 2013 - 2020 Teemu Piippo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #pragma once #include <QGenericMatrix> #include <type_traits> template<int Rows, int Columns, typename T = double> struct MatrixIterator; template<int Rows, int Columns> struct MatrixIndex { int row; int column; }; template<int Rows, int Columns, typename T = double> struct Matrix { using Iterator = MatrixIterator<Rows, Columns, T>; T values[Rows][Columns]; Iterator begin() { return {*this, {0, 0}}; } Iterator end() { return {*this, {Rows, 0}}; } T& operator()(int row, int column) { return this->values[row][column]; } T operator()(int row, int column) const { return this->values[row][column]; } T& operator[](const MatrixIndex<Rows, Columns>& index) { return (*this)(index.row, index.column); } T operator[](const MatrixIndex<Rows, Columns>& index) const { return (*this)(index.row, index.column); } }; template<int Rows, int Columns, typename T> struct MatrixIterator { struct Value { const MatrixIndex<Rows, Columns> index; decltype(std::declval<Matrix<Rows, Columns, T>>()(0, 0)) value; }; Matrix<Rows, Columns, T>& matrix; MatrixIndex<Rows, Columns> index; }; template<int Rows, int Columns> auto& operator++(MatrixIndex<Rows, Columns>& index) { index.column += 1; if (index.column >= Columns) { index.row += 1; index.column -= Columns; } return index; } template<int Rows, int Columns> bool operator==( const MatrixIndex<Rows, Columns>& one, const MatrixIndex<Rows, Columns>& other) { return one.row == other.row and one.column == other.column; } template<int Rows, int Columns, typename T> auto& operator++(MatrixIterator<Rows, Columns, T>& iterator) { ++iterator.index; return iterator; } template<int Rows, int Columns, typename T> bool operator==( const MatrixIterator<Rows, Columns, T>& one, const MatrixIterator<Rows, Columns, T>& other) { return &one.matrix == &other.matrix and one.index == other.index; } template<int Rows, int Columns, typename T> bool operator!=( const MatrixIterator<Rows, Columns, T>& one, const MatrixIterator<Rows, Columns, T>& other) { return not (one == other); } template<int Rows, int Columns, typename T> auto operator*(MatrixIterator<Rows, Columns, T>& iterator) -> typename MatrixIterator<Rows, Columns, T>::Value { return {iterator.index, iterator.matrix[iterator.index]}; } template<int Rows, int Columns, typename T> QGenericMatrix<Rows, Columns, T> matrixToQGenericMatrix(const Matrix<Rows, Columns, T>& matrix) { return {matrix.values}; } template<int Rows, int Columns, typename T> Matrix<Rows, Columns, T> matrixFromQGenericMatrix(const QGenericMatrix<Rows, Columns, T&> matrix) { Matrix<Rows, Columns, T> result; for (auto& cell : result) { matrix(cell.index.row, cell.index.column) = result[cell.index]; } return result; } using Matrix3x3 = Matrix<3, 3>; Q_DECLARE_METATYPE(Matrix3x3); using Matrix4x4 = Matrix<4, 4>; Q_DECLARE_METATYPE(Matrix4x4); template<int Rows, int Columns, typename T> QDataStream& operator<<(QDataStream& stream, const Matrix<Rows, Columns, T>& matrix) { for (auto& cell : matrix) { stream << cell.value; } return stream; } template<int Rows, int Columns, typename T> QDataStream& operator>>(QDataStream& stream, Matrix<Rows, Columns, T>& matrix) { for (auto& cell : matrix) { stream >> cell.value; } return stream; } Matrix4x4 combine(const Matrix3x3& topLeft, const struct Point3D& translation); static constexpr Matrix3x3 identity3x3 {{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}}; static constexpr Matrix4x4 identity4x4 {{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}}; namespace math { qreal det(qreal a, qreal b, qreal c, qreal d, qreal e, qreal f, qreal g, qreal h, qreal i); qreal det(const Matrix<2, 2>& matrix); qreal det(const Matrix3x3& matrix); qreal det(const Matrix4x4& matrix); }