From d729f9aaafa0fc494a1a9d197837b8cede6f11bb Mon Sep 17 00:00:00 2001 From: Riku Avelar Date: Fri, 18 Nov 2016 19:41:23 -0500 Subject: [PATCH] Object Selection --- src/glnodes/glnode.h | 3 ++ src/glnodes/scenegroup.cpp | 10 ++++- src/glnodes/scenegroup.h | 4 ++ src/glnodes/shapes.cpp | 16 ++++++++ src/glnodes/shapes.h | 9 +++++ src/shaders/basicShader.frag | 8 ++-- src/viewer/simpleViewer.cpp | 75 ++++++++++++++++++++++++++++-------- src/viewer/simpleViewer.h | 9 ++++- 8 files changed, 111 insertions(+), 23 deletions(-) diff --git a/src/glnodes/glnode.h b/src/glnodes/glnode.h index 6d88ffc..db77932 100644 --- a/src/glnodes/glnode.h +++ b/src/glnodes/glnode.h @@ -4,10 +4,13 @@ #include "../interfaces/ivisitable.h" #include "../interfaces/visitor.h" class Viewer; +class SceneGroup; class GlNode : public IVisitable { public: QMatrix4x4 transform; + virtual SceneGroup* getParent() = 0; + virtual void setParent(SceneGroup* s) = 0; }; #endif // GLNODE diff --git a/src/glnodes/scenegroup.cpp b/src/glnodes/scenegroup.cpp index 551339d..f9124bb 100644 --- a/src/glnodes/scenegroup.cpp +++ b/src/glnodes/scenegroup.cpp @@ -32,7 +32,7 @@ bool SceneGroup::hasNext() } void SceneGroup::addChild(GlNode* child){ - + child->setParent(this); children.push_back(child); //children.push_back(std::shared_ptr(child)); } @@ -40,3 +40,11 @@ void SceneGroup::addChild(GlNode* child){ void SceneGroup::accept(Visitor &v) { v.visit(*this); } + +SceneGroup* SceneGroup::getParent() { + return _parent; +} + +void SceneGroup::setParent(SceneGroup* s) { + _parent = s; +} diff --git a/src/glnodes/scenegroup.h b/src/glnodes/scenegroup.h index 9296bed..8008fef 100644 --- a/src/glnodes/scenegroup.h +++ b/src/glnodes/scenegroup.h @@ -10,6 +10,7 @@ class SceneGroup : public GlNode private: std::vector children; int childIndex = 0; + SceneGroup* _parent; public: void addChild(GlNode* c); GlNode* getChild(); @@ -19,6 +20,9 @@ public: GlNode* childAt(int i); + SceneGroup* getParent(); + void setParent(SceneGroup* s); + void accept(Visitor& v) override; SceneGroup(); }; diff --git a/src/glnodes/shapes.cpp b/src/glnodes/shapes.cpp index e03cc4b..f886192 100644 --- a/src/glnodes/shapes.cpp +++ b/src/glnodes/shapes.cpp @@ -17,6 +17,14 @@ void Cube::setColor(QColor& c) { color = QColor(c); } +SceneGroup* Cube::getParent() { + return _parent; +} + +void Cube::setParent(SceneGroup* c) { + _parent = c; +} + QColor Cube::getColor(){ return color; }; @@ -41,6 +49,14 @@ void Sphere::setType(int t) { this->type = t; } +SceneGroup* Sphere::getParent() { + return _parent; +} + +void Sphere::setParent(SceneGroup* c) { + _parent = c; +} + int Sphere::getType(){ return this->type; }; diff --git a/src/glnodes/shapes.h b/src/glnodes/shapes.h index 5f53a31..acd4184 100644 --- a/src/glnodes/shapes.h +++ b/src/glnodes/shapes.h @@ -4,6 +4,7 @@ #include #include #include "../interfaces/visitor.h" +class SceneGroup; class Shape : public GlNode { public: @@ -11,12 +12,15 @@ public: virtual QColor getColor() = 0; virtual void setType(int) = 0; virtual int getType() = 0; + virtual SceneGroup* getParent() = 0; + virtual void setParent(SceneGroup* s) = 0; }; class Cube : public Shape { private: int type = 0; + SceneGroup* _parent; public: Cube(){} QColor color; @@ -25,12 +29,15 @@ public: QColor getColor(); void setType(int); int getType(); + SceneGroup* getParent(); + void setParent(SceneGroup* s); }; class Sphere : public Shape { private: int type = 0; + SceneGroup* _parent; public: Sphere(){} QColor color; @@ -39,5 +46,7 @@ public: QColor getColor(); void setType(int); int getType(); + SceneGroup* getParent(); + void setParent(SceneGroup* s); }; #endif // SHAPES_H diff --git a/src/shaders/basicShader.frag b/src/shaders/basicShader.frag index 29e3e8f..475f041 100644 --- a/src/shaders/basicShader.frag +++ b/src/shaders/basicShader.frag @@ -89,10 +89,10 @@ main() vec3 nfNormal = normalize(fNormal); vec3 nviewDirection = normalize(fPosition); - fColor = calcDirLight(texColor, fPosition, fNormal) - + calcPointLight(texColor, fPosition, fNormal, 0)/4 - + calcPointLight(texColor, fPosition, fNormal, 1)/4 - + calcPointLight(texColor, fPosition, fNormal, 2)/4; + fColor = calcDirLight(texColor, fPosition, fNormal) + + calcPointLight(texColor, fPosition, fNormal, 0)/4 + + calcPointLight(texColor, fPosition, fNormal, 1)/4 + + calcPointLight(texColor, fPosition, fNormal, 2)/4; } else { fColor = texColor + ifColor; } diff --git a/src/viewer/simpleViewer.cpp b/src/viewer/simpleViewer.cpp index 490e0a1..b89d6f4 100644 --- a/src/viewer/simpleViewer.cpp +++ b/src/viewer/simpleViewer.cpp @@ -61,6 +61,7 @@ namespace QMatrix4x4 sunRotate; SceneGroup* selection; + PickedGeom selectedObj; int currentPoint = 0; // VERY lazy way of tracking light balls } @@ -187,17 +188,32 @@ void Viewer::mousePressEvent(QMouseEvent* e) { std::cout << "--------------------------------------------------\nPicking shape at " << x << " (" << this->x() << " + " << e->x() << "), " << y << endl; std::cout << "Window geom: " << this->window()->size().width() << "w, " << this->window()->size().height() << "h" << endl; - QMatrix4x4 selectedPosition = pickGeom(x, y); - if(!selectedPosition.isIdentity() && e->modifiers().testFlag(Qt::ShiftModifier)) - { - Cube* c = new Cube; - c->setType(TEX_WOODFLOOR); - SceneGroup* container = new SceneGroup; - //selectedPosition.copyDataTo(container->transform.data()); - container->transform = selectedPosition; - container->addChild(c); - root.addChild(container); - } else QGLViewer::mousePressEvent(e); + PickedGeom selectedGeom = pickGeom(x, y); + + if(!selectedGeom.position.isIdentity() && e->modifiers().testFlag(Qt::ControlModifier)) + { + if(selectedObj.shape->getParent() != nullptr) { + // Remove previous selection + selectedObj.shape->getParent()->getChildren()->erase( + std::remove(selectedObj.shape->getParent()->getChildren()->begin(), + selectedObj.shape->getParent()->getChildren()->end(), + selection), + selectedObj.shape->getParent()->getChildren()->end()); + } + selectedObj.shape = selectedGeom.shape; + selectedObj.shape->getParent()->addChild(selection); + } + + if(!selectedGeom.position.isIdentity() && e->modifiers().testFlag(Qt::ShiftModifier)) + { + Cube* c = new Cube; + c->setType(TEX_WOODFLOOR); + SceneGroup* container = new SceneGroup; + //selectedPosition.copyDataTo(container->transform.data()); + container->transform = selectedGeom.position; + container->addChild(c); + root.addChild(container); + } else QGLViewer::mousePressEvent(e); } void Viewer::mouseReleaseEvent(QMouseEvent* e) { @@ -236,6 +252,8 @@ void Viewer::init() { + // Default non existant cube + selectedObj.shape = new Cube(); QColor* c1 = new QColor(255, 0, 255, 255); QColor* c2 = new QColor(0, 255, 255, 255); @@ -252,8 +270,7 @@ void Viewer::init() //SceneGroup *sc1 = new SceneGroup(); //sc1->addChild(selection); - //root.addChild(sc1); - root.addChild(selection); + //root.addChild(sc1); s1->transform.rotate(360 * 1/3,0,1,0); s1->transform.translate(0.3,1,0); @@ -268,7 +285,6 @@ void Viewer::init() s3->transform.scale(0.05); s3->setColor(*c3); - for(int i = 0; i < 10; i++){ for(int j = 0; j < 10; j++){ Shape* cube = new Cube(); @@ -284,6 +300,23 @@ void Viewer::init() } } +void Viewer::resetSphereColors(){ + QColor* c1 = new QColor(255, 0, 255, 255); + QColor* c2 = new QColor(0, 255, 255, 255); + QColor* c3 = new QColor(255, 255, 0, 255); + + int i = 0;/* + + QColor* colors[3] = {c1, c2, c3}; + + while(selection.hasNext()) { + Shape currentSphere = dynamic_cast(selection->getChild()); + + currentSphere->setColor(colors[i++]); + }*/ + +} + void Viewer::initShaders() { @@ -732,7 +765,7 @@ void Viewer::changeColor(QColor c){ this->update(); } -QMatrix4x4 Viewer::pickGeom(int x, int y){ +PickedGeom Viewer::pickGeom(int x, int y){ makeCurrent(); @@ -744,6 +777,7 @@ QMatrix4x4 Viewer::pickGeom(int x, int y){ isPickingActivated = true; QMap mapColorToPosition; + QMap mapColorToShape; QColor c; QRgb startColor = 1; // alpha must be 100%, glReadPixels doesn't resturn alpha unsigned char pixelData[3]; @@ -774,6 +808,7 @@ QMatrix4x4 Viewer::pickGeom(int x, int y){ //std::cout << "Setting " << startColor << " to {" << components[0] << ", " << components[0] << ", " << components[1] << ", " << components[2] << "}\n"; currentTransform.translate(components[1], -components[2], -components[0]); mapColorToPosition.insert(startColor, currentTransform); + mapColorToShape.insert(startColor, currentCube); startColor++; } } @@ -807,11 +842,17 @@ QMatrix4x4 Viewer::pickGeom(int x, int y){ //std::cout << "Picked " << pickedInt << endl; QMatrix4x4 pickedPosition = mapColorToPosition.value(pickedInt, identityMatrix); + Shape* pickedShape = mapColorToShape.value(pickedInt); mapColorToPosition.clear(); m_program->setUniformValue(m_isPickingModeLoc, false); isPickingActivated = false; - doneCurrent(); + doneCurrent(); - return pickedPosition; + PickedGeom result = PickedGeom(); + + result.position = pickedPosition; + result.shape = pickedShape; + + return result; } diff --git a/src/viewer/simpleViewer.h b/src/viewer/simpleViewer.h index fd58f40..d58a467 100644 --- a/src/viewer/simpleViewer.h +++ b/src/viewer/simpleViewer.h @@ -37,6 +37,12 @@ QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram) + +struct PickedGeom { + Shape* shape; + QMatrix4x4 position; +}; + class Viewer : public QGLViewer, protected QOpenGLFunctions_4_0_Core, public Visitor @@ -71,11 +77,12 @@ protected : std::stack modelStack; private: + void resetSphereColors(); void initShaders(); void initGeometries(); void initBuffers(); void deselect(); - QMatrix4x4 pickGeom(int, int); + PickedGeom pickGeom(int, int); // shader switching variables and constants; QOpenGLShaderProgram *colorPickerShaderProgram;