matrix is now templated with N=int (usually 3)

Sun, 05 May 2013 00:53:13 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Sun, 05 May 2013 00:53:13 +0300
changeset 162
b7d65e89861a
parent 161
c9fba92c4e35
child 163
46955613626d

matrix is now templated with N=int (usually 3)

common.h file | annotate | diff | comparison | revisions
gldraw.cpp file | annotate | diff | comparison | revisions
gldraw.h file | annotate | diff | comparison | revisions
gui_actions.cpp file | annotate | diff | comparison | revisions
gui_editactions.cpp file | annotate | diff | comparison | revisions
ldtypes.cpp file | annotate | diff | comparison | revisions
ldtypes.h file | annotate | diff | comparison | revisions
main.cpp file | annotate | diff | comparison | revisions
types.cpp file | annotate | diff | comparison | revisions
types.h file | annotate | diff | comparison | revisions
--- a/common.h	Sat May 04 19:14:16 2013 +0300
+++ b/common.h	Sun May 05 00:53:13 2013 +0300
@@ -177,6 +177,6 @@
 
 // -----------------------------------------------------------------------------
 // Identity matrix
-extern const matrix g_identity;
+extern const matrix<3> g_identity;
 
 #endif // COMMON_H
\ No newline at end of file
--- a/gldraw.cpp	Sat May 04 19:14:16 2013 +0300
+++ b/gldraw.cpp	Sun May 05 00:53:13 2013 +0300
@@ -87,6 +87,7 @@
 	m_picking = m_rangepick = false;
 	m_camera = (GLRenderer::Camera) gl_camera.value;
 	m_drawToolTip = false;
+	m_planeDraw = false;
 	
 	m_pulseTimer = new QTimer (this);
 	connect (m_pulseTimer, SIGNAL (timeout ()), this, SLOT (slot_timerUpdate ()));
@@ -395,6 +396,44 @@
 	glMatrixMode (GL_MODELVIEW);
 }
 
+vertex GLRenderer::coord_2to3 (const QPoint& pos2d, const bool snap) const {
+	vertex pos3d;
+	const staticCameraMeta* cam = &g_staticCameras[m_camera];
+	const Axis axisX = cam->axisX;
+	const Axis axisY = cam->axisY;
+	const short negXFac = cam->negX ? -1 : 1,
+		negYFac = cam->negY ? -1 : 1;
+	
+	// Calculate cx and cy - these are the LDraw unit coords the cursor is at.
+	double cx = (-m_virtWidth + ((2 * pos2d.x () * m_virtWidth) / m_width) - m_panX) * g_storedBBoxSize - (negXFac * g_objOffset[axisX]);
+	double cy = (m_virtHeight - ((2 * pos2d.y () * m_virtHeight) / m_height) - m_panY) * g_storedBBoxSize - (negYFac * g_objOffset[axisY]);
+	
+	if (snap) {
+		cx = Grid::snap (cx, (Grid::Config) axisX);
+		cy = Grid::snap (cy, (Grid::Config) axisY);
+	}
+	
+	cx *= negXFac;
+	cy *= negYFac;
+	
+	pos3d = g_origin;
+	pos3d[axisX] = cx;
+	pos3d[axisY] = cy;
+	return pos3d;
+}
+
+QPoint GLRenderer::coord_3to2 (const vertex& pos3d) const {
+	QPoint pos2d (0, 0);
+	GLdouble glmatr[16];
+	glGetDoublev (GL_MODELVIEW, glmatr);
+	
+	matrix<4> matr (glmatr);
+	
+	vertex copy = pos3d;
+	copy.transform (matrix<3> (matr), g_origin);
+	return QPoint (copy[X], copy[Y]);
+}
+
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
@@ -411,23 +450,8 @@
 	m_hoverpos = g_origin;
 	
 	if (m_camera != Free) {
-		const staticCameraMeta* cam = &g_staticCameras[m_camera];
-		const Axis axisX = cam->axisX;
-		const Axis axisY = cam->axisY;
-		const short negXFac = cam->negX ? -1 : 1,
-			negYFac = cam->negY ? -1 : 1;
-		
-		// Calculate cx and cy - these are the LDraw unit coords the cursor is at.
-		double cx = Grid::snap ((-m_virtWidth + ((2 * m_pos.x () * m_virtWidth) / m_width) - m_panX) * g_storedBBoxSize -
-			(negXFac * g_objOffset[axisX]), (Grid::Config) axisX);
-		double cy = Grid::snap ((m_virtHeight - ((2 * m_pos.y () * m_virtHeight) / m_height) - m_panY) * g_storedBBoxSize -
-			(negYFac * g_objOffset[axisY]), (Grid::Config) axisY);
-		cx *= negXFac;
-		cy *= negYFac;
-		
-		// Set the position we're hovering over based on this
-		m_hoverpos[axisX] = cx;
-		m_hoverpos[axisY] = cy;
+		// Calculate 3d position of the cursor
+		m_hoverpos = coord_2to3 (m_pos, true);
 		
 		// Paint the coordinates onto the screen.
 		str text;
@@ -439,10 +463,13 @@
 		
 		paint.drawText (m_width - textSize.width (), m_height - 16, textSize.width (),
 			textSize.height (), Qt::AlignCenter, text);
+		
+		// If we're plane drawing, draw the vertices onto the screen.
+		
 	}
 	
 	// Camera icons
-	if (!m_picking) {
+	if (!m_picking && m_planeDraw == false) {
 		// Draw a background for the selected camera
 		paint.setPen (m_thinBorderPen);
 		paint.setBrush (QBrush (QColor (0, 128, 160, 128)));
@@ -693,11 +720,15 @@
 // =============================================================================
 void GLRenderer::mouseReleaseEvent (QMouseEvent* ev) {
 	if ((m_lastButtons & Qt::LeftButton) && !(ev->buttons() & Qt::LeftButton)) {
-		if (!m_rangepick)
-			m_addpick = (m_keymods & Qt::ControlModifier);
-		
-		if (m_totalmove < 10 || m_rangepick)
-			pick (ev->x (), ev->y ());
+		if (m_planeDraw) {
+			m_planeDrawVerts.push_back ({m_hoverpos, m_pos});
+		} else {
+			if (!m_rangepick)
+				m_addpick = (m_keymods & Qt::ControlModifier);
+			
+			if (m_totalmove < 10 || m_rangepick)
+				pick (ev->x (), ev->y ());
+		}
 		
 		m_rangepick = false;
 		m_totalmove = 0;
@@ -943,6 +974,14 @@
 	update ();
 }
 
+void GLRenderer::beginPlaneDraw () {
+	if (m_camera == Free)
+		return;
+	
+	m_planeDraw = true;
+	update ();
+}
+
 // ========================================================================= //
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 // ========================================================================= //
--- a/gldraw.h	Sat May 04 19:14:16 2013 +0300
+++ b/gldraw.h	Sun May 05 00:53:13 2013 +0300
@@ -24,6 +24,11 @@
 #include "common.h"
 #include "ldtypes.h"
 
+typedef struct {
+	vertex pos3d;
+	QPoint pos2d;
+} GLPlaneDrawVertex;
+
 // =============================================================================
 // GLRenderer
 // 
@@ -82,17 +87,15 @@
 	Qt::MouseButtons m_lastButtons;
 	Qt::KeyboardModifiers m_keymods;
 	ulong m_totalmove;
-	bool m_darkbg;
-	double m_virtWidth, m_virtHeight;
-	Camera m_camera;
 	vertex m_hoverpos;
-	double m_rotX, m_rotY, m_rotZ, m_panX, m_panY, m_zoom;
-	bool m_picking, m_rangepick, m_addpick, m_drawToolTip, m_screencap;
+	double m_virtWidth, m_virtHeight, m_rotX, m_rotY, m_rotZ, m_panX, m_panY, m_zoom;
+	bool m_darkbg, m_picking, m_rangepick, m_addpick, m_drawToolTip, m_screencap, m_planeDraw;
 	QPoint m_pos, m_rangeStart;
 	QPen m_thinBorderPen, m_thickBorderPen;
-	Camera m_toolTipCamera;
+	Camera m_camera, m_toolTipCamera;
 	uint m_axeslist;
-	short m_width, m_height;
+	ushort m_width, m_height;
+	std::vector<GLPlaneDrawVertex> m_planeDrawVerts;
 	
 	void compileOneObject (LDObject* obj);
 	void compileSubObject (LDObject* obj, const GLenum gltype);
@@ -102,6 +105,9 @@
 	void drawGLScene () const;
 	void calcCameraIconRects ();
 	
+	vertex coord_2to3 (const QPoint& pos2d, const bool snap) const;
+	QPoint coord_3to2 (const vertex& pos3d) const;
+	
 private slots:
 	void slot_timerUpdate ();
 	void slot_toolTipTimer ();
--- a/gui_actions.cpp	Sat May 04 19:14:16 2013 +0300
+++ b/gui_actions.cpp	Sun May 05 00:53:13 2013 +0300
@@ -390,6 +390,11 @@
 }
 
 // =============================================================================
+MAKE_ACTION (beginPlaneDraw, "Begin drawing", "draw", "Begin drawing geometry", KEY (Space)) {
+	g_win->R ()->beginPlaneDraw ();
+}
+
+// =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 // Debug things
--- a/gui_editactions.cpp	Sat May 04 19:14:16 2013 +0300
+++ b/gui_editactions.cpp	Sun May 05 00:53:13 2013 +0300
@@ -566,7 +566,7 @@
 	const double angle = (pi * currentGrid ().confs[Grid::Angle]->value) / 360;
 	
 	// ref: http://en.wikipedia.org/wiki/Transformation_matrix#Rotation_2
-	matrix transform (
+	matrix<3> transform ({
 		(l * l * (1 - cos (angle))) + cos (angle),
 		(m * l * (1 - cos (angle))) - (n * sin (angle)),
 		(n * l * (1 - cos (angle))) + (m * sin (angle)),
@@ -578,7 +578,7 @@
 		(l * n * (1 - cos (angle))) - (m * sin (angle)),
 		(m * n * (1 - cos (angle))) + (l * sin (angle)),
 		(n * n * (1 - cos (angle))) + cos (angle)
-	);
+	});
 	
 	// Calculate center vertex
 	for (LDObject* obj : sel) {
--- a/ldtypes.cpp	Sat May 04 19:14:16 2013 +0300
+++ b/ldtypes.cpp	Sun May 05 00:53:13 2013 +0300
@@ -267,7 +267,7 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-static void transformObject (LDObject* obj, matrix transform, vertex pos, short parentcolor) {
+static void transformObject (LDObject* obj, matrix<3> transform, vertex pos, short parentcolor) {
 	switch (obj->getType()) {
 	case OBJ_Line:
 	case OBJ_CondLine:
@@ -281,9 +281,9 @@
 		{
 			LDSubfile* ref = static_cast<LDSubfile*> (obj);
 			
-			matrix mNewMatrix = transform * ref->mMatrix;
+			matrix<3> newMatrix = transform * ref->mMatrix;
 			ref->vPosition.transform (transform, pos);
-			ref->mMatrix = mNewMatrix;
+			ref->mMatrix = newMatrix;
 		}
 		break;
 	
--- a/ldtypes.h	Sat May 04 19:14:16 2013 +0300
+++ b/ldtypes.h	Sun May 05 00:53:13 2013 +0300
@@ -227,7 +227,7 @@
 	LDOBJ_COLORED (true)
 	
 	vertex vPosition; // Position of the subpart
-	matrix mMatrix; // Transformation matrix for the subpart
+	matrix<3> mMatrix; // Transformation matrix for the subpart
 	str zFileName; // Filename of the subpart
 	OpenFile* pFile; // Pointer to opened file for this subfile. null if unopened.
 	
@@ -338,10 +338,10 @@
 	
 	LDRadial::Type eRadialType;
 	vertex vPosition;
-	matrix mMatrix;
+	matrix<3> mMatrix;
 	short dDivisions, dSegments, dRingNum;
 	
-	LDRadial (LDRadial::Type eRadialType, vertex vPosition, matrix mMatrix,
+	LDRadial (LDRadial::Type eRadialType, vertex vPosition, matrix<3> mMatrix,
 		short dDivisions, short dSegments, short dRingNum) :
 		eRadialType (eRadialType), vPosition (vPosition), mMatrix (mMatrix),
 		dDivisions (dDivisions), dSegments (dSegments), dRingNum (dRingNum) {}
--- a/main.cpp	Sat May 04 19:14:16 2013 +0300
+++ b/main.cpp	Sun May 05 00:53:13 2013 +0300
@@ -32,7 +32,7 @@
 const QApplication* g_app = null;
 
 const vertex g_origin (0.0f, 0.0f, 0.0f);
-const matrix g_identity (1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
+const matrix<3> g_identity ({1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f});
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
--- a/types.cpp	Sat May 04 19:14:16 2013 +0300
+++ b/types.cpp	Sun May 05 00:53:13 2013 +0300
@@ -28,85 +28,13 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-void vertex::transform (matrix transmatrx, vertex pos) {
+void vertex::transform (matrix<3> matr, vertex pos) {
 	double x2, y2, z2;
-	x2 = (transmatrx[0] * coord (X)) + (transmatrx[1] * coord (Y)) + (transmatrx[2] * coord (Z)) + pos[X];
-	y2 = (transmatrx[3] * coord (X)) + (transmatrx[4] * coord (Y)) + (transmatrx[5] * coord (Z)) + pos[Y];
-	z2 = (transmatrx[6] * coord (X)) + (transmatrx[7] * coord (Y)) + (transmatrx[8] * coord (Z)) + pos[Z];
+	x2 = (matr[0] * coord (X)) + (matr[1] * coord (Y)) + (matr[2] * coord (Z)) + pos[X];
+	y2 = (matr[3] * coord (X)) + (matr[4] * coord (Y)) + (matr[5] * coord (Z)) + pos[Y];
+	z2 = (matr[6] * coord (X)) + (matr[7] * coord (Y)) + (matr[8] * coord (Z)) + pos[Z];
 	
 	coord (X) = x2;
 	coord (Y) = y2;
 	coord (Z) = z2;
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-matrix::matrix (vector<double> vals) {
-	assert (vals.size() == (sizeof m_vals / sizeof *m_vals));
-	memcpy (&m_vals[0], &(*vals.begin ()), sizeof m_vals);
-}
-
-// -----------------------------------------------------------------------------
-matrix::matrix (double fillval) {
-	for (short i = 0; i < 9; ++i)
-		m_vals[i] = fillval;
-}
-
-// -----------------------------------------------------------------------------
-matrix::matrix (double a, double b, double c, double d, double e, double f,
-	double g, double h, double i)
-{
-	m_vals[0] = a; m_vals[1] = b; m_vals[2] = c;
-	m_vals[3] = d; m_vals[4] = e; m_vals[5] = f;
-	m_vals[6] = g; m_vals[7] = h; m_vals[8] = i;
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-void matrix::zero () {
-	memset (&m_vals[0], 0, sizeof m_vals);
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-matrix matrix::mult (matrix other) {
-	matrix val;
-	val.zero ();
-	
-	for (short i = 0; i < 3; ++i)
-	for (short j = 0; j < 3; ++j)
-	for (short k = 0; k < 3; ++k)
-		val[(i * 3) + j] += m_vals[(i * 3) + k] * other[(k * 3) + j];
-	
-	return val;
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-void matrix::testOutput () {
-	for (short i = 0; i < 3; ++i) {
-		for (short j = 0; j < 3; ++j)
-			printf ("%*f\t", 10, m_vals[(i * 3) + j]);
-		
-		printf ("\n");
-	}
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-str matrix::stringRep () {
-	str val;
-	for (short i = 0; i < 9; ++i) {
-		if (i > 0)
-			val += ' ';
-		
-		val.appendformat ("%s", ftoa (m_vals[i]).chars());
-	}
-	
-	return val;
 }
\ No newline at end of file
--- a/types.h	Sat May 04 19:14:16 2013 +0300
+++ b/types.h	Sun May 05 00:53:13 2013 +0300
@@ -20,6 +20,7 @@
 #define TYPES_H
 
 #include "common.h"
+#include "misc.h"
 
 typedef unsigned int uint;
 typedef short unsigned int ushort;
@@ -38,14 +39,106 @@
 template<class T> using initlist = std::initializer_list<T>;
 using std::vector;
 
-class matrix;
-
 enum Axis { X, Y, Z };
 static const Axis g_Axes[3] = {X, Y, Z};
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
+// matrix
+// 
+// A templated, mathematical N x N matrix
+// =============================================================================
+template<int N> class matrix {
+public:
+	// Constructors
+	matrix () {}
+	matrix (initlist<double> vals) {
+		assert (vals.size() == N * N);
+		memcpy (&m_vals[0], &(*vals.begin ()), sizeof m_vals);
+	}
+	
+	matrix (double fillval) {
+		for (short i = 0; i < (N * N); ++i)
+			m_vals[i] = fillval;
+	}
+	
+	matrix (double vals[]) {
+		for (short i = 0; i < (N * N); ++i)
+			m_vals[i] = vals[i];
+	}
+	
+	template<int M> matrix (matrix<M> other) {
+		assert (M >= N);
+		
+		for (short i = 0; i < M; ++i)
+		for (short j = 0; j < M; ++j) {
+			const short idx = (i * M) + j;
+			m_vals[idx] = other[idx];
+		}
+	}
+	
+	matrix<N> mult (matrix<N> other) {
+		matrix val;
+		val.zero ();
+
+		for (short i = 0; i < N; ++i)
+		for (short j = 0; j < N; ++j)
+		for (short k = 0; k < N; ++k)
+			val[(i * N) + j] += m_vals[(i * N) + k] * other[(k * N) + j];
+
+		return val;
+	}
+	
+	matrix<N>& operator= (matrix<N> other) {
+		memcpy (&m_vals[0], &other.m_vals[0], sizeof (double) * N * N);
+		return *this;
+	}
+	
+	matrix<N> operator* (matrix<N> other) {
+		return mult (other);
+	}
+	
+	double& operator[] (const uint idx) {
+		return m_vals[idx];
+	}
+	
+	const double& operator[] (const uint idx) const {
+		return m_vals[idx];
+	}
+	
+	void zero () {
+		memset (&m_vals[0], 0, sizeof (double) * N * N);
+	}
+	
+	void puts () const {
+		for (short i = 0; i < N; ++i) {
+			for (short j = 0; j < N; ++j)
+				printf ("%*f\t", 10, m_vals[(i * 3) + j]);
+			
+			printf ("\n");
+		}
+	}
+	
+	str stringRep () const {
+		str val;
+		for (short i = 0; i < N * N; ++i) {
+			if (i > 0)
+				val += ' ';
+			
+			val.appendformat ("%s", ftoa (m_vals[i]).chars());
+		}
+		
+		return val;	
+	}
+
+private:
+	double m_vals[N * N];
+};
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 // vertex
 // 
 // Vertex class, contains a single point in 3D space. Not to be confused with
@@ -62,92 +155,50 @@
 		m_coords[Z] = z;
 	}
 	
-	// =========================================================================
 	void move (vertex other) {
 		for (const Axis ax : g_Axes)
 			m_coords[ax] += other[ax];
 	}
 	
-	// =========================================================================
 	vertex& operator+= (vertex other) {
 		move (other);
 		return *this;
 	}
 	
-	// =========================================================================
-	vertex operator/ (const double d) {
+	vertex operator/ (const double d) const {
 		vertex other (*this);
 		return other /= d;
 	}
 	
-	// =========================================================================
 	vertex& operator/= (const double d) {
 		for (const Axis ax : g_Axes)
 			m_coords[ax] /= d;
 		return *this;
 	}
 	
-	// =========================================================================
 	vertex operator- () const {
 		return vertex (-m_coords[X], -m_coords[Y], -m_coords[Z]);
 	}
 	
-	// =========================================================================
-	double& coord (const ushort n) const {
-		return const_cast<double&> (m_coords[n]);
+	double& coord (const ushort n) {
+		return m_coords[n];
 	}
 	
-	double& operator[] (const Axis ax) const {
+	const double& coord (const ushort n) const {
+		return m_coords[n];
+	}
+	
+	double& operator[] (const Axis ax) {
 		return coord ((ushort) ax);
 	}
 	
-	double& operator[] (const ushort n) const {
-		return coord (n);
+	const double& operator[] (const Axis ax) const {
+		return coord ((ushort) ax);
 	}
 	
 	vertex midpoint (vertex& other);
 	str stringRep (const bool mangled);
-	void transform (matrix mMatrix, vertex pos);
-};
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-// matrix
-// 
-// A mathematical 3x3 matrix
-// =============================================================================
-class matrix {
-public:
-	// Constructors
-	matrix () {}
-	matrix (std::vector<double> vals);
-	matrix (double fillval);
-	matrix (double a, double b, double c,
-		double d, double e, double f,
-		double g, double h, double i);
-	
-	matrix mult (matrix mOther);
-	
-	matrix& operator= (matrix mOther) {
-		memcpy (&m_vals[0], &mOther.m_vals[0], sizeof m_vals);
-		return *this;
-	}
-	
-	matrix operator* (matrix mOther) {
-		return mult (mOther);
-	}
-	
-	inline double& operator[] (const uint uIndex) {
-		return m_vals[uIndex];
-	}
-	
-	void zero ();
-	void testOutput ();
-	str stringRep ();
-
-private:
-	double m_vals[9];
+	void transform (matrix<3> matr, vertex pos);
 };
 
 #endif // TYPES_H
\ No newline at end of file

mercurial