Picking improvements

Mon, 15 Apr 2013 02:56:42 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Mon, 15 Apr 2013 02:56:42 +0300
changeset 107
195aa036da7f
parent 106
46e4202a44fc
child 108
351aef26f444

Picking improvements

gldraw.cpp file | annotate | diff | comparison | revisions
gldraw.h file | annotate | diff | comparison | revisions
ldtypes.h file | annotate | diff | comparison | revisions
str.cpp file | annotate | diff | comparison | revisions
str.h file | annotate | diff | comparison | revisions
zz_historyDialog.cpp file | annotate | diff | comparison | revisions
--- a/gldraw.cpp	Mon Apr 15 01:51:53 2013 +0300
+++ b/gldraw.cpp	Mon Apr 15 02:56:42 2013 +0300
@@ -254,7 +254,7 @@
 		glRotatef (fRotZ, 0.0f, 0.0f, 1.0f);
 		
 		for (LDObject* obj : g_CurrentFile->objects)
-			glCallList (obj->uGLList);
+			glCallList ((g_bPicking == false) ? obj->uGLList : obj->uGLPickList);
 	glPopMatrix ();
 }
 
@@ -275,14 +275,24 @@
 	}
 	
 	for (LDObject* obj : g_CurrentFile->objects) {
-		GLuint uList = glGenLists (1);
-		glNewList (uList, GL_COMPILE);
+		GLuint* upaLists[2] = {
+			&obj->uGLList,
+			&obj->uGLPickList
+		};
 		
-		compileOneObject (obj);
+		for (GLuint* upMemberList : upaLists) {
+			GLuint uList = glGenLists (1);
+			glNewList (uList, GL_COMPILE);
+			
+			g_bPicking = (upMemberList == &obj->uGLPickList);
+			compileOneObject (obj);
+			g_bPicking = false;
+			
+			glEndList ();
+			*upMemberList = uList;
+		}
 		
-		glEndList ();
-		uaObjLists.push_back (uList);
-		obj->uGLList = uList;
+		uaObjLists.push_back (obj->uGLList);
 	}
 }
 
@@ -407,12 +417,13 @@
 void GLRenderer::mouseReleaseEvent (QMouseEvent* event) {
 	if ((qMouseButtons & Qt::LeftButton) && !(event->buttons() & Qt::LeftButton)) {
 		if (ulTotalMouseMove < 10)
-			pick (event->x(), event->y());
+			pick (event->x(), event->y(), (qKeyMods & Qt::ControlModifier));
 		
 		ulTotalMouseMove = 0;
 	}
 }
 
+// ========================================================================= //
 void GLRenderer::mousePressEvent (QMouseEvent* event) {
 	qMouseButtons = event->buttons();
 	if (event->buttons() & Qt::LeftButton)
@@ -453,27 +464,46 @@
 // ========================================================================= //
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 // ========================================================================= //
-void GLRenderer::pick (uint mx, uint my) {
-	g_ForgeWindow->paSelection.clear ();
+void GLRenderer::keyPressEvent (QKeyEvent* qEvent) {
+	qKeyMods = qEvent->modifiers ();
+}
+
+void GLRenderer::keyReleaseEvent (QKeyEvent* qEvent) {
+	qKeyMods = qEvent->modifiers ();
+}
+
+// ========================================================================= //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// ========================================================================= //
+void GLRenderer::pick (uint uMouseX, uint uMouseY, bool bAdd) {
+	if (bAdd == false) {
+		// Clear the selection if we don't wish to add to it.
+		std::vector<LDObject*> paOldSelection = g_ForgeWindow->paSelection;
+		g_ForgeWindow->paSelection.clear ();
+		
+		// Recompile the prior selection to remove the highlight color
+		for (LDObject* obj : paOldSelection)
+			recompileObject (obj);
+	}
 	
 	glDisable (GL_DITHER);
 	glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
 	
 	g_bPicking = true;
 	
-	compileObjects ();
 	paintGL ();
 	
-	GLubyte pixel[3];
-	GLint viewport[4];
-	glGetIntegerv (GL_VIEWPORT, viewport);
-	glReadPixels (mx, viewport[3] - my, 1, 1, GL_RGB, GL_UNSIGNED_BYTE,
-		reinterpret_cast<GLvoid*> (pixel));
+	GLubyte ucaPixel[3];
+	GLint daViewport[4];
+	glGetIntegerv (GL_VIEWPORT, daViewport);
+	glReadPixels (uMouseX, daViewport[3] - uMouseY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE,
+		reinterpret_cast<GLvoid*> (ucaPixel));
 	
-	const bool bHasSelection = (pixel[0] != 255 || pixel[1] != 255 || pixel[2] != 255);
+	// If we hit a white pixel, we selected the background. This no object is selected.
+	const bool bHasSelection = (ucaPixel[0] != 255 || ucaPixel[1] != 255 || ucaPixel[2] != 255);
 	
 	if (bHasSelection) {
-		ulong idx = pixel[0] + (pixel[1] * 256) + (pixel[2] * 256 * 256);
+		ulong idx = ucaPixel[0] + (ucaPixel[1] * 256) + (ucaPixel[2] * 256 * 256);
 		
 		LDObject* obj = g_CurrentFile->object (idx);
 		g_ForgeWindow->paSelection.push_back (obj);
@@ -493,36 +523,40 @@
 	g_ForgeWindow->updateSelection ();
 	
 	setBackground ();
-	hardRefresh ();
+	
+	for (LDObject* obj : g_ForgeWindow->getSelectedObjects ())
+		recompileObject (obj);
+	
+	paintGL ();
+	swapBuffers ();
 }
 
 // ========================================================================= //
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 // ========================================================================= //
-void GLRenderer::updateObjectColors() {
-	for (LDObject* obj : g_ForgeWindow->getSelectedObjects ()) {
-		// Replace the old list with the new one.
-		for (ulong i = 0; i < uaObjLists.size(); ++i)
-			if (uaObjLists[i] == obj->uGLList)
-				uaObjLists.erase (uaObjLists.begin() + i);
-		
-		GLuint uList = glGenLists (1);
-		glNewList (uList, GL_COMPILE);
-		
-		compileOneObject (obj);
-		
-		glEndList ();
-		uaObjLists.push_back (uList);
-		obj->uGLList = uList;
-	}
+void GLRenderer::recompileObject (LDObject* obj) {
+	// Replace the old list with the new one.
+	for (ulong i = 0; i < uaObjLists.size(); ++i)
+		if (uaObjLists[i] == obj->uGLList)
+			uaObjLists.erase (uaObjLists.begin() + i);
+	
+	GLuint uList = glGenLists (1);
+	glNewList (uList, GL_COMPILE);
+	
+	compileOneObject (obj);
+	
+	glEndList ();
+	uaObjLists.push_back (uList);
+	obj->uGLList = uList;
 }
 
 // ========================================================================= //
 void GLRenderer::slot_timerUpdate () {
 	++g_dPulseTick %= g_dNumPulseTicks;
-	printf ("%d\n", g_dPulseTick);
 	
-	updateObjectColors ();
+	for (LDObject* obj : g_ForgeWindow->getSelectedObjects ())
+		recompileObject (obj);
+	
 	paintGL ();
 	swapBuffers ();
 }
\ No newline at end of file
--- a/gldraw.h	Mon Apr 15 01:51:53 2013 +0300
+++ b/gldraw.h	Mon Apr 15 02:56:42 2013 +0300
@@ -39,7 +39,7 @@
 	void hardRefresh ();
 	void compileObjects ();
 	void setBackground ();
-	void pick (uint mx, uint my);
+	void pick (uint uMouseX, uint uMouseY, bool bAdd);
 	QColor getMainColor ();
 	
 	double fRotX, fRotY, fRotZ;
@@ -54,6 +54,8 @@
 	void mousePressEvent (QMouseEvent* event);
 	void mouseMoveEvent (QMouseEvent* event);
 	void mouseReleaseEvent (QMouseEvent* event);
+	void keyPressEvent (QKeyEvent* qEvent);
+	void keyReleaseEvent (QKeyEvent* qEvent);
 
 private:
 	std::vector<GLuint> uaObjLists;
@@ -63,7 +65,7 @@
 	void compileVertex (vertex& vrt);
 	void clampAngle (double& fAngle);
 	void setObjectColor (LDObject* obj);
-	void updateObjectColors ();
+	void recompileObject (LDObject* obj);
 	
 	QTimer* qPulseTimer;
 	
--- a/ldtypes.h	Mon Apr 15 01:51:53 2013 +0300
+++ b/ldtypes.h	Mon Apr 15 02:56:42 2013 +0300
@@ -78,7 +78,7 @@
 	short dColor;
 	
 	// OpenGL list for this object
-	uint uGLList;
+	uint uGLList, uGLPickList;
 	
 	// Object this object was referenced from, if any
 	LDSubfile* parent;
--- a/str.cpp	Mon Apr 15 01:51:53 2013 +0300
+++ b/str.cpp	Mon Apr 15 02:56:42 2013 +0300
@@ -285,8 +285,6 @@
 }
 
 // ============================================================================
-// It works otherwise but I'm having trouble with the initializer_list
-/*
 void str::strip (char c) {
 	strip ({c});
 }
@@ -315,7 +313,6 @@
 	
 	delete[] buf;
 }
-*/
 
 void str::insert (char* c, unsigned int pos) {
 	str s1 = substr (0, pos);
--- a/str.h	Mon Apr 15 01:51:53 2013 +0300
+++ b/str.h	Mon Apr 15 02:56:42 2013 +0300
@@ -159,10 +159,8 @@
 	
 	std::vector<str> split (str del, bool bNoBlanks = false);
 	
-	/*
 	void strip (char c);
 	void strip (std::initializer_list<char> unwanted);
-	*/
 	
 	// ======================================================================
 	// OPERATORS
--- a/zz_historyDialog.cpp	Mon Apr 15 01:51:53 2013 +0300
+++ b/zz_historyDialog.cpp	Mon Apr 15 02:56:42 2013 +0300
@@ -260,20 +260,21 @@
 	QListWidgetItem* qItem = qHistoryList->selectedItems ()[0];
 	
 	// Find the index of the edit
-	long idx = -1;
-	QListWidgetItem* it;
-	while ((it = qHistoryList->item (++idx)) != null)
-		if (it == qItem)
+	long lIdx;
+	for (lIdx = 0; lIdx < qHistoryList->count (); ++lIdx)
+		if (qHistoryList->item (lIdx) == qItem)
 			break;
 	
-	idx--; // qHistoryList is 0-based, History is -1-based.
+	// qHistoryList is 0-based, History is -1-based, thus decrement
+	// the index now
+	lIdx--;
 	
-	if (idx == History::pos ())
+	if (lIdx == History::pos ())
 		return;
 	
 	// Seek to the selected edit by repeadetly undoing or redoing.
-	while (History::pos () != idx) {
-		if (History::pos () > idx)
+	while (History::pos () != lIdx) {
+		if (History::pos () > lIdx)
 			History::undo ();
 		else
 			History::redo ();

mercurial