Object Selection

This commit is contained in:
Riku Avelar 2016-11-18 19:41:23 -05:00
parent 48e5889f60
commit d729f9aaaf
8 changed files with 111 additions and 23 deletions

View File

@ -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

View File

@ -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<GlNode>(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;
}

View File

@ -10,6 +10,7 @@ class SceneGroup : public GlNode
private:
std::vector<GlNode*> 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();
};

View File

@ -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;
};

View File

@ -4,6 +4,7 @@
#include <QVector4D>
#include <QColor>
#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

View File

@ -61,6 +61,7 @@ namespace
QMatrix4x4 sunRotate;
SceneGroup* selection;
PickedGeom selectedObj;
int currentPoint = 0; // VERY lazy way of tracking light balls
}
@ -187,14 +188,29 @@ 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))
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 = selectedPosition;
container->transform = selectedGeom.position;
container->addChild(c);
root.addChild(container);
} else QGLViewer::mousePressEvent(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);
@ -253,7 +271,6 @@ void Viewer::init()
//SceneGroup *sc1 = new SceneGroup();
//sc1->addChild(selection);
//root.addChild(sc1);
root.addChild(selection);
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<Shape*>(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<QRgb, QMatrix4x4> mapColorToPosition;
QMap<QRgb, Shape*> 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();
return pickedPosition;
PickedGeom result = PickedGeom();
result.position = pickedPosition;
result.shape = pickedShape;
return result;
}

View File

@ -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<QMatrix4x4> 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;