diff --git a/ReadMe b/ReadMe new file mode 100644 index 0000000..82d4d62 --- /dev/null +++ b/ReadMe @@ -0,0 +1,155 @@ +#!/bin/sh sudo +#Pour compiler pensé a installer : qt4, opencv-dev, ... mingw pour la cross-compilation + #sous ubuntu : apt-get installe qt4-lib qt4-dev opencv-core opencv-dev mingw64 + #sous freebsd faire : pkg install opencv-2.* opencv-core qt4-* + #sous windows : voir intall de qt+mingw et télécharger opencv précompiler et ... + + #seul la plateforme et le compilateur faire: + # qmake -r -spec plateforme-compilateur *.pro + # make + +#exemple: plateforme-compilateur freebsd-clang +# * = le nom du ficher .pro à généré + + + + + +#full_path +cpath=`pwd` +CXX= c++ +#======================================================================= + set_mac_arch() { + # First check to see if maci64 is even possible on this hardware + if [ "`/usr/sbin/sysctl -n hw.cpu64bit_capable`" = "0" ]; then + # maci64 is not possible. So set the arch to maci. + ARCH="maci" + CXX = "clang++" + return + fi + + # Now check to see if maci64 is asked for + if [ "$MACI64" = "0" ]; then + # only maci is wanted, so arch is maci. + ARCH="maci" + CXX= "clang++" + return + fi + } + +# +#======================================================================= +set_arch(){ + if [ -f /bin/uname ]; then + case "`/bin/uname`" in + Freebsd) # Solaris + case "`/bin/uname -p`" in + amd64) + ARCH="freebsd" + CXX="c++" + ;; + i386) + ARCH="freebsd" + CXX= "c++" + ;; + esac + ;; + Linux) + case "`/bin/uname -m`" in + i*86) + ARCH="linux" + CXX="g++" + ;; + x86_64) + ARCH="linux" + CXX= "g++" + ;; + esac + ;; + # Usually uname lives in /usr/bin on the Mac, but sometimes people +# have links in /bin that link uname to /usr/bin. Because of this +# Mac needs to be listed in the checks for both /bin/uname and /usr/bin/uname + Darwin) # Mac OS X + case "`/bin/uname -p`" in + i386) + set_mac_arch + ;; + esac + ;; + *) + : + ;; + esac + elif [ -f /usr/bin/uname ]; then + case "`/usr/bin/uname`" in + Darwin) # Mac OS X + case "`/usr/bin/uname -p`" in + i386) + set_mac_arch + ;; + esac + ;; + esac + fi + return 0; + } +# +#======================================================================= +packet_install(){ + if[ "$ARCH" == "Ubuntu"] + apt-get installe qt4-lib qt4-dev opencv-core opencv-dev mingw64 + ;; + elif[ "$ARCH" == "Freebsd"] + pkg install opencv-2.* opencv-core qt4-* + ;; + elif[ "$ARCH" == "maci"] + install opencv opencv-core qt4 + fi + return 0; +} +tp_install(){ + thisDir = "`pwd`" + list = "tp1_rendu_IM6 tp2_rendu_IM6 tp3_rendu_IM6 tp4_rendu_IM6" + for i in list; + do + qmake -spec $ARCH-$CXX ./$i/*.pro && make && make clean + done + +} +help(){ +echo "" +echo "usage : sh $0 " +echo " x : 0 - automatique;" +echo " 1 - compilation direct" +echo " 2 - exécution de binaire" +echo " y: si x=2, numéros du tp a exécuter" +} +check(){ + stat = "Ok" + if[["$1" ==""]] + stat = "" + return + fi + if[["$1" == "0" | "$1" =="1"] & ["$2" != ""]] + stat="" + return + fi + if[["$2" =="1" | "$2" =="2"| "$2" =="3"| "$2" =="4"]] + stat = "" + return + fi +} +run(){ + check() + if [$stat ==""] + help() + exit 1 + fi + if ["$1" == "0"] + packet_install() + tp_install() + + + + fi +} \ No newline at end of file diff --git a/aquarium/TP_Animation_Comport.pro b/aquarium/TP_Animation_Comport.pro new file mode 100755 index 0000000..5dadf58 --- /dev/null +++ b/aquarium/TP_Animation_Comport.pro @@ -0,0 +1,88 @@ +QT += core gui opengl + + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +contains(QT_VERSION, ^5\\.[0-8]\\..*) { + message("* Using Qt $${QT_VERSION}.") + QT += widgets + + # On my system I have to specify g++ as compiler else it will use clang++ by default + #QMAKE_CXX=g++ + #QMAKE_CC=gcc +} + +SOURCES += \ + main.cpp \ + widget.cpp \ + point3D.cpp \ + poisson.cpp \ + vector.cpp \ + banc.cpp \ + obstacle.cpp \ + predateur.cpp \ + aquarium.cpp \ + mainwidget.cpp + + + +HEADERS += \ + widget.h \ + point3D.h \ + poisson.h \ + vector.h \ + banc.h \ + obstacle.h \ + predateur.h \ + aquarium.h \ + mainwidget.h + + + +## OpenCV and Glut settings for Unix/Linux +unix:!mac { + message("* Using settings for Unix/Linux.") + INCLUDEPATH += /usr/local/include/opencv \ + /usr/include/ + + LIBS += -L/usr/local/lib/ \ + -L/usr/lib/ \ + -lopencv_core \ + -lopencv_highgui \ + -lopencv_imgproc \ + -lGLU + #-lglut +} + +## OpenCV settings for Mac OS X +macx { + message("* Using settings for Mac OS X.") + INCLUDEPATH += /usr/local/include/opencv + + LIBS += -L/usr/local/lib/ \ + -lopencv_core \ + -lopencv_highgui \ + -lopencv_imgproc +} + +## OpenCV settings for Windows and OpenCV 2.4.2 +win32 { + message("* Using settings for Windows.") + # INCLUDEPATH += "C:\\Dev\\SDK_ROOT\\opencv2.4.7\\build\\include" \ + # "C:\\Dev\\SDK_ROOT\\opencv2.4.7\\build\\include\\opencv" \ + # "C:\\Dev\\SDK_ROOT\\opencv2.4.7\\build\\include\\opencv2" + + #CONFIG(debug, debug | release) { + # LIBS += -L"C:\\Dev\\SDK_ROOT\\opencv2.4.7\\build\\x86\\vc10\\lib" \ + # -lopencv_core247d \ + # -lopencv_highgui247d \ + # -lopencv_imgproc247d + #} + + #CONFIG(release, debug | release) { + # LIBS += -L"C:\\Dev\\SDK_ROOT\\opencv2.4.7\\build\\x86\\vc10\\lib" \ + # -lopencv_core247 \ + # -lopencv_highgui247 \ + # -lopencv_imgproc247 + #} +} + diff --git a/aquarium/aquarium.cpp b/aquarium/aquarium.cpp new file mode 100644 index 0000000..a506cb3 --- /dev/null +++ b/aquarium/aquarium.cpp @@ -0,0 +1,100 @@ +#include "aquarium.h" +#include "qgl.h" + +aquarium::aquarium(double rayon, point3D origine):Obstacle(rayon, origine) +{ + rayon_max= rayon; + position = origine; + c[0]= .0; c[1]= .30; c[2]= 1., c[3] = 1.0; +} + +void aquarium::anime(float temps) +{ + +// Enemis[0]->anime(temps, *Bancs[0]); + for(uint i=0; i < Bancs.size();i++){ + for(uint j= 0; janime(temps,*Bancs[i]); + //Obstacle::anime(temps,*Bancs[i]); + Bancs[i]->anime(temps); + anime(*Bancs[i]); + // + + } +} + +void aquarium::anime(Banc &B) +{ + //[1] les poissons voisins, au moyen de la méthode dans_voisinage() + std::deque liste_voisin; + double L=0.; + for(uint j =0; j < B.banc_de_fish.size();j++) + if(B.banc_de_fish[j]->dans_voisinage(position,1.+ (rayon_max *.35)/rayon_max)) + liste_voisin.push_back(j); + + //[2] . Calcule du vecteur v1 correspondant à la séparation + //[3] Calcule du vecteur vitesse v2 correspondant à l'alignement + // la différence entre le vecteur vitesse actuel et la moyenne des vecteurs vitesse des poissons voisins. + //[4] . Calculer un vecteur vitesse v3 correspondant à la cohésion : calculer la moyenne des + // positions des poissons voisins (= centre de masse), le vecteur v3 est donné par la + // différence entre ce centre de masse et la position du poisson considéré. + + point3D v1,v2,v3, v; + for(uint j = 0; j< liste_voisin.size();j++){ + v1 = v1 + B.banc_de_fish[liste_voisin[j]]->position; + v2 = v2 + B.banc_de_fish[liste_voisin[j]]->vitesse; + } + if(liste_voisin.size()){ + v1 = v1 /liste_voisin.size(); + v2 = vitesse - v2/liste_voisin.size(); + v3 = position - v1; + v = v1 * 1.80 + v2 * 1.70 + v3 * 1.75; + } + if(liste_voisin.size()>0) + L= 1./double(liste_voisin.size()); + + for(uint j = 0; j< liste_voisin.size();j++){ + B.banc_de_fish[liste_voisin[j]]->vitesse = (B.banc_de_fish[liste_voisin[j]]->vitesse * (1-L) + v * (L)) ; + point3D::normalize(B.banc_de_fish[liste_voisin[j]]->vitesse); + } +} + +void aquarium::affiche() +{ + for(uint i=0; i< Obs.size();i++){ + Obs[i]->affiche(); + } + /* for(uint i=0; i< Enemis.size();i++){ + Enemis[i]->affiche(); + } + */ + + for(uint i=0; i< Bancs.size();i++){ + glColor3d(drand48(),drand48(), drand48()); + Bancs[i]->affiche(); + } + Obstacle::affiche(); +} + +void aquarium::init(uint nb_obs) +{ + /*cout<< rayon_max; + if ((nb_obs<2)) + nb_obs = 2; + *///for(uint i=0; i<2; i++) + { + point3D vit = point3D(drand48() *5., drand48()* 2.5, drand48()* 5.); + point3D::normalize(vit); + Banc* b = new Banc(position, + vit, + 25., + 0.95); + Bancs.push_back(b); + + } + //for(uint i=0; i Bancs; + deque< Obstacle * > Obs; + deque< Predateur * > Enemis; +public: + aquarium(double rayon= 10.0, point3D origine=point3D(0.,0.,0.)); + void anime(float temps); + void anime(Banc& temps); + void affiche(); + void init(uint nb_obs = 2); +}; + +#endif // AQUARIUM_H diff --git a/aquarium/banc.cpp b/aquarium/banc.cpp new file mode 100644 index 0000000..91dff4a --- /dev/null +++ b/aquarium/banc.cpp @@ -0,0 +1,54 @@ +#include "banc.h" + +Banc::Banc(point3D p, point3D v, int nb_pesca, double coesion):nb_poisson(nb_pesca), L(coesion) +{ + pos=p; + vit = v; + for(int i=0; i< nb_poisson;i++) + banc_de_fish.push_back(new Poisson(point3D(p.x + drand48()*2., + p.y + drand48()*2., + p.z + drand48())*2., + v)); +} + +void Banc::anime(float temps){ + for(uint i=0; i< banc_de_fish.size(); i++) + { //[1] les poissons voisins, au moyen de la méthode dans_voisinage() + std::deque liste_voisin; + L=0.009; + for(uint j =0; j < banc_de_fish.size();j++) + if(j!=i) + if(banc_de_fish[j]->dans_voisinage(banc_de_fish[i]->position, 1.5)) + liste_voisin.push_back(j); + + //[2] . Calcule du vecteur v1 correspondant à la séparation + //[3] Calcule du vecteur vitesse v2 correspondant à l'alignement + // la différence entre le vecteur vitesse actuel et la moyenne des vecteurs vitesse des poissons voisins. + //[4] . Calculer un vecteur vitesse v3 correspondant à la cohésion : calculer la moyenne des + // positions des poissons voisins (= centre de masse), le vecteur v3 est donné par la + // différence entre ce centre de masse et la position du poisson considéré. + + point3D v1,v2,v3, v; + for(uint j = 0; j< liste_voisin.size();j++){ + v1 = v1 + banc_de_fish[liste_voisin[j]]->position; + v2 = v2 + banc_de_fish[liste_voisin[j]]->vitesse; + } + if(liste_voisin.size()){ + v1 = v1 /liste_voisin.size(); + v2 = vit - v2/liste_voisin.size(); + v3 = banc_de_fish[i]->position - v1; + v = v1 * 1.80 + v2 * 1.0 + v3 * 1.50; + } + if(liste_voisin.size() > 0 ) + L= 1./liste_voisin.size(); + //else L = .9; + banc_de_fish[i]->vitesse = banc_de_fish[i]->vitesse * (1.- L) + v * L; + point3D::normalize(banc_de_fish[i]->vitesse); + banc_de_fish[i]->anime(temps); + } +} + +void Banc::affiche(){ +for (uint i = 0; i < banc_de_fish.size();i++) + banc_de_fish[i]->affiche(); +} diff --git a/aquarium/banc.h b/aquarium/banc.h new file mode 100644 index 0000000..56fd526 --- /dev/null +++ b/aquarium/banc.h @@ -0,0 +1,25 @@ +#ifndef BANC_H +#define BANC_H +#include "poisson.h" +#include + +class Banc +{ + +public: + + void anime(float temps); + void affiche(); + Banc(point3D origin, point3D vitesse, int nb_pesca=10, double coesion=0.9); +private: + int nb_poisson; + double L; + + point3D pos, vit; + deque banc_de_fish; + friend class Obstacle; + friend class aquarium; + +}; + +#endif // BANC_H diff --git a/aquarium/main.cpp b/aquarium/main.cpp new file mode 100755 index 0000000..4ca66bd --- /dev/null +++ b/aquarium/main.cpp @@ -0,0 +1,22 @@ +/* Copyright (C) 2013 Karl Phillip Buhr + * + * This work is licensed under the Creative Commons Attribution-ShareAlike License. + * To view a copy of this license, visit: + * https://creativecommons.org/licenses/by-sa/2.5/legalcode + * + * Or to read the human-readable summary of the license: + * https://creativecommons.org/licenses/by-sa/2.5/ + */ +#include +#include "mainwidget.h" + +int main(int argc, char* argv[]) +{ + QApplication app(argc, argv); + // For OpenGL Graphics + mainWidget widget; + widget.show(); + + return app.exec(); +} + diff --git a/aquarium/mainwidget.cpp b/aquarium/mainwidget.cpp new file mode 100755 index 0000000..33bdda6 --- /dev/null +++ b/aquarium/mainwidget.cpp @@ -0,0 +1,50 @@ +#include "mainwidget.h" +#include +mainWidget::mainWidget(QWidget *parent) : + QMainWindow(parent) +{ + _menu = new QMenu("File"); + _menu->addAction("Op3n", this, SLOT(_open())); + _menu->addSeparator(); + _menu->addAction("Exit", this, SLOT(close())); + _menu_bar.addMenu(_menu); + _menu = new QMenu("Help"); + _menu->addAction("Commande", this, SLOT(_help())); + _menu->addSeparator(); + _menu->addAction("About", this, SLOT(_about())); + _menu_bar.addMenu(_menu); + setMenuBar(&_menu_bar); + resize(650,580); + setCentralWidget(&gl_widget); + //gl_widget.setParent(this); +} + +void mainWidget::keyPressEvent(QKeyEvent* event){ + gl_widget.keyPressEvent(event); +} +void mainWidget::wheelEvent(QWheelEvent *event){ + gl_widget.wheelEvent(event); +} +void mainWidget::mousePressEvent(QMouseEvent *event){ + gl_widget.mousePressEvent(event); +} +void mainWidget::mouseMoveEvent(QMouseEvent *event){ + gl_widget.mouseMoveEvent(event); +} + +void mainWidget::_help() +{ + QString text = QString(tr("Commande Clavier:\n" + " A : selecteur d'axe de rotation" + "S : de/active calcule des normale Face/vertices.\n" + " F/C,X/V,B/N : deplacer la lumiere.\n" + " K : de/active le lissage de fong.\n" + "Fleches: slice horizontal/vertical" + "\n" + "Command Sourie:\n" + "Mollet: fait varier la profondeur de champs\n" + "btn droit/gauche: rotation du monde.\n")); + QLabel* l = new QLabel(text); + l->show(); +} + diff --git a/aquarium/mainwidget.h b/aquarium/mainwidget.h new file mode 100755 index 0000000..143429c --- /dev/null +++ b/aquarium/mainwidget.h @@ -0,0 +1,36 @@ +#ifndef MAINWIDGET_H +#define MAINWIDGET_H +#ifdef _WIN32 +#include +#include +#include +#else +#include +#include +#include +#endif +#include "widget.h" + +class mainWidget : public QMainWindow +{ + Q_OBJECT +public: + explicit mainWidget(QWidget *parent = 0); + void keyPressEvent(QKeyEvent *event); + void wheelEvent(QWheelEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +signals: + +public slots: + void _help(); + +private: + QMenuBar _menu_bar; + QMenu* _menu; + // For OpenGL Graphics + GLWidget gl_widget; +}; + +#endif // MAINWIDGET_H diff --git a/aquarium/obstacle.cpp b/aquarium/obstacle.cpp new file mode 100644 index 0000000..617b851 --- /dev/null +++ b/aquarium/obstacle.cpp @@ -0,0 +1,102 @@ +#include "obstacle.h" +#include "banc.h" +#include "math.h" +#include +Obstacle::Obstacle(double Rayon, point3D origine) +{ + rayon_max = Rayon; + position = origine; + nb_logitude= 20; pas_logitude=20.; + nb_latitude=20; pas_latitude=20.; + c=new double[4](); + c[0]= .4; c[1]= .7; c[2]= .3, c[3] = .3; + sphereGene(); +} +Obstacle::~Obstacle(){ + delete c; +} +void Obstacle::sphereGene(){ // genératione de la map plan ou sphérique + //a chaque l'atitude on stocks les point relativement aux logitude[0-180] + + maillage.clear(); + for(double delta = 0; delta < 361; delta+=pas_logitude){ + //int r = (delta*rayon_max)/180.;// rayon de la parrallele i + deque ln, ls; + for(double tetha = 0; tetha < 91; tetha += pas_latitude){ + ln.push_back(point3D(rayon_max * sin(tetha*M_PI/180) *cosf(delta*M_PI/180),rayon_max * sin(tetha*M_PI/180) *sinf(delta*M_PI/180), rayon_max * cosf(tetha*M_PI/180))); + ls.push_back(point3D(rayon_max * sin(tetha*M_PI/180) *cosf(delta*M_PI/180),rayon_max * sin(tetha*M_PI/180) * sinf(delta*M_PI/180), (-1.)*rayon_max * cosf(tetha*M_PI/180))); + } + if( delta != 0){ // ajout symetrique des paralléle + maillage.push_front(ln); + maillage.push_back(ls); + } + else maillage.push_back(ln); + } +} +void Obstacle::affiche(){ + glColor4dv(c); + glBegin(GL_TRIANGLES); + for(uint i = 1; i < maillage.size()-1; i++){ + for(uint p = 1; p< maillage[i].size()-1; p++){ + //demi quad 1 + glVertex3d(maillage[i-1][p].x + position.x, maillage[i-1][p].y + position.y, maillage[i-1][p].z + position.z); + glVertex3d(maillage[i][p].x + position.x, maillage[i][p].y + position.y, maillage[i][p].z + position.z); + glVertex3d(maillage[i-1][p+1].x + position.x, maillage[i-1][p+1].y + position.y, maillage[i-1][p+1].z + position.z); + //demie quad 2 + glVertex3d(maillage[i][p].x + position.x, maillage[i][p].y + position.y, maillage[i][p].z+ position.z); + glVertex3d(maillage[i][p+1].x + position.x, maillage[i][p+1].y, maillage[i][p+1].z+ position.z); + glVertex3d(maillage[i-1][p+1].x + position.x, maillage[i-1][p+1].y+ position.y, maillage[i-1][p+1].z + position.z); + + } + } + + for(uint p = 1; p< maillage[0].size()-1; p++){ + //demi quad 1 + glVertex3d(maillage[maillage.size()-1][p].x + position.x,maillage[maillage.size()-1][p].y + position.y,maillage[maillage.size()-1][p].z + position.z); + glVertex3d(maillage[0][p].x + position.x,maillage[0][p].y + position.y,maillage[0][p].z + position.z); + glVertex3d(maillage[maillage.size()-1][p+1].x + position.x,maillage[maillage.size()-1][p+1].y + position.y,maillage[maillage.size()-1][p+1].z + position.z); + //demie quad 2 + glVertex3d(maillage[0][p].x + position.x,maillage[0][p].y + position.y,maillage[0][p].z + position.z); + glVertex3d(maillage[0][p+1].x + position.x,maillage[0][p+1].y + position.y,maillage[0][p+1].z + position.z); + glVertex3d(maillage[maillage.size()-1][p+1].x + position.x,maillage[maillage.size()-1][p+1].y + position.y,maillage[maillage.size()-1][p+1].z + position.z); + } + glEnd(); + +} + +void Obstacle::anime(float temps, Banc& B){ + + + //[1] les poissons voisins, au moyen de la méthode dans_voisinage() + std::deque liste_voisin; + double L=0.; + for(uint j =0; j < B.banc_de_fish.size();j++) + if(B.banc_de_fish[j]->dans_voisinage(position, (rayon_max*1.01)/rayon_max)) + liste_voisin.push_back(j); + + //[2] . Calcule du vecteur v1 correspondant à la séparation + //[3] Calcule du vecteur vitesse v2 correspondant à l'alignement + // la différence entre le vecteur vitesse actuel et la moyenne des vecteurs vitesse des poissons voisins. + //[4] . Calculer un vecteur vitesse v3 correspondant à la cohésion : calculer la moyenne des + // positions des poissons voisins (= centre de masse), le vecteur v3 est donné par la + // différence entre ce centre de masse et la position du poisson considéré. + + point3D v1,v2,v3, v; + for(uint j = 0; j< liste_voisin.size();j++){ + v1 = v1 + B.banc_de_fish[liste_voisin[j]]->position; + v2 = v2 + B.banc_de_fish[liste_voisin[j]]->vitesse; + } + if(liste_voisin.size()){ + v1 = v1 /liste_voisin.size(); + v2 = vitesse - v2/liste_voisin.size(); + v3 = position - v1; + v = v1 * 1.50 + v2 * 1.0 + v3 * 1.50; + } + if(liste_voisin.size()) + L= 1.- 1./double(liste_voisin.size()); + else L = 1. - .99; + for(uint j = 0; j< liste_voisin.size();j++){ + B.banc_de_fish[liste_voisin[j]]->vitesse =( B.banc_de_fish[liste_voisin[j]]->vitesse * (1.- L) + v * L) ; + point3D::normalize(B.banc_de_fish[liste_voisin[j]]->vitesse); + } +} diff --git a/aquarium/obstacle.h b/aquarium/obstacle.h new file mode 100644 index 0000000..ca9d9ac --- /dev/null +++ b/aquarium/obstacle.h @@ -0,0 +1,24 @@ +#ifndef OBSTACLE_H +#define OBSTACLE_H + +#include +#include +#include "banc.h" +class Obstacle +{ +public: + Obstacle(double Rayon=1.0, point3D origine=point3D()); //sphere unité par défault + virtual ~Obstacle(); + void sphereGene(); //mode sphére par default + void affiche(); + void anime(float temps, Banc &B); +protected: + double* c; + point3D position, vitesse; // vitesse nulle pour les objet statics + deque< deque > maillage;// parléle en x et cercle en lati + uint nb_logitude, nb_latitude; + double pas_logitude, pas_latitude, rayon_max; + +}; + +#endif // OBSTACLE_H diff --git a/aquarium/point3D.cpp b/aquarium/point3D.cpp new file mode 100755 index 0000000..43a1c4e --- /dev/null +++ b/aquarium/point3D.cpp @@ -0,0 +1,97 @@ +#include "point3D.h" +#include + +/**********************************************************************/ +/**********************************************************************/ +/* */ +/* methodes de la classe point3D */ +/* */ +/**********************************************************************/ +/**********************************************************************/ +point3D::point3D(){ + x = 0.0; y = 0.0; z = 0.0; +} + +point3D::point3D(const double X,const double Y,const double Z){ + x=X; y=Y; z=Z; +} + +bool point3D::operator==(const point3D &op) const { + return( x == op.x && y == op.y && z == op.z); +} + +point3D& point3D::operator=(const point3D &op) { + x = op.x; y = op.y; z = op.z; +return *this; +} + +point3D point3D::operator+(const point3D &op) const { + return( point3D( x + op.x, y + op.y, z + op.z) ); +} + +point3D point3D::operator-(const point3D &op) const { + return( point3D( x - op.x, y - op.y, z - op.z) ); +} + +point3D& point3D::operator*=(const double op) { + x *= op; y *= op; z *= op; +return *this; +} + +point3D point3D::operator*(const double op) const { + return ( point3D( x * op, y * op, z * op) ); +} + +point3D& point3D::operator/=(const double op) { + x /= op; y /= op; z /= op; +return *this; +} + +point3D point3D::operator/(const double op) const { + return ( point3D( x / op, y / op, z / op) ); +} + +ostream& operator<<(ostream& p, point3D op) { + p << "(" << op.x <<", " << op.y << ", " << op.z << ")"; +return(p); +} + +istream& operator>>(istream& p, point3D &op) +{ + cout << "Entrez x:"; + p >> op.x; + cout << "Entrez y:"; + p >> op.y; + cout << "Entrez z:"; + p >> op.z; + +return (p); +} + +double point3D::produit_scalaire(const point3D& _v1, const point3D& _v2){ + return _v1.x * _v2.x + _v1.y * _v2.y + _v1.z * _v2.z; +} + +point3D point3D::produit_vectoriel(const point3D& _v1 , const point3D& _v2){ //produit vectoriel + point3D res; + res.x = _v1.y * _v2.z - _v1.z * _v2.y; + res.y = _v1.z * _v2.x - _v1.x * _v2.z; + res.z = _v1.x * _v2.y - _v1.y * _v2.x; + return res; +} +point3D point3D::PointsToVecteur(const point3D& _p1, const point3D& _p2) { + point3D res; + + res.x = _p2.x - _p1.x; + res.y = _p2.y - _p1.y; + res.z = _p2.z - _p1.z; + +return res; +} +void point3D::normalize( point3D& _v) { + +double lenght = sqrtf(produit_scalaire(_v, _v)); + _v.x /= lenght; + _v.y /= lenght; + _v.z /= lenght; +} diff --git a/aquarium/point3D.h b/aquarium/point3D.h new file mode 100755 index 0000000..7e4d96d --- /dev/null +++ b/aquarium/point3D.h @@ -0,0 +1,60 @@ +#ifndef _point3D_H +#define _point3D_H + +#include +using namespace std ; + +#ifndef M_PI + #define M_PI 3.14159265358979323846 +#endif + +/******************* point3D ******************/ +/** + * @brief The point3D class + * stock les coordonées 3d d'un point + * + */ +class point3D{ + +public: + + double x; + double y; + double z; + + + + point3D(); // (0,0,0) par defaut + + point3D(const double, const double, const double); + + + bool operator==(const point3D &)const; + + point3D& operator=(const point3D &); + + point3D operator+(const point3D &)const; + + point3D operator-(const point3D &)const; + + point3D& operator*=(const double); //produit par un scalaire + + point3D operator*(const double)const; //idem + point3D operator*(const point3D)const; //produit par un scalaire entre + // coefficient retourne (x*x1, y*y1, z*z1) + + point3D& operator/=(const double); //division par un scalaire + + point3D operator/(const double)const; //idem + + friend ostream& operator<<(ostream&, point3D); + + friend istream& operator>>(istream&, point3D &); + // methode statique sur de vecteur3D declarer comme point3D + static double produit_scalaire(const point3D& _v1, const point3D& _v2); // produit scalaire vecteur 3D + static point3D produit_vectoriel(const point3D& _v1 , const point3D& _v2); //produit vectoriel + static point3D PointsToVecteur(const point3D& _p1, const point3D& _p2) ; + static void normalize(point3D& _v); +}; + +#endif diff --git a/aquarium/poisson.cpp b/aquarium/poisson.cpp new file mode 100644 index 0000000..6eddc94 --- /dev/null +++ b/aquarium/poisson.cpp @@ -0,0 +1,30 @@ +#include "poisson.h" +#include +#include +#include +Poisson::Poisson(point3D p, point3D v) +{ + srand(0); + position = p * drand48();// origine du monde + vitesse = v ;//point3D((rand() % 10)/100.,(rand() % 3)/100.,(rand() % 10)/100.);// veteur null + v_init = vitesse; + distance = 0; // z&éros +} +void Poisson::anime( float temps ){ + if(vitesse == point3D(0.,0.,0.)) + vitesse = v_init; + position = position + vitesse * temps; +} +bool Poisson::dans_voisinage( point3D p, double seuil){ + point3D m = p - position; + distance = sqrtf(pow(m.x,2) +pow(m.z,2) + pow(m.z,2)); + return (distance > seuil ? false:true); +} +void Poisson::affiche(){ + glColor3d(1.,03,.6); + glBegin(GL_TRIANGLE_STRIP); + glVertex3d(position.x+.5, position.y, position.z); + glVertex3d(position.x, position.y, position.z+1.); + glVertex3d(position.x-.5, position.y, position.z); + glEnd(); +} diff --git a/aquarium/poisson.h b/aquarium/poisson.h new file mode 100644 index 0000000..cfe59db --- /dev/null +++ b/aquarium/poisson.h @@ -0,0 +1,27 @@ +#ifndef POISSON_H +#define POISSON_H + +#include "point3D.h" +#include "vector.h" +class Poisson +{ +public: + + void anime(float t); + bool dans_voisinage( point3D p, double seuil = 1.5); + void affiche(); +//signals: + + //public slots: +// Poisson(point3D p); + Poisson(point3D p, point3D v); +private: + point3D position; + point3D vitesse, v_init; + double distance; + friend class Banc; + friend class Obstacle; + friend class aquarium; +}; + +#endif // POISSON_H diff --git a/aquarium/predateur.cpp b/aquarium/predateur.cpp new file mode 100644 index 0000000..c2919f3 --- /dev/null +++ b/aquarium/predateur.cpp @@ -0,0 +1,14 @@ +#include "predateur.h" +#include "banc.h" +Predateur::Predateur(point3D vMax, double Rayon, point3D origine):Obstacle(Rayon, origine) +{ + c=new double[3]; + c[0]= .8; c[1]= .1; c[2]= .63; + vitesse_max = vMax; +} + +void Predateur::anime(float temps, Banc &unbanc) +{ + +} + diff --git a/aquarium/predateur.h b/aquarium/predateur.h new file mode 100644 index 0000000..319a7a2 --- /dev/null +++ b/aquarium/predateur.h @@ -0,0 +1,16 @@ +#ifndef PREDATEUR_H +#define PREDATEUR_H +#include "obstacle.h" + +class Predateur : virtual public Obstacle // virtual pour au cas je créer différent type de prédateur (optimise l'utilisation mémoire) +{ +public: + Predateur(point3D vitesse=point3D(1.,0,1.), double rayon= 3.0, point3D origine=point3D(30.,30.,30.)); + void anime(float temps, Banc& unbanc); + + +private: + point3D vitesse_max; +}; + +#endif // PREDATEUR_H diff --git a/aquarium/vector.cpp b/aquarium/vector.cpp new file mode 100755 index 0000000..3f390e0 --- /dev/null +++ b/aquarium/vector.cpp @@ -0,0 +1,279 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// vector.cpp +// +// Description +// Classe définissant un vecteur. +// +// Copyright +// Laboratoire LSIS +// Equipe LXAO +// +// Historique +// 12/05/1999 Création par Sébastien Thon +// +/////////////////////////////////////////////////////////////////////////////// + + + +#include +#include +#include "vector.h" + + + +double Vector::operator % ( const Vector& v ) const +{ + return x*v.x + y*v.y + z*v.z; +} + + + +Vector Vector::operator ^ ( const Vector& v ) const +{ + return Vector( y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x ); +} + + + +void Vector::normalize() +{ + double len = (double)sqrt( x*x + y*y + z*z ); + + if( len == 0 ) + { + x=0; + y=0; + z=0; + } + else + { + x/=len; + y/=len; + z/=len; + } +} + + + +Vector Vector::operator + ( const Vector& v ) const +{ + return Vector( x+v.x, y+v.y, z+v.z ); +} + + + +Vector Vector::operator + ( double d ) const +{ + return Vector( x+d, y+d, z+d ); +} + + + +Vector operator + ( const Vector& v1, const Vector& v2 ) +{ + return Vector( v1.x+v2.x, v1.y+v2.y, v1.z+v2.z ); +} + + + +Vector Vector::operator - ( const Vector& v ) const +{ + return Vector( x-v.x, y-v.y, z-v.z ); +} + + + +Vector Vector::operator - ( double d ) const +{ + return Vector( x-d, y-d, z-d ); +} + + + +Vector operator - ( const Vector& v1, const Vector& v2 ) +{ + return Vector( v1.x-v2.x, v1.y-v2.y, v1.z-v2.z ); +} + + + +Vector Vector::operator - () const +{ + return Vector( -x, -y, -z ); +} + + + +Vector Vector::operator * ( const Vector& v ) const +{ + return Vector( x*v.x, y*v.y, z*v.z ); +} + + + +Vector operator * ( const Vector& v1, const Vector& v2 ) +{ + return Vector( v1.x*v2.x, v1.y*v2.y, v1.z*v2.z ); +} + + + +Vector Vector::operator * ( double d ) const +{ + return Vector( x*d, y*d, z*d ); +} + + + +Vector Vector::operator / ( double d ) const +{ + return Vector( x/d, y/d, z/d ); +} + + + +Vector Vector::operator / ( const Vector& v ) const +{ + return Vector( x/v.x, y/v.y, z/v.z ); +} + + + +Vector operator / ( const Vector& v1, const Vector& v2 ) +{ + return Vector( v1.x/v2.x, v1.y/v2.y, v1.z/v2.z ); +} + + + +int Vector::operator == ( const Vector& v ) +{ + return( (x == v.x) && (y == v.y) && (z == v.z) ); +} + + + +int Vector::operator != ( const Vector& v ) +{ + return( (x != v.x) || (y != v.y) || (z != v.z) ); +} + + + +int Vector::operator > ( const Vector& v ) +{ + return( (x > v.x) || (y > v.y) || (z > v.z) ); +} + + + +int Vector::operator < ( const Vector& v ) +{ + return( (x < v.x) || (y < v.y) || (z < v.z) ); +} + + + +Vector& Vector::operator = ( const Vector& v ) +{ + x = v.x; + y = v.y; + z = v.z; + return *this; +} + + + +Vector& Vector::operator += ( const Vector& v ) +{ + x += v.x; + y += v.y; + z += v.z; + return *this; +} + + + +Vector& Vector::operator -= ( const Vector& v ) +{ + x -= v.x; + y -= v.y; + z -= v.z; + return *this; +} + + + +Vector& Vector::operator += ( double d ) +{ + x += d; + y += d; + z += d; + return *this; +} + + + +Vector& Vector::operator -= ( double d ) +{ + x -= d; + y -= d; + z -= d; + return *this; +} + + + +Vector& Vector::operator *= ( double d ) +{ + x *= d; + y *= d; + z *= d; + return *this; +} + + + +Vector& Vector::operator /= ( double d ) +{ + x /= d; + y /= d; + z /= d; + return *this; +} + + + +double Vector::length() const +{ + return (double)sqrt( x*x + y*y + z*z ); +} + + + +double Vector::distance( const Vector& v ) const +{ + return (double)sqrt( (x-v.x)*(x-v.x) + (y-v.y)*(y-v.y) + (z-v.z)*(z-v.z) ); +} + + + +double Vector::distance( double _x, double _y, double _z ) const +{ + return (double)sqrt( (x-_x)*(x-_x) + (y-_y)*(y-_y) + (z-_z)*(z-_z) ); +} + + + +double Vector::distance_squared( const Vector& v ) const +{ + return (x-v.x)*(x-v.x) + (y-v.y)*(y-v.y) + (z-v.z)*(z-v.z); +} + + + +double Vector::distance_squared( double _x, double _y, double _z ) const +{ + return (x-_x)*(x-_x) + (y-_y)*(y-_y) + (z-_z)*(z-_z); +} diff --git a/aquarium/vector.h b/aquarium/vector.h new file mode 100755 index 0000000..0b019a9 --- /dev/null +++ b/aquarium/vector.h @@ -0,0 +1,101 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// vector.cpp +// +// Description +// Classe définissant un vecteur. +// +// Copyright +// Laboratoire LSIS +// Equipe LXAO +// +// Historique +// 12/05/1999 Création par Sébastien Thon +// 3/05/2015 Modifier par Thierry Nibert-siber +// +/////////////////////////////////////////////////////////////////////////////// + + + +#ifndef VECTOR_H +#define VECTOR_H + + + +#include + + + +class Vector +{ +public: + /*Vector( double x1=0, double y1=0, double z1=0 ); + Vector( const Vector& v );*/ + + Vector(): + x(0), y(0), z(0) {} + Vector (double x1, double y1, double z1): + x(x1), y(y1), z(z1) {} + Vector ( const Vector &v ): + x(v.x), + y(v.y), + z(v.z) {} + + double distance( const Vector& v ) const; + double distance( double _x, double _y, double _z ) const; + + double distance_squared( const Vector& v ) const; + double distance_squared( double _x, double _y, double _z ) const; + + double operator % ( const Vector& v ) const; // produit scalaire + Vector operator ^ ( const Vector& v ) const; // produit vectoriel + void normalize(); + + Vector operator + ( const Vector& v ) const; + Vector operator + ( double d ) const; + Vector operator - ( const Vector& v ) const; + Vector operator - ( double d ) const; + Vector operator - () const; + + Vector operator * ( const Vector& v ) const; + Vector operator * ( double d ) const; + Vector operator / ( const Vector& v ) const; + Vector operator / ( double d ) const; + + int operator > ( const Vector& v ); + int operator < ( const Vector& v ); + int operator == ( const Vector& v ); + int operator != ( const Vector& v ); + + Vector& operator = ( const Vector& v ); + Vector& operator += ( const Vector& v ); + Vector& operator -= ( const Vector& v ); + Vector& operator += ( double d ); + Vector& operator -= ( double d ); + Vector& operator *= ( double d ); + Vector& operator /= ( double d ); + + friend Vector operator + ( double d, const Vector& v ) + { + return Vector( v.x+d, v.y+d, v.z+d ); + } + + friend Vector operator * ( double d, const Vector& v ) + { + return Vector( v.x*d, v.y*d, v.z*d ); + } + + friend std::ostream& operator << ( std::ostream& os, const Vector& v ) + { + return os << v.x << ", " << v.y << ", " << v.z; + } + + double length() const; + + + double x, y, z; +}; + + + +#endif diff --git a/aquarium/widget.cpp b/aquarium/widget.cpp new file mode 100755 index 0000000..958f6a4 --- /dev/null +++ b/aquarium/widget.cpp @@ -0,0 +1,263 @@ +/* Copyright (C) 2013 Karl Phillip Buhr + * + * This work is licensed under the Creative Commons Attribution-ShareAlike License. + * To view a copy of this license, visit: + * https://creativecommons.org/licenses/by-sa/2.5/legalcode + * + * Or to read the human-readable summary of the license: + * https://creativecommons.org/licenses/by-sa/2.5/ + */ +#include "widget.h" +#include + +#include +#include +#include +#include + +GLWidget::GLWidget(QWidget *parent) +: QGLWidget(parent) +{ + _width = 0; + _height = 0; + _texture = 0; + _fps = 30; + distance = -5.0; + x=0;x_rot = 0.; + y=0;y_rot = 0.; + z=0; z_rot = .0; + now.start(); + nb_obs = 1; + aqua = new aquarium(20.); + +} + +GLWidget::~GLWidget() +{ + glDeleteTextures(1, &_texture); + +} + +void GLWidget::_tick() +{ + + + // triggers paintGL() + update(); + //updateGL(); + + // Set timer according to FPS + QTimer::singleShot(1000/_fps, this, SLOT(_tick())); + +} + +void GLWidget::initializeGL() +{ + distance = -10.0; + x_rot = 0.; + y_rot = 0.; + z_rot = 0.; + aqua->init(6); + // Set clear color as black + qglClearColor(Qt::darkGray); + glEnable(GL_DEPTH_TEST); + + // Retrieve FPS from the camera + //_fps = cv_capture.get(CV_CAP_PROP_FPS); + if (!_fps || _fps <= 0) // if the function fails, fps is set to 15 + _fps = 15; + + qDebug() << "GLWidget::initializeGL: " << _fps << " fps"; + + /* Start the timer */ + + _tick(); +} + +void GLWidget::paintGL() +{ + aqua->anime(now.elapsed()/1000.); + now.start(); + // Clear the screen and depth buffer (with black) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glPolygonMode(GL_FRONT, GL_FILL); + glPolygonMode(GL_BACK, GL_FILL); + + + // Model view matrix +// glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glTranslatef(0.0, 0.0, distance); + glRotatef(x_rot / 16.0f, 1.0f, 0.0f, 0.0f); + glRotatef(y_rot / 16.0f, 0.0f, 1.0f, 0.0f); + glRotatef(z_rot / 16.0f, 0.0f, 0.0f, 1.0f); + + + if (glGetError() != GL_NO_ERROR) + { + qDebug()<< "GLWidget::paintGL: !!! Failed glTexImage2D" ; + } + + repereScene3D(100.); + aqua->affiche(); + + +} + +void GLWidget::resizeGL( int w, int h) +{ + _width = w; + _height = h; + + int side = qMin(_width, _height); + glViewport((_width - side) / 2, (_height - side) / 2, side, side); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); +#ifdef QT_OPENGL_ES_1 + glOrthof(-2, +2, -2, +2, 1.0, 15.0); +#else + glOrtho(-20., +20., -20., +20., -20., 100000.0); +#endif + glMatrixMode(GL_MODELVIEW); +} +/************************* + * + * Clavier + * + * *********************/ +void GLWidget::keyPressEvent(QKeyEvent *event) +{ + if(event->key() == Qt::Key_Space){ + distance = -10.0; + x_rot = 0.; + y_rot = 0.; + z_rot = 0.; + } + updateGL();// on modifie l'affichage +} + + +/************************* + * + * Sourie + * + * *********************/ + + +void GLWidget::wheelEvent(QWheelEvent *event) +{ + distance += (2.0 * event->delta() / 120.0); + updateGL(); +} +void GLWidget::mousePressEvent(QMouseEvent *event) +{ + last_pos = event->pos(); + // qDebug() <x() - last_pos.x(); + int dy = event->y() - last_pos.y(); + if (event->buttons() & Qt::LeftButton) { + setXRotation(x_rot + 8 * dy); + setYRotation(y_rot + 8 * dx); + } else if (event->buttons() & Qt::RightButton) { + setYRotation(x_rot + 8 * dy); + setZRotation(z_rot + 8 * dx); + } else if (event->buttons() & Qt::MiddleButton) { + distance = -1.0; + x_rot = 0.; + y_rot = 0.; + z_rot = 0.; + } + + last_pos = event->pos(); + // qDebug()< 360) + angle -= 360 * 16; +} + +void GLWidget::setXRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != x_rot) { + x_rot = angle; + //emit xRotationChanged(angle); + updateGL(); + } +} + +void GLWidget::setYRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != y_rot) { + y_rot = angle; + //emit yRotationChanged(angle); + updateGL(); + } +} + +void GLWidget::setZRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != z_rot) { + z_rot = angle; + //emit zRotationChanged(angle); + updateGL(); + } +} +/********************* + * * + * * Model view + * * + * *********************/ +void GLWidget::_view_ortho() // Set Up An Ortho View +{ + glMatrixMode(GL_PROJECTION); // Select Projection + glPushMatrix(); // Push The Matrix + glLoadIdentity(); // Reset The Matrix + glOrtho( 0, _width , _height, 0, -1, 1 ); // Select Ortho Mode (640x480) + glMatrixMode(GL_MODELVIEW); // Select Modelview Matrix + glPushMatrix(); // Push The Matrix + glLoadIdentity(); // Reset The Matrix +} + +void GLWidget::_view_perspective() // Set Up A Perspective View +{ + glMatrixMode( GL_PROJECTION ); // Select Projection + glPopMatrix(); // Pop The Matrix + glMatrixMode( GL_MODELVIEW ); // Select Modelview + glPopMatrix(); // Pop The Matrix +} +/************************* + * * + * * outil de dessin + * * + * * + * ***********************/ +// Repere orthonorme +void GLWidget::repereScene3D(float l) +{ + + glBegin (GL_LINES); + glColor3d(1.,0.,0.) ; // red axe + glVertex3f (0., 0., 0.); + glVertex3f (l, 0., 0.); + + glColor3d(0.,1.,0.) ;// green axe + glVertex3f (0., 0., 0.); + glVertex3f (0., l, 0.); + + glColor3d(0.,0.,1.) ;//bleu axe + glVertex3f (0., 0., 0.); + glVertex3f (0., 0., l); + glEnd (); + +} diff --git a/aquarium/widget.h b/aquarium/widget.h new file mode 100755 index 0000000..49a1349 --- /dev/null +++ b/aquarium/widget.h @@ -0,0 +1,57 @@ +/* Copyright (C) 2013 Karl Phillip Buhr + * + * This work is licensed under the Creative Commons Attribution-ShareAlike License. + * To view a copy of this license, visit: + * https://creativecommons.org/licenses/by-sa/2.5/legalcode + * + * Or to read the human-readable summary of the license: + * https://creativecommons.org/licenses/by-sa/2.5/ + */ +#pragma once + +#include +#include +#include +#include"aquarium.h" +class GLWidget : public QGLWidget +{ + Q_OBJECT +public: + explicit GLWidget(QWidget* parent = 0); + virtual ~GLWidget(); + + /* OpenGL initialization, viewport resizing, and painting */ + + void initializeGL(); + void paintGL(); + void resizeGL( int width, int height); + + void keyPressEvent(QKeyEvent *event); + void wheelEvent(QWheelEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + + /* Helper functions */ + void setXRotation(int angle); + void setYRotation(int angle); + void setZRotation(int angle); + + void _view_ortho(); + void _view_perspective(); + static void repereScene3D(float l); +private: + int _width; + int _height; + + QTime now; + QPoint last_pos; + double x,y,z, distance; + double x_rot,y_rot,z_rot; + aquarium* aqua; + int nb_obs; + int _fps; + GLuint _texture; + +protected slots: + void _tick(); +}; diff --git a/fumee/TP_Fumee.pro b/fumee/TP_Fumee.pro new file mode 100755 index 0000000..df9afe2 --- /dev/null +++ b/fumee/TP_Fumee.pro @@ -0,0 +1,75 @@ +QT += core gui opengl + +contains(QT_VERSION, ^5\\.[0-8]\\..*) { + message("* Using Qt $${QT_VERSION}.") + QT += widgets + + # On my system I have to specify g++ as compiler else it will use clang++ by default + #QMAKE_CXX=g++ + #QMAKE_CC=gcc +} + +SOURCES += \ + main.cpp \ + widget.cpp \ + bouffee.cpp \ + fumee.cpp \ + vector.cpp \ + mainwidget.cpp + +HEADERS += \ + widget.h \ + bouffee.h \ + fumee.h \ + vector.h \ + mainwidget.h + +### OpenCV and Glut settings for Unix/Linux +unix:!mac { + message("* Using settings for Unix/Linux.") +# INCLUDEPATH += /usr/local/include/opencv \ +# /usr/include/ + + LIBS += -L/usr/local/lib/ \ +# -L/usr/lib/ \ +# -lopencv_core \ +# -lopencv_highgui \ +# -lopencv_imgproc \ + -lGLU +# #-lglut +} + +### OpenCV settings for Mac OS X +macx { + message("* Using settings for Mac OS X.") + INCLUDEPATH += /usr/local/include/opencv + + LIBS += -L/usr/local/lib/ \ +# -lopencv_core \ +# -lopencv_highgui \ +# -lopencv_imgproc + -lGLU +} + +## OpenCV settings for Windows and OpenCV 2.4.2 +win32 { + message("* Using settings for Windows.") +# INCLUDEPATH += $(OPENCV_DIR)"\\include" \ +# $(OPENCV_DIR)"\\include\\opencv" \ +# $(OPENCV_DIR)"\\include\\opencv2" + +# CONFIG(debug, debug | release) { +# LIBS += -L$(OPENCV_DIR)"\\x86\\vc10\\lib" \ +# -lopencv_core247d \ +# -lopencv_highgui247d \ +# -lopencv_imgproc247d + } + +# CONFIG(release, debug | release) { +# LIBS += -L$(OPENCV_DIR)"\\x86\\vc10\\lib" \ +# -lopencv_core247 \ +# -lopencv_highgui247 \ +# -lopencv_imgproc247 +# } +#} + diff --git a/fumee/bouffee.cpp b/fumee/bouffee.cpp new file mode 100755 index 0000000..e1d46e1 --- /dev/null +++ b/fumee/bouffee.cpp @@ -0,0 +1,133 @@ +#include "bouffee.h" +#include +#include "vector.h" + +Bouffee::Bouffee(double _posx, double _posy, double _posz, double _vie) +{ + pos[0]=_posx + .005*pow(-1.0, rand()%1); + pos[1]=_posy + .005*pow(-1.0, rand()%1); + pos[2]=_posz + .005*pow(-1.0, rand()%1); + + for (int i=0; i<3; i++){ + + if(i!=1) + vitesse[i]=( rand()%10)/1000.0 * pow(-1.0, rand()%2); + else vitesse[i]=( rand()%10)/100.0 ; + } + vie= _vie *15.5; + vieMax= vie; +} +void Bouffee::anime(double& temps) +{ + //double n_x=pos[0], n_y=pos[1], n_z=pos[2]; // possition courante + vie -= temps; + //double px=0.,py=0.,pz=0.; + for (int i=0; i<3; i++) + pos[i] += vitesse[i] * temps; + +} + +/********************************************* + * + * + * + * + * ******************************************/ +void Bouffee::setPos(double val, int numPos){ + pos[numPos]=val; + +} +void Bouffee::setVitesse(double val, int numPos){ + pos[numPos]=val; + +} +double Bouffee::getPos(int numPos){ + return pos[numPos]; +} +double Bouffee::getVitesse(int numPos){ + return vitesse[numPos]; +} +double Bouffee::getVie(){ + return vie; +} + +/********************************************* + * + * + * + * + * ******************************************/ +void Bouffee::affiche(){ + glEnable(GL_TEXTURE_2D); + // Comme on ne veut pas que ce quadrilatère soit affecté + // par la lumière, on désactive l’éclairage juste avant + // de l’afficher, et on le réactivera juste après. Vous + // n’aurez donc pas besoin de spécifier la normale du + // quadrilatère + glDisable(GL_LIGHTING); + // On veut pouvoir voir les deux côtés du quadrilatère + glDisable(GL_CULL_FACE); + // On active le blending pour que la couleur de la texture + // se mélange à la couleur du reste de la scène dans des + // proportions données par la valeur alpha de chaque texel + // de la texture + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + // On récupère le positionnement de la camera + float matrice [16]; + glGetFloatv( GL_MODELVIEW_MATRIX, matrice ); + + Vector Haut, Droite; + double taille=(vieMax-vie)/vieMax; + + Droite.x = matrice[0] * ( 2* taille ); + Droite.y = matrice[4] * ( 2* taille ); + Droite.z = matrice[8] * ( 2* taille ); + + Haut.x = matrice[1] * ( 2* taille); + Haut.y = matrice[5] * ( 2* taille ); + Haut.z = matrice[9] * ( 2* taille ); + Vector A, B, C, D; + + // On calcule la position des 4 sommets du quadrilatère + A.x = pos[0] + Haut.x - Droite.x; + A.y = pos[1] + Haut.y - Droite.y; + A.z = pos[2] + Haut.z - Droite.z; + + B.x = pos[0] + Haut.x + Droite.x; + B.y = pos[1] + Haut.y + Droite.y; + B.z = pos[2] + Haut.z + Droite.z; + + C.x = pos[0] - Haut.x + Droite.x; + C.y = pos[1] - Haut.y + Droite.y; + C.z = pos[2] - Haut.z + Droite.z; + + D.x = pos[0] - Haut.x - Droite.x; + D.y = pos[1] - Haut.y - Droite.y; + D.z = pos[2] - Haut.z - Droite.z; + + // + // + // + // Affichage du quadrilatère texturé avec la texture RGBA + // Draw a 2D face with texture + // Affichage du billboard + glBegin(GL_QUADS); + glColor4d(1.,1.,1.,1. - taille); + glTexCoord2f(0.0, 0.0); glVertex3f(D.x,D.y,D.z); + glTexCoord2f(0.0, 1.); glVertex3f(C.x,C.y,C.z); + glTexCoord2f(1.0, 1.0); glVertex3f(B.x,B.y,B.z); + glTexCoord2f(1.0, 0.0 ); glVertex3f(A.x,A.y,A.z); + glEnd(); + + + // On désactive le blending + glDisable(GL_BLEND); + // On reactive l’utilisation de la lumière + glEnable(GL_LIGHTING); + // Pour ne voir qu’un seul côté des polygones + // (affichage plus rapide) + glEnable(GL_CULL_FACE); + glDisable(GL_TEXTURE_2D); +} diff --git a/fumee/bouffee.h b/fumee/bouffee.h new file mode 100755 index 0000000..6fe3ca9 --- /dev/null +++ b/fumee/bouffee.h @@ -0,0 +1,25 @@ +#ifndef BOUFFEE_H +#define BOUFFEE_H +#include +#include +class Bouffee +{ +public: + //Bouffee(); + Bouffee(double _posx=0.0, double _posy=0.0, double _posz=0.0, double _vie=3.0); + void anime(double& temps_ecoulee); + void setPos(double pos, int numPos); + void setVitesse(double val, int numVitesse); + double getPos(int numPos); + double getVitesse(int numPos); + double getVie(); + void affiche(); + +private: + double pos[3]; // pos x,y,z + double vitesse[3]; // pos x,y,z + double vie; // Temps de vie en seconde restant + double vieMax; +}; + +#endif // BOUFFEE_H diff --git a/fumee/fumee.cpp b/fumee/fumee.cpp new file mode 100755 index 0000000..b245b98 --- /dev/null +++ b/fumee/fumee.cpp @@ -0,0 +1,170 @@ +#include "fumee.h" +#include "vector.h" +#include +#include +Fumee::Fumee(double x0, double y0, double z0, double intervale_emision ) +{ + pos[0]=x0; + pos[1]=y0; + pos[2]=z0; + this->intervale_emision=intervale_emision; + temps_ecoule=0.0; + l_emision=intervale_emision+1.; + lastT.start(); +} + +void Fumee::affiche(GLuint * _texture){ + drawFumee(_texture[0]); + drawChemine(_texture[1]); +} + +void Fumee::drawFumee(GLuint &_texture) +{ + if(liste_Boufees.empty()) + return; + std::deque::iterator i; + i = liste_Boufees.begin(); + glDepthMask(GL_FALSE); + + glBindTexture(GL_TEXTURE_2D, _texture); + while (i != liste_Boufees.end()) { + i->affiche(); + i++; + } + + glDepthMask(GL_TRUE); +} + +void Fumee::drawChemine(GLuint &_texture) +{ + + glDepthMask(GL_FALSE); + + glBindTexture(GL_TEXTURE_2D, _texture); + glEnable(GL_TEXTURE_2D); + // Comme on ne veut pas que ce quadrilatère soit affecté + // par la lumière, on désactive l’éclairage juste avant + // de l’afficher, et on le réactivera juste après. Vous + // n’aurez donc pas besoin de spécifier la normale du + // quadrilatère + glDisable(GL_LIGHTING); + // On veut pouvoir voir les deux côtés du quadrilatère + glDisable(GL_CULL_FACE); + // On active le blending pour que la couleur de la texture + // se mélange à la couleur du reste de la scène dans des + // proportions données par la valeur alpha de chaque texel + // de la texture + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + // On récupère le positionnement de la camera + float matrice [16]; + glGetFloatv( GL_MODELVIEW_MATRIX, matrice ); + + Vector Haut, Droite; + double taille=3.0; + + Droite.x = matrice[0] * taille ; + Droite.y = matrice[4] * taille ; + Droite.z = matrice[8] * taille ; + + Haut.x = matrice[1] * taille; + Haut.y = matrice[5] * taille ; + Haut.z = matrice[9] * taille ; + Vector A, B, C, D; + + // On calcule la position des 4 sommets du quadrilatère + A.x = pos[0] + Haut.x - Droite.x; + A.y = pos[1] + Haut.y - Droite.y; + A.z = pos[2] + Haut.z - Droite.z; + + B.x = pos[0] + Haut.x + Droite.x; + B.y = pos[1] + Haut.y + Droite.y; + B.z = pos[2] + Haut.z + Droite.z; + + C.x = pos[0] - Haut.x + Droite.x; + C.y = pos[1] - Haut.y + Droite.y; + C.z = pos[2] - Haut.z + Droite.z; + + D.x = pos[0] - Haut.x - Droite.x; + D.y = pos[1] - Haut.y - Droite.y; + D.z = pos[2] - Haut.z - Droite.z; + + + // + // + // + // Affichage du quadrilatère texturé avec la texture RGBA + // Draw a 2D face with texture + // Affichage du billboard + glBegin(GL_QUADS); + glColor4d(1.,1.,1., .7); + glTexCoord2f(0.0, 0.0); glVertex3f(D.x,D.y,D.z); + glTexCoord2f(1.0, 0.0); glVertex3f(C.x,C.y,C.z); + glTexCoord2f(1.0, 1.0); glVertex3f(B.x,B.y,B.z); + glTexCoord2f(0.0, 1.0 ); glVertex3f(A.x,A.y,A.z); + glEnd(); + + + // On désactive le blending + glDisable(GL_BLEND); + // On reactive l’utilisation de la lumière + glEnable(GL_LIGHTING); + // Pour ne voir qu’un seul côté des polygones + // (affichage plus rapide) + glEnable(GL_CULL_FACE); + glDisable(GL_TEXTURE_2D); + glDepthMask(GL_TRUE); +} + +void Fumee::anime(QTime currenT){ + + + temps_ecoule = lastT.msecsTo(currenT)/1. ; + anime(temps_ecoule); + lastT=currenT; +} + +void Fumee::anime(double& temps){ + + ajoutBouffee(temps); + supBouffee(); + computePos(temps); +} + +void Fumee::ajoutBouffee(double& temps){ + + l_emision += temps; + if(intervale_emision <= l_emision){ + for(uint i=0; i <= 5; i++){ + Bouffee pff(pos[0] + .5, pos[1]+2.50, pos[2], intervale_emision); + liste_Boufees.push_back(pff); + } + l_emision=0.0; + } + +} +void Fumee::supBouffee(){ + if(liste_Boufees.empty()) + return; + std::deque::iterator i; + i = liste_Boufees.begin(); + while( i != liste_Boufees.end() ) + { + if( i->getVie() <= 0.0 ) + liste_Boufees.erase(i--); + i++; + + } +} +void Fumee::computePos(double& temps){ + if(liste_Boufees.empty() ) + return; + + std::deque::iterator i; + i = liste_Boufees.begin(); + while( i++ != liste_Boufees.end() ) + { + i->anime(temps); + } +} diff --git a/fumee/fumee.h b/fumee/fumee.h new file mode 100755 index 0000000..994ee32 --- /dev/null +++ b/fumee/fumee.h @@ -0,0 +1,32 @@ +#ifndef FUMEE_H +#define FUMEE_H +#include "bouffee.h" +#include +#include +/* amelioration à prévoire : + * - rendre de Bouffee varianble en fonction d'événement exterieur + * - ajouter un train ou autre objets texturer en source OK + * - optimiser au mieux les boucle cf openmp qtconcurent ... ('.') + * */ + +class Fumee +{ +public: + Fumee(double x0 , double y0 , double z0 , double intervale_emision);// intervale en mili seconde + void anime(double& temps); + void anime(QTime currenT); + void affiche(GLuint * _texture); + void drawFumee(GLuint &_texture); + void drawChemine(GLuint &_texture); +private: + void ajoutBouffee(double& temps); + void supBouffee(); + void computePos(double& temps); + double pos[3]; // origine de la fumee + std::deque liste_Boufees; + double intervale_emision, l_emision; + double temps_ecoule; + QTime lastT; +}; + +#endif // FUMEE_H diff --git a/fumee/main.cpp b/fumee/main.cpp new file mode 100755 index 0000000..4ca66bd --- /dev/null +++ b/fumee/main.cpp @@ -0,0 +1,22 @@ +/* Copyright (C) 2013 Karl Phillip Buhr + * + * This work is licensed under the Creative Commons Attribution-ShareAlike License. + * To view a copy of this license, visit: + * https://creativecommons.org/licenses/by-sa/2.5/legalcode + * + * Or to read the human-readable summary of the license: + * https://creativecommons.org/licenses/by-sa/2.5/ + */ +#include +#include "mainwidget.h" + +int main(int argc, char* argv[]) +{ + QApplication app(argc, argv); + // For OpenGL Graphics + mainWidget widget; + widget.show(); + + return app.exec(); +} + diff --git a/fumee/mainwidget.cpp b/fumee/mainwidget.cpp new file mode 100755 index 0000000..76525f6 --- /dev/null +++ b/fumee/mainwidget.cpp @@ -0,0 +1,46 @@ +#include "mainwidget.h" +#include +mainWidget::mainWidget(QWidget *parent) : + QMainWindow(parent) +{ + _menu = new QMenu("File"); + _menu->addAction("Op3n", this, SLOT(_open())); + _menu->addSeparator(); + _menu->addAction("Exit", this, SLOT(close())); + _menu_bar.addMenu(_menu); + _menu = new QMenu("Help"); + _menu->addAction("Commande", this, SLOT(_help())); + _menu->addSeparator(); + _menu->addAction("About", this, SLOT(_about())); + _menu_bar.addMenu(_menu); + setMenuBar(&_menu_bar); + resize(650,580); + setCentralWidget(&gl_widget); + //gl_widget.setParent(this); +} + +void mainWidget::keyPressEvent(QKeyEvent* event){ + gl_widget.keyPressEvent(event); +} +void mainWidget::wheelEvent(QWheelEvent *event){ + gl_widget.wheelEvent(event); +} +void mainWidget::mousePressEvent(QMouseEvent *event){ + gl_widget.mousePressEvent(event); +} +void mainWidget::mouseMoveEvent(QMouseEvent *event){ + gl_widget.mouseMoveEvent(event); +} + +void mainWidget::_help() +{ + QString text = QString(tr("Commande Clavier:\n" + " Espace : RAZ.\n" + "\n" + "Command Sourie:\n" + "Mollet: fait varier la profondeur de champs\n" + "btn droit/gauche: rotation du monde.\n")); + QLabel* l = new QLabel(text); + l->show(); +} + diff --git a/fumee/mainwidget.h b/fumee/mainwidget.h new file mode 100755 index 0000000..143429c --- /dev/null +++ b/fumee/mainwidget.h @@ -0,0 +1,36 @@ +#ifndef MAINWIDGET_H +#define MAINWIDGET_H +#ifdef _WIN32 +#include +#include +#include +#else +#include +#include +#include +#endif +#include "widget.h" + +class mainWidget : public QMainWindow +{ + Q_OBJECT +public: + explicit mainWidget(QWidget *parent = 0); + void keyPressEvent(QKeyEvent *event); + void wheelEvent(QWheelEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +signals: + +public slots: + void _help(); + +private: + QMenuBar _menu_bar; + QMenu* _menu; + // For OpenGL Graphics + GLWidget gl_widget; +}; + +#endif // MAINWIDGET_H diff --git a/fumee/vector.cpp b/fumee/vector.cpp new file mode 100755 index 0000000..924d2ce --- /dev/null +++ b/fumee/vector.cpp @@ -0,0 +1,279 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// vector.cpp +// +// Description +// Classe définissant un vecteur. +// +// Copyright +// Laboratoire LSIS +// Equipe LXAO +// +// Historique +// 12/05/1999 Création par Sébastien Thon +// +/////////////////////////////////////////////////////////////////////////////// + + + +#include +#include +#include "vector.h" + + + +double Vector::operator % ( const Vector& v ) const +{ + return x*v.x + y*v.y + z*v.z; +} + + + +Vector Vector::operator ^ ( const Vector& v ) const +{ + return Vector( y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x ); +} + + + +void Vector::normalize() +{ + double len = (double)sqrt( x*x + y*y + z*z ); + + if( len == 0 ) + { + x=0; + y=0; + z=0; + } + else + { + x/=len; + y/=len; + z/=len; + } +} + + + +Vector Vector::operator + ( const Vector& v ) const +{ + return Vector( x+v.x, y+v.y, z+v.z ); +} + + + +Vector Vector::operator + ( double d ) const +{ + return Vector( x+d, y+d, z+d ); +} + + + +Vector operator + ( const Vector& v1, const Vector& v2 ) +{ + return Vector( v1.x+v2.x, v1.y+v2.y, v1.z+v2.z ); +} + + + +Vector Vector::operator - ( const Vector& v ) const +{ + return Vector( x-v.x, y-v.y, z-v.z ); +} + + + +Vector Vector::operator - ( double d ) const +{ + return Vector( x-d, y-d, z-d ); +} + + + +Vector operator - ( const Vector& v1, const Vector& v2 ) +{ + return Vector( v1.x-v2.x, v1.y-v2.y, v1.z-v2.z ); +} + + + +Vector Vector::operator - () const +{ + return Vector( -x, -y, -z ); +} + + + +Vector Vector::operator * ( const Vector& v ) const +{ + return Vector( x*v.x, y*v.y, z*v.z ); +} + + + +Vector operator * ( const Vector& v1, const Vector& v2 ) +{ + return Vector( v1.x*v2.x, v1.y*v2.y, v1.z*v2.z ); +} + + + +Vector Vector::operator * ( double d ) const +{ + return Vector( x*d, y*d, z*d ); +} + + + +Vector Vector::operator / ( double d ) const +{ + return Vector( x/d, y/d, z/d ); +} + + + +Vector Vector::operator / ( const Vector& v ) const +{ + return Vector( x/v.x, y/v.y, z/v.z ); +} + + + +Vector operator / ( const Vector& v1, const Vector& v2 ) +{ + return Vector( v1.x/v2.x, v1.y/v2.y, v1.z/v2.z ); +} + + + +int Vector::operator == ( const Vector& v ) +{ + return( (x == v.x) && (y == v.y) && (z == v.z) ); +} + + + +int Vector::operator != ( const Vector& v ) +{ + return( (x != v.x) || (y != v.y) || (z != v.z) ); +} + + + +int Vector::operator > ( const Vector& v ) +{ + return( (x > v.x) || (y > v.y) || (z > v.z) ); +} + + + +int Vector::operator < ( const Vector& v ) +{ + return( (x < v.x) || (y < v.y) || (z < v.z) ); +} + + + +Vector& Vector::operator = ( const Vector& v ) +{ + x = v.x; + y = v.y; + z = v.z; + return *this; +} + + + +Vector& Vector::operator += ( const Vector& v ) +{ + x += v.x; + y += v.y; + z += v.z; + return *this; +} + + + +Vector& Vector::operator -= ( const Vector& v ) +{ + x -= v.x; + y -= v.y; + z -= v.z; + return *this; +} + + + +Vector& Vector::operator += ( double d ) +{ + x += d; + y += d; + z += d; + return *this; +} + + + +Vector& Vector::operator -= ( double d ) +{ + x -= d; + y -= d; + z -= d; + return *this; +} + + + +Vector& Vector::operator *= ( double d ) +{ + x *= d; + y *= d; + z *= d; + return *this; +} + + + +Vector& Vector::operator /= ( double d ) +{ + x /= d; + y /= d; + z /= d; + return *this; +} + + + +double Vector::length() const +{ + return (double)sqrt( x*x + y*y + z*z ); +} + + + +double Vector::distance( const Vector& v ) const +{ + return (double)sqrt( (x-v.x)*(x-v.x) + (y-v.y)*(y-v.y) + (z-v.z)*(z-v.z) ); +} + + + +double Vector::distance( double _x, double _y, double _z ) const +{ + return (double)sqrt( (x-_x)*(x-_x) + (y-_y)*(y-_y) + (z-_z)*(z-_z) ); +} + + + +double Vector::distance_squared( const Vector& v ) const +{ + return (x-v.x)*(x-v.x) + (y-v.y)*(y-v.y) + (z-v.z)*(z-v.z); +} + + + +double Vector::distance_squared( double _x, double _y, double _z ) const +{ + return (x-_x)*(x-_x) + (y-_y)*(y-_y) + (z-_z)*(z-_z); +} diff --git a/fumee/vector.h b/fumee/vector.h new file mode 100755 index 0000000..5398438 --- /dev/null +++ b/fumee/vector.h @@ -0,0 +1,99 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// vector.cpp +// +// Description +// Classe définissant un vecteur. +// +// Copyright +// Laboratoire LSIS +// Equipe LXAO +// +// Historique +// 12/05/1999 Création par Sébastien Thon +// 03/10/2015 Modification Thierry Nibert-siber +// +/////////////////////////////////////////////////////////////////////////////// + + + +#ifndef VECTOR_H +#define VECTOR_H + + + +#include + +class Vector +{ +public: + /*Vector( double x1=0, double y1=0, double z1=0 ); + Vector( const Vector& v );*/ + + Vector(): + x(0), y(0), z(0) {} + Vector (double x1, double y1, double z1): + x(x1), y(y1), z(z1) {} + Vector ( const Vector &v ): + x(v.x), + y(v.y), + z(v.z) {} + + double distance( const Vector& v ) const; + double distance( double _x, double _y, double _z ) const; + + double distance_squared( const Vector& v ) const; + double distance_squared( double _x, double _y, double _z ) const; + + double operator % ( const Vector& v ) const; // produit scalaire + Vector operator ^ ( const Vector& v ) const; // produit vectoriel + void normalize(); + + Vector operator + ( const Vector& v ) const; + Vector operator + ( double d ) const; + Vector operator - ( const Vector& v ) const; + Vector operator - ( double d ) const; + Vector operator - () const; + + Vector operator * ( const Vector& v ) const; + Vector operator * ( double d ) const; + Vector operator / ( const Vector& v ) const; + Vector operator / ( double d ) const; + + int operator > ( const Vector& v ); + int operator < ( const Vector& v ); + int operator == ( const Vector& v ); + int operator != ( const Vector& v ); + + Vector& operator = ( const Vector& v ); + Vector& operator += ( const Vector& v ); + Vector& operator -= ( const Vector& v ); + Vector& operator += ( double d ); + Vector& operator -= ( double d ); + Vector& operator *= ( double d ); + Vector& operator /= ( double d ); + + friend Vector operator + ( double d, const Vector& v ) + { + return Vector( v.x+d, v.y+d, v.z+d ); + } + + friend Vector operator * ( double d, const Vector& v ) + { + return Vector( v.x*d, v.y*d, v.z*d ); + } + + friend std::ostream& operator << ( std::ostream& os, const Vector& v ) + { + return os << v.x << ", " << v.y << ", " << v.z; + } + + double length() const; + + + double x, y, z; +}; + + + +#endif diff --git a/fumee/widget.cpp b/fumee/widget.cpp new file mode 100755 index 0000000..2d64cbe --- /dev/null +++ b/fumee/widget.cpp @@ -0,0 +1,320 @@ +/* Copyright (C) 2013 Karl Phillip Buhr + * + * This work is licensed under the Creative Commons Attribution-ShareAlike License. + * To view a copy of this license, visit: + * https://creativecommons.org/licenses/by-sa/2.5/legalcode + * + * Or to read the human-readable summary of the license: + * https://creativecommons.org/licenses/by-sa/2.5/ + */ +#include "widget.h" +#include +#include +#include +#include +#include + + +GLWidget::GLWidget(QWidget *parent) + : QGLWidget(parent),Fumee_1(NULL) +{ + _width = 0; + _height = 0; + _texture = new GLuint[2]; + _fps = 30; + // Fumee_1 = NULL; + + distance = -10.0; + x=0;x_rot = 0.; + y=0;y_rot = 0.; + z=0; z_rot = .0; + // + framedir = QString("../outils/Textures/fumee.png"); + framedir2 = QString("../outils/Textures/cheminee.png"); + + +} + +GLWidget::~GLWidget() +{ + glDeleteTextures(2, _texture); +} + +void GLWidget::_tick() +{ + // triggers paintGL() + update(); + //updateGL(); + // Set timer according to FPS + QTimer::singleShot(1000/_fps, this, SLOT(_tick())); + + +} + +void GLWidget::initializeGL() +{ + distance = -10.0; + x_rot = 180.; + y_rot = 0.; + z_rot = 0.; + Now.start(); + // Set clear color as black + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + + // Select pixel storage mode used by glTexImage2D + glPixelStorei (GL_UNPACK_ALIGNMENT, 1); + + // Create the texture + glGenTextures(2, _texture); + // Set clear color as black + qglClearColor(Qt::darkGray); + /* chargement des image de texture */ + + // Note: chargement de l'image qui servira de texture + qt_frame.load(framedir); + //qt_frame = qt_frame.convertToFormat(QImage::Format_ARGB6666_Premultiplied); + //qt_frame = qt_frame.rgbSwapped(); + + qt_frame2.load(framedir2); + // Retrieve FPS from the camera + //_fps = cv_capture.get(CV_CAP_PROP_FPS); + if (!_fps || _fps <= 0) // if the function fails, fps is set to 15 + _fps = 30; + + std::cerr << "GLWidget::initializeGL: " << _fps << " fps" << std::endl; + Fumee_1 = new Fumee(0.0,0.0,0.0,_fps/*10.5*/);// ne pas allez en deessous de 10ms en fonction du processeur utiliser + if (Fumee_1== NULL) + { + std::cout << "GLWidget::Fumee: !!! Failed to retrieve fumee" << std::endl; + return; + } + // Typical texture generation using data from the bitmap + + _texture[0] = bindTexture ( qt_frame, GL_TEXTURE_2D, GL_RGBA ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); + glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + + _texture[1] = bindTexture ( qt_frame2, GL_TEXTURE_2D, GL_RGBA ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); + glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + + glDisable(GL_TEXTURE_2D); + if (glGetError() != GL_NO_ERROR) + { + std::cout << "GLWidget::paintGL: !!! Failed glTexImage2D" << std::endl; + } + //QGLFormat::setDoubleBuffer(true); + /* Start the timer */ + + _tick(); +} + +void GLWidget::paintGL() +{ + + //animation + Fumee_1->anime(Now.currentTime()); + + // Clear the screen and depth buffer (with black) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + //_view_ortho(); + // Select the model view matrix and reset it + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glTranslatef(0.0, 0.0, distance); + glRotatef(x_rot / 16.0f, 1.0f, 0.0f, 0.0f); + glRotatef(y_rot / 16.0f, 0.0f, 1.0f, 0.0f); + glRotatef(z_rot / 16.0f, 0.0f, 0.0f, 1.0f); + + + repereScene3D(100.0f); + // _view_perspective(); + //qglColor(Qt::gray) ;// + // _view_ortho(); + qglColor(Qt::white) ; + Fumee_1->affiche(_texture); + //_view_perspective(); + swapBuffers(); + + + +} + +void GLWidget::resizeGL( int w, int h) +{ + _width = w; + _height = h; + + + int side = qMin(_width, _height); + glViewport((_width - side) / 2, (_height - side) / 2, side, side); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); +#ifdef QT_OPENGL_ES_1 + glOrthof(-2, +2, -2, +2, 1.0, 15.0); +#else + glOrtho(-20., +20, -20., +20., -1.0, 10000.0); +#endif + glMatrixMode(GL_MODELVIEW); +} +/************************* + * + * Clavier + * + * *********************/ +void GLWidget::keyPressEvent(QKeyEvent *event) +{ + if(event->key() == Qt::Key_Space){ + distance = -10.0; + x_rot = 0.; + y_rot = 0.; + z_rot = 0.; + } + update(); + updateGL();// on modifie l'affichage + +} + +/************************* + * + * Sourie + * + * *********************/ +void GLWidget::wheelEvent(QWheelEvent *event) +{ + distance += (1.35 * event->delta()/120.0 );// 120.0); + update(); + updateGL(); + +} + +void GLWidget::mousePressEvent(QMouseEvent *event) +{ + last_pos = event->pos(); + update(); + updateGL(); + + // qDebug() <x() - last_pos.x(); + int dy = event->y() - last_pos.y(); + if (event->buttons() & Qt::LeftButton) { + setXRotation(x_rot + 8 * dy); + setYRotation(y_rot + 8 * dx); + } else if (event->buttons() & Qt::RightButton) { + setYRotation(x_rot + 8 * dy); + setZRotation(z_rot + 8 * dx); + } else if (event->buttons() & Qt::MiddleButton) { + distance = -1.0; + x_rot = 0.; + y_rot = 0.; + z_rot = 0.; + } + qDebug()<< "("<pos(); + update(); + updateGL(); +} + +static void qNormalizeAngle(int &angle) +{ + while (angle < 0) + angle += 360 * 16; + while (angle > 360) + angle -= 360 * 16; +} + +void GLWidget::setXRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != x_rot) { + x_rot = angle; + //emit xRotationChanged(angle); + // updateGL(); + } +} + +void GLWidget::setYRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != y_rot) { + y_rot = angle; + //emit yRotationChanged(angle); + //updateGL(); + } +} + +void GLWidget::setZRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != z_rot) { + z_rot = angle; + //emit zRotationChanged(angle); + //updateGL(); + } +} +/********************* + * * + * * Model view + * * + * *********************/ +void GLWidget::_view_ortho() // Set Up An Ortho View +{ + double t = 50.; + glMatrixMode(GL_PROJECTION); // Select Projection + glPushMatrix(); // Push The Matrix + glLoadIdentity(); // Reset The Matrix + glOrtho( (-1.) * t, t, t, (-1.) *t, .0, 1000000 ); // Select Ortho Mode (640x480) + glMatrixMode(GL_MODELVIEW); // Select Modelview Matrix + glPushMatrix(); // Push The Matrix + glLoadIdentity(); // Reset The Matrix +} + +void GLWidget::_view_perspective() // Set Up A Perspective View +{ + glMatrixMode( GL_PROJECTION ); // Select Projection + glPopMatrix(); // Pop The Matrix + glMatrixMode( GL_MODELVIEW ); // Select Modelview + glPopMatrix(); // Pop The Matrix +} +/************************* + * * + * * outil de dessin + * * + * * + * ***********************/ +// Repere orthonorme +void GLWidget::repereScene3D(float l) +{ +glDisable(GL_LIGHTING); + glBegin (GL_LINES); + qglColor(Qt::darkRed) ; // red axe + glVertex3f (0., 0., 0.); + glVertex3f (l, 0., 0.); + + qglColor(Qt::darkGreen) ;// green axe + glVertex3f (0., 0., 0.); + glVertex3f (0., l, 0.); + + qglColor(Qt::darkBlue) ;//bleu axe + glVertex3f (0., 0., 0.); + glVertex3f (0., 0., l); + glEnd (); + glEnable(GL_LIGHTING); + +} + diff --git a/fumee/widget.h b/fumee/widget.h new file mode 100755 index 0000000..86124ce --- /dev/null +++ b/fumee/widget.h @@ -0,0 +1,62 @@ +/* Copyright (C) 2013 Karl Phillip Buhr + * + * This work is licensed under the Creative Commons Attribution-ShareAlike License. + * To view a copy of this license, visit: + * https://creativecommons.org/licenses/by-sa/2.5/legalcode + * + * Or to read the human-readable summary of the license: + * https://creativecommons.org/licenses/by-sa/2.5/ + */ +#pragma once +#include +#include +#include +#include +#include "fumee.h" +class GLWidget : public QGLWidget +{ + Q_OBJECT +public: + explicit GLWidget(QWidget* parent = 0); + virtual ~GLWidget(); + + /* OpenGL initialization, viewport resizing, and painting */ + + void initializeGL(); + void paintGL(); + void resizeGL( int width, int height); + + void keyPressEvent(QKeyEvent *event); + void wheelEvent(QWheelEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + //void timerEvent(QTimerEvent *event); + + /* Helper functions */ + void setXRotation(int angle); + void setYRotation(int angle); + void setZRotation(int angle); + + void _view_ortho(); + void _view_perspective(); + void repereScene3D(float l); + +private: + int _width; + int _height; + + QPoint last_pos; + double x,y,z, distance; + double x_rot,y_rot,z_rot; + + QImage qt_frame, qt_frame2; + QString framedir,framedir2; + QTime Now; + Fumee* Fumee_1; + //cv::VideoCapture cv_capture; + int _fps; + GLuint* _texture; + +protected slots: + void _tick(); +}; diff --git a/vague/TP_Animation_Vague.pro b/vague/TP_Animation_Vague.pro new file mode 100755 index 0000000..cec2846 --- /dev/null +++ b/vague/TP_Animation_Vague.pro @@ -0,0 +1,87 @@ +QT += core gui opengl + +contains(QT_VERSION, ^4\\.[0-8]\\..*) { + message("* Using Qt $${QT_VERSION}.") + QT += widgets + + # On my system I have to specify g++ as compiler else it will use clang++ by default + #QMAKE_CXX=g++ + #QMAKE_CC=gcc +} +contains(QT_VERSION, ^5\\.[0-8]\\..*) { + message("* Using Qt $${QT_VERSION}.") + QT += widgets + + # On my system I have to specify g++ as compiler else it will use clang++ by default + #QMAKE_CXX=g++ + #QMAKE_CC=gcc +} + +SOURCES += \ + main.cpp \ + widget.cpp \ + point3D.cpp \ + vector.cpp \ + vague.cpp \ + ocean.cpp \ + mainwidget.cpp + + + +HEADERS += \ + widget.h \ + point3D.h \ + vector.h \ + vague.h \ + ocean.h \ + mainwidget.h + + +CONFIG += static staticlib + +## OpenCV and Glut settings for Unix/Linux +unix:!mac { + message("* Using settings for Unix/Linux.") + INCLUDEPATH += /usr/local/include/opencv \ + /usr/include/ + + LIBS += -L/usr/local/lib/ \ + -L/usr/lib/ \ + -lGLU + +} + +## OpenCV settings for Mac OS X +macx { + message("* Using settings for Mac OS X.") + INCLUDEPATH += /usr/local/include/opencv + + LIBS += -L/usr/local/lib/ \ + -lopencv_core \ + -lopencv_highgui \ + -lopencv_imgproc +} + + +# OpenCV settings for Windows and OpenCV 2.4.2 +win32 { + message("* Using settings for Windows.") + + # INCLUDEPATH += "C:\\Dev\\SDK_ROOT\\opencv2.4.7\\build\\include" \ + # "C:\\Dev\\SDK_ROOT\\opencv2.4.7\\build\\include\\opencv" \ + # "C:\\Dev\\SDK_ROOT\\opencv2.4.7\\build\\include\\opencv2" + + #CONFIG(debug, debug | release) { + # LIBS += -L"C:\\Dev\\SDK_ROOT\\opencv2.4.7\\build\\x86\\vc10\\lib" \ + # -lopencv_core247d \ + # -lopencv_highgui247d \ + # -lopencv_imgproc247d + #} + + #CONFIG(release, debug | release) { + # LIBS += -L"C:\\Dev\\SDK_ROOT\\opencv2.4.7\\build\\x86\\vc10\\lib" \ + # -lopencv_core247 \ + # -lopencv_highgui247 \ + # -lopencv_imgproc247 + #} +} diff --git a/vague/main.cpp b/vague/main.cpp new file mode 100755 index 0000000..bce0cf1 --- /dev/null +++ b/vague/main.cpp @@ -0,0 +1,23 @@ +/* Copyright (C) 2013 Karl Phillip Buhr + * + * This work is licensed under the Creative Commons Attribution-ShareAlike License. + * To view a copy of this license, visit: + * https://creativecommons.org/licenses/by-sa/2.5/legalcode + * + * Or to read the human-readable summary of the license: + * https://creativecommons.org/licenses/by-sa/2.5/ + */ +#include +#include"mainwidget.h" + +int main(int argc, char* argv[]) +{ + QApplication app(argc, argv); + + // For OpenGL Graphics + mainWidget widget; + widget.show(); + + return app.exec(); +} + diff --git a/vague/mainwidget.cpp b/vague/mainwidget.cpp new file mode 100755 index 0000000..33bdda6 --- /dev/null +++ b/vague/mainwidget.cpp @@ -0,0 +1,50 @@ +#include "mainwidget.h" +#include +mainWidget::mainWidget(QWidget *parent) : + QMainWindow(parent) +{ + _menu = new QMenu("File"); + _menu->addAction("Op3n", this, SLOT(_open())); + _menu->addSeparator(); + _menu->addAction("Exit", this, SLOT(close())); + _menu_bar.addMenu(_menu); + _menu = new QMenu("Help"); + _menu->addAction("Commande", this, SLOT(_help())); + _menu->addSeparator(); + _menu->addAction("About", this, SLOT(_about())); + _menu_bar.addMenu(_menu); + setMenuBar(&_menu_bar); + resize(650,580); + setCentralWidget(&gl_widget); + //gl_widget.setParent(this); +} + +void mainWidget::keyPressEvent(QKeyEvent* event){ + gl_widget.keyPressEvent(event); +} +void mainWidget::wheelEvent(QWheelEvent *event){ + gl_widget.wheelEvent(event); +} +void mainWidget::mousePressEvent(QMouseEvent *event){ + gl_widget.mousePressEvent(event); +} +void mainWidget::mouseMoveEvent(QMouseEvent *event){ + gl_widget.mouseMoveEvent(event); +} + +void mainWidget::_help() +{ + QString text = QString(tr("Commande Clavier:\n" + " A : selecteur d'axe de rotation" + "S : de/active calcule des normale Face/vertices.\n" + " F/C,X/V,B/N : deplacer la lumiere.\n" + " K : de/active le lissage de fong.\n" + "Fleches: slice horizontal/vertical" + "\n" + "Command Sourie:\n" + "Mollet: fait varier la profondeur de champs\n" + "btn droit/gauche: rotation du monde.\n")); + QLabel* l = new QLabel(text); + l->show(); +} + diff --git a/vague/mainwidget.h b/vague/mainwidget.h new file mode 100755 index 0000000..143429c --- /dev/null +++ b/vague/mainwidget.h @@ -0,0 +1,36 @@ +#ifndef MAINWIDGET_H +#define MAINWIDGET_H +#ifdef _WIN32 +#include +#include +#include +#else +#include +#include +#include +#endif +#include "widget.h" + +class mainWidget : public QMainWindow +{ + Q_OBJECT +public: + explicit mainWidget(QWidget *parent = 0); + void keyPressEvent(QKeyEvent *event); + void wheelEvent(QWheelEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +signals: + +public slots: + void _help(); + +private: + QMenuBar _menu_bar; + QMenu* _menu; + // For OpenGL Graphics + GLWidget gl_widget; +}; + +#endif // MAINWIDGET_H diff --git a/vague/ocean.cpp b/vague/ocean.cpp new file mode 100755 index 0000000..048b8be --- /dev/null +++ b/vague/ocean.cpp @@ -0,0 +1,273 @@ +#include "ocean.h" +#include +#include +#include +#include +#include +#include +#include +#include +Ocean::Ocean(QString spectre, int nbvague, int nb_x, int nb_z) +{ + if (!spectre.isEmpty()){ + nombre_de_vagues = nbvague; + if(!loadSpectre(spectre)) + qDebug()<< "tes spectre de vague son suspecte bruh! puisque c'est comme ça au revoir"<< endl; + if(!loadMap(nb_x,nb_z)) + qDebug()<< "sorry cet map est suspect bruh! essayons a nouveau" < xline; + for(int z = 0; z < zs; z ++) + xline.push_back(Vpoint(point3D(x*x_size,0,z*z_size), point3D(0.0,0.0,0.0))); + Maillage.push_back(xline); + } + // replassage liste face + for(uint i = 1; i < Maillage.size()-1; i++){ + for(uint p = 0; p< Maillage[i].size()-1; p++){ + //demi triangle 1 + lfaces.push_back( face( sommet(i-1,p), sommet(i,p), sommet(i-1,p+1) )); + //demie quad 2 + lfaces.push_back( face( sommet(i,p), sommet(i,p+1), sommet(i-1,p+1) )); + + } + } + calcule_coordonnees_texture(); + calcul_normales_faces(); + if(smooth) + calcul_normales_points(); + return true; +} +void Ocean::calcule_coordonnees_texture() +{ + double x= (double)Maillage.size(); + for(uint i = 0; i < Maillage.size(); i++){ + double y= (double)Maillage[i].size(); // cas ou y variable (evolution ultérieur) + for(uint p = 0; p< Maillage[i].size(); p++){ + Maillage[i][p].s = (double)i / x; + Maillage[i][p].t = (double)p / y; + } + } +} +void Ocean::calcul_normales_points() { + for(uint i = 0; i < Maillage.size(); i++){ + for(uint p = 0; p< Maillage[i].size(); p++){ + Maillage[i][p].normale = point3D(0,0,0); + } + } + for(uint i =0; i< lfaces.size(); i++) { + Maillage[lfaces[i].S1.i][lfaces[i].S1.j].normale = Maillage[lfaces[i].S1.i][lfaces[i].S1.j].normale + lfacesnormales[i] ; + Maillage[lfaces[i].S2.i][lfaces[i].S2.j].normale = Maillage[lfaces[i].S2.i][lfaces[i].S2.j].normale + lfacesnormales[i] ; + Maillage[lfaces[i].S3.i][lfaces[i].S3.j].normale = Maillage[lfaces[i].S3.i][lfaces[i].S3.j].normale + lfacesnormales[i] ; + point3D::normalize(Maillage[lfaces[i].S1.i][lfaces[i].S1.j].normale ); + point3D::normalize(Maillage[lfaces[i].S2.i][lfaces[i].S2.j].normale ); + point3D::normalize(Maillage[lfaces[i].S2.i][lfaces[i].S2.j].normale); + + } +} +void Ocean::calcul_normales_faces() { + lfacesnormales.clear(); + point3D v1; + point3D v2; + //qDebug()<< "taille vide = "< +#include +#include +/* amelioration à prévoire : + * - rendre de vangue variable en amplitude superieur a 1 idem direction OK + * - ajouter de la mascotte ... ('.')' + * - optimiser au mieux les boucle cf openmp qtconcurent ... ('.') + * */ +class sommet +{ +public: + sommet(uint i,uint j):i(i),j(j) {} + uint i,j; +}; +class face +{ +public: + face(sommet s1, sommet s2, sommet s3): S1(s1),S2(s2),S3(s3) {} + sommet S1,S2,S3; +}; +class Ocean +{ +public: + ~Ocean(); + Ocean(QString spectre= QString(), int nbvague =0, int x_size= 20, int z_size = 20); + bool loadSpectre(QString = 0); // charge les spectre de propagation des vages + bool loadMap(int x, int z ); // chage un maille de taill x * z + void affiche();// affiche l'océan + double calcule_hauteur(const int& x, const int& z, const double& t); + void calcul_normales_faces(); + void calcul_normales_points(); + void calcule_coordonnees_texture(); + void anime(double& t); + void anime(void); + bool smooth, ligth; + float* lpos;// postion de la lumiere +private: + int nombre_de_vagues;// + deque Vagues;//tableau de vague + int x_points, z_points;// + + double x_size, z_size;//distance séparant deux points en x et en z + deque< deque > Maillage;//tableau de VPoint permettant de stocker les coordonnées du maillage + deque< face > lfaces; + deque lfacesnormales; + QTime lastT; +}; + +#endif // OCEAN_H diff --git a/vague/point3D.cpp b/vague/point3D.cpp new file mode 100755 index 0000000..43a1c4e --- /dev/null +++ b/vague/point3D.cpp @@ -0,0 +1,97 @@ +#include "point3D.h" +#include + +/**********************************************************************/ +/**********************************************************************/ +/* */ +/* methodes de la classe point3D */ +/* */ +/**********************************************************************/ +/**********************************************************************/ +point3D::point3D(){ + x = 0.0; y = 0.0; z = 0.0; +} + +point3D::point3D(const double X,const double Y,const double Z){ + x=X; y=Y; z=Z; +} + +bool point3D::operator==(const point3D &op) const { + return( x == op.x && y == op.y && z == op.z); +} + +point3D& point3D::operator=(const point3D &op) { + x = op.x; y = op.y; z = op.z; +return *this; +} + +point3D point3D::operator+(const point3D &op) const { + return( point3D( x + op.x, y + op.y, z + op.z) ); +} + +point3D point3D::operator-(const point3D &op) const { + return( point3D( x - op.x, y - op.y, z - op.z) ); +} + +point3D& point3D::operator*=(const double op) { + x *= op; y *= op; z *= op; +return *this; +} + +point3D point3D::operator*(const double op) const { + return ( point3D( x * op, y * op, z * op) ); +} + +point3D& point3D::operator/=(const double op) { + x /= op; y /= op; z /= op; +return *this; +} + +point3D point3D::operator/(const double op) const { + return ( point3D( x / op, y / op, z / op) ); +} + +ostream& operator<<(ostream& p, point3D op) { + p << "(" << op.x <<", " << op.y << ", " << op.z << ")"; +return(p); +} + +istream& operator>>(istream& p, point3D &op) +{ + cout << "Entrez x:"; + p >> op.x; + cout << "Entrez y:"; + p >> op.y; + cout << "Entrez z:"; + p >> op.z; + +return (p); +} + +double point3D::produit_scalaire(const point3D& _v1, const point3D& _v2){ + return _v1.x * _v2.x + _v1.y * _v2.y + _v1.z * _v2.z; +} + +point3D point3D::produit_vectoriel(const point3D& _v1 , const point3D& _v2){ //produit vectoriel + point3D res; + res.x = _v1.y * _v2.z - _v1.z * _v2.y; + res.y = _v1.z * _v2.x - _v1.x * _v2.z; + res.z = _v1.x * _v2.y - _v1.y * _v2.x; + return res; +} +point3D point3D::PointsToVecteur(const point3D& _p1, const point3D& _p2) { + point3D res; + + res.x = _p2.x - _p1.x; + res.y = _p2.y - _p1.y; + res.z = _p2.z - _p1.z; + +return res; +} +void point3D::normalize( point3D& _v) { + +double lenght = sqrtf(produit_scalaire(_v, _v)); + _v.x /= lenght; + _v.y /= lenght; + _v.z /= lenght; +} diff --git a/vague/point3D.h b/vague/point3D.h new file mode 100755 index 0000000..ee9ca18 --- /dev/null +++ b/vague/point3D.h @@ -0,0 +1,60 @@ +#ifndef _point3D_H +#define _point3D_H + +#include +using namespace std ; + +#ifndef M_PI + #define M_PI 3.14159265358979323846 +#endif + +/******************* point3D ******************/ +/** + * @brief The point3D class + * stock les coordonées 3d d'un point + * + */ +class point3D{ + +public: + + double x; + double y; + double z; + + + + point3D(); // (0,0,0) par defaut + + point3D(const double, const double, const double=0.0); + + + bool operator==(const point3D &)const; + + point3D& operator=(const point3D &); + + point3D operator+(const point3D &)const; + + point3D operator-(const point3D &)const; + + point3D& operator*=(const double); //produit par un scalaire + + point3D operator*(const double)const; //idem + point3D operator*(const point3D)const; //produit par un scalaire entre + // coefficient retourne (x*x1, y*y1, z*z1) + + point3D& operator/=(const double); //division par un scalaire + + point3D operator/(const double)const; //idem + + friend ostream& operator<<(ostream&, point3D); + + friend istream& operator>>(istream&, point3D &); + // methode statique sur de vecteur3D declarer comme point3D + static double produit_scalaire(const point3D& _v1, const point3D& _v2); // produit scalaire vecteur 3D + static point3D produit_vectoriel(const point3D& _v1 , const point3D& _v2); //produit vectoriel + static point3D PointsToVecteur(const point3D& _p1, const point3D& _p2) ; + static void normalize(point3D& _v); +}; + +#endif diff --git a/vague/vague.cpp b/vague/vague.cpp new file mode 100755 index 0000000..2ee7384 --- /dev/null +++ b/vague/vague.cpp @@ -0,0 +1,10 @@ +#include "vague.h" + +Vague::Vague(double Amp, double freq, double dir, double pha) +{ + amplitude = Amp; + frequence = freq; + direction = dir; + phase = pha; + +} diff --git a/vague/vague.h b/vague/vague.h new file mode 100755 index 0000000..3f38723 --- /dev/null +++ b/vague/vague.h @@ -0,0 +1,30 @@ +#ifndef VAGUE_H +#define VAGUE_H +#include "point3D.h" +#include "vector.h" +class Vpoint{ + // structure de point et sa normal +public: + inline Vpoint(point3D a, point3D v){ + point = a; + normale = v; + } + point3D point; + point3D normale; + double s,t; // coordonee texture + +}; + +class Vague +{ +public: + Vague(double amp=0, double freq=0, double dir=0, double phas=0); +private: + double amplitude, //amplitude de la vague + frequence, // frequance de la vague + direction, // direction de la vague + phase; // phase + friend class Ocean; +}; + +#endif // VAGUE_H diff --git a/vague/vector.cpp b/vague/vector.cpp new file mode 100755 index 0000000..3f390e0 --- /dev/null +++ b/vague/vector.cpp @@ -0,0 +1,279 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// vector.cpp +// +// Description +// Classe définissant un vecteur. +// +// Copyright +// Laboratoire LSIS +// Equipe LXAO +// +// Historique +// 12/05/1999 Création par Sébastien Thon +// +/////////////////////////////////////////////////////////////////////////////// + + + +#include +#include +#include "vector.h" + + + +double Vector::operator % ( const Vector& v ) const +{ + return x*v.x + y*v.y + z*v.z; +} + + + +Vector Vector::operator ^ ( const Vector& v ) const +{ + return Vector( y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x ); +} + + + +void Vector::normalize() +{ + double len = (double)sqrt( x*x + y*y + z*z ); + + if( len == 0 ) + { + x=0; + y=0; + z=0; + } + else + { + x/=len; + y/=len; + z/=len; + } +} + + + +Vector Vector::operator + ( const Vector& v ) const +{ + return Vector( x+v.x, y+v.y, z+v.z ); +} + + + +Vector Vector::operator + ( double d ) const +{ + return Vector( x+d, y+d, z+d ); +} + + + +Vector operator + ( const Vector& v1, const Vector& v2 ) +{ + return Vector( v1.x+v2.x, v1.y+v2.y, v1.z+v2.z ); +} + + + +Vector Vector::operator - ( const Vector& v ) const +{ + return Vector( x-v.x, y-v.y, z-v.z ); +} + + + +Vector Vector::operator - ( double d ) const +{ + return Vector( x-d, y-d, z-d ); +} + + + +Vector operator - ( const Vector& v1, const Vector& v2 ) +{ + return Vector( v1.x-v2.x, v1.y-v2.y, v1.z-v2.z ); +} + + + +Vector Vector::operator - () const +{ + return Vector( -x, -y, -z ); +} + + + +Vector Vector::operator * ( const Vector& v ) const +{ + return Vector( x*v.x, y*v.y, z*v.z ); +} + + + +Vector operator * ( const Vector& v1, const Vector& v2 ) +{ + return Vector( v1.x*v2.x, v1.y*v2.y, v1.z*v2.z ); +} + + + +Vector Vector::operator * ( double d ) const +{ + return Vector( x*d, y*d, z*d ); +} + + + +Vector Vector::operator / ( double d ) const +{ + return Vector( x/d, y/d, z/d ); +} + + + +Vector Vector::operator / ( const Vector& v ) const +{ + return Vector( x/v.x, y/v.y, z/v.z ); +} + + + +Vector operator / ( const Vector& v1, const Vector& v2 ) +{ + return Vector( v1.x/v2.x, v1.y/v2.y, v1.z/v2.z ); +} + + + +int Vector::operator == ( const Vector& v ) +{ + return( (x == v.x) && (y == v.y) && (z == v.z) ); +} + + + +int Vector::operator != ( const Vector& v ) +{ + return( (x != v.x) || (y != v.y) || (z != v.z) ); +} + + + +int Vector::operator > ( const Vector& v ) +{ + return( (x > v.x) || (y > v.y) || (z > v.z) ); +} + + + +int Vector::operator < ( const Vector& v ) +{ + return( (x < v.x) || (y < v.y) || (z < v.z) ); +} + + + +Vector& Vector::operator = ( const Vector& v ) +{ + x = v.x; + y = v.y; + z = v.z; + return *this; +} + + + +Vector& Vector::operator += ( const Vector& v ) +{ + x += v.x; + y += v.y; + z += v.z; + return *this; +} + + + +Vector& Vector::operator -= ( const Vector& v ) +{ + x -= v.x; + y -= v.y; + z -= v.z; + return *this; +} + + + +Vector& Vector::operator += ( double d ) +{ + x += d; + y += d; + z += d; + return *this; +} + + + +Vector& Vector::operator -= ( double d ) +{ + x -= d; + y -= d; + z -= d; + return *this; +} + + + +Vector& Vector::operator *= ( double d ) +{ + x *= d; + y *= d; + z *= d; + return *this; +} + + + +Vector& Vector::operator /= ( double d ) +{ + x /= d; + y /= d; + z /= d; + return *this; +} + + + +double Vector::length() const +{ + return (double)sqrt( x*x + y*y + z*z ); +} + + + +double Vector::distance( const Vector& v ) const +{ + return (double)sqrt( (x-v.x)*(x-v.x) + (y-v.y)*(y-v.y) + (z-v.z)*(z-v.z) ); +} + + + +double Vector::distance( double _x, double _y, double _z ) const +{ + return (double)sqrt( (x-_x)*(x-_x) + (y-_y)*(y-_y) + (z-_z)*(z-_z) ); +} + + + +double Vector::distance_squared( const Vector& v ) const +{ + return (x-v.x)*(x-v.x) + (y-v.y)*(y-v.y) + (z-v.z)*(z-v.z); +} + + + +double Vector::distance_squared( double _x, double _y, double _z ) const +{ + return (x-_x)*(x-_x) + (y-_y)*(y-_y) + (z-_z)*(z-_z); +} diff --git a/vague/vector.h b/vague/vector.h new file mode 100755 index 0000000..0b019a9 --- /dev/null +++ b/vague/vector.h @@ -0,0 +1,101 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// vector.cpp +// +// Description +// Classe définissant un vecteur. +// +// Copyright +// Laboratoire LSIS +// Equipe LXAO +// +// Historique +// 12/05/1999 Création par Sébastien Thon +// 3/05/2015 Modifier par Thierry Nibert-siber +// +/////////////////////////////////////////////////////////////////////////////// + + + +#ifndef VECTOR_H +#define VECTOR_H + + + +#include + + + +class Vector +{ +public: + /*Vector( double x1=0, double y1=0, double z1=0 ); + Vector( const Vector& v );*/ + + Vector(): + x(0), y(0), z(0) {} + Vector (double x1, double y1, double z1): + x(x1), y(y1), z(z1) {} + Vector ( const Vector &v ): + x(v.x), + y(v.y), + z(v.z) {} + + double distance( const Vector& v ) const; + double distance( double _x, double _y, double _z ) const; + + double distance_squared( const Vector& v ) const; + double distance_squared( double _x, double _y, double _z ) const; + + double operator % ( const Vector& v ) const; // produit scalaire + Vector operator ^ ( const Vector& v ) const; // produit vectoriel + void normalize(); + + Vector operator + ( const Vector& v ) const; + Vector operator + ( double d ) const; + Vector operator - ( const Vector& v ) const; + Vector operator - ( double d ) const; + Vector operator - () const; + + Vector operator * ( const Vector& v ) const; + Vector operator * ( double d ) const; + Vector operator / ( const Vector& v ) const; + Vector operator / ( double d ) const; + + int operator > ( const Vector& v ); + int operator < ( const Vector& v ); + int operator == ( const Vector& v ); + int operator != ( const Vector& v ); + + Vector& operator = ( const Vector& v ); + Vector& operator += ( const Vector& v ); + Vector& operator -= ( const Vector& v ); + Vector& operator += ( double d ); + Vector& operator -= ( double d ); + Vector& operator *= ( double d ); + Vector& operator /= ( double d ); + + friend Vector operator + ( double d, const Vector& v ) + { + return Vector( v.x+d, v.y+d, v.z+d ); + } + + friend Vector operator * ( double d, const Vector& v ) + { + return Vector( v.x*d, v.y*d, v.z*d ); + } + + friend std::ostream& operator << ( std::ostream& os, const Vector& v ) + { + return os << v.x << ", " << v.y << ", " << v.z; + } + + double length() const; + + + double x, y, z; +}; + + + +#endif diff --git a/vague/widget.cpp b/vague/widget.cpp new file mode 100755 index 0000000..057c649 --- /dev/null +++ b/vague/widget.cpp @@ -0,0 +1,413 @@ +/* Copyright (C) 2013 Karl Phillip Buhr + * + * This work is licensed under the Creative Commons Attribution-ShareAlike License. + * To view a copy of this license, visit: + * https://creativecommons.org/licenses/by-sa/2.5/legalcode + * + * Or to read the human-readable summary of the license: + * https://creativecommons.org/licenses/by-sa/2.5/ + */ +#include "widget.h" +#include +#include +#include +#include + + +GLWidget::GLWidget(QWidget *parent) +: QGLWidget(parent) +{ + + _width = 0; + _height = 0; + _texture = 0; + _fps = 30; + distance = -5.0; + activeZrotate = false; + x_trans = 0.0 ; x_rot = 0.; + y_trans = 0.0; y_rot = 0.; + z_trans = 0.0; z_rot = .0; + x_cam_eye=0.; y_cam_eye=0.; z_cam_eye=0.; + x_cam_center=100.; y_cam_center=0.; z_cam_center=100.; + x_cam_up=0.; y_cam_up=0.; z_cam_up=0.; + spectredir = QString("../outils/Spectre/spectrum.txt"); + framedir = QString("../outils/Textures/ocean.png"); + o1 = Ocean(spectredir,8,40,40); //evolution future vers un chargement via le gui + +} + +GLWidget::~GLWidget() +{ + glDeleteTextures(1, &_texture); +} + +void GLWidget::_tick() +{ + + // triggers paintGL() + update(); + + // Set timer according to FPS + QTimer::singleShot(1000/_fps, this, SLOT(_tick())); + + //updateOverlayGL(); + //updateGL(); +} + +void GLWidget::initializeGL() +{ + + distance = -10.0; + x_rot = -180.; + y_rot = -190.; + z_rot = -200.; + now.start(); + // Create the texture + glGenTextures(1, &_texture); + // Set clear color as black + qglClearColor(Qt::darkGray); + glEnable(GL_DEPTH_TEST); + //load bit map + qt_frame.load(framedir); + // Typical texture generation using data from the bitmap + _texture = bindTexture(qt_frame,GL_TEXTURE_2D,GL_RGBA); + // Transfer image data to the GPU + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); + glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + + if (!_fps || _fps <= 0) // if the function fails, fps is set to 15 + _fps = 60; + + std::cout << "GLWidget::initializeGL: " << _fps << " fps" << std::endl; + glShadeModel(GL_SMOOTH); // Mod�le d'ombrage : lissage de Gouraud + glEnable(GL_CULL_FACE); // Ne traite pas les faces cach�es + // Enable lighting + + glEnable(GL_DEPTH_TEST); // Active le Z-Buffer + glDepthFunc(GL_LEQUAL); // Mode de fonctionnement du Z-Buffer + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Active la correction de perspective (pour ombrage, texture, ...) + + /* Start the timer */ + _tick(); +} + +void GLWidget::paintGL() +{ + gluLookAt(x_cam_eye, y_cam_eye, z_cam_eye, + x_cam_center, y_cam_center, z_cam_center, + x_cam_up, y_cam_up, z_cam_up); + o1.anime(); + + // Clear the screen and depth buffer (with black) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glPolygonMode(GL_FRONT, GL_FILL); + glPolygonMode(GL_BACK, GL_LINE); + + + // Model view matrix + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glTranslatef(x_trans, y_trans, z_trans); + glRotatef(x_rot / 16.0f, 1.0f, 0.0f, 0.0f); + glRotatef(y_rot / 16.0f, 0.0f, 1.0f, 0.0f); + glRotatef(z_rot / 16.0f, 0.0f, 0.0f, 1.0f); + + + if (glGetError() != GL_NO_ERROR) + { + std::cout << "GLWidget::paintGL: !!! Failed glTexImage2D" << std::endl; + } + +// _view_ortho(); + repereScene3D(200.); + //qglColor(Qt::darkCyan); + o1.affiche(); + if(o1.smooth) + _draw_text(0.,30., 0., "K: Lissage de phong Acitf"); + else + _draw_text(0.,30., 0., "K: Lissage de phong Inacitf"); + _draw_text(0.,20., 0., "F/C: bouger la light"); + +// _view_perspective(); + + +} + +void GLWidget::resizeGL( int w, int h) +{ + _width = w; + _height = h; + + int side = qMin(_width, _height); + glViewport((_width - side) / 2, (_height - side) / 2, side, side); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); +#ifdef QT_OPENGL_ES_1 + glOrthof(-2, +2, -2, +2, 1.0, 15.0); +#else + glOrtho(-200, 200, -200, +200, -1.0, 100000.0); +#endif + glMatrixMode(GL_MODELVIEW); +} +/************************* + * + * Clavier + * + * *********************/ +void GLWidget::keyPressEvent(QKeyEvent *event) +{ + if(event->key() == Qt::Key_Space){ + distance = -10.0; + x_trans = 0.; + y_trans = 0; + z_trans =distance; + + x_rot = 0.; + y_rot = 0.; + z_rot = 0.; + } + //------------------------- + if(event->key() == Qt::Key_Up){ + y_trans += 3.0; + } + if(event->key() == Qt::Key_Down){ + y_trans -= 3.0; + } + if(event->key() == Qt::Key_Left){ + x_trans += 3.0; + } + if(event->key() == Qt::Key_Right){ + x_trans -= 3.0; + } + + //------------------------- + if(event->key() == Qt::Key_A){ + activeZrotate = !activeZrotate; + } + //------------------------- + /* if(event->key() == Qt::Key_Z){ + z_trans += 3.0; + distance = z_trans; + } + if(event->key() == Qt::Key_E){ + z_trans -= 3.0; + distance = z_trans; + } + // cam or worlde moving + if(event->key() == Qt::Key_U){//up + x_cam_center+=20.; y_cam_center+=20.; z_cam_center+=20; + + } + if(event->key() == Qt::Key_J){//down + x_cam_center-=20.; y_cam_center-=20.; z_cam_center-=20; + } + if(event->key() == Qt::Key_H){//left look + x_cam_center+=30.; y_cam_center=0.; z_cam_center+=30.; + } + if(event->key() == Qt::Key_K){//right look + x_cam_center-=30.; y_cam_center=0.; z_cam_center-=30.; + }*/ + //------------------------- + if(event->key() == Qt::Key_K){//right look + o1.smooth = !o1.smooth; + } + if(event->key() == Qt::Key_L){//right look + o1.ligth = !o1.ligth; + } + //----------ligth move---------------- + + if(event->key() == Qt::Key_F){//up x + o1.lpos[0] += 25.; + } + if(event->key() == Qt::Key_C){//down x + o1.lpos[0] -= 25.; + } + if(event->key() == Qt::Key_X){//up y + o1.lpos[1] += 25.; + } + if(event->key() == Qt::Key_V){//down y + o1.lpos[1] -= 25.; + } + if(event->key() == Qt::Key_B){//up z + o1.lpos[2] += 25.; + } + if(event->key() == Qt::Key_N){//down x + o1.lpos[2] -= 25.; + } + updateGL();// on modifie l'affichage +} + + +/************************* + * + * Sourie + * + * *********************/ + + +void GLWidget::wheelEvent(QWheelEvent *event) +{ + distance += (2.0 * event->delta() / 120.0); + z_trans = distance; + updateGL(); +} +void GLWidget::mousePressEvent(QMouseEvent *event) +{ + last_pos = event->pos(); + // qDebug() <x() - last_pos.x(); + int dy = event->y() - last_pos.y(); + if(activeZrotate){ + if (event->buttons() & Qt::LeftButton ) { + setXRotation(x_rot + 8 * dx); + //setYRotation(y_rot + 8 * dx); + } + if (event->buttons() & Qt::RightButton) { + setYRotation(y_rot + 8 * dy); + //setZRotation(z_rot + 8 * dx); + } + }else if (event->buttons() & Qt::LeftButton) { + setZRotation(z_rot + 8 * dy); + } + + if (event->buttons() & Qt::MiddleButton) { + distance = -1.0; + x_rot = 0.; + y_rot = 0.; + z_rot = 0.; + } + + last_pos = event->pos(); + // qDebug()< 360) + angle -= 360 *16; +} + +void GLWidget::setXRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != x_rot) { + x_rot = angle; + //emit xRotationChanged(angle); + updateGL(); + } +} + +void GLWidget::setYRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != y_rot) { + y_rot = angle; + //emit yRotationChanged(angle); + updateGL(); + } +} + +void GLWidget::setZRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != z_rot) { + z_rot = angle; + //emit zRotationChanged(angle); + updateGL(); + } +} +/********************* + * * + * * Model view + * * + * *********************/ +void GLWidget::_view_ortho() // Set Up An Ortho View +{ + glMatrixMode(GL_PROJECTION); // Select Projection + glPushMatrix(); // Push The Matrix + glLoadIdentity(); // Reset The Matrix + glOrtho( -2., 2. , 2., -2., -1, 10000 ); // Select Ortho Mode (640x480) + glMatrixMode(GL_MODELVIEW); // Select Modelview Matrix + glPushMatrix(); // Push The Matrix + glLoadIdentity(); // Reset The Matrix +} + +void GLWidget::_view_perspective() // Set Up A Perspective View +{ + glMatrixMode( GL_MODELVIEW ); // Select Modelview + glPopMatrix(); // Pop The Matrix + glMatrixMode( GL_PROJECTION ); // Select Projection + glPopMatrix(); // Pop The Matrix + +} +/************************* + * * + * * outil de dessin + * * + * * + * ***********************/ +// Repere orthonorme +void GLWidget::repereScene3D(float l) +{ + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glBegin (GL_LINES); + glColor3d(1.,0.,0.) ; // red axe + glVertex3f (0., 0., 0.); + glVertex3f (l, 0., 0.); + + glColor3d(0.,1.,0.) ;// green axe + glVertex3f (0., 0., 0.); + glVertex3f (0., l, 0.); + + glColor3d(0.,0.,1.) ;//bleu axe + glVertex3f (0., 0., 0.); + glVertex3f (0., 0., l); + glEnd (); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + +} +/////////////////////////////////////////////////////////////////////////////// +// Affiche le sol de la sc�ne. +//----------------------------------------------------------------------------- +// Param�tres : +// _ +// Retour : +// _ +/////////////////////////////////////////////////////////////////////////////// +void GLWidget::affiche_sol() +{ + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glNormal3f( 0.0f, 1.0f, 0.0f); // Normale du quadrilat�re + //qglColor(Qt::white); + glBegin(GL_QUADS); // Affichage d'un quadrilat�re + glVertex3f(-20, 0, -20); + glVertex3f(-20, 0, 20); + glVertex3f( 20, 0, 20); + glVertex3f( 20, 0, -20); + glEnd(); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); +} + +void GLWidget::_draw_text(double x, double y, double z, QString txt) +{ + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + qglColor(Qt::white); + renderText(x, y, z, txt, QFont("Arial", 12, QFont::Bold, false) ); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); +} diff --git a/vague/widget.h b/vague/widget.h new file mode 100755 index 0000000..9466d53 --- /dev/null +++ b/vague/widget.h @@ -0,0 +1,70 @@ +/* Copyright (C) 2013 Karl Phillip Buhr + * + * This work is licensed under the Creative Commons Attribution-ShareAlike License. + * To view a copy of this license, visit: + * https://creativecommons.org/licenses/by-sa/2.5/legalcode + * + * Or to read the human-readable summary of the license: + * https://creativecommons.org/licenses/by-sa/2.5/ + */ +#pragma once +#ifndef GLWINDGET_H +#define GLWINDGET_H + +//Qt libs +#include +#include +#include +#include +#include "ocean.h" + +class GLWidget : public QGLWidget +{ + Q_OBJECT +public: + explicit GLWidget(QWidget* parent = 0); + virtual ~GLWidget(); + + /* OpenGL initialization, viewport resizing, and painting */ + + void initializeGL(); + void paintGL(); + void resizeGL( int width, int height); + + void keyPressEvent(QKeyEvent *event); + void wheelEvent(QWheelEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + + /* Helper functions */ + void setXRotation(int angle); + void setYRotation(int angle); + void setZRotation(int angle); + + void _view_ortho(); + void _view_perspective(); + static void repereScene3D(float l); + static void affiche_sol(); + void _draw_text(double x, double y, double z, QString txt); +private: + + int _width; + int _height; + QString framedir, spectredir; + QImage qt_frame; + QPoint last_pos; + double x_trans,y_trans,z_trans, distance; + double x_cam_eye, y_cam_eye, z_cam_eye, + x_cam_center, y_cam_center, z_cam_center, + x_cam_up, y_cam_up, z_cam_up; + bool activeZrotate; + double x_rot,y_rot,z_rot; + + Ocean o1; + int _fps; + GLuint _texture; + QTime now; +protected slots: + void _tick(); +}; +#endif diff --git a/visage/TP_Animation_Visage.pro b/visage/TP_Animation_Visage.pro new file mode 100755 index 0000000..a5f4076 --- /dev/null +++ b/visage/TP_Animation_Visage.pro @@ -0,0 +1,108 @@ +QT += core gui opengl + +contains(QT_VERSION, ^4\\.[0-8]\\..*) { + message("* Using Qt $${QT_VERSION}.") + QT += widgets + + # On my system I have to specify g++ as compiler else it will use clang++ by default + #QMAKE_CXX=g++ + #QMAKE_CC=gcc +} +#greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +contains(QT_VERSION, ^5\\.[0-8]\\..*) { + message("* Using Qt $${QT_VERSION}.") + QT += widgets + + # On my system I have to specify g++ as compiler else it will use clang++ by default + #QMAKE_CXX=g++ + #QMAKE_CC=gcc +} + +SOURCES += \ + main.cpp \ + widget.cpp \ + objet3d.cpp \ + point3D.cpp \ + mainwidget.cpp + + + +HEADERS += \ + widget.h \ + objet3d.h \ + point3D.h \ + mainwidget.h + +INCLUDEPATH += . + +## OpenCV and Glut settings for Unix/Linux +unix:!mac { + message("* Using settings for Unix/Linux.") + INCLUDEPATH += /usr/local/include/opencv \ + /usr/include/ + + LIBS += -L/usr/local/lib/ \ + -L/usr/lib/ \ + -lopencv_core \ + -lopencv_highgui \ + -lopencv_imgproc \ + -lGLU + #-lglut +} + +## OpenCV settings for Mac OS X +macx { + message("* Using settings for Mac OS X.") + INCLUDEPATH += /usr/local/include/opencv + + LIBS += -L/usr/local/lib/ \ + -lopencv_core \ + -lopencv_highgui \ + -lopencv_imgproc +} + +## OpenCV settings for Windows and OpenCV 2.4.11 +win32 { + + message("* Using settings for Windows cross compile.") + INCLUDEPATH += ${HOME}/.wine/drive_c/opencv/build/include \ + ${HOME}/.wine/drive_c/opencv/build/include/opencv \ + ${HOME}/.wine/drive_c/opencv/build/include/opencv2 + CONFIG += -static -staticlib + + CONFIG(debug, debug | release) { + LIBS += -L ${HOME}/.wine/drive_c/opencv/build/x86/vc10/lib \ + -lopencv_core2411d \ + -lopencv_highgui2411d \ + -lopencv_imgproc2411d + } + + CONFIG(release, debug | release) { + LIBS += -L ${HOME}/.wine/drive_c/opencv/build/x86/vc10/lib \ + -lopencv_core2411 \ + -lopencv_highgui2411 \ + -lopencv_imgproc2411 + } +} +## OpenCV settings for Windows and OpenCV 2.4.7 +#win32 { + #message("* Using settings for Windows.") + # INCLUDEPATH += "C:\\Dev\\SDK_ROOT\\opencv2.4.7\\build\\include" \ + # "C:\\Dev\\SDK_ROOT\\opencv2.4.7\\build\\include\\opencv" \ + # "C:\\Dev\\SDK_ROOT\\opencv2.4.7\\build\\include\\opencv2" + + #CONFIG(debug, debug | release) { + # LIBS += -L"C:\\Dev\\SDK_ROOT\\opencv2.4.7\\build\\x86\\vc10\\lib" \ + # -lopencv_core247d \ + # -lopencv_highgui247d \ + # -lopencv_imgproc247d + #} + + #CONFIG(release, debug | release) { + # LIBS += -L"C:\\Dev\\SDK_ROOT\\opencv2.4.7\\build\\x86\\vc10\\lib" \ + # -lopencv_core247 \ + # -lopencv_highgui247 \ + # -lopencv_imgproc247 + #} +#} + diff --git a/visage/main.cpp b/visage/main.cpp new file mode 100755 index 0000000..4ca66bd --- /dev/null +++ b/visage/main.cpp @@ -0,0 +1,22 @@ +/* Copyright (C) 2013 Karl Phillip Buhr + * + * This work is licensed under the Creative Commons Attribution-ShareAlike License. + * To view a copy of this license, visit: + * https://creativecommons.org/licenses/by-sa/2.5/legalcode + * + * Or to read the human-readable summary of the license: + * https://creativecommons.org/licenses/by-sa/2.5/ + */ +#include +#include "mainwidget.h" + +int main(int argc, char* argv[]) +{ + QApplication app(argc, argv); + // For OpenGL Graphics + mainWidget widget; + widget.show(); + + return app.exec(); +} + diff --git a/visage/mainwidget.cpp b/visage/mainwidget.cpp new file mode 100755 index 0000000..8c18580 --- /dev/null +++ b/visage/mainwidget.cpp @@ -0,0 +1,49 @@ +#include "mainwidget.h" +#include +mainWidget::mainWidget(QWidget *parent) : + QMainWindow(parent) +{ + _menu = new QMenu("File"); + _menu->addAction("Op3n", this, SLOT(_open())); + _menu->addSeparator(); + _menu->addAction("Exit", this, SLOT(close())); + _menu_bar.addMenu(_menu); + _menu = new QMenu("Help"); + _menu->addAction("Commande", this, SLOT(_help())); + _menu->addSeparator(); + _menu->addAction("About", this, SLOT(_about())); + _menu_bar.addMenu(_menu); + setMenuBar(&_menu_bar); + resize(650,580); + setCentralWidget(&gl_widget); + //gl_widget.setParent(this); +} + +void mainWidget::keyPressEvent(QKeyEvent* event){ + gl_widget.keyPressEvent(event); +} +void mainWidget::wheelEvent(QWheelEvent *event){ + gl_widget.wheelEvent(event); +} +void mainWidget::mousePressEvent(QMouseEvent *event){ + gl_widget.mousePressEvent(event); +} +void mainWidget::mouseMoveEvent(QMouseEvent *event){ + gl_widget.mouseMoveEvent(event); +} + +void mainWidget::_help() +{ + QString text = QString(tr("Commande Clavier:\n" + "S : de/active calcule des normale Face/vertices.\n" + " L : de/active la lumiere.\n" + " K : de/active le lissage de fong.\n" + " Espace: RAZ" + "\n" + "Command Sourie:\n" + "Mollet: fait varier la profondeur de champs\n" + "btn droit/gauche: rotation du monde.\n")); + QLabel* l = new QLabel(text); + l->show(); +} + diff --git a/visage/mainwidget.h b/visage/mainwidget.h new file mode 100755 index 0000000..143429c --- /dev/null +++ b/visage/mainwidget.h @@ -0,0 +1,36 @@ +#ifndef MAINWIDGET_H +#define MAINWIDGET_H +#ifdef _WIN32 +#include +#include +#include +#else +#include +#include +#include +#endif +#include "widget.h" + +class mainWidget : public QMainWindow +{ + Q_OBJECT +public: + explicit mainWidget(QWidget *parent = 0); + void keyPressEvent(QKeyEvent *event); + void wheelEvent(QWheelEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +signals: + +public slots: + void _help(); + +private: + QMenuBar _menu_bar; + QMenu* _menu; + // For OpenGL Graphics + GLWidget gl_widget; +}; + +#endif // MAINWIDGET_H diff --git a/visage/objet3d.cpp b/visage/objet3d.cpp new file mode 100755 index 0000000..d063e37 --- /dev/null +++ b/visage/objet3d.cpp @@ -0,0 +1,352 @@ +#include +#include +#include +#include +#include +#include +#include +#include +Objet3D::Objet3D(QString name) +{ + nom = name; + nbsommets=0; + nbfaces=0; + id=0; + smooth = false; +} + + +Objet3D::Objet3D(const Objet3D& C) +{ + nom = C.nom; + nbsommets=C.nbsommets; + nbfaces=C.nbfaces; + lpoints = C.lpoints; + lfaces = C.lfaces; + //ne pas recopier les normal + lpointsnormales = C.lpointsnormales ; + lfacesnormales = C.lfacesnormales; + smooth =C.smooth; + min = C.min; + max = C.max; + centroid = C.centroid; +} + +bool Objet3D::charger_Off(QString objet){ + nom = objet.split('/').last().split('.').first(); + QFile file(objet); + if(!file.open(QIODevice::ReadOnly)) { + QMessageBox::information(0, "error Ouverture fichier", file.errorString()); + return false; + } + + QTextStream in(&file); + int lin=-1; + while(!in.atEnd()) { + QString line = in.readLine(); + QStringList list_value; + line = line.simplified(); + if((line != "OFF")&& lin ==-1) // controle header + { + QMessageBox::information(0, "Erreur dans l'en tête du fichier OFF", file.errorString()); + return false; + } + if(lin == -1) + lin = 0; + if(lin == 0) + { + uint v=0; + line = in.readLine(); + line = line.simplified(); + list_value = line.split(' '); + // qDebug()<< list_value << endl; + nbsommets = list_value[0].toUInt( ); + nbfaces = list_value[1].toUInt(); + v = list_value[2].toUInt(); + id = v; + lin=1; + + lpoints.clear(); + lfaces.clear(); + lfacesnormales.clear(); + + line = in.readLine(); + line = line.simplified(); + } + if(lpoints.size() < nbsommets) { // chargement des sommet + point3D p; + list_value = line.split(' '); + //qDebug()<< list_value << endl; + p.x=list_value[0].toDouble(); + p.y=list_value[1].toDouble(); + p.z=list_value[2].toDouble(); + + if (min.x > p.x) + min.x = p.x; + if (min.y > p.y) + min.y = p.y; + if (min.z > p.z) + min.z = p.z; + + if (max.x < p.x) + max.x = p.x; + if (max.y < p.y) + max.y = p.y; + if (max.z < p.z) + max.z = p.z; + + lpoints.push_back(p); + }else if(lfaces.size() < nbfaces){ + + uint v=0; + face F; + + list_value = line.split(' '); + //qDebug()<< list_value << endl; + + v=list_value[0].toUInt(); + F.S1=list_value[1].toUInt(); + F.S2=list_value[2].toUInt(); + F.S3=list_value[3].toUInt(); + + if (v != 3) { + QMessageBox::information(0, "Erreur au chargement des faces, non triangulaires", file.errorString()); + return false; + } + lfaces.push_back(F); + } + } + //calcul du centroid de l'objet à partir de la boîte min/max + centroid.x = (max.x + min.x) / 2.0f; + centroid.y = (max.y + min.y) / 2.0f; + centroid.z = (max.z + min.z) / 2.0f; + /*qDebug() << "Chargement du fichier " << objet + << "\t" << "parmétres : " << nbsommets + << " points - " << nbfaces << " arêtes\n" + << "\t" << "Box : MAX(" << max.x + << " " << max.y << " " << max.z + << ")\t" << " MIN(" + << min.x << " " << min.y << " " << min.z + << ")\t" << " CENTROID(" << centroid.x + << " " << centroid.y << " " << centroid.z <<")." << endl; + */ + calcul_normales_faces(); + calcul_normales_points(); + file.close(); + return true; + +} +void Objet3D::calcul_normales_points() { + lpointsnormales.clear(); + + //qDebug()<< "taille vide = "<& lnp, deque& lnf, deque& lp, deque& lf, deque& borne) +{ + for(uint i =borne[0]; i< borne[1]; i++) { + lnp[lf[i].S1] = lnp[lf[i].S1] + lnf[lf[i].S1] ; + lnp[lf[i].S2] = lnp[lf[i].S2] + lnf[lf[i].S2] ; + lnp[lf[i].S3] = lnp[lf[i].S3] + lnf[lf[i].S3] ; + + } + + +} + +void Objet3D::calcul_normales_face(deque& lnf, deque& lp, deque& lf, uint debut, uint fin) +{ + point3D v1; + point3D v2; + //qDebug()<< "taille normal = "< p.x) + min.x = p.x; + if (min.y > p.y) + min.y = p.y; + if (min.z > p.z) + min.z = p.z; + + if (max.x < p.x) + max.x = p.x; + if (max.y < p.y) + max.y = p.y; + if (max.z < p.z) + max.z = p.z; + + lpoints.push_back(p); + } + //calcul du centroid de l'objet à partir de la boîte min/max + centroid.x = (max.x + min.x) / 2.0f; + centroid.y = (max.y + min.y) / 2.0f; + centroid.z = (max.z + min.z) / 2.0f; + /*qDebug() << "Chargement du Maillage " << nom + << "\t" << "parmétres : " << nbsommets + << " points - " << nbfaces << " arêtes\n" + << "\t" << "Box : MAX(" << max.x + << " " << max.y << " " << max.z + << ")\t" << " MIN(" + << min.x << " " << min.y << " " << min.z + << ")\t" << " CENTROID(" << centroid.x + << " " << centroid.y << " " << centroid.z <<")." << endl;*/ + if(!smooth){ + calcul_normales_faces(); + calcul_normales_points(); + /* // sequence multi thread a ameliore + * deque b1, b2, b3; + while ( lpointsnormales.size() < lpoints.size()) { + lpointsnormales.push_back(point3D(0.,0.,0.)); + } + b1.push_back(0);b1.push_back(lfacesnormales.size()/3); + b2.push_back(lfacesnormales.size()/3);b2.push_back(2 * lfacesnormales.size()/3); + b3.push_back(2 * lfacesnormales.size()/3);b1.push_back(lfacesnormales.size()); + QFuture t1 = QtConcurrent::run(Objet3D::calcul_normales_point, lpointsnormales, lfacesnormales, lpoints, lfaces, b1); + QFuture t2 = QtConcurrent::run(Objet3D::calcul_normales_point, lpointsnormales, lfacesnormales, lpoints, lfaces, b2); + QFuture t3 = QtConcurrent::run(Objet3D::calcul_normales_point, lpointsnormales, lfacesnormales, lpoints, lfaces, b3); + t1.waitForFinished(); + t2.waitForFinished(); + t3.waitForFinished(); + for(uint i = 0;i t1 = QtConcurrent::run(Objet3D::calcul_normales_face, lfacesnormales, lpoints, lfaces, 0, lfacesnormales.size()/3); + QFuture t2 = QtConcurrent::run(Objet3D::calcul_normales_face, lfacesnormales, lpoints, lfaces, lfacesnormales.size()/3, 2*lfacesnormales.size()/3); + QFuture t3 = QtConcurrent::run(Objet3D::calcul_normales_face, lfacesnormales, lpoints, lfaces, 2*lfacesnormales.size()/3, lfacesnormales.size()); + t1.waitForFinished(); + t2.waitForFinished(); + t3.waitForFinished(); + */ + +} diff --git a/visage/objet3d.h b/visage/objet3d.h new file mode 100755 index 0000000..25888aa --- /dev/null +++ b/visage/objet3d.h @@ -0,0 +1,51 @@ +#ifndef OBJET3D_H +#define OBJET3D_H +#include "point3D.h" +#include +#include + +class face { +public: + unsigned int S1; + unsigned int S2; + unsigned int S3; +}; +class Objet3D +{ +public: + Objet3D(QString = QString("")); + Objet3D(const Objet3D&); // recopie + + + bool charger_Off(QString objet); + //bool loadObj(QString objet); + void calcul_normales_points(); + void calcul_normales_faces(); + static void calcul_normales_point(deque& lnp, deque& lnf, deque& lp, deque& lf,deque&); + static void calcul_normales_face(deque& lnf, deque& lp, deque& lf, uint debut, uint fin); + bool smooth, ligth; + + void interpolation(const Objet3D& debut, const Objet3D& fin, const float& t); + + void affiche() const; + void draw_normale_faces() const; + void draw_normale_point() const; +private : + QString nom; + + unsigned int nbsommets; + unsigned int nbfaces; + + unsigned int id; + + deque lpoints; + deque lfaces; + deque lpointsnormales; + deque lfacesnormales; + + point3D min; + point3D max; + point3D centroid; +}; + +#endif // OBJET3D_H diff --git a/visage/point3D.cpp b/visage/point3D.cpp new file mode 100755 index 0000000..eb4e610 --- /dev/null +++ b/visage/point3D.cpp @@ -0,0 +1,97 @@ +#include +#include + +/**********************************************************************/ +/**********************************************************************/ +/* */ +/* methodes de la classe point3D */ +/* */ +/**********************************************************************/ +/**********************************************************************/ +point3D::point3D(){ + x = 0.0; y = 0.0; z = 0.0; +} + +point3D::point3D(const double X,const double Y,const double Z){ + x=X; y=Y; z=Z; +} + +bool point3D::operator==(const point3D &op) const { + return( x == op.x && y == op.y && z == op.z); +} + +point3D& point3D::operator=(const point3D &op) { + x = op.x; y = op.y; z = op.z; +return *this; +} + +point3D point3D::operator+(const point3D &op) const { + return( point3D( x + op.x, y + op.y, z + op.z) ); +} + +point3D point3D::operator-(const point3D &op) const { + return( point3D( x - op.x, y - op.y, z - op.z) ); +} + +point3D& point3D::operator*=(const double op) { + x *= op; y *= op; z *= op; +return *this; +} + +point3D point3D::operator*(const double op) const { + return ( point3D( x * op, y * op, z * op) ); +} + +point3D& point3D::operator/=(const double op) { + x /= op; y /= op; z /= op; +return *this; +} + +point3D point3D::operator/(const double op) const { + return ( point3D( x / op, y / op, z / op) ); +} + +ostream& operator<<(ostream& p, point3D op) { + p << "(" << op.x <<", " << op.y << ", " << op.z << ")"; +return(p); +} + +istream& operator>>(istream& p, point3D &op) +{ + cout << "Entrez x:"; + p >> op.x; + cout << "Entrez y:"; + p >> op.y; + cout << "Entrez z:"; + p >> op.z; + +return (p); +} + +double point3D::produit_scalaire(const point3D& _v1, const point3D& _v2){ + return _v1.x * _v2.x + _v1.y * _v2.y + _v1.z * _v2.z; +} + +point3D point3D::produit_vectoriel(const point3D& _v1 , const point3D& _v2){ //produit vectoriel + point3D res; + res.x = _v1.y * _v2.z - _v1.z * _v2.y; + res.y = _v1.z * _v2.x - _v1.x * _v2.z; + res.z = _v1.x * _v2.y - _v1.y * _v2.x; + return res; +} +point3D point3D::PointsToVecteur(const point3D& _p1, const point3D& _p2) { + point3D res; + + res.x = _p2.x - _p1.x; + res.y = _p2.y - _p1.y; + res.z = _p2.z - _p1.z; + +return res; +} +void point3D::normalize( point3D& _v) { + +double lenght = sqrtf(produit_scalaire(_v, _v)); + _v.x /= lenght; + _v.y /= lenght; + _v.z /= lenght; +} diff --git a/visage/point3D.h b/visage/point3D.h new file mode 100755 index 0000000..7e4d96d --- /dev/null +++ b/visage/point3D.h @@ -0,0 +1,60 @@ +#ifndef _point3D_H +#define _point3D_H + +#include +using namespace std ; + +#ifndef M_PI + #define M_PI 3.14159265358979323846 +#endif + +/******************* point3D ******************/ +/** + * @brief The point3D class + * stock les coordonées 3d d'un point + * + */ +class point3D{ + +public: + + double x; + double y; + double z; + + + + point3D(); // (0,0,0) par defaut + + point3D(const double, const double, const double); + + + bool operator==(const point3D &)const; + + point3D& operator=(const point3D &); + + point3D operator+(const point3D &)const; + + point3D operator-(const point3D &)const; + + point3D& operator*=(const double); //produit par un scalaire + + point3D operator*(const double)const; //idem + point3D operator*(const point3D)const; //produit par un scalaire entre + // coefficient retourne (x*x1, y*y1, z*z1) + + point3D& operator/=(const double); //division par un scalaire + + point3D operator/(const double)const; //idem + + friend ostream& operator<<(ostream&, point3D); + + friend istream& operator>>(istream&, point3D &); + // methode statique sur de vecteur3D declarer comme point3D + static double produit_scalaire(const point3D& _v1, const point3D& _v2); // produit scalaire vecteur 3D + static point3D produit_vectoriel(const point3D& _v1 , const point3D& _v2); //produit vectoriel + static point3D PointsToVecteur(const point3D& _p1, const point3D& _p2) ; + static void normalize(point3D& _v); +}; + +#endif diff --git a/visage/widget.cpp b/visage/widget.cpp new file mode 100755 index 0000000..27765fc --- /dev/null +++ b/visage/widget.cpp @@ -0,0 +1,319 @@ +/* Copyright (C) 2013 Karl Phillip Buhr + * + * This work is licensed under the Creative Commons Attribution-ShareAlike License. + * To view a copy of this license, visit: + * https://creativecommons.org/licenses/by-sa/2.5/legalcode + * + * Or to read the human-readable summary of the license: + * https://creativecommons.org/licenses/by-sa/2.5/ + */ + +#include +#include +#include +#include +#include +#include "widget.h" +GLWidget::GLWidget(QWidget *parent) + : QGLWidget(parent) +{ + _width = 0; + _height = 0; + _texture = 0; + _fps = 0; + distance = -5.0; + x=0;x_rot = 0.; + y=0;y_rot = 0.; + z=0; z_rot = .0; + + t=0.0; interp=0; + Objet3D* obj = new Objet3D; + obj->charger_Off(QString("../outils/visages_off/visage_normal.off")); + obj_visage_inter.charger_Off(QString("../outils/visages_off/visage_normal.off")); + visage.push_back(obj); + + + obj = new Objet3D; + obj->charger_Off(QString("../outils/visages_off/visage_joie.off")); + visage.push_back(obj); + + obj = new Objet3D; + obj->charger_Off(QString("../outils/visages_off/visage_degout.off")); + visage.push_back(obj); + + + obj = new Objet3D; + obj->charger_Off(QString("../outils/visages_off/visage_surprise.off")); + visage.push_back(obj); + + obj = new Objet3D; + obj->charger_Off(QString("../outils/visages_off/visage_colere.off")); + visage.push_back(obj); + + obj = new Objet3D; + obj->charger_Off(QString("../outils/visages_off/visage_tristesse.off")); + visage.push_back(obj); + + + obj = new Objet3D; + obj->charger_Off(QString("../outils/visages_off/visage_peur.off")); + visage.push_back(obj); + + +} + +GLWidget::~GLWidget() +{ + glDeleteTextures(1, &_texture); +} + +void GLWidget::_tick() +{ + + // triggers paintGL() + update(); + //updateGL(); + + // Set timer according to FPS + QTimer::singleShot(1000/_fps, this, SLOT(_tick())); + +} + +void GLWidget::initializeGL() +{ + distance = -10.0; + x_rot = 0.; + y_rot = 0.; + z_rot = 0.; + // Set clear color as black + qglClearColor(Qt::darkGray); + glEnable(GL_DEPTH_TEST); + + // Retrieve FPS from the camera + //_fps = cv_capture.get(CV_CAP_PROP_FPS); + if (!_fps || _fps <= 0) // if the function fails, fps is set to 15 + _fps = 25; + + qDebug() << "GLWidget::initializeGL: " << _fps << " fps"; + + /* Start the timer */ + + _tick(); +} + +void GLWidget::paintGL() +{ + if(interp < (visage.size()-1) ) + obj_visage_inter.interpolation(*visage[interp], *visage[interp+1], t= min(1.0, t+.1 )); + if(interp == (visage.size()-1) ) + obj_visage_inter.interpolation(*visage[interp], *visage[0], t= min(1.0, t+.1 )); + + if(t >= 1.0) {t=0.0; interp = (interp+1) % (visage.size()-1); } + + // Clear the screen and depth buffer (with black) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glPolygonMode(GL_FRONT, GL_FILL); + glPolygonMode(GL_BACK, GL_LINE); + + + // Model view matrix + // glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glTranslatef(0.0, 0.0, distance); + glRotatef(x_rot / 16.0f, 1.0f, 0.0f, 0.0f); + glRotatef(y_rot / 16.0f, 0.0f, 1.0f, 0.0f); + glRotatef(z_rot / 16.0f, 0.0f, 0.0f, 1.0f); + + + if (glGetError() != GL_NO_ERROR) + { + qDebug()<< "GLWidget::paintGL: !!! Failed glTexImage2D" ; + } + + repereScene3D(10); + //qglColor(Qt::darkCyan) ;// + obj_visage_inter.affiche(); + if( obj_visage_inter.ligth) + _draw_text(12.,0.,0.,"Light : On"); + else _draw_text(12.,0.,0.,"Light : Off"); + + if(obj_visage_inter.smooth ) + _draw_text(10.,2.,0.,"DrawNormal : Face"); + else _draw_text(12.,2.,0.,"DrawNormal :" + " Vertex"); +} + +void GLWidget::resizeGL( int w, int h) +{ + _width = w; + _height = h; + + int side = qMin(_width, _height); + glViewport((_width - side) / 2, (_height - side) / 2, side, side); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); +#ifdef QT_OPENGL_ES_1 + glOrthof(-2, +2, -2, +2, 1.0, 15.0); +#else + glOrtho(-15.0, +20, -20, +20.0, 1.0, 50.0); +#endif + glMatrixMode(GL_MODELVIEW); +} +/************************* + * + * Clavier + * + * *********************/ +void GLWidget::keyPressEvent(QKeyEvent *event) +{ + if(event->key() == Qt::Key_Space){ + distance = -10.0; + x_rot = 0.; + y_rot = 0.; + z_rot = 0.; + } + if(event->key() == Qt::Key_S){ // active/deactive le calcule normale face + obj_visage_inter.smooth = !obj_visage_inter.smooth; + } + if(event->key() == Qt::Key_L){ //active/déactive la lumiere autour de l'objet + obj_visage_inter.ligth = !obj_visage_inter.ligth; + } + updateGL();// on modifie l'affichage +} + + +/************************* + * + * Sourie + * + * *********************/ + + +void GLWidget::wheelEvent(QWheelEvent *event) +{ + distance += (2.0 * event->delta() / 120.0); + updateGL(); +} +void GLWidget::mousePressEvent(QMouseEvent *event) +{ + last_pos = event->pos(); + // qDebug() <x() - last_pos.x(); + int dy = event->y() - last_pos.y(); + if (event->buttons() & Qt::LeftButton) { + setXRotation(x_rot + 8 * dy); + setYRotation(y_rot + 8 * dx); + } else if (event->buttons() & Qt::RightButton) { + setYRotation(x_rot + 8 * dy); + setZRotation(z_rot + 8 * dx); + } else if (event->buttons() & Qt::MiddleButton) { + distance = -1.0; + x_rot = 0.; + y_rot = 0.; + z_rot = 0.; + } + + last_pos = event->pos(); + // qDebug()< 360) + angle -= 360 * 16; +} + +void GLWidget::setXRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != x_rot) { + x_rot = angle; + //emit xRotationChanged(angle); + updateGL(); + } +} + +void GLWidget::setYRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != y_rot) { + y_rot = angle; + //emit yRotationChanged(angle); + updateGL(); + } +} + +void GLWidget::setZRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != z_rot) { + z_rot = angle; + //emit zRotationChanged(angle); + updateGL(); + } +} +/********************* + * * + * * Model view + * * + * *********************/ +void GLWidget::_view_ortho() // Set Up An Ortho View +{ + glMatrixMode(GL_PROJECTION); // Select Projection + glPushMatrix(); // Push The Matrix + glLoadIdentity(); // Reset The Matrix + glOrtho( 0, _width , _height, 0, -1, 1 ); // Select Ortho Mode (640x480) + glMatrixMode(GL_MODELVIEW); // Select Modelview Matrix + glPushMatrix(); // Push The Matrix + glLoadIdentity(); // Reset The Matrix +} + +void GLWidget::_view_perspective() // Set Up A Perspective View +{ + glMatrixMode( GL_PROJECTION ); // Select Projection + glPopMatrix(); // Pop The Matrix + glMatrixMode( GL_MODELVIEW ); // Select Modelview + glPopMatrix(); // Pop The Matrix +} +/************************* + * * + * * outil de dessin + * * + * * + * ***********************/ +// Repere orthonorme +void GLWidget::repereScene3D(float l) +{ + glDisable(GL_LIGHTING); + + glBegin (GL_LINES); + glColor3d(1.,0.,0.) ; // red axe + glVertex3f (0., 0., 0.); + glVertex3f (l, 0., 0.); + + glColor3d(0.,1.,0.) ;// green axe + glVertex3f (0., 0., 0.); + glVertex3f (0., l, 0.); + + glColor3d(0.,0.,1.) ;//bleu axe + glVertex3f (0., 0., 0.); + glVertex3f (0., 0., l); + glEnd (); + glEnable(GL_LIGHTING); + +} +void GLWidget::_draw_text(double x, double y, double z, QString txt) +{ + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + qglColor(Qt::white); + renderText(x, y, z, txt, QFont("Arial", 12, QFont::Bold, false) ); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); +} diff --git a/visage/widget.h b/visage/widget.h new file mode 100755 index 0000000..6655b12 --- /dev/null +++ b/visage/widget.h @@ -0,0 +1,60 @@ +/* Copyright (C) 2013 Karl Phillip Buhr + * + * This work is licensed under the Creative Commons Attribution-ShareAlike License. + * To view a copy of this license, visit: + * https://creativecommons.org/licenses/by-sa/2.5/legalcode + * + * Or to read the human-readable summary of the license: + * https://creativecommons.org/licenses/by-sa/2.5/ + */ +#pragma once +#include +#include +#include +#include +#include "objet3d.h" + +class GLWidget : public QGLWidget +{ + Q_OBJECT +public: + explicit GLWidget(QWidget* parent = 0); + virtual ~GLWidget(); + + /* OpenGL initialization, viewport resizing, and painting */ + + void initializeGL(); + void paintGL(); + void resizeGL( int width, int height); + + void keyPressEvent(QKeyEvent *event); + void wheelEvent(QWheelEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + + /* Helper functions */ + void setXRotation(int angle); + void setYRotation(int angle); + void setZRotation(int angle); + + void _view_ortho(); + void _view_perspective(); + static void repereScene3D(float l); + void _draw_text(double x, double y, double z, QString txt); +private: + int _width; + int _height; + + QPoint last_pos; + double x,y,z, distance; + double x_rot,y_rot,z_rot; + + double t; + uint interp; + int _fps; + GLuint _texture; + Objet3D obj_visage_inter; + deque visage; +protected slots: + void _tick(); +};