Commit 6d919e3a by Alisa Jung

first draft for scenegraph. Includes only boxes, but seems to be working so far

Create new box with given tesselation, set proper name, create and transform (translate + rotate) multiple boxes. No Box selection yet.
parent 06b6dd64
#include "box.h"
Box::Box(int ID, char* name, int tesselation) : Primitive(ID, name, tesselation)
Box::Box(int ID, QString name, int tesselation) : Primitive(ID, name, tesselation)
{
qDebug() << "adding box " << ID;
}
Box::~Box(){
......
......@@ -8,7 +8,7 @@
class Box : public Primitive
{
public:
Box(int ID, char* name, int tesselation);
Box(int ID, QString name, int tesselation);
~Box();
void drawPrimitive() override;
};
......
#include "controller.h"
#include "myglwidget.h"
#include "scenegraph.h"
Controller::Controller()
{
modeCamera = true;
currentWidgetIndex = 0;
scene = new SceneGraph();
currentTransform = 0;
tesselation = 1;
}
Controller::~Controller(){
}
SceneGraph* Controller::getSceneGraph(){
return scene;
}
void Controller::initActions(QAction *cam, QAction *manipulate){
modeCameraAction = cam;
modeManipulateAction = manipulate;
......@@ -71,6 +79,12 @@ void Controller::showQuadView(){
}
void Controller::setTessellation(int t){
qDebug() << "Tesselation: " << t;
tesselation = t;
}
void Controller::setCtrlPressed(bool isCtrlPressed){
ctrlPressed = isCtrlPressed;
}
......@@ -121,18 +135,24 @@ void Controller::processMouseMoveEvent(QMouseEvent *event, MyGLWidget *widget){
QPoint diff = currentPosition - lastClickPosition;
lastClickPosition = currentPosition;
if (modeCamera){
//view change
widget->translateCamera(-0.01*diff.x(),0.01*diff.y());
} else{
widget->translateQube(0.01*diff.x(),-0.01*diff.y());
} else if (currentTransform){
qDebug("CurrentTransform not null");
//state change for model
QVector3D diffV(0.01*diff.x(),-0.01*diff.y(),0);
diffV = widget->getCameraRotation().conjugate().rotatedVector(diffV);
scene->addTranslation(currentTransform,diffV);
}
}else if (leftButtonPressed){
QQuaternion q = computeRotation(event->pos());
if (modeCamera){
//TODO nur bei perspective widget
//TODO widget->rotateCamera
//guess this counts as view selection...
widget->rotateCamera(q);
}else{
widget->rotateQube(q);
}else if (currentTransform){//only if sth is selected
qDebug("CurrentTransform not null");
//state change for model
scene->addRotation(currentTransform,q);
}
}
}
......@@ -200,5 +220,11 @@ QQuaternion Controller::computeRotation(QPoint newPosition){
q.normalize();
qDebug() << "quaternion diff " << q << "xo " << xOld << "yo " << yOld << " x new " << xNew << " ynew " << yNew;
qDebug() << "v1 " << v1 << ", v2 " << v2;
return q;
}
void Controller::addBox(){
currentTransform = scene->addBox(tesselation);
}
......@@ -13,9 +13,12 @@
#include <QDebug>
#include <QObject>
#include <QAction>
#include <QQuaternion>
#include <QGridLayout>
#include <rigidbodytransformation.h>
class MyGLWidget;
class SceneGraph;
class Controller : public QObject
{
......@@ -37,6 +40,10 @@ public:
void setScreenScenter(QPoint center);
void setCtrlPressed(bool isCtrlPressed);
SceneGraph* getSceneGraph();
RigidBodyTransformation* currentTransform;
private:
QAction *modeCameraAction;
QAction *modeManipulateAction;
......@@ -59,6 +66,9 @@ private:
QQuaternion computeRotation(QPoint newPosition);
int tesselation;
SceneGraph* scene;
public slots:
void switchToModeCamera();
......@@ -69,6 +79,10 @@ public slots:
void showDoubleView();
void showQuadView();
void setTessellation(int t);
void addBox();
};
#endif // CONTROLLER_H
......@@ -77,6 +77,7 @@ MainWindow::MainWindow(QWidget *parent)
//4.0 Widget //Assignment 2: Multiple Widgets.
qDebug("widgets...");
{
controller = new Controller();
myGLWidget = new MyGLWidget(0,controller, true, QQuaternion(),this);
setCentralWidget(myGLWidget);
......@@ -104,7 +105,7 @@ MainWindow::MainWindow(QWidget *parent)
QWidget* central_widget = new QWidget(this);
central_widget->setLayout(viewLayout);
setCentralWidget(central_widget);
}
qDebug("tesselation...");
//tesselation slider
......@@ -116,6 +117,7 @@ MainWindow::MainWindow(QWidget *parent)
tesselationSlider->setMaximum(16);
tesselationSlider->setValue(1);
toolBar->addWidget(tesselationSlider);
connect(tesselationSlider,SIGNAL(valueChanged(int)),controller,SLOT(setTessellation(int)));
//4.1.1 connect shading actions to slot
MyGLWidget* allWidgets[4] = {myGLWidget, viewFront, viewLeft, viewTop};
......@@ -124,7 +126,6 @@ MainWindow::MainWindow(QWidget *parent)
connect(shadeFlatAction,SIGNAL(triggered(bool)),allWidgets[i],SLOT(shadeFlatSlot()));
connect(shadeGouraudAction,SIGNAL(triggered(bool)),allWidgets[i],SLOT(shadeGouraudSlot()));
connect(shadePhongAction,SIGNAL(triggered(bool)),allWidgets[i],SLOT(shadePhongSlot()));
connect(tesselationSlider,SIGNAL(valueChanged(int)),allWidgets[i],SLOT(setTessellation(int)));
}
controller->initViewWidgets(allWidgets,viewSplitter1,viewSplitter3,viewLayout);
......@@ -201,6 +202,19 @@ MainWindow::MainWindow(QWidget *parent)
viewGroup->addAction(quadViewAction);
controller->showSingleView();//for whatever reason this works better than setting everything up above. After spending 2 hours setting up the views I honestly don*t care anymore about coding this prettier.
//Assignment 2: 3) add boxes etc.
{
addBox = new QAction("Add Box", toolBar);
addBox->setIcon(QIcon(":/grapa-a2-iconset/box.png"));
addBox->setCheckable(false);
toolBar->addAction(addBox);
toolBar->insertSeparator(addBox);
connect(addBox, SIGNAL(triggered(bool)),controller, SLOT(addBox()));
}
qDebug("Done initializing");
......
......@@ -79,6 +79,8 @@ private:
Controller* controller;
QAction* addBox;
public slots :
void showAboutBox ( ) ;
};
......
#include "myglwidget.h"
#include "controller.h"
#include "scenegraph.h"
//QGLShaderProgram *MyGLWidget::phongShader;
......@@ -9,21 +10,18 @@ MyGLWidget::MyGLWidget(int index, Controller* c, bool isPerspective, QQuaternion
this->index = index;
MyGLWidget::modeCamera = true;
tesselation = 1;
qubeRotation = QQuaternion();
cameraRotation = initialRotation;
cameraStartRotation = initialRotation;
cubeTranslation = QVector3D(0,0,0);
camRotCenter = QVector3D(0,0,0);
cameraZoom = cameraZoomDefault;
clickStartPosition = QPoint(0,0);
rightButtonPressed = false;
controller = c;
this->isPerspective = isPerspective;
this->isFocused = isPerspective; //start with focus on perspective view
platzhalter = "bla";
primitive = new Box(0,platzhalter,1);
rbt = new RigidBodyTransformation(primitive);
scene = controller->getSceneGraph();
scene->registerView(this);
}
MyGLWidget::~MyGLWidget()
......@@ -150,7 +148,8 @@ void MyGLWidget::paintGL(){
glMultMatrixf(camRot.data());
glTranslatef(camRotCenter.x(),camRotCenter.y(),camRotCenter.z());
rbt->drawChild();
scene->drawAll();
//rbt->drawChild();
//has to be down here or will be overpainted by above code
if (isFocused) highlightViewport();
......@@ -244,31 +243,6 @@ void MyGLWidget::translateCamera(double xDiff, double yDiff, double zDiff)
updateGL();
}
void MyGLWidget::translateQube(double xDiff, double yDiff){
// cubeTranslation += cameraRotation.conjugate().rotatedVector(QVector3D(xDiff, yDiff,0));
rbt->addTranslation(cameraRotation.conjugate().rotatedVector(QVector3D(xDiff, yDiff,0)));
updateGL();
}
void MyGLWidget::rotateQube(QQuaternion diff){
/*
* Wikipedia: Two rotation quaternions can be combined into
* one equivalent quaternionby the relation:
* q' = q_2*q_1'
* in which q′ corresponds to the rotation q1 followed by the rotation q2.
* (Note that quaternion multiplication is not commutative.)
*/
rbt->addRotation(diff);
// qubeRotation = diff*qubeRotation;
// qubeRotation.normalize();
updateGL();
}
void MyGLWidget::rotateCamera(QQuaternion diff){
if (isPerspective){
cameraRotation = diff*cameraRotation;
......@@ -277,6 +251,16 @@ void MyGLWidget::rotateCamera(QQuaternion diff){
}
}
QQuaternion MyGLWidget::getCameraRotation(){
return cameraRotation;
}
void MyGLWidget::modelChanged(){
qDebug("update view");
updateGL();
}
//4.1.2 User Input: Zooming
void MyGLWidget::wheelEvent(QWheelEvent *event){
cameraZoom += 0.01*event->delta();//0.01 seemed to be a good factor
......@@ -318,17 +302,7 @@ void MyGLWidget::shadePhongSlot(){
updateGL();
}
//4.1.1 tesselation slot
void MyGLWidget::setTessellation(int t){
qDebug() << "Tesselation: " << t;
tesselation = t;
updateGL();
}
void MyGLWidget::resetCamera(){
qubeRotation = QQuaternion();
cubeTranslation = QVector3D(0,0,0);
camRotCenter = QVector3D(0,0,0);
cameraZoom = cameraZoomDefault;
cameraRotation = cameraStartRotation;
......
......@@ -17,8 +17,9 @@
#include <rigidbodytransformation.h>//vorläufig, bis szenengraph steht.
#include <box.h>
class Controller;
class Controller;
class SceneGraph;
class MyGLWidget : public QGLWidget
{
......@@ -37,15 +38,15 @@ class MyGLWidget : public QGLWidget
/* Assignment 2*/
bool modeCamera;
void translateCamera(double xDiff, double yDiff, double zDiff = 0);
void translateQube(double xDiff, double yDiff);
void rotateCamera(QQuaternion diff);
void rotateQube(QQuaternion diff);
QQuaternion getCameraRotation();
void initShaderStuff();
int getIndex();
void setFocused(bool isFocused);//Tell view if it is focused and therefore needs a yellow border
void modelChanged();
protected:
//4.1 Core Functionality
void initializeGL();
......@@ -73,20 +74,9 @@ private:
QQuaternion cameraStartRotation;
QVector3D camRotCenter;
//translate camera
QPoint clickStartPosition;
bool rightButtonPressed;
QVector3D cubeTranslation;
//rotate cube
bool leftButtonPressed;
QQuaternion qubeRotation;
QPoint screenCenter;//Center of screen in pixel coordinates
//Phong Shader
QGLShaderProgram *phongShader;
RigidBodyTransformation* rbt;
Primitive* primitive;
char* platzhalter;
......@@ -96,13 +86,13 @@ private:
double windowWidth, windowHeight;
bool isFocused;
SceneGraph* scene;
public slots:
//4.1.1 slots for shading modes
void shadeWireframeSlot();
void shadeFlatSlot();
void shadeGouraudSlot();
void shadePhongSlot();
void setTessellation(int t);
void resetCamera();
};
......
......@@ -9,7 +9,11 @@ Primitive::~Primitive(){
}
Primitive::Primitive(int ID, char* name, int tesselation){
QString Primitive::getName(){
return name;
}
Primitive::Primitive(int ID, QString name, int tesselation){
this->ID = ID;
this->name = name;
this->tesselation = tesselation;
......
......@@ -8,13 +8,15 @@ class Primitive
public:
Primitive();
~Primitive();
Primitive(int ID, char* name, int tesselation);
Primitive(int ID, QString name, int tesselation);
virtual void drawPrimitive();
QString getName();
protected:
int ID;
char* name;
QString name;
int tesselation;
};
......
......@@ -7,6 +7,7 @@ RigidBodyTransformation::RigidBodyTransformation(Primitive* child)
tz = 0;
rotation = QQuaternion();
this->child = child;
qDebug() << "new rbt " << tx << "," << ty << "," << tz << ", rot " << rotation;
}
void RigidBodyTransformation::setTranslation(double x, double y, double z){
......@@ -37,6 +38,8 @@ void RigidBodyTransformation::setRotation(QQuaternion newRotation){
void RigidBodyTransformation::drawChild(){
//should be easily extendable to drawChildren
qDebug() << "Draw " << child->getName() << " at " << tx << "," << ty << "," << tz << ", rot " << rotation;
//set up transform
//for cube rotation
QMatrix4x4 m = QMatrix4x4();
......@@ -46,10 +49,12 @@ void RigidBodyTransformation::drawChild(){
QMatrix4x4 translateRot1 = QMatrix4x4(1,0,0,tx,0,1,0,ty,0,0,1,tz,0,0,0,1);
//stack matrices
glPushMatrix();
glMultMatrixf(translateRot1.data());//Punkte zurück schieben damit rotation um qube zentrum ist
glMultMatrixf(m.data());
//maybe a foreach later on?
child->drawPrimitive();
glPopMatrix();
}
#include "scenegraph.h"
#include "myglwidget.h"
SceneGraph::SceneGraph()
{
nodes = QList<RigidBodyTransformation*>();
views = QList<MyGLWidget*>();
idCounter = 0;
boxIndex = 1;
nextBoxName = "Box 1";
}
void SceneGraph::registerView(MyGLWidget* view){
views.append(view);
}
RigidBodyTransformation* SceneGraph::addBox(int tesselation){
Box* b = new Box(idCounter,nextBoxName,tesselation);
idCounter++;
boxIndex++;
nextBoxName = "Box " + boxIndex;
qDebug("New box added in scenegraph");
RigidBodyTransformation* r = new RigidBodyTransformation(b);
nodes.append(r);
qDebug("Notify Views...");
notifyViews();
return r;
}
void SceneGraph::drawAll(){
QList<RigidBodyTransformation*>::iterator i;
for (i = nodes.begin(); i != nodes.end(); ++i){
(*i)->drawChild();
}
}
void SceneGraph::addRotation(RigidBodyTransformation *r, QQuaternion diff){
r->addRotation(diff);
notifyViews();
}
void SceneGraph::addTranslation(RigidBodyTransformation *r, QVector3D diff){
r->addTranslation(diff);
notifyViews();
}
void SceneGraph::notifyViews(){
QList<MyGLWidget*>::iterator i;
for (i = views.begin(); i != views.end(); i++){
(*i)->modelChanged();
}
}
#ifndef SCENEGRAPH_H
#define SCENEGRAPH_H
#include <QList>
#include <rigidbodytransformation.h>
#include <box.h>
class MyGLWidget;
class SceneGraph
{
public:
SceneGraph();
RigidBodyTransformation* addBox(int tesselation);
void drawAll();
void registerView(MyGLWidget* view);
void notifyViews();
void addTranslation(RigidBodyTransformation* r, QVector3D diff);
void addRotation(RigidBodyTransformation* r, QQuaternion diff);
private:
int idCounter;
int boxIndex;
QString nextBoxName;
QList<RigidBodyTransformation*> nodes;
QList<MyGLWidget*> views;
};
#endif // SCENEGRAPH_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment