Mon, 15 Apr 2013 02:56:42 +0300
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 ();