replaced the Matrix class with QMatrix4x4

Sun, 17 Jun 2018 13:53:33 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Sun, 17 Jun 2018 13:53:33 +0300
changeset 1403
7a2d84112983
parent 1402
8bbf2af8c3f5
child 1404
16eb4257e662

replaced the Matrix class with QMatrix4x4

CMakeLists.txt file | annotate | diff | comparison | revisions
src/algorithms/geometry.cpp file | annotate | diff | comparison | revisions
src/algorithms/geometry.h file | annotate | diff | comparison | revisions
src/algorithms/invert.cpp file | annotate | diff | comparison | revisions
src/algorithms/invert.h file | annotate | diff | comparison | revisions
src/dialogs/subfilereferenceeditor.cpp file | annotate | diff | comparison | revisions
src/editmodes/circleMode.cpp file | annotate | diff | comparison | revisions
src/format.h file | annotate | diff | comparison | revisions
src/linetypes/circularprimitive.cpp file | annotate | diff | comparison | revisions
src/linetypes/circularprimitive.h file | annotate | diff | comparison | revisions
src/linetypes/modelobject.cpp file | annotate | diff | comparison | revisions
src/linetypes/modelobject.h file | annotate | diff | comparison | revisions
src/matrixinput.cpp file | annotate | diff | comparison | revisions
src/matrixinput.h file | annotate | diff | comparison | revisions
src/parser.cpp file | annotate | diff | comparison | revisions
src/toolsets/algorithmtoolset.cpp file | annotate | diff | comparison | revisions
src/toolsets/movetoolset.cpp file | annotate | diff | comparison | revisions
src/types/matrix.cpp file | annotate | diff | comparison | revisions
src/types/matrix.h file | annotate | diff | comparison | revisions
src/types/vertex.cpp file | annotate | diff | comparison | revisions
src/types/vertex.h file | annotate | diff | comparison | revisions
src/widgets/matrixeditor.cpp file | annotate | diff | comparison | revisions
src/widgets/matrixeditor.h file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Sun Jun 10 23:25:08 2018 +0300
+++ b/CMakeLists.txt	Sun Jun 17 13:53:33 2018 +0300
@@ -50,7 +50,6 @@
 	src/librariesmodel.cpp
 	src/main.cpp
 	src/mainwindow.cpp
-	src/matrixinput.cpp
 	src/model.cpp
 	src/partdownloader.cpp
 	src/partdownloadrequest.cpp
@@ -95,7 +94,6 @@
 	src/toolsets/toolset.cpp
 	src/toolsets/viewtoolset.cpp
 	src/types/boundingbox.cpp
-	src/types/matrix.cpp
 	src/types/vertex.cpp
 	src/widgets/colorbutton.cpp
 	src/widgets/doublespinbox.cpp
@@ -125,7 +123,6 @@
 	src/librariesmodel.h
 	src/main.h
 	src/mainwindow.h
-	src/matrixinput.h
 	src/model.h
 	src/partdownloader.h
 	src/partdownloadrequest.h
@@ -178,7 +175,6 @@
 	src/toolsets/viewtoolset.h
 	src/types/boundingbox.h
 	src/types/library.h
-	src/types/matrix.h
 	src/types/vertex.h
 	src/widgets/colorbutton.h
 	src/widgets/doublespinbox.h
--- a/src/algorithms/geometry.cpp	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/algorithms/geometry.cpp	Sun Jun 17 13:53:33 2018 +0300
@@ -69,35 +69,10 @@
 }
 
 
-void rotateVertex(Vertex& vertex, const Vertex& rotationPoint, const Matrix& transformationMatrix)
-{
-	vertex -= rotationPoint.toVector();
-	vertex.transform (transformationMatrix, {0, 0, 0});
-	vertex += rotationPoint.toVector();
-}
-
-
-void rotateObjects(int l, int m, int n, double angle, const QVector<LDObject*>& objects)
+void rotateObjects(float l, float m, float n, double angle, const QVector<LDObject*>& objects)
 {
-	Vertex rotationPoint = getRotationPoint (objects);
-	double cosAngle = cos(angle);
-	double sinAngle = sin(angle);
-
-	// ref: http://en.wikipedia.org/wiki/Transformation_matrix#Rotation_2
-	Matrix transformationMatrix (
-	{
-		(l * l * (1 - cosAngle)) + cosAngle,
-		(m * l * (1 - cosAngle)) - (n * sinAngle),
-		(n * l * (1 - cosAngle)) + (m * sinAngle),
-
-		(l * m * (1 - cosAngle)) + (n * sinAngle),
-		(m * m * (1 - cosAngle)) + cosAngle,
-		(n * m * (1 - cosAngle)) - (l * sinAngle),
-
-		(l * n * (1 - cosAngle)) - (m * sinAngle),
-		(m * n * (1 - cosAngle)) + (l * sinAngle),
-		(n * n * (1 - cosAngle)) + cosAngle
-	});
+	QVector3D rotationPoint = getRotationPoint (objects).toVector();
+	QQuaternion orientation = QQuaternion::fromAxisAndAngle({l, m, n}, angle);
 
 	// Apply the above matrix to everything
 	for (LDObject* obj : objects)
@@ -107,21 +82,20 @@
 			for (int i = 0; i < obj->numVertices(); ++i)
 			{
 				Vertex v = obj->vertex (i);
-				rotateVertex(v, rotationPoint, transformationMatrix);
+				v += rotationPoint;
+				v.rotate(orientation);
+				v -= rotationPoint;
 				obj->setVertex (i, v);
 			}
 		}
 		else if (obj->hasMatrix())
 		{
 			LDMatrixObject* mo = dynamic_cast<LDMatrixObject*> (obj);
-
-			// Transform the position
-			Vertex v = mo->position();
-			rotateVertex(v, rotationPoint, transformationMatrix);
-			mo->setPosition (v);
-
-			// Transform the matrix
-			mo->setTransformationMatrix(transformationMatrix * mo->transformationMatrix());
+			QMatrix4x4 matrix = mo->transformationMatrix();
+			matrix.translate(rotationPoint);
+			matrix.rotate(orientation);
+			matrix.translate(-rotationPoint);
+			mo->setTransformationMatrix(matrix);
 		}
 	}
 }
@@ -138,15 +112,8 @@
 			// Calculate center vertex
 			for (LDObject* obj : objs)
 			{
-				if (obj->hasMatrix())
-				{
-					box << static_cast<LDMatrixObject*> (obj)->position();
-				}
-				else
-				{
-					for (int i = 0; i < obj->numVertices(); ++i)
-						box << obj->vertex(i);
-				}
+				for (int i = 0; i < obj->numVertices(); ++i)
+					box << obj->vertex(i);
 			}
 
 			return box.center();
--- a/src/algorithms/geometry.h	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/algorithms/geometry.h	Sun Jun 17 13:53:33 2018 +0300
@@ -31,6 +31,5 @@
 QPointF pointOnLDrawCircumference(int segment, int divisions);
 QVector<QLineF> makeCircle(int segments, int divisions, double radius);
 qreal distanceFromPointToRectangle(const QPointF& point, const QRectF& rectangle);
-void rotateObjects(int l, int m, int n, double angle, const QVector<LDObject*>& objects);
+void rotateObjects(float l, float m, float n, double angle, const QVector<LDObject*>& objects);
 Vertex getRotationPoint(const QVector<LDObject*>& objs);
-void rotateVertex(Vertex& vertex, const Vertex& rotationPoint, const Matrix& transformationMatrix);
--- a/src/algorithms/invert.cpp	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/algorithms/invert.cpp	Sun Jun 17 13:53:33 2018 +0300
@@ -69,9 +69,9 @@
 /*
  * Returns a matrix that causes a flip on the given dimension.
  */
-Matrix flipmatrix(Axis dimension)
+QMatrix4x4 flipmatrix(Axis dimension)
 {
-	Matrix result = Matrix::identity;
+	QMatrix4x4 result;
 
 	switch (dimension)
 	{
--- a/src/algorithms/invert.h	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/algorithms/invert.h	Sun Jun 17 13:53:33 2018 +0300
@@ -20,6 +20,6 @@
 #include "../main.h"
 
 bool isflat(class Model* model, Axis* axis);
-Matrix flipmatrix(Axis axis);
+QMatrix4x4 flipmatrix(Axis dimension);
 void invert(LDObject* obj, class DocumentManager* context);
 void invertPolygon(LDPolygon& polygon);
--- a/src/dialogs/subfilereferenceeditor.cpp	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/dialogs/subfilereferenceeditor.cpp	Sun Jun 17 13:53:33 2018 +0300
@@ -30,7 +30,6 @@
 {
 	this->ui.setupUi(this);
 	this->ui.referenceName->setText(reference->referenceName());
-	this->ui.matrixEditor->setPosition(reference->position());
 	this->ui.matrixEditor->setMatrix(reference->transformationMatrix());
 	this->color = reference->color();
 	::setColorButton(this->ui.colorButton, this->color);
@@ -67,7 +66,6 @@
 	this->reference->setReferenceName(this->ui.referenceName->text());
 	this->reference->setColor(this->color);
 	this->reference->setTransformationMatrix(this->ui.matrixEditor->matrix());
-	this->reference->setPosition(this->ui.matrixEditor->position());
 	QDialog::accept();
 }
 
--- a/src/editmodes/circleMode.cpp	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/editmodes/circleMode.cpp	Sun Jun 17 13:53:33 2018 +0300
@@ -93,7 +93,7 @@
 	int divisions = m_window->ringToolDivisions();
 	double dist0 = getCircleDrawDist(0);
 	double dist1 = getCircleDrawDist(1);
-	Vertex displacement = m_drawedVerts.first();
+	QVector3D translation = m_drawedVerts.first().toVector();
 
 	if (dist1 < dist0)
 		qSwap(dist0, dist1);
@@ -102,9 +102,10 @@
 	{
 		// Special case: radii are the same, there's no area. Use a circle.
 		// transform = shearMatrixForPlane(renderer());
-		Matrix transform = Matrix::fromQMatrix(renderer()->currentCamera().transformationMatrix(1));
-		transform *= Matrix::scaleMatrix(dist0);
-		model.emplace<LDCircularPrimitive>(PrimitiveModel::Circle, segments, divisions, transform, displacement);
+		QMatrix4x4 transform = renderer()->currentCamera().transformationMatrix(1);
+		transform.scale(dist0);
+		transform.translate(translation);
+		model.emplace<LDCircularPrimitive>(PrimitiveModel::Circle, segments, divisions, transform);
 		finishDraw(model);
 		return;
 	}
@@ -112,9 +113,10 @@
 	{
 		// Special case #2: one radius is 0, so use a disc.
 		//transform = shearMatrixForPlane(renderer());
-		Matrix transform = Matrix::fromQMatrix(renderer()->currentCamera().transformationMatrix(1));
-		transform *= Matrix::scaleMatrix(max(dist0, dist1));
-		model.emplace<LDCircularPrimitive>(PrimitiveModel::Disc, segments, divisions, transform, displacement);
+		QMatrix4x4 transform = renderer()->currentCamera().transformationMatrix(1);
+		transform.scale(max(dist0, dist1));
+		transform.translate(translation);
+		model.emplace<LDCircularPrimitive>(PrimitiveModel::Disc, segments, divisions, transform);
 		finishDraw(model);
 		return;
 	}
@@ -130,9 +132,10 @@
 		{
 			primitiveModel.ringNumber = component.num;
 			LDDocument* primitiveFile = primitives()->getPrimitive(primitiveModel);
-			Matrix matrix = Matrix::fromQMatrix(renderer()->currentCamera().transformationMatrix(component.scale));
+			QMatrix4x4 matrix = renderer()->currentCamera().transformationMatrix(component.scale);
+			matrix.translate(translation);
 			// matrix = shearMatrixForPlane(renderer()) * matrix;
-			model.emplace<LDSubfileReference>(primitiveFile->name(), matrix, m_drawedVerts.first());
+			model.emplace<LDSubfileReference>(primitiveFile->name(), matrix);
 		}
 	}
 	else
--- a/src/format.h	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/format.h	Sun Jun 17 13:53:33 2018 +0300
@@ -22,7 +22,6 @@
 #include <QModelIndex>
 #include "basics.h"
 #include "colors.h"
-#include "types/matrix.h"
 #include "types/vertex.h"
 
 // Converts a given value into a string that can be retrieved with text().
@@ -39,7 +38,6 @@
 	StringFormatArg (float a) : m_text (QString::number (a)) {}
 	StringFormatArg (double a) : m_text (QString::number (a)) {}
 	StringFormatArg (const Vertex& a) : m_text (a.toString()) {}
-	StringFormatArg (const Matrix& a) : m_text (a.toString()) {}
 	StringFormatArg (const char* a) : m_text (a) {}
 	StringFormatArg (LDColor a) : m_text (a.indexString()) {}
 
--- a/src/linetypes/circularprimitive.cpp	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/linetypes/circularprimitive.cpp	Sun Jun 17 13:53:33 2018 +0300
@@ -27,14 +27,11 @@
 	return format("%1%2-%3%4.dat", prefix, numerator, denominator, stem());
 }
 
-LDCircularPrimitive::LDCircularPrimitive(
-	PrimitiveModel::Type type,
+LDCircularPrimitive::LDCircularPrimitive(PrimitiveModel::Type type,
 	int segments,
 	int divisions,
-	const Matrix& transformationMatrix,
-	const Vertex& position
-) :
-	LDMatrixObject {transformationMatrix, position},
+	const QMatrix4x4& matrix) :
+	LDMatrixObject {matrix},
 	m_type {type},
 	m_segments {segments},
 	m_divisions {divisions} {}
@@ -46,7 +43,7 @@
 
 QString LDCircularPrimitive::asText() const
 {
-	return LDSubfileReference(buildFilename(), transformationMatrix(), position()).asText();
+	return LDSubfileReference(buildFilename(), transformationMatrix()).asText();
 }
 
 void LDCircularPrimitive::getVertices(DocumentManager* /* context */, QSet<Vertex>& vertices) const
@@ -60,7 +57,7 @@
 		for (double y_value : {0.0, 1.0})
 		{
 			Vertex vertex {point2d.x(), y_value, point2d.y()};
-			vertex.transform(transformationMatrix(), position());
+			vertex.transform(transformationMatrix());
 			vertices.insert(vertex);
 		}
 	}
@@ -86,7 +83,7 @@
 		for (int i = 0; i < object->numVertices(); i += 1)
 		{
 			Vertex vertex = object->vertex(i);
-			vertex.transform(transformationMatrix(), position());
+			vertex.transform(transformationMatrix());
 			object->setVertex(i, vertex);
 		}
 	}
@@ -106,7 +103,7 @@
 		for (int i = 0; i < object->numVertices(); i += 1)
 		{
 			Vertex vertex = object->vertex(i);
-			vertex.transform(transformationMatrix(), position());
+			vertex.transform(transformationMatrix());
 			object->setVertex(i, vertex);
 		}
 
@@ -174,8 +171,9 @@
 		position().toString(true)
 	).simplified();
 
-	for (int i = 0; i < 9; ++i)
-		result += format("%1%2", transformationMatrix().value(i), (i != 8) ? " " : "");
+	for (int i = 0; i < 3; ++i)
+	for (int j = 0; j < 3; ++j)
+		result += format("%1%2", transformationMatrix()(i, j), (i != 2 or j != 2) ? " " : "");
 
 	result += ')';
 	return result;
--- a/src/linetypes/circularprimitive.h	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/linetypes/circularprimitive.h	Sun Jun 17 13:53:33 2018 +0300
@@ -12,8 +12,7 @@
 		PrimitiveModel::Type type,
 		int segments,
 		int divisions,
-		const Matrix& transformationMatrix,
-		const Vertex& position
+		const QMatrix4x4& matrix
 	);
 
 	LDObjectType type() const override;
--- a/src/linetypes/modelobject.cpp	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/linetypes/modelobject.cpp	Sun Jun 17 13:53:33 2018 +0300
@@ -51,11 +51,25 @@
 //
 QString LDSubfileReference::asText() const
 {
-	QString val = format ("1 %1 %2 ", color(), position());
-	val += transformationMatrix().toString();
-	val += ' ';
-	val += m_referenceName;
-	return val;
+	auto cellString = [&](int row, int column) { return QString::number(transformationMatrix()(row, column)); };
+
+	return QStringList {
+		"1",
+		color().indexString(),
+		cellString(0, 3), // x
+		cellString(1, 3), // y
+		cellString(2, 3), // z
+		cellString(0, 0), // matrix start
+		cellString(0, 1), // ...
+		cellString(0, 2), // ...
+		cellString(1, 0), // ...
+		cellString(1, 1), // ...
+		cellString(1, 2), // ...
+		cellString(2, 0), // ...
+		cellString(2, 1), // ...
+		cellString(2, 2), // matrix end
+		referenceName()
+	}.join(" ");
 }
 
 QString LDBezierCurve::asText() const
@@ -112,39 +126,25 @@
 
 // =============================================================================
 //
-static void TransformObject (LDObject* obj, Matrix transform, Vertex pos, LDColor parentcolor)
+static void TransformObject (LDObject* object, const QMatrix4x4& matrix, LDColor parentcolor)
 {
-	switch (obj->type())
+	if (object->hasMatrix()) {
+		LDMatrixObject* reference = static_cast<LDMatrixObject*>(object);
+		QMatrix4x4 newMatrix = matrix * reference->transformationMatrix();
+		reference->setTransformationMatrix(newMatrix);
+	}
+	else
 	{
-	case LDObjectType::EdgeLine:
-	case LDObjectType::ConditionalEdge:
-	case LDObjectType::Triangle:
-	case LDObjectType::Quadrilateral:
-		for (int i = 0; i < obj->numVertices(); ++i)
+		for (int i = 0; i < object->numVertices(); ++i)
 		{
-			Vertex v = obj->vertex (i);
-			v.transform (transform, pos);
-			obj->setVertex (i, v);
+			Vertex vertex = object->vertex(i);
+			vertex.transform(matrix);
+			object->setVertex(i, vertex);
 		}
-		break;
-
-	case LDObjectType::SubfileReference:
-		{
-			LDSubfileReference* ref = static_cast<LDSubfileReference*> (obj);
-			Matrix newMatrix = transform * ref->transformationMatrix();
-			Vertex newpos = ref->position();
-			newpos.transform (transform, pos);
-			ref->setPosition (newpos);
-			ref->setTransformationMatrix (newMatrix);
-		}
-		break;
-
-	default:
-		break;
 	}
 
-	if (obj->color() == MainColor)
-		obj->setColor (parentcolor);
+	if (object->color() == MainColor)
+		object->setColor(parentcolor);
 }
 
 /*
@@ -201,7 +201,7 @@
 			if (shouldInvert(parentWinding, context))
 				::invert(object, context);
 
-			TransformObject(object, transformationMatrix(), position(), color());
+			TransformObject(object, transformationMatrix(), color());
 		}
 
 		model.merge(inlined);
@@ -280,7 +280,7 @@
 		for (LDPolygon& entry : data)
 		{
 			for (int i = 0; i < entry.numVertices(); ++i)
-				entry.vertices[i].transform (transformationMatrix(), position());
+				entry.vertices[i].transform(transformationMatrix());
 
 			if (shouldInvert(parentWinding, context))
 				::invertPolygon(entry);
@@ -303,12 +303,12 @@
 //
 // Moves this object using the given vector
 //
-void LDObject::move (const QVector3D vector)
+void LDObject::move(const QVector3D& vector)
 {
 	if (hasMatrix())
 	{
 		LDMatrixObject* mo = static_cast<LDMatrixObject*> (this);
-		mo->setPosition (mo->position() + vector);
+		mo->translate(vector);
 	}
 	else
 	{
@@ -409,39 +409,32 @@
 	changeProperty(&m_coords[i], vert);
 }
 
-LDMatrixObject::LDMatrixObject (const Matrix& transform, const Vertex& pos) :
-	m_position (pos),
-	m_transformationMatrix (transform) {}
+LDMatrixObject::LDMatrixObject(const QMatrix4x4& matrix) :
+	m_transformationMatrix {matrix} {}
 
-void LDMatrixObject::setCoordinate (const Axis axis, double value)
+Vertex LDMatrixObject::position() const
 {
-	Vertex position = this->position();
-	position.setCoordinate(axis, value);
-	this->setPosition(position);
-}
-
-const Vertex& LDMatrixObject::position() const
-{
-	return m_position;
+	QVector4D column = m_transformationMatrix.column(3);
+	return {column.x(), column.y(), column.z()};
 }
 
 // =============================================================================
 //
-void LDMatrixObject::setPosition (const Vertex& a)
-{
-	changeProperty(&m_position, a);
-}
-
-// =============================================================================
-//
-const Matrix& LDMatrixObject::transformationMatrix() const
+const QMatrix4x4& LDMatrixObject::transformationMatrix() const
 {
 	return m_transformationMatrix;
 }
 
-void LDMatrixObject::setTransformationMatrix (const Matrix& val)
+void LDMatrixObject::translate(const QVector3D& offset)
 {
-	changeProperty(&m_transformationMatrix, val);
+	QMatrix4x4 matrix = transformationMatrix();
+	matrix.translate(offset);
+	setTransformationMatrix(matrix);
+}
+
+void LDMatrixObject::setTransformationMatrix(const QMatrix4x4& newMatrix)
+{
+	changeProperty(&m_transformationMatrix, newMatrix);
 }
 
 LDError::LDError (QString contents, QString reason) :
@@ -509,10 +502,9 @@
 
 LDSubfileReference::LDSubfileReference(
 	QString referenceName,
-	const Matrix& transformationMatrix,
-	const Vertex& position
+	const QMatrix4x4& matrix
 ) :
-	LDMatrixObject {transformationMatrix, position},
+	LDMatrixObject {matrix},
 	m_referenceName {referenceName} {}
 
 // =============================================================================
@@ -574,8 +566,9 @@
 {
 	QString result = format ("%1 %2, (", referenceName(), position().toString(true));
 
-	for (int i = 0; i < 9; ++i)
-		result += format("%1%2", transformationMatrix().value(i), (i != 8) ? " " : "");
+	for (int i = 0; i < 3; ++i)
+	for (int j = 0; j < 3; ++j)
+		result += format("%1%2", transformationMatrix()(i, j), (i != 2 or j != 2) ? " " : "");
 
 	result += ')';
 	return result;
@@ -606,7 +599,6 @@
 void LDMatrixObject::serialize(Serializer& serializer)
 {
 	LDObject::serialize(serializer);
-	serializer << m_position;
 	serializer << m_transformationMatrix;
 }
 
--- a/src/linetypes/modelobject.h	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/linetypes/modelobject.h	Sun Jun 17 13:53:33 2018 +0300
@@ -72,7 +72,7 @@
 	bool isHidden() const;
 	virtual bool isRasterizable() const { return false; } // Can this object be rasterized?
 	virtual bool isScemantic() const; // Does this object have meaning in the part model?
-	void move (const QVector3D vector);
+	void move (const QVector3D& vector);
 	virtual int numVertices() const;
 	virtual int numPolygonVertices() const;
 	virtual QString objectListText() const;
@@ -117,22 +117,20 @@
 {
 public:
 	LDMatrixObject() = default;
-	LDMatrixObject(const Matrix& transformationMatrix, const Vertex& pos);
+	LDMatrixObject(const QMatrix4x4& matrix);
 
 	bool hasMatrix() const override { return true; }
-	const Vertex& position() const;
-	void setCoordinate (const Axis ax, double value);
-	void setPosition (const Vertex& a);
-	void setTransformationMatrix (const Matrix& value);
-	const Matrix& transformationMatrix() const;
+	Vertex position() const;
+	void setTransformationMatrix(const QMatrix4x4& newMatrix);
+	const QMatrix4x4& transformationMatrix() const;
+	void translate(const QVector3D& offset);
 	void serialize(class Serializer& serializer) override;
 
 protected:
 	bool shouldInvert(Winding winding, DocumentManager* context);
 
 private:
-	Vertex m_position;
-	Matrix m_transformationMatrix = Matrix::identity;
+	QMatrix4x4 m_transformationMatrix;
 };
 
 /*
@@ -171,7 +169,7 @@
 	static const LDObjectType SubclassType = LDObjectType::SubfileReference;
 
 	LDSubfileReference() = default;
-	LDSubfileReference(QString referenceName, const Matrix& transformationMatrix, const Vertex& position);
+	LDSubfileReference(QString referenceName, const QMatrix4x4& matrix = {});
 
 	virtual LDObjectType type() const override
 	{
--- a/src/matrixinput.cpp	Sun Jun 10 23:25:08 2018 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-/*
- *  LDForge: LDraw parts authoring CAD
- *  Copyright (C) 2013 - 2018 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/>.
- */
-
-#include <QGridLayout>
-#include "matrixinput.h"
-
-MatrixInput::MatrixInput(QWidget *parent) : QWidget(parent)
-{
-	QGridLayout* layout = new QGridLayout {this};
-	setLayout(layout);
-
-	for (int i = 0; i < 3; ++i)
-	for (int j = 0; j < 3; ++j)
-	{
-		_spinboxes[i * 3 + j] = new QDoubleSpinBox {this};
-		layout->addWidget(_spinboxes[i * 3 + j], i, j);
-	}
-}
-
-int MatrixInput::decimals() const
-{
-	return _spinboxes[0]->decimals();
-}
-
-double MatrixInput::maximum() const
-{
-	return _spinboxes[0]->maximum();
-}
-
-double MatrixInput::minimum() const
-{
-	return _spinboxes[0]->minimum();
-}
-
-QString MatrixInput::prefix() const
-{
-	return _spinboxes[0]->prefix();
-}
-
-void MatrixInput::setDecimals(int precision)
-{
-	for (QDoubleSpinBox* spinbox : _spinboxes)
-		spinbox->setDecimals(precision);
-}
-
-void MatrixInput::setMaximum(double maximum)
-{
-	for (QDoubleSpinBox* spinbox : _spinboxes)
-		spinbox->setMaximum(maximum);
-}
-
-void MatrixInput::setMinimum(double minimum)
-{
-	for (QDoubleSpinBox* spinbox : _spinboxes)
-		spinbox->setMinimum(minimum);
-}
-
-void MatrixInput::setPrefix(const QString& prefix)
-{
-	for (QDoubleSpinBox* spinbox : _spinboxes)
-		spinbox->setPrefix(prefix);
-}
-
-void MatrixInput::setRange(double minimum, double maximum)
-{
-	for (QDoubleSpinBox* spinbox : _spinboxes)
-		spinbox->setRange(minimum, maximum);
-}
-
-void MatrixInput::setSingleStep(double singleStep)
-{
-	for (QDoubleSpinBox* spinbox : _spinboxes)
-		spinbox->setSingleStep(singleStep);
-}
-
-void MatrixInput::setSuffix(const QString& suffix)
-{
-	for (QDoubleSpinBox* spinbox : _spinboxes)
-		spinbox->setSuffix(suffix);
-}
-
-QString MatrixInput::suffix()
-{
-	return _spinboxes[0]->suffix();
-}
-
-void MatrixInput::setValue(const Matrix& value)
-{
-	for (int i = 0; i < 3; ++i)
-	for (int j = 0; j < 3; ++j)
-		_spinboxes[i * 3 + j]->setValue(value(i, j));
-}
-
-Matrix MatrixInput::value()
-{
-	Matrix result;
-
-	for (int i = 0; i < 3; ++i)
-	for (int j = 0; j < 3; ++j)
-		result(i, j) = _spinboxes[i * 3 + j]->value();
-
-	return result;
-}
--- a/src/matrixinput.h	Sun Jun 10 23:25:08 2018 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- *  LDForge: LDraw parts authoring CAD
- *  Copyright (C) 2013 - 2018 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 "main.h"
-#include <QDoubleSpinBox>
-
-/*
- * Models a 3×3 array of spinboxes for matrix input.
- */
-class MatrixInput : public QWidget
-{
-	Q_OBJECT
-
-public:
-	explicit MatrixInput(QWidget *parent = 0);
-	int decimals() const;
-	double maximum() const;
-	double minimum() const;
-	QString prefix() const;
-	void setDecimals(int precision);
-	void setMaximum(double maximum);
-	void setMinimum(double minimum);
-	void setPrefix(const QString& prefix);
-	void setRange(double minimum, double maximum);
-	void setSingleStep(double singleStep);
-	void setSuffix(const QString& suffix);
-	QString suffix();
-	void setValue(const Matrix& value);
-	Matrix value();
-
-private:
-	QDoubleSpinBox* _spinboxes[9];
-};
--- a/src/parser.cpp	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/parser.cpp	Sun Jun 17 13:53:33 2018 +0300
@@ -383,12 +383,14 @@
 				CheckTokenNumbers (tokens, 1, 13);
 
 				Vertex displacement = parseVertex (tokens, 2);  // 2 - 4
-				Matrix transform;
+				QMatrix4x4 matrix;
+				matrix.translate(displacement.x, displacement.y, displacement.z);
 				QString referenceName = tokens[14];
 
 				for (int i = 0; i < 9; ++i)
-					transform.value(i) = tokens[i + 5].toDouble(); // 5 - 13
+					matrix(i / 3, i % 3) = tokens[i + 5].toDouble(); // 5 - 13
 
+				matrix.optimize();
 				static const QRegExp circularPrimitiveRegexp {R"((?:(\d+)\\)?(\d+)-(\d+)(cyli|edge|disc|ndis)\.dat)"};
 				LDObject* obj;
 
@@ -417,13 +419,12 @@
 						type,
 						segments,
 						resolution,
-						transform,
-						displacement
+						matrix
 					);
 				}
 				else
 				{
-					obj = model.emplaceAt<LDSubfileReference>(position, referenceName, transform, displacement);
+					obj = model.emplaceAt<LDSubfileReference>(position, referenceName, matrix);
 				}
 
 				obj->setColor(LDColor {tokens[1].toInt(nullptr, 0)});
--- a/src/toolsets/algorithmtoolset.cpp	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/toolsets/algorithmtoolset.cpp	Sun Jun 17 13:53:33 2018 +0300
@@ -161,17 +161,12 @@
 
 		if (mo)
 		{
-			Vertex position = mo->position();
-			Matrix matrix = mo->transformationMatrix();
+			QMatrix4x4 matrix = mo->transformationMatrix();
 
-			for (Axis axis : {X, Y, Z})
-				position[axis] = roundToDecimals(position[axis], config::roundPositionPrecision());
-
-			for (int i : {0, 1, 2})
-			for (int j : {0, 1, 2})
+			for (int i : {0, 1, 2, 3})
+			for (int j : {0, 1, 2, 3})
 				matrix(i, j) = roundToDecimals(matrix(i, j), config::roundMatrixPrecision());
 
-			mo->setPosition(position);
 			mo->setTransformationMatrix(matrix);
 			num += 12;
 		}
@@ -266,12 +261,14 @@
 					fixVertex(point);
 					object->setVertex(i, point);
 				}
-				if (object->type() == LDObjectType::SubfileReference)
+				if (object->hasMatrix())
 				{
-					LDSubfileReference* reference = static_cast<LDSubfileReference*>(object);
+					LDMatrixObject* reference = static_cast<LDMatrixObject*>(object);
 					Vertex point = reference->position();
 					fixVertex(point);
-					reference->setPosition(point);
+					QMatrix4x4 matrix = reference->transformationMatrix();
+					matrix.setColumn(3, {(float) point.x, (float) point.y, (float) point.z, 1});
+					reference->setTransformationMatrix(matrix);
 				}
 			}
 		}
@@ -607,7 +604,7 @@
 			currentDocument()->remove(object);
 
 		// Add a reference to the new subfile to where the selection was
-		currentDocument()->emplaceAt<LDSubfileReference>(referencePosition, subfile->name(), Matrix::identity, Vertex {0, 0, 0});
+		currentDocument()->emplaceAt<LDSubfileReference>(referencePosition, subfile->name());
 
 		// Refresh stuff
 		m_window->updateDocumentList();
--- a/src/toolsets/movetoolset.cpp	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/toolsets/movetoolset.cpp	Sun Jun 17 13:53:33 2018 +0300
@@ -116,7 +116,7 @@
 
 double MoveToolset::getRotateActionAngle()
 {
-	return (pi * grid()->angleSnap()) / 180;
+	return grid()->angleSnap();
 }
 
 void MoveToolset::rotateXPos()
--- a/src/types/matrix.cpp	Sun Jun 10 23:25:08 2018 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,265 +0,0 @@
-/*
- *  LDForge: LDraw parts authoring CAD
- *  Copyright (C) 2013 - 2018 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/>.
- */
-
-#include "../basics.h"
-#include "../format.h"
-#include "matrix.h"
-
-const Matrix Matrix::identity {1, 0, 0, 0, 1, 0, 0, 0, 1};
-
-/*
- * Default-constructor for a matrix
- */
-Matrix::Matrix() :
-    m_values{0} {}
-
-/*
- * Constructs a matrix from a single fill value.
- */
-Matrix::Matrix (double fillvalue) :
-    m_values {fillvalue} {}
-
-/*
- * Constructs a matrix from an initializer list.
- * Note: the initializer list must have exactly 9 values.
- */
-Matrix::Matrix (const std::initializer_list<double>& values)
-{
-	int i = 0;
-
-	for (double value : values)
-	{
-		if (i < 9)
-			m_values[i++] = value;
-		else
-			break;
-	}
-}
-
-/*
- * Returns a string representation of the matrix
- */
-QString Matrix::toString() const
-{
-	QString val;
-
-	for (int i = 0; i < 9; ++i)
-	{
-		if (i > 0)
-			val += ' ';
-
-		val += QString::number (m_values[i]);
-	}
-
-	return val;
-}
-
-/*
- * Fills the matrix with zeros
- */
-void Matrix::zero()
-{
-	for (double& value : m_values)
-		value = 0;
-}
-
-/*
- * Performs matrix multiplication.
- * Note: A*B is not equivalent to B*A!
- */
-Matrix Matrix::multiply (const Matrix& other) const
-{
-	Matrix result;
-
-	for (int i = 0; i < 3; ++i)
-	for (int j = 0; j < 3; ++j)
-	for (int k = 0; k < 3; ++k)
-		result(i, j) += (*this)(i, k) * other(k, j);
-
-	return result;
-}
-
-/*
- * Returns the matrix's determinant
- */
-double Matrix::determinant() const
-{
-	return (value (0) * value (4) * value (8)) +
-		   (value (1) * value (5) * value (6)) +
-		   (value (2) * value (3) * value (7)) -
-		   (value (2) * value (4) * value (6)) -
-		   (value (1) * value (3) * value (8)) -
-		   (value (0) * value (5) * value (7));
-}
-
-/*
- * Returns a value in matrix value (index math must be done manually)
- */
-double& Matrix::value(int index)
-{
-	return m_values[index];
-}
-
-/*
- * Returns a value in matrix value (index math must be done manually)
- */
-const double& Matrix::value(int index) const
-{
-	return m_values[index];
-}
-
-/*
- * Performs matrix multiplication
- */
-Matrix Matrix::operator*(const Matrix &other) const
-{
-	return multiply(other);
-}
-
-/*
- * Returns a row of the matrix
- */
-Matrix::RowView Matrix::operator[](int row)
-{
-	return RowView {*this, row};
-}
-
-/*
- * Returns a row of the matrix
- */
-Matrix::ConstRowView Matrix::operator[](int row) const
-{
-	return ConstRowView {*this, row};
-}
-
-/*
- * Checks whether the two matrices are equal
- */
-bool Matrix::operator==(const Matrix& other) const
-{
-	for (int i = 0; i < countof(m_values); ++i)
-	{
-		if (not qFuzzyCompare(m_values[i], other.m_values[i]))
-			return false;
-	}
-	return true;
-}
-
-/**
- * @brief Matrix::operator !=
- * @param other
- * @return whether the two matrices are not equal
- */
-bool Matrix::operator!=(const Matrix& other) const
-{
-	return not operator==(other);
-}
-
-double& Matrix::operator()(int row, int column)
-{
-	return m_values[row * 3 + column];
-}
-
-const double& Matrix::operator()(int row, int column) const
-{
-	return m_values[row * 3 + column];
-}
-
-double* Matrix::begin()
-{
-	return m_values;
-}
-
-const double* Matrix::begin() const
-{
-	return m_values;
-}
-
-double* Matrix::end()
-{
-	return m_values + countof(m_values);
-}
-
-const double* Matrix::end() const
-{
-	return m_values + countof(m_values);
-}
-
-Matrix::RowView::RowView(Matrix &matrix, int row) :
-    _matrix {matrix},
-    _row {row} {}
-
-double& Matrix::RowView::operator[](int column)
-{
-	return _matrix.value(_row * 3 + column);
-}
-
-Matrix& Matrix::RowView::matrix() const
-{
-	return _matrix;
-}
-
-int Matrix::RowView::row()
-{
-	return _row;
-}
-
-Matrix::ConstRowView::ConstRowView(const Matrix &matrix, int row) :
-    _matrix {matrix},
-    _row {row} {}
-
-const double& Matrix::ConstRowView::operator[](int column)
-{
-	return _matrix.value(_row * 3 + column);
-}
-
-const Matrix& Matrix::ConstRowView::matrix() const
-{
-	return _matrix;
-}
-
-int Matrix::ConstRowView::row()
-{
-	return _row;
-}
-
-Matrix Matrix::fromQMatrix(const QMatrix4x4& matrix)
-{
-	Matrix result;
-
-	for (int i = 0; i < 3; ++i)
-	for (int j = 0; j < 3; ++j)
-		result(i, j) = matrix(i, j);
-
-	return result;
-}
-
-Matrix Matrix::scaleMatrix(qreal scalar)
-{
-	return {
-		scalar, 0, 0,
-		0, scalar, 0,
-		0, 0, scalar
-	};
-}
-
-Matrix& Matrix::operator*=(const Matrix& other)
-{
-	*this = *this * other;
-	return *this;
-}
--- a/src/types/matrix.h	Sun Jun 10 23:25:08 2018 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- *  LDForge: LDraw parts authoring CAD
- *  Copyright (C) 2013 - 2018 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 <QString>
-#include <QMetaType>
-
-/*
- * A mathematical 3 × 3 matrix
- */
-class Matrix
-{
-public:
-	class RowView;
-	class ConstRowView;
-
-	Matrix();
-	Matrix (const std::initializer_list<double>& values);
-	Matrix (double fillval);
-
-	double* begin();
-	const double* begin() const;
-	double determinant() const;
-	double* end();
-	const double* end() const;
-	Matrix multiply(const Matrix& other) const;
-	QString toString() const;
-	double& value(int index);
-	const double& value(int index) const;
-	void zero();
-
-	bool operator==(const Matrix& other) const;
-	bool operator!=(const Matrix& other) const;
-	Matrix operator*(const Matrix& other) const;
-	RowView operator[](int row);
-	ConstRowView operator[](int row) const;
-	double& operator()(int row, int column);
-	const double& operator()(int row, int column) const;
-	Matrix& operator*=(const Matrix& other);
-
-	static const Matrix identity;
-	static Matrix fromQMatrix(const QMatrix4x4& matrix);
-	static Matrix scaleMatrix(qreal scalar);
-
-private:
-	double m_values[9];
-};
-
-Q_DECLARE_METATYPE(Matrix)
-
-/*
- * A structure that provides a view into a row in a matrix.
- * This is returned by operator[] so that the matrix can be accessed by A[i][j]
- */
-class Matrix::RowView
-{
-public:
-	RowView(Matrix &matrix, int row);
-	double& operator[](int column);
-	Matrix& matrix() const;
-	int row();
-
-private:
-	Matrix& _matrix;
-	const int _row;
-};
-
-/*
- * Const version of the above
- */
-class Matrix::ConstRowView
-{
-public:
-	ConstRowView(const Matrix &matrix, int row);
-	const double& operator[](int column);
-	const Matrix& matrix() const;
-	int row();
-
-private:
-	const Matrix& _matrix;
-	const int _row;
-};
--- a/src/types/vertex.cpp	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/types/vertex.cpp	Sun Jun 17 13:53:33 2018 +0300
@@ -19,14 +19,28 @@
 #include "vertex.h"
 #include "../format.h"
 
-void Vertex::transform(const Matrix& matrix, const Vertex& pos)
+template<typename MatrixType>
+void transformVertex(Vertex& vertex, const MatrixType& matrix)
 {
-	double x2 = (matrix(0, 0) * x) + (matrix(0, 1) * y) + (matrix(0, 2) * z) + pos.x;
-	double y2 = (matrix(1, 0) * x) + (matrix(1, 1) * y) + (matrix(1, 2) * z) + pos.y;
-	double z2 = (matrix(2, 0) * x) + (matrix(2, 1) * y) + (matrix(2, 2) * z) + pos.z;
-	this->x = x2;
-	this->y = y2;
-	this->z = z2;
+	double newX = (matrix(0, 0) * vertex.x) + (matrix(0, 1) * vertex.y) + (matrix(0, 2) * vertex.z);
+	double newY = (matrix(1, 0) * vertex.x) + (matrix(1, 1) * vertex.y) + (matrix(1, 2) * vertex.z);
+	double newZ = (matrix(2, 0) * vertex.x) + (matrix(2, 1) * vertex.y) + (matrix(2, 2) * vertex.z);
+	vertex.x = newX;
+	vertex.y = newY;
+	vertex.z = newZ;
+}
+
+void Vertex::transform(const QMatrix4x4& matrix)
+{
+	transformVertex(*this, matrix);
+	x += matrix(0, 3);
+	y += matrix(1, 3);
+	z += matrix(2, 3);
+}
+
+void Vertex::rotate(const QQuaternion& orientation)
+{
+	*this = Vertex {0, 0, 0} + orientation.rotatedVector(toVector());
 }
 
 void Vertex::apply(ApplyFunction func)
--- a/src/types/vertex.h	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/types/vertex.h	Sun Jun 17 13:53:33 2018 +0300
@@ -32,7 +32,8 @@
 	void apply(ApplyConstFunction func) const;
 	QString toString(bool mangled = false) const;
 	QVector3D toVector() const;
-	void transform(const class Matrix& matrix, const Vertex& pos);
+	void transform(const QMatrix4x4& matrix);
+	void rotate(const QQuaternion& orientation);
 	Vertex transformed(const GLRotationMatrix& matrix) const;
 	void setCoordinate(Axis ax, qreal value);
 
--- a/src/widgets/matrixeditor.cpp	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/widgets/matrixeditor.cpp	Sun Jun 17 13:53:33 2018 +0300
@@ -1,12 +1,11 @@
 #include "matrixeditor.h"
 #include "ui_matrixeditor.h"
 
-MatrixEditor::MatrixEditor(const Matrix& matrix, const Vertex& position, QWidget *parent) :
+MatrixEditor::MatrixEditor(const QMatrix4x4& matrix, QWidget *parent) :
 	QWidget {parent},
 	ui {*new Ui_MatrixEditor}
 {
 	this->ui.setupUi(this);
-	this->setPosition(position);
 	this->setMatrix(matrix);
 
 	for (int i : {0, 1, 2})
@@ -32,7 +31,7 @@
 }
 
 MatrixEditor::MatrixEditor(QWidget* parent) :
-	MatrixEditor {Matrix::identity, {0, 0, 0}, parent} {}
+	MatrixEditor {{}, parent} {}
 
 MatrixEditor::~MatrixEditor()
 {
@@ -152,18 +151,9 @@
 	catch (const std::out_of_range&) {}
 }
 
-Vertex MatrixEditor::position() const
+QMatrix4x4 MatrixEditor::matrix() const
 {
-	return {
-		this->ui.positionX->value(),
-		this->ui.positionY->value(),
-		this->ui.positionZ->value()
-	};
-}
-
-Matrix MatrixEditor::matrix() const
-{
-	Matrix transformationMatrix;
+	QMatrix4x4 transformationMatrix;
 
 	for (int i : {0, 1, 2})
 	for (int j : {0, 1, 2})
@@ -171,17 +161,11 @@
 		transformationMatrix(i, j) = this->matrixCell(i, j)->value();
 	}
 
+	transformationMatrix.translate(ui.positionX->value(), ui.positionY->value(), ui.positionZ->value());
 	return transformationMatrix;
 }
 
-void MatrixEditor::setPosition(const Vertex& position)
-{
-	this->ui.positionX->setValue(position.x);
-	this->ui.positionY->setValue(position.y);
-	this->ui.positionZ->setValue(position.z);
-}
-
-void MatrixEditor::setMatrix(const Matrix& matrix)
+void MatrixEditor::setMatrix(const QMatrix4x4& matrix)
 {
 	for (int i : {0, 1, 2})
 	for (int j : {0, 1, 2})
@@ -190,6 +174,10 @@
 		withSignalsBlocked(spinbox, [&](){ spinbox->setValue(matrix(i, j)); });
 	}
 
+	ui.positionX->setValue(matrix(0, 3));
+	ui.positionY->setValue(matrix(1, 3));
+	ui.positionZ->setValue(matrix(2, 3));
+
 	// Fill in the initial scaling values
 	for (int column : {0, 1, 2})
 	{
--- a/src/widgets/matrixeditor.h	Sun Jun 10 23:25:08 2018 +0300
+++ b/src/widgets/matrixeditor.h	Sun Jun 17 13:53:33 2018 +0300
@@ -10,18 +10,12 @@
 	Q_OBJECT
 
 public:
-	MatrixEditor(
-		const Matrix& matrix = Matrix::identity,
-		const Vertex& position = {0, 0, 0},
-		QWidget* parent = nullptr
-	);
+	MatrixEditor(const QMatrix4x4& matrix = {}, QWidget* parent = nullptr);
 	MatrixEditor(QWidget* parent);
 	~MatrixEditor();
 
-	Vertex position() const;
-	Matrix matrix() const;
-	void setPosition(const Vertex& position);
-	void setMatrix(const Matrix& matrix);
+	QMatrix4x4 matrix() const;
+	void setMatrix(const QMatrix4x4& matrix);
 
 private slots:
 	void scalingChanged();

mercurial