replaced matrix and vertex classes with glm

Sun, 26 Jan 2020 14:29:30 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Sun, 26 Jan 2020 14:29:30 +0200
changeset 33
4c41bfe2ec6e
parent 32
767592024ec5
child 34
1de2b8d64e9f

replaced matrix and vertex classes with glm

CMakeLists.txt file | annotate | diff | comparison | revisions
src/basics.h file | annotate | diff | comparison | revisions
src/gl/common.h file | annotate | diff | comparison | revisions
src/gl/compiler.cpp file | annotate | diff | comparison | revisions
src/gl/compiler.h file | annotate | diff | comparison | revisions
src/invert.cpp file | annotate | diff | comparison | revisions
src/invert.h file | annotate | diff | comparison | revisions
src/linetypes/conditionaledge.cpp file | annotate | diff | comparison | revisions
src/linetypes/conditionaledge.h file | annotate | diff | comparison | revisions
src/linetypes/edge.cpp file | annotate | diff | comparison | revisions
src/linetypes/edge.h file | annotate | diff | comparison | revisions
src/linetypes/object.h file | annotate | diff | comparison | revisions
src/linetypes/quadrilateral.cpp file | annotate | diff | comparison | revisions
src/linetypes/quadrilateral.h file | annotate | diff | comparison | revisions
src/linetypes/subfilereference.cpp file | annotate | diff | comparison | revisions
src/linetypes/subfilereference.h file | annotate | diff | comparison | revisions
src/linetypes/triangle.cpp file | annotate | diff | comparison | revisions
src/linetypes/triangle.h file | annotate | diff | comparison | revisions
src/maths.h file | annotate | diff | comparison | revisions
src/matrix.cpp file | annotate | diff | comparison | revisions
src/matrix.h file | annotate | diff | comparison | revisions
src/parser.cpp file | annotate | diff | comparison | revisions
src/types/boundingbox.cpp file | annotate | diff | comparison | revisions
src/types/boundingbox.h file | annotate | diff | comparison | revisions
src/utility.h file | annotate | diff | comparison | revisions
src/vertex.cpp file | annotate | diff | comparison | revisions
src/vertex.h file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Sun Jan 26 01:06:27 2020 +0200
+++ b/CMakeLists.txt	Sun Jan 26 14:29:30 2020 +0200
@@ -29,13 +29,11 @@
 	src/invert.cpp
 	src/main.cpp
 	src/mainwindow.cpp
-	src/matrix.cpp
 	src/model.cpp
 	src/modeleditcontext.cpp
 	src/parser.cpp
 	src/uiutilities.cpp
 	src/version.cpp
-	src/vertex.cpp
 	src/gl/compiler.cpp
 	src/gl/partrenderer.cpp
 	src/linetypes/comment.cpp
@@ -63,7 +61,6 @@
 	src/main.h
 	src/mainwindow.h
 	src/maths.h
-	src/matrix.h
 	src/model.h
 	src/modeleditcontext.h
 	src/parser.h
@@ -71,7 +68,6 @@
 	src/uiutilities.h
 	src/utility.h
 	src/version.h
-	src/vertex.h
 	src/gl/common.h
 	src/gl/compiler.h
 	src/gl/partrenderer.h
--- a/src/basics.h	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/basics.h	Sun Jan 26 14:29:30 2020 +0200
@@ -31,6 +31,7 @@
 #include <QVariant>
 #include <QVector>
 #include <QVector3D>
+#include <glm/glm.hpp>
 
 using GLRotationMatrix = QMatrix4x4;
 
@@ -83,3 +84,6 @@
 {
 	return N;
 }
+
+Q_DECLARE_METATYPE(glm::vec3)
+Q_DECLARE_METATYPE(glm::mat4)
--- a/src/gl/common.h	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/gl/common.h	Sun Jan 26 14:29:30 2020 +0200
@@ -22,7 +22,6 @@
 #include <QGenericMatrix>
 #include "basics.h"
 #include "colors.h"
-#include "vertex.h"
 
 namespace gl
 {
@@ -33,13 +32,7 @@
 	static const QMatrix4x4 bottomCameraMatrix = {1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1};
 	static const QMatrix4x4 backCameraMatrix = {-1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1};
 	static const QMatrix4x4 rightCameraMatrix = {0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1};
-
-	// Conversion matrix from LDraw to OpenGL coordinates.
-	static const QMatrix4x4 ldrawToGL = {1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1};
-
 	static constexpr QRgb BlackRgb = 0xff000000;
-	static constexpr GLfloat near = 1.0f;
-	static constexpr GLfloat far = 10000.0f;
 	struct Polygon;
 }
 
@@ -53,7 +46,7 @@
 		ConditionalEdge
 	};
 	Type type;
-	Point3D vertices[4];
+	glm::vec3 vertices[4];
 	Color color;
 	linetypes::Id id;
 
@@ -91,15 +84,15 @@
 
 namespace gl
 {
-	inline Polygon edgeLine(const Point3D& v_1, const Point3D& v_2, Color color, linetypes::Id id)
+	inline Polygon edgeLine(const glm::vec3& v_1, const glm::vec3& v_2, Color color, linetypes::Id id)
 	{
 		return {Polygon::EdgeLine, {v_1, v_2}, color, id};
 	}
 
 	inline Polygon triangle(
-		const Point3D& v_1,
-		const Point3D& v_2,
-		const Point3D& v_3,
+		const glm::vec3& v_1,
+		const glm::vec3& v_2,
+		const glm::vec3& v_3,
 		Color color,
 		linetypes::Id id)
 	{
@@ -107,10 +100,10 @@
 	}
 
 	inline Polygon quadrilateral(
-		const Point3D& v_1,
-		const Point3D& v_2,
-		const Point3D& v_3,
-		const Point3D& v_4,
+		const glm::vec3& v_1,
+		const glm::vec3& v_2,
+		const glm::vec3& v_3,
+		const glm::vec3& v_4,
 		Color color,
 		linetypes::Id id)
 	{
@@ -118,10 +111,10 @@
 	}
 
 	inline Polygon conditionalEdge(
-		const Point3D& v_1,
-		const Point3D& v_2,
-		const Point3D& control_1,
-		const Point3D& control_2,
+		const glm::vec3& v_1,
+		const glm::vec3& v_2,
+		const glm::vec3& control_1,
+		const glm::vec3& control_2,
 		Color color,
 		linetypes::Id id)
 	{
--- a/src/gl/compiler.cpp	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/gl/compiler.cpp	Sun Jan 26 14:29:30 2020 +0200
@@ -166,9 +166,9 @@
 	reserveMore(normalsBuffer, polygon.numPolygonVertices() * 3_z);
 	for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1)
 	{
-		const Point3D& v1 = vertexRing[i - 1];
-		const Point3D& v2 = vertexRing[i];
-		const Point3D& v3 = vertexRing[i + 1];
+		const glm::vec3& v1 = vertexRing[i - 1];
+		const glm::vec3& v2 = vertexRing[i];
+		const glm::vec3& v3 = vertexRing[i + 1];
 		const QVector3D normal = QVector3D::crossProduct(v3 - v2, v1 - v2).normalized();
 		for (const GLfloat coord : {normal.x(), normal.y(), normal.z()})
 			normalsBuffer.push_back(coord);
@@ -179,7 +179,7 @@
 	// Transform vertices so that they're suitable for GL rendering
 	for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1)
 	{
-		Point3D& point = polygon.vertices[i];
+		glm::vec3& point = polygon.vertices[i];
 		this->boundingBox.consider(polygon.vertices[i]);
 		vertexBuffer.push_back(static_cast<GLfloat>(point.x));
 		vertexBuffer.push_back(static_cast<GLfloat>(point.y));
@@ -212,7 +212,7 @@
 	return color;
 }
 
-Point3D gl::Compiler::modelCenter() const
+glm::vec3 gl::Compiler::modelCenter() const
 {
 	return boxCenter(this->boundingBox);
 }
--- a/src/gl/compiler.h	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/gl/compiler.h	Sun Jan 26 14:29:30 2020 +0200
@@ -20,7 +20,6 @@
 #include "main.h"
 #include "gl/common.h"
 #include "types/boundingbox.h"
-#include <glm/glm.hpp>
 #include <glm/gtc/type_ptr.hpp>
 #include <QMap>
 #include <QSet>
@@ -54,7 +53,7 @@
 	void buildPolygon(Polygon polygon, std::vector<GLfloat>* vboData);
 	std::size_t vboSize(gl::ArrayClass arrayClass) const;
 	QColor getColorForPolygon(const gl::Polygon& polygon);
-	Point3D modelCenter() const;
+	glm::vec3 modelCenter() const;
 	double modelDistance() const;
 	void initialize();
 	void bindVertexArray(gl::ArrayClass arrayClass);
--- a/src/invert.cpp	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/invert.cpp	Sun Jan 26 14:29:30 2020 +0200
@@ -18,7 +18,6 @@
 
 #include "main.h"
 #include "model.h"
-#include "matrix.h"
 #include "gl/common.h"
 #include "invert.h"
 
@@ -73,10 +72,11 @@
 /*
  * Returns a matrix that causes a flip on the given dimension.
  */
-Matrix4x4 math::flipmatrix(const Axis dimension)
+glm::mat4 math::flipmatrix(const Axis dimension)
 {
-	Matrix4x4 result = identity4x4;
-	result(static_cast<int>(dimension), static_cast<int>(dimension)) = -1;
+	glm::mat4 result = glm::mat4();
+	const int k = static_cast<int>(dimension);
+	result[k][k] = -1;
 	return result;
 }
 
--- a/src/invert.h	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/invert.h	Sun Jan 26 14:29:30 2020 +0200
@@ -18,14 +18,13 @@
 
 #pragma once
 #include "main.h"
-#include "matrix.h"
 #include "gl/common.h"
 
 bool isflat(class Model* model, Axis* axis);
 
 namespace math
 {
-	Matrix4x4 flipmatrix(Axis dimension);
+	glm::mat4 flipmatrix(Axis dimension);
 }
 //void invert(LDObject* obj, class DocumentManager* context);
 
--- a/src/linetypes/conditionaledge.cpp	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/linetypes/conditionaledge.cpp	Sun Jan 26 14:29:30 2020 +0200
@@ -1,10 +1,10 @@
 #include "conditionaledge.h"
 
 linetypes::ConditionalEdge::ConditionalEdge(
-	const Point3D& point_1,
-	const Point3D& point_2,
-	const Point3D& controlPoint_1,
-	const Point3D& controlPoint_2,
+	const glm::vec3& point_1,
+	const glm::vec3& point_2,
+	const glm::vec3& controlPoint_1,
+	const glm::vec3& controlPoint_2,
 	const Color color_index) :
 	Edge{point_1, point_2, color_index},
 	controlPoint_1{controlPoint_1},
@@ -12,7 +12,7 @@
 {
 }
 
-linetypes::ConditionalEdge::ConditionalEdge(const QVector<Point3D>& vertices, const Color color) :
+linetypes::ConditionalEdge::ConditionalEdge(const QVector<glm::vec3>& vertices, const Color color) :
 	Edge{vertices[0], vertices[1], color},
 	controlPoint_1{vertices[2]},
 	controlPoint_2{vertices[3]}
@@ -24,9 +24,9 @@
 	switch (property)
 	{
 	case Property::ControlPoint1:
-		return controlPoint_1;
+		return QVariant::fromValue(controlPoint_1);
 	case Property::ControlPoint2:
-		return controlPoint_2;
+		return QVariant::fromValue(controlPoint_2);
 	default:
 		return Edge::getProperty(property);
 	}
@@ -40,9 +40,9 @@
 	switch (property)
 	{
 	case Property::ControlPoint1:
-		controlPoint_1 = value.value<Point3D>();
+		controlPoint_1 = value.value<glm::vec3>();
 	case Property::ControlPoint2:
-		controlPoint_2 = value.value<Point3D>();
+		controlPoint_2 = value.value<glm::vec3>();
 	default:
 		return Edge::setProperty(property, value);
 	}
@@ -51,6 +51,6 @@
 QString linetypes::ConditionalEdge::textRepresentation() const
 {
 	return Edge::textRepresentation() + utility::format("%1 %2",
-		vertexToStringParens(controlPoint_1),
-		vertexToStringParens(controlPoint_2));
+		utility::vertexToStringParens(controlPoint_1),
+		utility::vertexToStringParens(controlPoint_2));
 }
--- a/src/linetypes/conditionaledge.h	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/linetypes/conditionaledge.h	Sun Jan 26 14:29:30 2020 +0200
@@ -11,18 +11,18 @@
 public:
 	ConditionalEdge() = default;
 	ConditionalEdge(
-		const Point3D& point_1,
-		const Point3D& point_2,
-		const Point3D& controlPoint_1,
-		const Point3D& controlPoint_2,
+		const glm::vec3& point_1,
+		const glm::vec3& point_2,
+		const glm::vec3& controlPoint_1,
+		const glm::vec3& controlPoint_2,
 		const Color colorIndex = colors::edge);
-	ConditionalEdge(const QVector<Point3D>& vertices, const Color color);
+	ConditionalEdge(const QVector<glm::vec3>& vertices, const Color color);
 	QVariant getProperty(Property property) const override;
 	SetPropertyResult setProperty(
 		Property property,
 		const QVariant& value) override;
 	QString textRepresentation() const override;
 private:
-	Point3D controlPoint_1 = {};
-	Point3D controlPoint_2 = {};
+	glm::vec3 controlPoint_1 = {};
+	glm::vec3 controlPoint_2 = {};
 };
--- a/src/linetypes/edge.cpp	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/linetypes/edge.cpp	Sun Jan 26 14:29:30 2020 +0200
@@ -1,14 +1,14 @@
 #include "edge.h"
 
 linetypes::Edge::Edge(
-	const Point3D& point_1,
-	const Point3D& point_2,
+	const glm::vec3& point_1,
+	const glm::vec3& point_2,
 	const Color color_index) :
 	ColoredObject{color_index},
 	point_1{point_1},
 	point_2{point_2} {}
 
-linetypes::Edge::Edge(const QVector<Point3D>& vertices, const Color color) :
+linetypes::Edge::Edge(const QVector<glm::vec3>& vertices, const Color color) :
 	ColoredObject{color},
 	point_1{vertices[0]},
 	point_2{vertices[1]}
@@ -20,9 +20,9 @@
 	switch (property)
 	{
 	case Property::Point1:
-		return point_1;
+		return QVariant::fromValue(point_1);
 	case Property::Point2:
-		return point_2;
+		return QVariant::fromValue(point_2);
 	default:
 		return BaseClass::getProperty(property);
 	}
@@ -34,10 +34,10 @@
 	switch (property)
 	{
 	case Property::Point1:
-		point_1 = value.value<Point3D>();
+		point_1 = value.value<glm::vec3>();
 		return SetPropertyResult::Success;
 	case Property::Point2:
-		point_2 = value.value<Point3D>();
+		point_2 = value.value<glm::vec3>();
 		return SetPropertyResult::Success;
 	default:
 		return BaseClass::setProperty(property, value);
@@ -46,7 +46,7 @@
 
 QString linetypes::Edge::textRepresentation() const
 {
-	return utility::format("%1 %2", vertexToStringParens(point_1), vertexToStringParens(point_2));
+	return utility::format("%1 %2", utility::vertexToStringParens(point_1), utility::vertexToStringParens(point_2));
 }
 
 void linetypes::Edge::getPolygons(
--- a/src/linetypes/edge.h	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/linetypes/edge.h	Sun Jan 26 14:29:30 2020 +0200
@@ -11,9 +11,9 @@
 public:
 	using BaseClass = ColoredObject;
 	Edge() = default;
-	Edge(const Point3D& point_1, const Point3D& point_2,
+	Edge(const glm::vec3& point_1, const glm::vec3& point_2,
 		 const Color colorIndex = colors::edge);
-	Edge(const QVector<Point3D>& vertices, const Color color);
+	Edge(const QVector<glm::vec3>& vertices, const Color color);
 	QVariant getProperty(Property property) const override;
 	SetPropertyResult setProperty(
 		Property property,
@@ -21,6 +21,6 @@
 	QString textRepresentation() const override;
 	void getPolygons(std::vector<gl::Polygon>& polygons, GetPolygonsContext* context) const override;
 private:
-	Point3D point_1 = {};
-	Point3D point_2 = {};
+	glm::vec3 point_1 = {};
+	glm::vec3 point_2 = {};
 };
--- a/src/linetypes/object.h	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/linetypes/object.h	Sun Jan 26 14:29:30 2020 +0200
@@ -4,7 +4,6 @@
 #include <QStringView>
 #include "main.h"
 #include "colors.h"
-#include "vertex.h"
 #include "gl/common.h"
 
 namespace linetypes
--- a/src/linetypes/quadrilateral.cpp	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/linetypes/quadrilateral.cpp	Sun Jan 26 14:29:30 2020 +0200
@@ -1,17 +1,17 @@
 #include "quadrilateral.h"
 
 linetypes::Quadrilateral::Quadrilateral(
-	const Point3D& point_1,
-	const Point3D& point_2,
-	const Point3D& point_3,
-	const Point3D& point_4,
+	const glm::vec3& point_1,
+	const glm::vec3& point_2,
+	const glm::vec3& point_3,
+	const glm::vec3& point_4,
 	Color color_index) :
 	ColoredObject{color_index},
 	points{point_1, point_2, point_3, point_4}
 {
 }
 
-linetypes::Quadrilateral::Quadrilateral(const QVector<Point3D>& vertices, const Color color) :
+linetypes::Quadrilateral::Quadrilateral(const QVector<glm::vec3>& vertices, const Color color) :
 	ColoredObject{color},
 	points{vertices[0], vertices[1], vertices[2], vertices[3]}
 {
@@ -22,13 +22,13 @@
 	switch (id)
 	{
 	case Property::Point1:
-		return points[0];
+		return QVariant::fromValue(points[0]);
 	case Property::Point2:
-		return points[1];
+		return QVariant::fromValue(points[1]);
 	case Property::Point3:
-		return points[2];
+		return QVariant::fromValue(points[2]);
 	case Property::Point4:
-		return points[3];
+		return QVariant::fromValue(points[3]);
 	default:
 		return ColoredObject::getProperty(id);
 	}
@@ -42,16 +42,16 @@
 	switch (id)
 	{
 	case Property::Point1:
-		points[0] = value.value<Point3D>();
+		points[0] = value.value<glm::vec3>();
 		return SetPropertyResult::Success;
 	case Property::Point2:
-		points[1] = value.value<Point3D>();
+		points[1] = value.value<glm::vec3>();
 		return SetPropertyResult::Success;
 	case Property::Point3:
-		points[2] = value.value<Point3D>();
+		points[2] = value.value<glm::vec3>();
 		return SetPropertyResult::Success;
 	case Property::Point4:
-		points[3] = value.value<Point3D>();
+		points[3] = value.value<glm::vec3>();
 		return SetPropertyResult::Success;
 	default:
 		return ColoredObject::setProperty(id, value);
@@ -61,10 +61,10 @@
 QString linetypes::Quadrilateral::textRepresentation() const
 {
 	return utility::format("%1 %2 %3 %4",
-		vertexToStringParens(points[0]),
-		vertexToStringParens(points[1]),
-		vertexToStringParens(points[2]),
-			vertexToStringParens(points[3]));
+		utility::vertexToStringParens(points[0]),
+		utility::vertexToStringParens(points[1]),
+		utility::vertexToStringParens(points[2]),
+		utility::vertexToStringParens(points[3]));
 }
 
 void linetypes::Quadrilateral::getPolygons(
--- a/src/linetypes/quadrilateral.h	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/linetypes/quadrilateral.h	Sun Jan 26 14:29:30 2020 +0200
@@ -11,17 +11,17 @@
 public:
 	Quadrilateral() = default;
 	Quadrilateral(
-	const Point3D &point_1,
-	const Point3D &point_2,
-	const Point3D &point_3,
-	const Point3D &point_4,
+	const glm::vec3 &point_1,
+	const glm::vec3 &point_2,
+	const glm::vec3 &point_3,
+	const glm::vec3 &point_4,
 	Color colorIndex = colors::main);
-	Quadrilateral(const QVector<Point3D>& vertices, const Color color);
+	Quadrilateral(const QVector<glm::vec3>& vertices, const Color color);
 	QVariant getProperty(Property id) const override;
 	SetPropertyResult setProperty(Property id, const QVariant& value) override;
 	QString textRepresentation() const override;
 	void getPolygons(std::vector<gl::Polygon>& polygons, GetPolygonsContext* context) const override;
 	void invert() override;
 private:
-	Point3D points[4] = {{}};
+	glm::vec3 points[4] = {{}};
 };
--- a/src/linetypes/subfilereference.cpp	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/linetypes/subfilereference.cpp	Sun Jan 26 14:29:30 2020 +0200
@@ -2,7 +2,7 @@
 #include "documentmanager.h"
 #include "invert.h"
 
-linetypes::SubfileReference::SubfileReference(const Matrix4x4& transformation,
+linetypes::SubfileReference::SubfileReference(const glm::mat4& transformation,
 	const QString& referenceName,
 	const Color color) :
 	ColoredObject{color},
@@ -32,7 +32,7 @@
 	switch (property)
 	{
 	case Property::Transformation:
-		this->transformation = value.value<Matrix4x4>();
+		this->transformation = value.value<glm::mat4>();
 		return SetPropertyResult::Success;
 	case Property::ReferenceName:
 		this->referenceName = value.toString();
@@ -44,7 +44,7 @@
 
 QString linetypes::SubfileReference::textRepresentation() const
 {
-	return referenceName + " " + vertexToStringParens(this->position());
+	return referenceName + " " + utility::vertexToStringParens(this->position());
 }
 
 void linetypes::SubfileReference::getPolygons(
@@ -54,14 +54,16 @@
 	Model* model = this->resolve(context->documents);
 	if (model != nullptr)
 	{
-		const bool needInverting = math::det(this->transformation) < 0;
+		const bool needInverting = glm::determinant(this->transformation) < 0;
 		const std::vector<gl::Polygon> modelPolygons = model->getPolygons(context->documents);
 		polygons.reserve(polygons.size() + modelPolygons.size());
 		for (gl::Polygon polygon : modelPolygons)
 		{
 			for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1)
 			{
-				polygon.vertices[i] = math::transform(polygon.vertices[i], this->transformation);
+				glm::vec4 vertex {polygon.vertices[i], 1};
+				vertex = this->transformation * vertex;
+				polygon.vertices[i] = vertex;
 			}
 			if (needInverting != this->isInverted)
 			{
@@ -77,9 +79,9 @@
 	}
 }
 
-Point3D linetypes::SubfileReference::position() const
+glm::vec3 linetypes::SubfileReference::position() const
 {
-	return {this->transformation(0, 3), this->transformation(1, 3), this->transformation(2, 3)};
+	return {this->transformation[3][0], this->transformation[3][1], this->transformation[3][2]};
 }
 
 void linetypes::SubfileReference::invert()
--- a/src/linetypes/subfilereference.h	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/linetypes/subfilereference.h	Sun Jan 26 14:29:30 2020 +0200
@@ -1,6 +1,5 @@
 #pragma once
 #include "object.h"
-#include "matrix.h"
 
 class Model;
 
@@ -14,18 +13,18 @@
 public:
 	SubfileReference() = default;
 	SubfileReference(
-		const Matrix4x4& transformation,
+		const glm::mat4& transformation,
 		const QString &referenceName,
 		const Color color = colors::main);
 	QVariant getProperty(Property property) const override;
 	SetPropertyResult setProperty(Property property, const QVariant& value) override;
 	QString textRepresentation() const override;
 	void getPolygons(std::vector<gl::Polygon>& polygons, GetPolygonsContext* context) const override;
-	Point3D position() const;
+	glm::vec3 position() const;
 	void invert() override;
 private:
 	Model* resolve(DocumentManager* documents) const;
-	Matrix4x4 transformation;
+	glm::mat4 transformation;
 	QString referenceName;
 	bool isInverted = false;
 };
--- a/src/linetypes/triangle.cpp	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/linetypes/triangle.cpp	Sun Jan 26 14:29:30 2020 +0200
@@ -1,16 +1,16 @@
 #include "triangle.h"
 
 linetypes::Triangle::Triangle(
-	const Point3D& point_1,
-	const Point3D& point_2,
-	const Point3D& point_3,
+	const glm::vec3& point_1,
+	const glm::vec3& point_2,
+	const glm::vec3& point_3,
 	Color color_index) :
 	ColoredObject{color_index},
 	points{point_1, point_2, point_3}
 {
 }
 
-linetypes::Triangle::Triangle(const QVector<Point3D>& vertices, const Color color) :
+linetypes::Triangle::Triangle(const QVector<glm::vec3>& vertices, const Color color) :
 	ColoredObject{color},
 	points{vertices[0], vertices[1], vertices[2]}
 {
@@ -21,11 +21,11 @@
 	switch (id)
 	{
 	case Property::Point1:
-		return points[0];
+		return QVariant::fromValue(points[0]);
 	case Property::Point2:
-		return points[1];
+		return QVariant::fromValue(points[1]);
 	case Property::Point3:
-		return points[2];
+		return QVariant::fromValue(points[2]);
 	default:
 		return ColoredObject::getProperty(id);
 	}
@@ -37,13 +37,13 @@
 	switch (id)
 	{
 	case Property::Point1:
-		points[0] = value.value<Point3D>();
+		points[0] = value.value<glm::vec3>();
 		return SetPropertyResult::Success;
 	case Property::Point2:
-		points[1] = value.value<Point3D>();
+		points[1] = value.value<glm::vec3>();
 		return SetPropertyResult::Success;
 	case Property::Point3:
-		points[2] = value.value<Point3D>();
+		points[2] = value.value<glm::vec3>();
 		return SetPropertyResult::Success;
 	default:
 		return ColoredObject::setProperty(id, value);
@@ -53,9 +53,9 @@
 QString linetypes::Triangle::textRepresentation() const
 {
 	return utility::format("%1 %2 %3",
-		vertexToStringParens(points[0]),
-		vertexToStringParens(points[1]),
-		vertexToStringParens(points[2]));
+		utility::vertexToStringParens(points[0]),
+		utility::vertexToStringParens(points[1]),
+		utility::vertexToStringParens(points[2]));
 }
 
 void linetypes::Triangle::getPolygons(
--- a/src/linetypes/triangle.h	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/linetypes/triangle.h	Sun Jan 26 14:29:30 2020 +0200
@@ -10,17 +10,17 @@
 public:
 	Triangle() = default;
 	Triangle(
-		const Point3D &point_1,
-		const Point3D &point_2,
-		const Point3D &point_3,
+		const glm::vec3 &point_1,
+		const glm::vec3 &point_2,
+		const glm::vec3 &point_3,
 		Color colorIndex = colors::main);
-	Triangle(const QVector<Point3D>& vertices, const Color color);
+	Triangle(const QVector<glm::vec3>& vertices, const Color color);
 	QVariant getProperty(Property id) const override;
 	SetPropertyResult setProperty(Property id, const QVariant& value) override;
 	QString textRepresentation() const override;
 	void getPolygons(std::vector<gl::Polygon>& polygons, GetPolygonsContext* context) const override;
 	void invert() override;
 private:
-	Point3D points[3] = {{}};
+	glm::vec3 points[3] = {{}};
 };
 
--- a/src/maths.h	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/maths.h	Sun Jan 26 14:29:30 2020 +0200
@@ -18,6 +18,7 @@
 
 #pragma once
 #include <cmath>
+#include "utility.h"
 
 namespace math
 {
@@ -90,3 +91,8 @@
 		return arg + sum<T>(rest...);
 	}
 }
+
+inline unsigned int qHash(const glm::vec3& key)
+{
+	return qHash(key.x) ^ utility::rotl10(qHash(key.y)) ^ utility::rotl20(qHash(key.z));
+}
--- a/src/matrix.cpp	Sun Jan 26 01:06:27 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- *  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/>.
- */
-
-#include "matrix.h"
-#include "vertex.h"
-
-Matrix4x4 combine(const Matrix3x3& topLeft, const Point3D& translation)
-{
-	return {{
-		{topLeft(0, 0), topLeft(0, 1), topLeft(0, 2), translation.x},
-		{topLeft(1, 0), topLeft(1, 1), topLeft(1, 2), translation.y},
-		{topLeft(2, 0), topLeft(2, 1), topLeft(2, 2), translation.z},
-		{0, 0, 0, 1}
-	}};
-}
-
-/*
- * Computes the determinant of a 3×3 matrix with each variable passed in row-major order.
- */
-qreal math::det(qreal a, qreal b, qreal c, qreal d, qreal e, qreal f, qreal g, qreal h, qreal i)
-{
-	return a*e*i + b*f*g + c*d*h - a*f*h - b*d*i - c*e*g;
-}
-
-/*
- * Computes the determinant of a 2×2 matrix.
- */
-qreal math::det(const Matrix<2, 2>& matrix)
-{
-	return matrix(0, 0) * matrix(1, 1) - matrix(0, 1) * matrix(1, 0);
-}
-
-/*
- * Computes the determinant of a 3×3 matrix.
- */
-qreal math::det(const Matrix3x3& matrix)
-{
-	return math::sum(
-		+matrix(0, 0) * matrix(1, 1) * matrix(2, 2),
-		-matrix(0, 0) * matrix(1, 2) * matrix(2, 1),
-		-matrix(0, 1) * matrix(1, 0) * matrix(2, 2),
-		+matrix(0, 1) * matrix(1, 2) * matrix(2, 0),
-		+matrix(0, 2) * matrix(1, 0) * matrix(2, 1),
-		-matrix(0, 2) * matrix(1, 1) * matrix(2, 0));
-}
-
-/*
- * Computes the determinant of a 4×4 matrix.
- */
-qreal math::det(const Matrix4x4& matrix)
-{
-	qreal sum = 0;
-
-	for (int column : {0, 1, 2, 3})
-	{
-		int column_1 = (column >= 1) ? 0 : 1;
-		int column_2 = (column >= 2) ? 1 : 2;
-		int column_3 = (column >= 3) ? 2 : 3;
-		sum += ((column % 1) ? -1 : 1) * math::det(
-			matrix(1, column_1), matrix(1, column_2), matrix(1, column_3),
-			matrix(2, column_1), matrix(2, column_2), matrix(2, column_3),
-			matrix(3, column_1), matrix(3, column_2), matrix(3, column_3));
-	}
-
-	return sum;
-}
--- a/src/matrix.h	Sun Jan 26 01:06:27 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/*
- *  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);
-}
--- a/src/parser.cpp	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/parser.cpp	Sun Jan 26 14:29:30 2020 +0200
@@ -92,7 +92,7 @@
 			if (partTypeString.startsWith("Unofficial_"))
 				partTypeString = partTypeString.mid(strlen("Unofficial_"));
 			header.type = typeStrings.value(partTypeString, LDHeader::Part);
-			header.qualfiers = 0;
+			header.qualfiers = {};
 			if (tokens.contains("Alias"))
 				header.qualfiers |= LDHeader::Alias;
 			if (tokens.contains("Physical_Color"))
@@ -279,7 +279,7 @@
 	}
 }
 
-static Point3D vertexFromStrings(
+static glm::vec3 vertexFromStrings(
 	const QStringList& tokens,
 	const int startingPosition)
 {
@@ -296,9 +296,9 @@
 	return {x, y, z};
 }
 
-static Matrix3x3 matrixFromStrings(const QStringList& tokens, const int startingPosition)
+static glm::mat4 matrixFromStrings(const QStringList& tokens, const int startingPosition, const int positionStartingIndex)
 {
-	Matrix3x3 result;
+	glm::mat4 result = glm::mat4{1};
 	for (int i = 0; i < 9; i += 1)
 	{
 		const int row = i / 3;
@@ -309,7 +309,18 @@
 			throw BodyParseError{"too few tokens available"};
 		}
 		bool ok;
-		result(row, column) = tokens[index].toFloat(&ok);
+		// note that glm::mat4 is column-major
+		result[column][row] = tokens[index].toFloat(&ok);
+		if (not ok)
+		{
+			throw BodyParseError{"non-numeric values for matrix"};
+		}
+	}
+	for (int i = 0; i < 3; i += 1)
+	{
+		bool ok;
+		const auto value = tokens[i + positionStartingIndex].toFloat(&ok);
+		result[3][i] = value;
 		if (not ok)
 		{
 			throw BodyParseError{"non-numeric values for matrix"};
@@ -347,10 +358,9 @@
 		throw BodyParseError{"wrong amount of tokens in a type-1 line"};
 	}
 	const Color color = colorFromString(tokens[colorPosition]);
-	const Point3D position = vertexFromStrings(tokens, positionPosition);
-	const Matrix3x3 transform = matrixFromStrings(tokens, transformPosition);
+	const glm::mat4 transform = matrixFromStrings(tokens, transformPosition, positionPosition);
 	const QString& name = tokens[namePosition];
-	return std::make_unique<linetypes::SubfileReference>(combine(transform, position), name, color);
+	return std::make_unique<linetypes::SubfileReference>(transform, name, color);
 }
 
 template<typename T, int NumVertices>
@@ -366,7 +376,7 @@
 		throw BodyParseError{"wrong amount of tokens"};
 	}
 	const Color color = colorFromString(tokens[colorPosition]);
-	QVector<Point3D> vertices;
+	QVector<glm::vec3> vertices;
 	vertices.reserve(NumVertices);
 	for (int i = 0; i < NumVertices; i += 1)
 	{
--- a/src/types/boundingbox.cpp	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/types/boundingbox.cpp	Sun Jan 26 14:29:30 2020 +0200
@@ -18,13 +18,13 @@
 
 #include "boundingbox.h"
 
-BoundingBox& BoundingBox::operator<<(const Point3D& vertex)
+BoundingBox& BoundingBox::operator<<(const glm::vec3& vertex)
 {
 	this->consider(vertex);
 	return *this;
 }
 
-void BoundingBox::consider(const Point3D& vertex)
+void BoundingBox::consider(const glm::vec3& vertex)
 {
 	this->minimum.x = math::min(vertex.x, this->minimum.x);
 	this->minimum.y = math::min(vertex.y, this->minimum.y);
@@ -37,19 +37,19 @@
 /*
  * Returns the length of the bounding box on the longest measure.
  */
-double longestMeasure(const BoundingBox& box)
+float longestMeasure(const BoundingBox& box)
 {
 	if (box != emptyBoundingBox)
 	{
-		const double dx = std::abs(box.minimum.x - box.maximum.x);
-		const double dy = std::abs(box.minimum.y - box.maximum.y);
-		const double dz = std::abs(box.minimum.z - box.maximum.z);
-		const double size = std::max(std::max(dx, dy), dz);
-		return std::max(size / 2.0, 1.0);
+		const float dx = std::abs(box.minimum.x - box.maximum.x);
+		const float dy = std::abs(box.minimum.y - box.maximum.y);
+		const float dz = std::abs(box.minimum.z - box.maximum.z);
+		const float size = std::max(std::max(dx, dy), dz);
+		return std::max(size / 2.0f, 1.0f);
 	}
 	else
 	{
-		return 0.0;
+		return 0.0f;
 	}
 }
 
@@ -57,7 +57,7 @@
 /*
  * Yields the center of the bounding box.
  */
-Point3D boxCenter(const BoundingBox& box)
+glm::vec3 boxCenter(const BoundingBox& box)
 {
 	if (box != emptyBoundingBox)
 	{
@@ -69,16 +69,16 @@
 	}
 	else
 	{
-		return origin;
+		return glm::vec3{0, 0, 0};
 	}
 }
 
 /*
  * Returns the length of the bounding box's space diagonal.
  */
-double spaceDiagonal(const BoundingBox& box)
+float spaceDiagonal(const BoundingBox& box)
 {
-	return math::distance(box.minimum, box.maximum);
+	return glm::distance(box.minimum, box.maximum);
 }
 
 bool operator==(const BoundingBox &box_1, const BoundingBox &box_2)
--- a/src/types/boundingbox.h	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/types/boundingbox.h	Sun Jan 26 14:29:30 2020 +0200
@@ -17,21 +17,22 @@
  */
 
 #pragma once
-#include "vertex.h"
+#include "basics.h"
+#include "maths.h"
 
 class BoundingBox
 {
 public:
-	void consider(const Point3D& vertex);
-	Point3D minimum {math::infinity, math::infinity, math::infinity};
-	Point3D maximum {-math::infinity, -math::infinity, -math::infinity};
-	BoundingBox& operator<<(const Point3D& v);
+	void consider(const glm::vec3& vertex);
+	glm::vec3 minimum {math::infinity, math::infinity, math::infinity};
+	glm::vec3 maximum {-math::infinity, -math::infinity, -math::infinity};
+	BoundingBox& operator<<(const glm::vec3& v);
 };
 
-static constexpr BoundingBox emptyBoundingBox = {};
-Point3D boxCenter(const BoundingBox& box);
-double longestMeasure(const BoundingBox& box);
-double spaceDiagonal(const BoundingBox& box);
+inline const BoundingBox emptyBoundingBox = {};
+glm::vec3 boxCenter(const BoundingBox& box);
+float longestMeasure(const BoundingBox& box);
+float spaceDiagonal(const BoundingBox& box);
 
 bool operator==(const BoundingBox& box_1, const BoundingBox& box_2);
 bool operator!=(const BoundingBox& box_1, const BoundingBox& box_2);
--- a/src/utility.h	Sun Jan 26 01:06:27 2020 +0200
+++ b/src/utility.h	Sun Jan 26 14:29:30 2020 +0200
@@ -70,4 +70,9 @@
 	{
 		return std::find(std::begin(container), std::end(container), value) != std::end(container);
 	}
+
+	inline QString vertexToStringParens(const glm::vec3& vertex)
+	{
+		return utility::format("(%1, %2, %3)", vertex.x, vertex.y, vertex.z);
+	}
 }
--- a/src/vertex.cpp	Sun Jan 26 01:06:27 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,221 +0,0 @@
-/*
- *  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/>.
- */
-
-#include "main.h"
-#include "vertex.h"
-
-/*
-void Vertex::transform(const Matrix& matrix, const Vertex& pos)
-{
-	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;
-}
-*/
-
-Point3D::CoordinateType& Point3D::get(Axis axis)
-{
-	switch (axis)
-	{
-	case X:
-		return this->x;
-	case Y:
-		return this->y;
-	case Z:
-		return this->z;
-	default:
-		throw std::runtime_error("Non-axis given to Vertex::operator[]");
-	}
-}
-
-Point3D::CoordinateType Point3D::get(Axis axis) const
-{
-	switch (axis)
-	{
-	case X:
-		return this->x;
-	case Y:
-		return this->y;
-	case Z:
-		return this->z;
-	default:
-		return 0;
-	}
-}
-
-Point3D::operator QVariant() const
-{
-	return QVariant::fromValue(*this);
-}
-
-void Point3D::assign(Axis axis, CoordinateType value)
-{
-	this->get(axis) = value;
-}
-
-Point3D VertexFromVector(const QVector3D& vector)
-{
-	return {vector.x(), vector.y(), vector.z()};
-}
-
-Point3D operator*(const Point3D& point, Point3D::CoordinateType scalar)
-{
-	return {point.x * scalar, point.y * scalar, point.z * scalar};
-}
-
-Point3D& operator+=(Point3D& point, const QVector3D& other)
-{
-	point.x += other.x();
-	point.y += other.y();
-	point.z += other.z();
-	return point;
-}
-
-Point3D operator+(Point3D point, const QVector3D& other)
-{
-	point += other;
-	return point;
-}
-
-
-QVector3D vertexToVector(const Point3D& vertex)
-{
-	return {
-		static_cast<float>(vertex.x),
-		static_cast<float>(vertex.y),
-		static_cast<float>(vertex.z)
-	};
-}
-
-Point3D operator-(Point3D point, const QVector3D& vector)
-{
-	point -= vector;
-	return point;
-}
-
-Point3D& operator-=(Point3D& point, const QVector3D& vector)
-{
-	point.x -= vector.x();
-	point.y -= vector.y();
-	point.z -= vector.z();
-	return point;
-}
-
-QVector3D operator-(const Point3D& point, const Point3D& other)
-{
-	return {
-		static_cast<float>(point.x - other.x),
-		static_cast<float>(point.y - other.y),
-		static_cast<float>(point.z - other.z)
-	};
-}
-
-Point3D& operator*=(Point3D& point, Point3D::CoordinateType scalar)
-{
-	point.x *= scalar;
-	point.y *= scalar;
-	point.z *= scalar;
-	return point;
-}
-
-bool operator==(const Point3D& point, const Point3D& other)
-{
-	return point.x == other.x and point.y == other.y and point.z == other.z;
-}
-
-bool operator!=(const Point3D& point, const Point3D& other)
-{
-	return not (point == other);
-}
-
-bool operator<(const Point3D& point, const Point3D& other)
-{
-	if (not qFuzzyCompare(point.x, other.x))
-		return point.x < other.x;
-	else if (not qFuzzyCompare(point.y, other.y))
-		return point.y < other.y;
-	else
-		return point.z < other.z;
-}
-
-/*
- * Transforms the specified vertex with a transformation matrix
- */
-Point3D math::transform(const Point3D& point, const Matrix4x4& matrix)
-{
-	return {
-		matrix(0, 0) * point.x
-			+ matrix(0, 1) * point.y
-			+ matrix(0, 2) * point.z
-			+ matrix(0, 3),
-		matrix(1, 0) * point.x
-			+ matrix(1, 1) * point.y
-			+ matrix(1, 2) * point.z
-			+ matrix(1, 3),
-		matrix(2, 0) * point.x
-			+ matrix(2, 1) * point.y
-			+ matrix(2, 2) * point.z
-			+ matrix(2, 3),
-	};
-}
-
-/*
- * Returns the distance from one vertex to another.
- */
-qreal math::distance(const Point3D& one, const Point3D& other)
-{
-	return (one - other).length();
-}
-
-/*
- * Returns a vertex with all coordinates inverted.
- */
-Point3D operator-(const Point3D& vertex)
-{
-	return {-vertex.x, -vertex.y, -vertex.z};
-}
-
-/*
- * Inserts this vertex into a data stream. This is needed for vertices to be
- * stored in QSettings.
- */
-QDataStream& operator<<(QDataStream& out, const Point3D& vertex)
-{
-	return out << vertex.x << vertex.y << vertex.z;
-}
-
-/*
- * Takes a vertex from a data stream.
- */
-QDataStream& operator>>(QDataStream& in, Point3D& vertex)
-{
-	return in >> vertex.x >> vertex.y >> vertex.z;
-}
-
-unsigned int qHash(const Point3D& key)
-{
-	return qHash(key.x) ^ utility::rotl10(qHash(key.y)) ^ utility::rotl20(qHash(key.z));
-}
-
-QString vertexToStringParens(const Point3D& vertex)
-{
-	return utility::format("(%1, %2, %3)", vertex.x, vertex.y, vertex.z);
-}
--- a/src/vertex.h	Sun Jan 26 01:06:27 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- *  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 <functional>
-#include <QVector3D>
-#include "basics.h"
-#include "maths.h"
-#include "matrix.h"
-
-struct Point3D
-{
-	double x, y, z;
-	using CoordinateType = decltype(x);
-	void assign(Axis axis, CoordinateType value);
-	CoordinateType& get(Axis ax);
-	CoordinateType get(Axis ax) const;
-	operator QVariant() const;
-};
-
-constexpr Point3D origin = {0, 0, 0};
-
-namespace math
-{
-	Point3D transform(const Point3D& point, const Matrix4x4& matrix);
-	qreal distance(const Point3D& one, const Point3D& other);
-}
-
-Point3D& operator+=(Point3D &point, const QVector3D& other);
-Point3D operator+(Point3D point, const QVector3D& other);
-QVector3D operator-(const Point3D& point, const Point3D& other);
-Point3D operator-(Point3D point, const QVector3D& vector);
-Point3D& operator-=(Point3D &point, const QVector3D& vector);
-Point3D& operator*=(Point3D &point, Point3D::CoordinateType scalar);
-Point3D operator*(const Point3D &point, Point3D::CoordinateType scalar);
-bool operator<(const Point3D &point, const Point3D& other);
-bool operator==(const Point3D &point, const Point3D& other);
-bool operator!=(const Point3D &point, const Point3D& other);
-
-inline Point3D operator*(qreal scalar, const Point3D& vertex)
-{
-	return vertex * scalar;
-}
-
-Q_DECLARE_METATYPE(Point3D)
-Point3D vertexFromVector(const QVector3D& vector);
-QVector3D vertexToVector(const Point3D &vertex);
-QString vertexToStringParens(const Point3D& vertex);
-unsigned int qHash(const Point3D& key);
-Point3D operator-(const Point3D& vertex);
-QDataStream& operator<<(QDataStream& out, const Point3D& vertex);
-QDataStream& operator>>(QDataStream& in, Point3D& vertex);
-
-/*
- * Calls 'function' with the x, y and z coordinates of 'vertex'.
- */
-template<typename Function>
-inline auto xyz(Function&& function, const Point3D& vertex)
-{
-	return function(vertex.x, vertex.y, vertex.z);
-}

mercurial