portfolio/vague/ocean.cpp
thierry_nibert 5b6730b2dc add files
2026-08-01 16:49:57 +02:00

274 lines
10 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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();
}