Now capable of calculating coordinates based on mouse x and y and snapping them to the grid

Sun, 28 Apr 2013 04:04:36 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Sun, 28 Apr 2013 04:04:36 +0300
changeset 146
2ab24976acaa
parent 145
ddf24c380be6
child 147
291a1fe2d278

Now capable of calculating coordinates based on mouse x and y and snapping them to the grid

config.cpp file | annotate | diff | comparison | revisions
file.cpp file | annotate | diff | comparison | revisions
file.h file | annotate | diff | comparison | revisions
gldraw.cpp file | annotate | diff | comparison | revisions
gldraw.h file | annotate | diff | comparison | revisions
gui.cpp file | annotate | diff | comparison | revisions
gui.h file | annotate | diff | comparison | revisions
gui_actions.cpp file | annotate | diff | comparison | revisions
gui_editactions.cpp file | annotate | diff | comparison | revisions
history.cpp file | annotate | diff | comparison | revisions
misc.cpp file | annotate | diff | comparison | revisions
misc.h file | annotate | diff | comparison | revisions
--- a/config.cpp	Sat Apr 27 16:22:35 2013 +0300
+++ b/config.cpp	Sun Apr 28 04:04:36 2013 +0300
@@ -121,7 +121,7 @@
 				break;
 		}
 		
-		switch (const_cast<config*> (cfg)->getType()) {
+		switch (cfg->getType()) {
 		case CONFIG_int:
 			static_cast<intconfig*> (cfg)->value = atoi (valstring.chars());
 			break;
--- a/file.cpp	Sat Apr 27 16:22:35 2013 +0300
+++ b/file.cpp	Sun Apr 28 04:04:36 2013 +0300
@@ -612,7 +612,7 @@
 // =============================================================================
 ulong OpenFile::addObject (LDObject* obj) {
 	if (this != g_CurrentFile) {
-		objects.insert (objects.end (), obj);
+		objects.push_back (obj);
 		return objects.size() - 1;
 	}
 	
--- a/file.h	Sat Apr 27 16:22:35 2013 +0300
+++ b/file.h	Sun Apr 28 04:04:36 2013 +0300
@@ -59,8 +59,12 @@
 	// At what point was this file last saved?
 	long savePos;
 	
-	LDObject* object (size_t uPos) const {
-		return objects[uPos];
+	LDObject* object (ulong pos) const {
+		return objects[pos];
+	}
+	
+	void insertObj (const ulong pos, LDObject* obj) {
+		objects.insert (objects.begin () + pos, obj);
 	}
 };
 
--- a/gldraw.cpp	Sat Apr 27 16:22:35 2013 +0300
+++ b/gldraw.cpp	Sun Apr 28 04:04:36 2013 +0300
@@ -58,7 +58,7 @@
 	rotX = 30.0f;
 	rotY = 325.f;
 	panX = panY = rotZ = 0.0f;
-	zoom = 1.0f;
+	zoom = 5.0f;
 }
 
 // =============================================================================
@@ -85,6 +85,7 @@
 	
 	glLineWidth (gl_linethickness);
 	
+	setAutoFillBackground (false);
 	setMouseTracking (true);
 	setFocusPolicy (Qt::WheelFocus);
 	compileObjects ();
@@ -223,7 +224,7 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 void GLRenderer::refresh () {
-	paintGL ();
+	update ();
 	swapBuffers ();
 }
 
@@ -245,54 +246,74 @@
 	glViewport (0, 0, w, h);
 	glMatrixMode (GL_PROJECTION);
 	glLoadIdentity ();
-	gluPerspective (45.0f, (double)w / (double)h, 0.1f, 100.0f);
+	gluPerspective (45.0f, (double)w / (double)h, 1.0f, 100.0f);
+	glMatrixMode (GL_MODELVIEW);
+}
+
+char g_staticCameras[6][3] = {
+	{ 0, 0, 1 },
+	{ 0, 0, -1 },
+	{ 1, 0, 0 },
+	{ -1, 0, 0 },
+	{ 0, 1, 0 },
+	{ 0, -1, 0 },
+};
+
+GLRenderer::Camera cam = GLRenderer::Front;
+
+void GLRenderer::drawGLScene () {
+	if (g_CurrentFile == null)
+		return;
+	
+	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+	glEnable (GL_DEPTH_TEST);
+	
+	if (cam != GLRenderer::Free) {
+		glMatrixMode (GL_PROJECTION);
+		glPushMatrix ();
+		
+		glLoadIdentity ();
+		glOrtho (-vw, vw, -vh, vh, -100.0, 100.0);
+		glTranslatef (panX, panY, 0.0f);
+		glRotatef (90.f, g_staticCameras[cam][0], g_staticCameras[cam][1], g_staticCameras[cam][2]);
+	} else {
+		glMatrixMode (GL_MODELVIEW);
+		glPushMatrix ();
+		glLoadIdentity ();
+		
+		glTranslatef (0.0f, 0.0f, -5.0f);
+		glTranslatef (panX, panY, -zoom);
+		glRotatef (rotX, 1.0f, 0.0f, 0.0f);
+		glRotatef (rotY, 0.0f, 1.0f, 0.0f);
+		glRotatef (rotZ, 0.0f, 0.0f, 1.0f);
+	}
+			
+		for (LDObject* obj : g_CurrentFile->objects)
+			glCallList ((picking == false) ? obj->uGLList : obj->uGLPickList);
+	glPopMatrix ();
 	glMatrixMode (GL_MODELVIEW);
 }
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-void GLRenderer::paintGL () {
-	if (g_CurrentFile == null)
-		return;
+void GLRenderer::paintEvent (QPaintEvent* ev) {
+	drawGLScene ();
 	
-	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-	
-	glMatrixMode (GL_PROJECTION);
+	vw = zoom;
+	vh = (height * vw) / width;
+	const double cx = Grid::snap ((-vw + ((2 * mouseX * vw) / width) - panX) * g_StoredBBoxSize - (g_faObjectOffset[0]), Grid::X);
+	const double cy = Grid::snap ((vh - ((2 * mouseY * vh) / height) - panY) * g_StoredBBoxSize - (g_faObjectOffset[2]), Grid::Z);
 	
-	glPushMatrix ();
-		glLoadIdentity ();
-		
-		double x = zoom;
-		double y = (height * x) / width;
-		
-		glOrtho (-x, x, -y, y, -100.0, 100.0);
-		
-		glTranslatef (panX, panY, -5.0f);
-		glRotatef (90.f, 0.0f, 1.0f, 0.0f);
-		
-		for (LDObject* obj : g_CurrentFile->objects)
-			glCallList ((picking == false) ? obj->uGLList : obj->uGLPickList);
-	glPopMatrix ();
-	glMatrixMode (GL_MODELVIEW);
+	str text;
+	text.format ("(%.3f, %.3f)", cx, cy);
+	QFontMetrics metrics = QFontMetrics (font ());
+	QRect textSize = metrics.boundingRect (0, 0, width, height, Qt::AlignCenter, text);
 	
-#if 0
-	glMatrixMode (GL_MODELVIEW);
-	
-	glPushMatrix ();
-		glLoadIdentity ();
-		
-		glTranslatef (0.0f, 0.0f, -5.0f);
-		glTranslatef (panX, panY, -zoom);
-		
-		glRotatef (rotX, 1.0f, 0.0f, 0.0f);
-		glRotatef (rotY, 0.0f, 1.0f, 0.0f);
-		glRotatef (rotZ, 0.0f, 0.0f, 1.0f);
-		
-		for (LDObject* obj : g_CurrentFile->objects)
-			glCallList ((picking == false) ? obj->uGLList : obj->uGLPickList);
-	glPopMatrix ();
-#endif
+	QPainter paint (this);
+	paint.setRenderHint (QPainter::Antialiasing);
+	paint.drawText (width - textSize.width (), height - 16, textSize.width (),
+		textSize.height (), Qt::AlignCenter, text);
 	
 	// If we're range-picking, draw a rectangle encompassing the selection area.
 	if (rangepick && !picking) {
@@ -301,6 +322,18 @@
 			x1 = pos.x (),
 			y1 = pos.y ();
 		
+		QRect rect (x0, y0, x1 - x0, y1 - y0);
+		QColor fillColor = (addpick ? "#80FF00" : "#00CCFF");
+		QColor borderColor = Qt::black;
+		fillColor.setAlphaF (0.2f);
+		borderColor.setAlphaF (0.8f);
+		QPen borderPen (borderColor, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
+		
+		paint.setPen (borderPen);
+		paint.setBrush (QBrush (fillColor));
+		paint.drawRect (rect);
+		
+#if 0
 		glMatrixMode (GL_PROJECTION);
 		
 		glPushMatrix ();
@@ -331,6 +364,7 @@
 		glPopMatrix ();
 		
 		glMatrixMode (GL_MODELVIEW);
+#endif
 	}
 }
 
@@ -515,6 +549,8 @@
 }
 
 // =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 void GLRenderer::mousePressEvent (QMouseEvent* ev) {
 	if (ev->buttons () & Qt::LeftButton)
 		totalmove = 0;
@@ -555,7 +591,7 @@
 	}
 	
 	pos = ev->pos ();
-	updateGL ();
+	update ();
 }
 
 // =============================================================================
@@ -571,13 +607,11 @@
 
 // =============================================================================
 void GLRenderer::wheelEvent (QWheelEvent* ev) {
-	printf ("%.5f -> ", zoom);
-	// zoom += (-ev->delta () / 100.0);
 	zoom *= (ev->delta () < 0) ? 1.2f : (1.0f / 1.2f);
-	printf ("%.5f\n", zoom);
 	zoom = clamp (zoom, 0.01, 100.0);
+	
+	update ();
 	ev->accept ();
-	updateGL ();
 }
 
 // =============================================================================
@@ -591,9 +625,9 @@
 		pulseTimer->stop ();
 }
 
-// ========================================================================= //
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-// ========================================================================= //
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 void GLRenderer::pick (uint mouseX, uint mouseY) {
 	GLint viewport[4];
 	LDObject* removedObject = null;
@@ -613,7 +647,7 @@
 	// Paint the picking scene
 	glDisable (GL_DITHER);
 	glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
-	paintGL ();
+	drawGLScene ();
 	
 	glGetIntegerv (GL_VIEWPORT, viewport);
 	
@@ -715,8 +749,9 @@
 	if (removedObject != null)
 		recompileObject (removedObject);
 	
-	paintGL ();
+	drawGLScene ();
 	swapBuffers ();
+	update ();
 }
 
 // ========================================================================= //
@@ -745,8 +780,7 @@
 	for (LDObject* obj : g_ForgeWindow->sel)
 		recompileObject (obj);
 	
-	paintGL ();
-	swapBuffers ();
+	update ();
 }
 
 // =============================================================================
@@ -754,7 +788,7 @@
 	w = width;
 	h = height;
 	uchar* cap = new uchar[4 * w * h];
-	paintGL ();
+	update ();
 	
 	// Capture the pixels
 	glReadPixels (0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, cap);
--- a/gldraw.h	Sat Apr 27 16:22:35 2013 +0300
+++ b/gldraw.h	Sun Apr 28 04:04:36 2013 +0300
@@ -35,6 +35,16 @@
 	Q_OBJECT
 	
 public:
+	enum Camera {
+		Front,
+		Back,
+		Top,
+		Bottom,
+		Left,
+		Right,
+		Free
+	};
+	
 	GLRenderer (QWidget* parent = null);
 	void hardRefresh ();
 	void compileObjects ();
@@ -61,7 +71,7 @@
 protected:
 	void initializeGL ();
 	void resizeGL (int w, int h);
-	void paintGL ();
+	// void paintGL ();
 	
 	void mousePressEvent (QMouseEvent* ev);
 	void mouseMoveEvent (QMouseEvent* ev);
@@ -69,6 +79,7 @@
 	void keyPressEvent (QKeyEvent* ev);
 	void keyReleaseEvent (QKeyEvent* ev);
 	void wheelEvent (QWheelEvent* ev);
+	void paintEvent (QPaintEvent* ev);
 
 private:
 	std::vector<GLuint> objLists;
@@ -77,6 +88,7 @@
 	Qt::KeyboardModifiers keymods;
 	ulong totalmove;
 	bool darkbg;
+	double vw, vh;
 	
 	void compileOneObject (LDObject* obj);
 	template<class T> void compileSubObject (LDObject* obj, const GLenum eGLType,
@@ -84,6 +96,7 @@
 	void compileVertex (vertex& vrt);
 	void clampAngle (double& fAngle);
 	void setObjectColor (LDObject* obj);
+	void drawGLScene ();
 	
 private slots:
 	void slot_timerUpdate ();
--- a/gui.cpp	Sat Apr 27 16:22:35 2013 +0300
+++ b/gui.cpp	Sun Apr 28 04:04:36 2013 +0300
@@ -22,6 +22,7 @@
 #include <qmenubar.h>
 #include <qstatusbar.h>
 #include <qsplitter.h>
+#include <qcoreapplication.h>
 #include "common.h"
 #include "gldraw.h"
 #include "gui.h"
@@ -143,6 +144,14 @@
 	setTitle ();
 	setMinimumSize (320, 200);
 	resize (800, 600);
+	
+	connect (QCoreApplication::instance (), SIGNAL (aboutToQuit ()), this, SLOT (slot_lastSecondCleanup ()));
+}
+
+// =============================================================================
+void ForgeWindow::slot_lastSecondCleanup () {
+	R->setParent (null);
+	delete R;
 }
 
 // =============================================================================
@@ -200,6 +209,7 @@
 	qViewMenu->addAction (ACTION (resetView));			// Reset View
 	qViewMenu->addSeparator ();							// -----
 	qViewMenu->addAction (ACTION (screencap));			// Screencap Part
+	qViewMenu->addAction (ACTION (showHistory));			// Edit History
 	
 	// Insert menu
 	qInsertMenu = menuBar ()->addMenu (tr ("&Insert"));
@@ -261,10 +271,6 @@
 	qMoveMenu->addAction (ACTION (rotateZPos));			// Rotate +Z
 	qMoveMenu->addAction (ACTION (rotateZNeg));			// Rotate -Z
 	
-	// Control menu
-	qControlMenu = menuBar ()->addMenu (tr ("&Control"));
-	qControlMenu->addAction (ACTION (showHistory));		// Show History
-	
 #ifndef RELEASE
 	// Debug menu
 	qDebugMenu = menuBar ()->addMenu (tr ("&Debug"));
--- a/gui.h	Sat Apr 27 16:22:35 2013 +0300
+++ b/gui.h	Sun Apr 28 04:04:36 2013 +0300
@@ -164,6 +164,7 @@
 	void slot_action ();
 	void slot_recentFile ();
 	void slot_quickColor ();
+	void slot_lastSecondCleanup ();
 };
 
 // -----------------------------------------------------------------------------
--- a/gui_actions.cpp	Sat Apr 27 16:22:35 2013 +0300
+++ b/gui_actions.cpp	Sun Apr 28 04:04:36 2013 +0300
@@ -275,7 +275,7 @@
 	for (LDObject* obj : objs) {
 		historyCopies.push_back (obj->clone ());
 		historyIndices.push_back (idx);
-		g_CurrentFile->objects.insert (g_CurrentFile->objects.begin () + idx, obj);
+		g_CurrentFile->insertObj (idx, obj);
 		g_ForgeWindow->sel.push_back (obj);
 		
 		idx++;
@@ -316,7 +316,7 @@
 	for (str line : str (te_edit->toPlainText ()).split ("\n")) {
 		LDObject* obj = parseLine (line);
 		
-		g_CurrentFile->objects.insert (g_CurrentFile->objects.begin () + idx, obj);
+		g_CurrentFile->insertObj (idx, obj);
 		historyIndices.push_back (idx);
 		historyCopies.push_back (obj->clone ());
 		g_ForgeWindow->sel.push_back (obj);
--- a/gui_editactions.cpp	Sat Apr 27 16:22:35 2013 +0300
+++ b/gui_editactions.cpp	Sun Apr 28 04:04:36 2013 +0300
@@ -91,7 +91,7 @@
 		historyCopies.push_back (obj->clone ());
 		
 		LDObject* copy = obj->clone ();
-		g_CurrentFile->objects.insert (g_CurrentFile->objects.begin() + idx++, copy);
+		g_CurrentFile->insertObj (idx, copy);
 		g_ForgeWindow->sel.push_back (copy);
 	}
 	
@@ -154,7 +154,7 @@
 			// This object is now inlined so it has no parent anymore.
 			inlineobj->parent = null;
 			
-			g_CurrentFile->objects.insert (g_CurrentFile->objects.begin() + idx++, inlineobj);
+			g_CurrentFile->insertObj (idx++, inlineobj);
 		}
 		
 		// Delete the subfile now as it's been inlined.
@@ -209,7 +209,7 @@
 		// Replace the quad with the first triangle and add the second triangle
 		// after the first one.
 		g_CurrentFile->objects[lIndex] = triangles[0];
-		g_CurrentFile->objects.insert (g_CurrentFile->objects.begin() + lIndex + 1, triangles[1]);
+		g_CurrentFile->insertObj (lIndex + 1, triangles[1]);
 		
 		// Delete this quad now, it has been split.
 		delete obj;
@@ -304,7 +304,7 @@
 			ulong idx = obj->getIndex (g_CurrentFile) + i + 1;
 			
 			lines[i]->dColor = dEdgeColor;
-			g_CurrentFile->objects.insert (g_CurrentFile->objects.begin() + idx, lines[i]);
+			g_CurrentFile->insertObj (idx, lines[i]);
 			
 			ulaIndices.push_back (idx);
 			paObjs.push_back (lines[i]->clone ());
@@ -354,7 +354,7 @@
 			pVert->vPosition = vaCoords[i];
 			pVert->dColor = obj->dColor;
 			
-			g_CurrentFile->objects.insert (g_CurrentFile->objects.begin() + ++idx, pVert);
+			g_CurrentFile->insertObj (++idx, pVert);
 			ulaIndices.push_back (idx);
 			paObjs.push_back (pVert->clone ());
 		}
@@ -401,7 +401,7 @@
 	History::redo ();
 }
 
-MAKE_ACTION (showHistory, "Show History", "history", "Show the history dialog.", (0)) {
+MAKE_ACTION (showHistory, "Edit History", "history", "Show the history dialog.", (0)) {
 	HistoryDialog dlg;
 	dlg.exec ();
 }
@@ -552,7 +552,7 @@
 				if (!inverted) {
 					// Not inverted, thus prefix it with a new invertnext.
 					LDBFC* bfc = new LDBFC (LDBFC::InvertNext);
-					g_CurrentFile->objects.insert (g_CurrentFile->objects.begin () + idx, bfc);
+					g_CurrentFile->insertObj (idx, bfc);
 					
 					paHistory.push_back (new AddHistory ({idx}, {bfc->clone ()}));
 				}
--- a/history.cpp	Sat Apr 27 16:22:35 2013 +0300
+++ b/history.cpp	Sun Apr 28 04:04:36 2013 +0300
@@ -146,10 +146,8 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 void EditHistory::undo () {
-	for (ulong idx : ulaIndices) {
-		printf ("undo %lu\n", idx);
+	for (ulong idx : ulaIndices)
 		g_CurrentFile->object (idx)->replace (paOldObjs[idx]->clone ());
-	}
 	
 	g_ForgeWindow->refresh ();
 }
--- a/misc.cpp	Sat Apr 27 16:22:35 2013 +0300
+++ b/misc.cpp	Sun Apr 28 04:04:36 2013 +0300
@@ -101,6 +101,27 @@
 	{ "Fine",	{ &grid_fine_x,		&grid_fine_y,	&grid_fine_z,	&grid_fine_angle	} }
 };
 
+template<class T> inline T abs (T a) {
+	return (a >= 0) ? a : -a;
+}
+
+// =============================================================================
+double Grid::snap (double in, const Grid::Config axis) {
+	const double gridval = currentGrid ().confs[axis]->value;
+	const long mult = abs (in / gridval);
+	const bool neg = (in < 0);
+	
+	double out = mult * gridval;
+	
+	if (abs<double> (in) - (mult * gridval) > gridval / 2)
+		out += gridval;
+	
+	if (neg && out != 0)
+		out *= -1;
+	
+	return out;
+}
+
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
--- a/misc.h	Sat Apr 27 16:22:35 2013 +0300
+++ b/misc.h	Sun Apr 28 04:04:36 2013 +0300
@@ -43,6 +43,14 @@
 	floatconfig* const confs[4];
 } gridinfo;
 
+extern_cfg (int, grid);
+static const short g_NumGrids = 3;
+extern const gridinfo g_GridInfo[3];
+
+inline const gridinfo& currentGrid () {
+	return g_GridInfo[grid];
+}
+
 namespace Grid {
 	enum Type {
 		Coarse,
@@ -56,16 +64,10 @@
 		Z,
 		Angle
 	};
+	
+	double snap (double value, const Grid::Config axis);
 };
 
-extern_cfg (int, grid);
-static const short g_NumGrids = 3;
-extern const gridinfo g_GridInfo[3];
-
-inline const gridinfo& currentGrid () {
-	return g_GridInfo[grid];
-}
-
 template<class T> void dataswap (T& a, T& b) {
 	T c = a;
 	a = b;

mercurial