Made fixed cameras matrix-based. This simplifies some math.

Mon, 20 Feb 2017 07:56:21 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Mon, 20 Feb 2017 07:56:21 +0200
changeset 1151
0eddb5bcf25b
parent 1150
262345e53050
child 1152
a66d943591d8

Made fixed cameras matrix-based. This simplifies some math.

cameracube.dat file | annotate | diff | comparison | revisions
src/basics.h file | annotate | diff | comparison | revisions
src/editmodes/circleMode.cpp file | annotate | diff | comparison | revisions
src/format.h file | annotate | diff | comparison | revisions
src/glShared.h file | annotate | diff | comparison | revisions
src/glcamera.cpp file | annotate | diff | comparison | revisions
src/glcamera.h file | annotate | diff | comparison | revisions
src/glrenderer.cpp file | annotate | diff | comparison | revisions
src/glrenderer.h file | annotate | diff | comparison | revisions
src/types/matrix.cpp file | annotate | diff | comparison | revisions
src/types/matrix.h file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cameracube.dat	Mon Feb 20 07:56:21 2017 +0200
@@ -0,0 +1,88 @@
+2 24 -5 -10 3 -1 -10 3
+2 24 -3 -10 3 -3 -10 -1
+2 24 -5 -10 3 -5 -10 2.5
+2 24 -1 -10 3 -1 -10 2.5
+2 24 -3.5 -10 -1 -2.5 -10 -1
+2 24 7 -10 9 9 -10 9
+2 24 9 -10 9 9 -10 7
+2 24 9 -10 9 6 -10 6
+2 24 1 -10 2 1 -10 -3
+2 24 1 -10 1 2 -10 2
+2 24 2 -10 2 4 -10 2
+2 24 4 -10 2 5 -10 1
+2 24 5 -10 1 5 -10 0
+2 24 5 -10 0 4 -10 -1
+2 24 4 -10 -1 2 -10 -1
+2 24 2 -10 -1 1 -10 0
+4 12 10 -10 10 -10 -10 10 -10 -10 -10 10 -10 -10
+2 24 0 -5 -10 -5 -5 -10
+2 24 -4 -2 -10 -2 -2 -10
+2 24 -4 -5 -10 -4 1 -10
+2 24 -5 1 -10 -3 1 -10
+2 24 0 -5 -10 0 -4 -10
+2 24 2 -5 -10 2 0 -10
+2 24 2 0 -10 3 1 -10
+2 24 1 -3 -10 3 -3 -10
+2 24 7 -9 -10 9 -9 -10
+2 24 9 -9 -10 9 -7 -10
+2 24 9 -9 -10 6 -6 -10
+4 18 -10 -10 -10 10 -10 -10 10 10 -10 -10 10 -10
+2 24 -10 -5 5 -10 3 5
+2 24 -10 3 6 -10 3 1
+2 24 -10 3 1 -10 2 1
+2 24 -10 -5 6 -10 -5 4
+2 24 -10 -5 -2 -10 1 -2
+2 24 -10 1 -2 -10 3 -4
+2 24 -10 -2 0 -10 -2 -4
+2 24 -10 -9 -7 -10 -9 -9
+2 24 -10 -9 -9 -10 -7 -9
+2 24 -10 -9 -9 -10 -6 -6
+4 30 -10 -10 10 -10 -10 -10 -10 10 -10 -10 10 10
+4 11 -10 10 -10 10 10 -10 10 10 10 -10 10 10
+2 24 -6 10 -5 -1 10 -5
+2 24 -1 10 -5 0 10 -4
+2 24 0 10 -4 0 10 -2
+2 24 0 10 -2 -1 10 -1
+2 24 -1 10 -1 -5 10 -1
+2 24 -1 10 -1 0 10 0
+2 24 0 10 0 0 10 2
+2 24 0 10 2 -1 10 3
+2 24 -1 10 3 -6 10 3
+2 24 -5 10 3 -5 10 -5
+2 24 4 10 -5 4 10 1
+2 24 4 10 1 6 10 3
+2 24 9 10 -9 6 10 -6
+2 24 9 10 -9 9 10 -7
+2 24 7 10 -9 9 10 -9
+2 24 2 10 -3 6 10 -3
+4 9 10 -10 10 -10 -10 10 -10 10 10 10 10 10
+2 24 -7 -9 10 -9 -9 10
+2 24 -9 -9 10 -9 -7 10
+2 24 -9 -9 10 -6 -6 10
+2 24 5 -4 10 5 4 10
+2 24 6 -4 10 2 -4 10
+2 24 2 -4 10 1 -3 10
+2 24 1 -3 10 1 -1 10
+2 24 1 -1 10 2 0 10
+2 24 2 0 10 5 0 10
+2 24 2 0 10 1 1 10
+2 24 1 1 10 1 3 10
+2 24 1 3 10 2 4 10
+2 24 2 4 10 6 4 10
+2 24 -2 -4 10 -2 4 10
+2 24 -2 1 10 -5 -2 10
+2 24 -3 0 10 -6 4 10
+4 2 10 -10 -10 10 -10 10 10 10 10 10 10 -10
+2 24 10 -9 7 10 -9 9
+2 24 10 -9 9 10 -7 9
+2 24 10 -9 9 10 -6 6
+2 24 10 -4 -5 10 4 -5
+2 24 10 -4 -6 10 -4 -1
+2 24 10 -4 -1 10 -3 0
+2 24 10 -3 0 10 -1 0
+2 24 10 -1 0 10 0 -1
+2 24 10 0 -1 10 0 -5
+2 24 10 0 -3 10 4 0
+2 24 10 -4 3 10 2 3
+2 24 10 2 3 10 4 5
+2 24 10 -2 1 10 -2 5
--- a/src/basics.h	Sat Feb 18 02:02:29 2017 +0200
+++ b/src/basics.h	Mon Feb 20 07:56:21 2017 +0200
@@ -29,9 +29,9 @@
 #include <math.h>
 #include "macros.h"
 #include "transform.h"
-#include "types/matrix.h"
 
 class LDObject;
+class Matrix;
 using LDObjectList = QList<LDObject*>;
 
 template<typename T, typename R>
--- a/src/editmodes/circleMode.cpp	Sat Feb 18 02:02:29 2017 +0200
+++ b/src/editmodes/circleMode.cpp	Mon Feb 20 07:56:21 2017 +0200
@@ -26,6 +26,7 @@
 #include "../mainwindow.h"
 #include "../mathfunctions.h"
 #include "../miscallenous.h"
+#include "../documentmanager.h"
 #include "../grid.h"
 #include "../linetypes/modelobject.h"
 #include "../linetypes/quadrilateral.h"
@@ -83,7 +84,7 @@
 		// If the radii are the same, there's no ring space to fill. Use a circle.
 		primitiveModel.type = PrimitiveModel::Circle;
 		primitiveFile = primitives()->getPrimitive(primitiveModel);
-		transform = renderer()->currentCamera().transformationMatrix(dist0);
+		transform = Matrix::fromRotationMatrix(renderer()->currentCamera().transformationMatrix(dist0));
 		circleOrDisc = true;
 	}
 	else if (dist0 == 0 or dist1 == 0)
@@ -91,7 +92,7 @@
 		// If either radii is 0, use a disc.
 		primitiveModel.type = PrimitiveModel::Disc;
 		primitiveFile = primitives()->getPrimitive(primitiveModel);
-		transform = renderer()->currentCamera().transformationMatrix((dist0 != 0) ? dist0 : dist1);
+		transform = Matrix::fromRotationMatrix(renderer()->currentCamera().transformationMatrix((dist0 != 0) ? dist0 : dist1));
 		circleOrDisc = true;
 	}
 	else if (g_RingFinder.findRings(dist0, dist1))
@@ -103,8 +104,8 @@
 		{
 			primitiveModel.ringNumber = component.num;
 			primitiveFile = primitives()->getPrimitive(primitiveModel);
-			model.emplace<LDSubfileReference>(primitiveFile, renderer()->currentCamera().transformationMatrix(component.scale),
-			                                  m_drawedVerts.first());
+			Matrix matrix = Matrix::fromRotationMatrix(renderer()->currentCamera().transformationMatrix(component.scale));
+			model.emplace<LDSubfileReference>(primitiveFile, matrix, m_drawedVerts.first());
 		}
 	}
 	else
@@ -150,15 +151,6 @@
 	if (circleOrDisc and primitiveFile)
 		model.emplace<LDSubfileReference>(primitiveFile, transform, m_drawedVerts.first());
 
-	if (not model.isEmpty())
-	{
-		Axis relZ = renderer()->getRelativeZ();;
-		int l = (relZ == X ? 1 : 0);
-		int m = (relZ == Y ? 1 : 0);
-		int n = (relZ == Z ? 1 : 0);
-		math()->rotateObjects(l, m, n, -m_angleOffset, model.objects());
-	}
-
 	finishDraw (model);
 }
 
--- a/src/format.h	Sat Feb 18 02:02:29 2017 +0200
+++ b/src/format.h	Mon Feb 20 07:56:21 2017 +0200
@@ -21,6 +21,7 @@
 #include <QGenericMatrix>
 #include "basics.h"
 #include "colors.h"
+#include "types/matrix.h"
 
 // Converts a given value into a string that can be retrieved with text().
 // Used as the argument type to the formatting functions, hence its name.
--- a/src/glShared.h	Sat Feb 18 02:02:29 2017 +0200
+++ b/src/glShared.h	Mon Feb 20 07:56:21 2017 +0200
@@ -19,8 +19,33 @@
 #pragma once
 
 #include <QOpenGLFunctions>
+#include <QGenericMatrix>
 #include "basics.h"
 
+class GLRotationMatrix : public QGenericMatrix<4, 4, GLfloat>
+{
+public:
+	GLRotationMatrix() {}
+	GLRotationMatrix(GLfloat values[16]) :
+	    QGenericMatrix<4, 4, GLfloat> {values} {}
+	GLRotationMatrix(std::initializer_list<GLfloat>&& values)
+	{
+		auto iterator = values.begin();
+
+		for (int i = 0; i < 4; ++i)
+		for (int j = 0; j < 4; ++j)
+		{
+			(*this)(i, j) = *iterator;
+			++iterator;
+		}
+	}
+};
+
+inline void glMultMatrixf(const GLRotationMatrix& matrix)
+{
+	glMultMatrixf(matrix.constData());
+}
+
 class LDObject;
 
 struct LDPolygon
--- a/src/glcamera.cpp	Sat Feb 18 02:02:29 2017 +0200
+++ b/src/glcamera.cpp	Mon Feb 20 07:56:21 2017 +0200
@@ -25,7 +25,7 @@
  */
 GLCamera::GLCamera(QString name, FixedCameraParameters&& bag) :
     m_name {name},
-    m_glrotate {bag.glRotateX, bag.glRotateY, bag.glRotateZ},
+    m_rotationMatrix {bag.rotationMatrix},
     m_localX {bag.localX},
     m_localY {bag.localY},
     m_negatedX {bag.negatedX},
@@ -40,14 +40,6 @@
     m_isFree {true} {}
 
 /*
- * Returns OpenGL rotation information for this camera.
- */
-int GLCamera::glRotate(Axis axis) const
-{
-	return m_glrotate[axis];
-}
-
-/*
  * Returns whether or not the given axis is negated on this camera.
  */
 bool GLCamera::isAxisNegated(Axis axis) const
@@ -243,35 +235,21 @@
 	return m_name;
 }
 
+const GLRotationMatrix& GLCamera::transformationMatrix() const
+{
+	return m_rotationMatrix;
+}
+
 /*
  * Returns the camera's transformation matrix, scaled by the given scale value.
  */
-Matrix GLCamera::transformationMatrix(double scale) const
+GLRotationMatrix GLCamera::transformationMatrix(double scale) const
 {
-	// Matrix templates. 2 is substituted with the scale value, 1 is inverted to -1 if needed.
-	static const Matrix templates[3] =
-	{
-	    { 2, 0, 0, 0, 1, 0, 0, 0, 2 },
-	    { 2, 0, 0, 0, 0, 2, 0, 1, 0 },
-	    { 0, 1, 0, 2, 0, 0, 0, 0, 2 },
-	};
-
-	Matrix transform;
+	GLRotationMatrix matrix = m_rotationMatrix;
 
-	if (m_localX == X and m_localY == Z)
-		transform = templates[0];
-	else if (m_localX == X and m_localY == Y)
-		transform = templates[1];
-	if (m_localX == Y and m_localY == Z)
-		transform = templates[2];
+	for (int i = 0; i < 4; ++i)
+	for (int j = 0; j < 4; ++j)
+		matrix(i, j) *= scale;
 
-	for (double& value : transform)
-	{
-		if (value == 2)
-			value = scale;
-		else if (value == 1 and (glRotate(X) + glRotate(Y) + glRotate(Z)) < 0)
-			value = -1;
-	}
-
-	return transform;
+	return matrix;
 }
--- a/src/glcamera.h	Sat Feb 18 02:02:29 2017 +0200
+++ b/src/glcamera.h	Mon Feb 20 07:56:21 2017 +0200
@@ -18,12 +18,11 @@
 
 #pragma once
 #include "main.h"
+#include "glShared.h"
 
 struct FixedCameraParameters
 {
-	int glRotateX;
-	int glRotateY;
-	int glRotateZ;
+	GLRotationMatrix rotationMatrix;
 	Axis localX;
 	Axis localY;
 	bool negatedX;
@@ -52,7 +51,6 @@
 	Vertex convert2dTo3d(const QPoint& pos2d, Grid* grid = nullptr) const;
 	QPoint convert3dTo2d(const Vertex& pos3d) const;
 	double depth() const;
-	int glRotate(Axis axis) const;
 	bool isAxisNegated(Axis axis) const;
 	const QString& name() const;
 	void pan(int xMove, int yMove);
@@ -61,7 +59,8 @@
 	Q_SLOT void rendererResized(int width, int height);
 	void setPanning(double x, double y);
 	void setZoom(double zoom);
-	Matrix transformationMatrix(double scale) const;
+	const GLRotationMatrix& transformationMatrix() const;
+	GLRotationMatrix transformationMatrix(double scale) const;
 	const QSizeF& virtualSize() const;
 	double zoom() const;
 	void zoomNotch(bool inward);
@@ -74,7 +73,7 @@
 	double m_zoom = 30;
 	QSize m_size;
 	QSizeF m_virtualSize;
-	int m_glrotate[3] = {0, 0, 0}; // GL model transformation to use
+	GLRotationMatrix m_rotationMatrix;
 	Axis m_localX = X; // Which axis to use for Y
 	Axis m_localY = Y; // Which axis to use for Y
 	bool m_isFree = false; // Is this the free camera?
--- a/src/glrenderer.cpp	Sat Feb 18 02:02:29 2017 +0200
+++ b/src/glrenderer.cpp	Mon Feb 20 07:56:21 2017 +0200
@@ -37,6 +37,17 @@
 
 const QPen GLRenderer::thinBorderPen {QColor {0, 0, 0, 208}, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin};
 
+// Transformation matrices for the fixed cameras.
+const GLRotationMatrix GLRenderer::topCameraMatrix = GLRotationMatrix {};
+const GLRotationMatrix GLRenderer::frontCameraMatrix = {{1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1}};
+const GLRotationMatrix GLRenderer::leftCameraMatrix = {{0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 1}};
+const GLRotationMatrix GLRenderer::bottomCameraMatrix = {{1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1}};
+const GLRotationMatrix GLRenderer::backCameraMatrix = {{-1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1}};
+const GLRotationMatrix GLRenderer::rightCameraMatrix = {{0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1}};
+
+// Conversion matrix from LDraw to OpenGL coordinates.
+const GLRotationMatrix GLRenderer::ldrawToGLAdapterMatrix = {{1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1}};
+
 /*
  * Constructs a GL renderer.
  */
@@ -45,12 +56,12 @@
     HierarchyElement {parent},
     m_model {model},
     m_cameras {
-        {"Top camera", {1,  0, 0, X, Z, false, false, false}}, // top
-        {"Front camera", {0,  0, 1, X, Y, false,  true, false}}, // front
-        {"Left camera", {0,  1, 0, Z, Y,  true,  true, false}}, // left
-        {"Bottom camera", {-1,  0, 0, X, Z, false,  true, true}}, // bottom
-        {"Back camera", {0,  0, -1, X, Y,  true,  true, true}}, // back
-        {"Right camera", {0, -1, 0, Z, Y, false,  true, true}}, // right
+        {"Top camera", {topCameraMatrix, X, Z, false, false, false}}, // top
+        {"Front camera", {frontCameraMatrix, X, Y, false,  true, false}}, // front
+        {"Left camera", {leftCameraMatrix, Z, Y,  true,  true, false}}, // left
+        {"Bottom camera", {bottomCameraMatrix, X, Z, false,  true, true}}, // bottom
+        {"Back camera", {backCameraMatrix, X, Y,  true,  true, true}}, // back
+        {"Right camera", {rightCameraMatrix, Z, Y, false,  true, true}}, // right
         {"Free camera", GLCamera::FreeCamera}, // free
     }
 {
@@ -380,16 +391,8 @@
 		const QSizeF& virtualSize = currentCamera().virtualSize();
 		glOrtho(-virtualSize.width(), virtualSize.width(), -virtualSize.height(), virtualSize.height(), -100.0f, 100.0f);
 		glTranslatef(panning (X), panning (Y), 0.0f);
-
-		if (camera() != Camera::Front and camera() != Camera::Back)
-			glRotatef(90.0f, currentCamera().glRotate(X), currentCamera().glRotate(Y), 0);
-
-		// Back camera needs to be handled differently
-		if (camera() == Camera::Back)
-		{
-			glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
-			glRotatef(180.0f, 0.0f, 0.0f, 1.0f);
-		}
+		glMultMatrixf(currentCamera().transformationMatrix());
+		glMultMatrixf(ldrawToGLAdapterMatrix);
 	}
 	else
 	{
--- a/src/glrenderer.h	Sat Feb 18 02:02:29 2017 +0200
+++ b/src/glrenderer.h	Mon Feb 20 07:56:21 2017 +0200
@@ -105,6 +105,13 @@
 	QPen textPen() const;
 
 	static const QPen thinBorderPen;
+	static const GLRotationMatrix topCameraMatrix;
+	static const GLRotationMatrix frontCameraMatrix;
+	static const GLRotationMatrix leftCameraMatrix;
+	static const GLRotationMatrix bottomCameraMatrix;
+	static const GLRotationMatrix backCameraMatrix;
+	static const GLRotationMatrix rightCameraMatrix;
+	static const GLRotationMatrix ldrawToGLAdapterMatrix;
 
 signals:
 	void objectHighlightingChanged(LDObject* object);
--- a/src/types/matrix.cpp	Sat Feb 18 02:02:29 2017 +0200
+++ b/src/types/matrix.cpp	Mon Feb 20 07:56:21 2017 +0200
@@ -250,4 +250,15 @@
 int Matrix::ConstRowView::row()
 {
 	return _row;
-}
\ No newline at end of file
+}
+
+Matrix Matrix::fromRotationMatrix(const GLRotationMatrix& rotationMatrix)
+{
+	Matrix result;
+
+	for (int i = 0; i < 3; ++i)
+	for (int j = 0; j < 3; ++j)
+		result(i, j) = rotationMatrix(i, j);
+
+	return result;
+}
--- a/src/types/matrix.h	Sat Feb 18 02:02:29 2017 +0200
+++ b/src/types/matrix.h	Mon Feb 20 07:56:21 2017 +0200
@@ -18,6 +18,7 @@
 
 #pragma once
 #include <QString>
+#include "../glShared.h"
 
 /*
  * A mathematical 3 x 3 matrix
@@ -53,6 +54,7 @@
 	const double& operator()(int row, int column) const;
 
 	static const Matrix identity;
+	static Matrix fromRotationMatrix(const GLRotationMatrix& rotationMatrix);
 
 private:
 	double m_values[9];

mercurial