274 lines
10 KiB
C++
Executable File
274 lines
10 KiB
C++
Executable File
#include "ocean.h"
|
||
#include <QFile>
|
||
#include <QTextStream>
|
||
#include <QMessageBox>
|
||
#include <QDebug>
|
||
#include <QString>
|
||
#include <QGLWidget>
|
||
#include<QTime>
|
||
#include <math.h>
|
||
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" <<endl;
|
||
|
||
}
|
||
else qDebug()<< "un ocean sans spectre des vages, qui a vider la baignoir!? 0.o"<< endl;
|
||
lpos = new float[3](); // tableau initialisez a 0
|
||
smooth=false;
|
||
ligth = false;
|
||
}
|
||
Ocean::~Ocean(){
|
||
delete[] lpos;
|
||
}
|
||
|
||
|
||
bool Ocean::loadMap(int xs, int zs){
|
||
if((xs == 0) || (zs == 0))
|
||
return false;
|
||
|
||
Maillage.clear();
|
||
x_points = xs;
|
||
z_points = zs;
|
||
x_size = xs*.30;
|
||
z_size = zs*.30;
|
||
for(int x = 0; x < (xs); x ++){
|
||
deque<Vpoint> 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 = "<<lfacesnormales.size()<< endl;
|
||
while ( lfacesnormales.size() < lfaces.size()) {
|
||
|
||
v1 = point3D::PointsToVecteur(Maillage[lfaces[lfacesnormales.size()].S2.i][lfaces[lfacesnormales.size()].S2.j].point,
|
||
Maillage[lfaces[lfacesnormales.size()].S1.i][lfaces[lfacesnormales.size()].S1.j].point);
|
||
v2 = point3D::PointsToVecteur(Maillage[lfaces[lfacesnormales.size()].S1.i][lfaces[lfacesnormales.size()].S1.j].point,
|
||
Maillage[lfaces[lfacesnormales.size()].S3.i][lfaces[lfacesnormales.size()].S3.j].point);
|
||
|
||
point3D n= point3D::produit_vectoriel(v2, v1);
|
||
point3D::normalize(n);
|
||
//n = n * pow(-1., lfacesnormales.size()%2);
|
||
lfacesnormales.push_back(n);
|
||
}
|
||
}
|
||
|
||
bool Ocean::loadSpectre(QString dir){
|
||
double phase= 0.0;
|
||
QFile file(dir);
|
||
if(!file.open(QIODevice::ReadOnly)) {
|
||
QMessageBox::information(0, "error Ouverture fichier", file.errorString());
|
||
return false;
|
||
}
|
||
QTextStream in(&file);
|
||
qsrand(QTime::currentTime().second());
|
||
while(!in.atEnd()) {
|
||
QString line = in.readLine();
|
||
QStringList list_value;
|
||
line = line.simplified();
|
||
list_value = line.split(' ');
|
||
phase= 5.0 *(double)qrand()/RAND_MAX + 0;
|
||
double n= drand48() * 4;
|
||
Vague v(list_value[0].toDouble() * n, list_value[1].toDouble(), list_value[2].toDouble()*n, phase);
|
||
Vagues.push_back(v);
|
||
}
|
||
file.close();
|
||
return true;
|
||
}
|
||
void Ocean::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
|
||
//if(ligth)
|
||
|
||
glEnable(GL_LIGHTING);
|
||
glEnable(GL_LIGHT0);
|
||
|
||
glLightfv(GL_LIGHT0,GL_POSITION,lpos);
|
||
|
||
// 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);
|
||
glBegin(GL_TRIANGLES);
|
||
if(!smooth)
|
||
for(uint i= 0 ; i< lfaces.size();i++)
|
||
{
|
||
/*glColor4d(lfacesnormales[i].x,
|
||
lfacesnormales[i].y,
|
||
lfacesnormales[i].z, .75);*/
|
||
glNormal3d(lfacesnormales[i].x,
|
||
lfacesnormales[i].y,
|
||
lfacesnormales[i].z);
|
||
glTexCoord2d( Maillage[lfaces[i].S1.i][lfaces[i].S1.j].s,
|
||
Maillage[lfaces[i].S1.i][lfaces[i].S1.j].t);
|
||
glVertex3d(Maillage[lfaces[i].S1.i][lfaces[i].S1.j].point.x,
|
||
Maillage[lfaces[i].S1.i][lfaces[i].S1.j].point.y,
|
||
Maillage[lfaces[i].S1.i][lfaces[i].S1.j].point.z);
|
||
|
||
glTexCoord2d( Maillage[lfaces[i].S2.i][lfaces[i].S2.j].s,
|
||
Maillage[lfaces[i].S2.i][lfaces[i].S2.j].t);
|
||
glVertex3d(Maillage[lfaces[i].S2.i][lfaces[i].S2.j].point.x,
|
||
Maillage[lfaces[i].S2.i][lfaces[i].S2.j].point.y,
|
||
Maillage[lfaces[i].S2.i][lfaces[i].S2.j].point.z);
|
||
|
||
glTexCoord2d( Maillage[lfaces[i].S3.i][lfaces[i].S3.j].s,
|
||
Maillage[lfaces[i].S3.i][lfaces[i].S3.j].t);
|
||
glVertex3d(Maillage[lfaces[i].S3.i][lfaces[i].S3.j].point.x,
|
||
Maillage[lfaces[i].S3.i][lfaces[i].S3.j].point.y,
|
||
Maillage[lfaces[i].S3.i][lfaces[i].S3.j].point.z);
|
||
|
||
}
|
||
else{
|
||
for(uint i= 0 ; i< lfaces.size();i++)
|
||
{
|
||
|
||
/*glColor3d(Maillage[lfaces[i].S1.i][lfaces[i].S1.j].normale.x,
|
||
Maillage[lfaces[i].S1.i][lfaces[i].S1.j].normale.y,
|
||
Maillage[lfaces[i].S1.i][lfaces[i].S1.j].normale.z);*/
|
||
glNormal3d(Maillage[lfaces[i].S1.i][lfaces[i].S1.j].normale.x,
|
||
Maillage[lfaces[i].S1.i][lfaces[i].S1.j].normale.y,
|
||
Maillage[lfaces[i].S1.i][lfaces[i].S1.j].normale.z);
|
||
glTexCoord2d( Maillage[lfaces[i].S1.i][lfaces[i].S1.j].s,
|
||
Maillage[lfaces[i].S1.i][lfaces[i].S1.j].t);
|
||
glVertex3d(Maillage[lfaces[i].S1.i][lfaces[i].S1.j].point.x,
|
||
Maillage[lfaces[i].S1.i][lfaces[i].S1.j].point.y,
|
||
Maillage[lfaces[i].S1.i][lfaces[i].S1.j].point.z);
|
||
|
||
/*glColor3d(Maillage[lfaces[i].S2.i][lfaces[i].S2.j].normale.x,
|
||
Maillage[lfaces[i].S2.i][lfaces[i].S2.j].normale.y,
|
||
Maillage[lfaces[i].S2.i][lfaces[i].S2.j].normale.z);*/
|
||
glNormal3d(Maillage[lfaces[i].S2.i][lfaces[i].S2.j].normale.x,
|
||
Maillage[lfaces[i].S2.i][lfaces[i].S2.j].normale.y,
|
||
Maillage[lfaces[i].S2.i][lfaces[i].S2.j].normale.z);
|
||
glTexCoord2d( Maillage[lfaces[i].S2.i][lfaces[i].S2.j].s,
|
||
Maillage[lfaces[i].S2.i][lfaces[i].S2.j].t);
|
||
glVertex3d(Maillage[lfaces[i].S2.i][lfaces[i].S2.j].point.x,
|
||
Maillage[lfaces[i].S2.i][lfaces[i].S2.j].point.y,
|
||
Maillage[lfaces[i].S2.i][lfaces[i].S2.j].point.z);
|
||
|
||
/* glColor3d(Maillage[lfaces[i].S3.i][lfaces[i].S3.j].normale.x,
|
||
Maillage[lfaces[i].S3.i][lfaces[i].S3.j].normale.y,
|
||
Maillage[lfaces[i].S3.i][lfaces[i].S3.j].normale.z);*/
|
||
glNormal3d(Maillage[lfaces[i].S3.i][lfaces[i].S3.j].normale.x,
|
||
Maillage[lfaces[i].S3.i][lfaces[i].S3.j].normale.y,
|
||
Maillage[lfaces[i].S3.i][lfaces[i].S3.j].normale.z);
|
||
glTexCoord2d( Maillage[lfaces[i].S3.i][lfaces[i].S3.j].s,
|
||
Maillage[lfaces[i].S3.i][lfaces[i].S3.j].t);
|
||
glVertex3d(Maillage[lfaces[i].S3.i][lfaces[i].S3.j].point.x,
|
||
Maillage[lfaces[i].S3.i][lfaces[i].S3.j].point.y,
|
||
Maillage[lfaces[i].S3.i][lfaces[i].S3.j].point.z);
|
||
|
||
}
|
||
|
||
|
||
}
|
||
glEnd();
|
||
double a = .5;
|
||
glBegin(GL_QUADS);
|
||
glVertex3d(lpos[0] - a,lpos[1] ,lpos[2] - a);
|
||
glVertex3d(lpos[0] - a,lpos[1] ,lpos[2] + a);
|
||
glVertex3d(lpos[0] + a,lpos[1] ,lpos[2] -a);
|
||
glVertex3d(lpos[0] + a,lpos[1] ,lpos[2] + a);
|
||
glEnd();
|
||
// On désactive le blending
|
||
glDisable(GL_BLEND);
|
||
// On reactive l’utilisation de la lumière
|
||
|
||
// Pour ne voir qu’un seul côté des polygones
|
||
// (affichage plus rapide)
|
||
glEnable(GL_CULL_FACE);
|
||
glDisable(GL_TEXTURE_2D);
|
||
}
|
||
double Ocean::calcule_hauteur(const int& x, const int& z, const double& t){
|
||
float hauteur = 0.;
|
||
float k;
|
||
|
||
for( uint i=0; i<Vagues.size(); i++ ){
|
||
k = 4.0 * M_PI * M_PI *
|
||
Vagues[i].frequence * Vagues[i].frequence / 9.81;
|
||
hauteur += Vagues[i].amplitude *
|
||
cos( k*(x*cos(Vagues[i].direction)
|
||
+z*sin(Vagues[i].direction))-
|
||
2.0f*M_PI*Vagues[i].frequence*t
|
||
+ Vagues[i].phase );
|
||
}
|
||
return hauteur;
|
||
}
|
||
void Ocean::anime(void){
|
||
|
||
|
||
double temps_ecoule = lastT.elapsed() * 1. ;
|
||
anime(temps_ecoule);
|
||
lastT.start();
|
||
}
|
||
void Ocean::anime(double& t){
|
||
for(uint x = 0; x < Maillage.size(); x++){
|
||
for(uint z = 0; z < Maillage[x].size(); z++){
|
||
Maillage[x][z].point.y= calcule_hauteur(x,z, t);
|
||
|
||
}
|
||
}
|
||
calcul_normales_faces();
|
||
if(smooth)
|
||
calcul_normales_points();
|
||
}
|