From a26fa20bf45cc1f346bf01e3d2e2dfbff66eca6b Mon Sep 17 00:00:00 2001
From: BELARIBI NADJIB <nbelaribi@etu.unistra.fr>
Date: Fri, 13 Mar 2020 16:50:12 +0100
Subject: [PATCH] local frame

---
 TP_Geom3D_2018/Projet_modeling/meshquad.cpp | 436 +++++++++++---------
 1 file changed, 244 insertions(+), 192 deletions(-)

diff --git a/TP_Geom3D_2018/Projet_modeling/meshquad.cpp b/TP_Geom3D_2018/Projet_modeling/meshquad.cpp
index 3d57c40..db22ef4 100644
--- a/TP_Geom3D_2018/Projet_modeling/meshquad.cpp
+++ b/TP_Geom3D_2018/Projet_modeling/meshquad.cpp
@@ -1,6 +1,7 @@
-#include "meshquad.h"
+ #include "meshquad.h"
 #include "matrices.h"
 
+#define MAX 100000
 using namespace std ;
 void MeshQuad::clear()
 {
@@ -29,11 +30,11 @@ void MeshQuad::add_quad(int i1, int i2, int i3, int i4)
 
 void MeshQuad::convert_quads_to_tris(const std::vector<int>& quads, std::vector<int>& tris)
 {
-	tris.clear();
-	tris.reserve(3*quads.size()/2);
+    tris.clear();
+    tris.reserve(3*quads.size()/2);
 
-	// Pour chaque quad on genere 2 triangles
-	// Attention a repecter l'orientation des triangles
+    // Pour chaque quad on genere 2 triangles
+    // Attention a repecter l'orientation des triangles
 
      int index = 0 ;
 
@@ -50,94 +51,84 @@ void MeshQuad::convert_quads_to_tris(const std::vector<int>& quads, std::vector<
          index += 4 ;
      }
 
-
-
 }
 
 void MeshQuad::convert_quads_to_edges(const std::vector<int>& quads, std::vector<int>& edges)
 {
-	edges.clear();
-	edges.reserve(quads.size()); // ( *2 /2 !)
-	// Pour chaque quad on genere 4 aretes, 1 arete = 2 indices.
-	// Mais chaque arete est commune a 2 quads voisins !
-	// Comment n'avoir qu'une seule fois chaque arete ?
-
-
-    int index = 0 ;
-    unsigned int i ;
-
-    for( i = 0 ; i < quads.size()/4 ; i++)
-    {
-        if (i == 0 )
-        {
-              edges.push_back(quads[index]) ;
-              edges.push_back(quads[index+1]) ;
-        }
-        edges.push_back(quads[index+1]) ;
-        edges.push_back(quads[index+2]) ;
-        edges.push_back(quads[index+2]) ;
-        edges.push_back(quads[index+3]) ;
-        edges.push_back(quads[index+3]) ;
-        edges.push_back(quads[index]) ;
-
-
-        index += 4 ;
-    }
-
+    edges.clear();
+    edges.reserve(quads.size()); // ( *2 /2 !)
+    // Pour chaque quad on genere 4 aretes, 1 arete = 2 indices.
+    // Mais chaque arete est commune a 2 quads voisins !
+    // Comment n'avoir qu'une seule fois chaque arete ?
+
+    int i ,i1,i2,i3,i4;
+     for(i = 0 ; i < quads.size()/4 ; i+=4)
+     {
+         i1 = quads.at(i) ;
+         i2 = quads.at(i+1) ;
+         i2 = quads.at(i+2) ;
+         i2 = quads.at(i+3) ;
+
+         if(i1 < i2)
+         {
+            edges.push_back(i1);
+            edges.push_back(i2);
+         }
+         if(i2 < i3)
+         {
+            edges.push_back(i2);
+            edges.push_back(i3);
+         }
+         if(i3 < i4)
+         {
+            edges.push_back(i3);
+            edges.push_back(i4);
+         }
+         if(i4 < i1)
+         {
+            edges.push_back(i4);
+            edges.push_back(i1);
+         }
+     }
 }
 
 
 void MeshQuad::bounding_sphere(Vec3& C, float& R)
 {
-	// C=
-	// R=
+    // C=
+    // R=
 }
 
 
 void MeshQuad::create_cube()
 {
     clear();
-
-    // ajouter 8 sommets (-1 +1)
-    Vec3 p0, p1, p2, p3, p4, p5, p6, p7, p8;
-
-        p0= Vec3(-0.5,-0.5,+0.5) ;  // P0
-        p1= Vec3(0.5,-0.5,+0.5);  // P1
-        p2= Vec3(0.5,+0.5,+0.5);  // P2
-        p3= Vec3(-0.5,+0.5,+0.5);  // P3
-        p4= Vec3(-0.5,-0.5,-0.5);  // P4
-        p5= Vec3(0.5,-0.5,-0.5);  // P5
-        p6= Vec3(0.5,+0.5,-0.5);  // P6
-        p7= Vec3(-0.5,+0.5,-0.5);   // P7
-
-
-    int i0, i1, i2, i3, i4, i5, i6, i7;
-
-    i0 = add_vertex(p0);
-    i1 = add_vertex(p1);
-    i2 = add_vertex(p2);
-    i3 = add_vertex(p3);
-    i4 = add_vertex(p4);
-    i5 = add_vertex(p5);
-    i6 = add_vertex(p6);
-    i7 = add_vertex(p7);
-
-    // ajouter 6 faces (sens trigo)
-    add_quad(i1, i2, i3, i0);
-    add_quad(i3, i2, i6, i7);
-    add_quad(i1, i2, i6, i5);
-    add_quad(i0, i3, i7, i4);
-    add_quad(i5, i6, i7, i4);
-    add_quad(i1, i5, i4, i0);
-
-    gl_update();
+        // ajouter 8 sommets (-1 +1)
+        int i1 = add_vertex(Vec3(-1,1,1));
+        int i2 = add_vertex(Vec3(-1,-1,1));
+        int i3 = add_vertex(Vec3(1,-1,1));
+        int i4 = add_vertex(Vec3(1,1,1));
+        int i5 = add_vertex(Vec3(-1,1,-1));
+        int i6 = add_vertex(Vec3(-1,-1,-1));
+        int i7 = add_vertex(Vec3(1,-1,-1));
+        int i8 = add_vertex(Vec3(1,1,-1));
+
+        // ajouter 6 faces (sens trigo)
+        add_quad(i1,i2,i3,i4);
+        add_quad(i4,i3,i7,i8);
+        add_quad(i8,i7,i6,i5);
+        add_quad(i5,i6,i2,i1);
+        add_quad(i2,i6,i7,i3);
+        add_quad(i1,i4,i8,i5);
+
+        gl_update();
 }
 
 Vec3 MeshQuad::normal_of(const Vec3& A, const Vec3& B, const Vec3& C)
 {
-	// Attention a l'ordre des points !
-	// le produit vectoriel n'est pas commutatif U ^ V = - V ^ U
-	// ne pas oublier de normaliser le resultat.
+    // Attention a l'ordre des points !
+    // le produit vectoriel n'est pas commutatif U ^ V = - V ^ U
+    // ne pas oublier de normaliser le resultat.
 
     Vec3 AB = Vec3(B[0]-A[0],B[1]-A[1],B[2]-A[2]) ;
     Vec3 BC = Vec3(C[0]-B[0],C[1]-B[1],C[2]-B[2]) ;
@@ -166,96 +157,157 @@ float MeshQuad::calcul_aire(Vec3 p1,Vec3 p2,Vec3 p3,Vec3 p4)
 
 bool MeshQuad::is_points_in_quad(const Vec3& P, const Vec3& A, const Vec3& B, const Vec3& C, const Vec3& D)
 {
-	// On sait que P est dans le plan du quad.
+    // On sait que P est dans le plan du quad.
+
+    // P est-il au dessus des 4 plans contenant chacun la normale au quad et une arete AB/BC/CD/DA ?
+    // si oui il est dans le quad
 
-	// P est-il au dessus des 4 plans contenant chacun la normale au quad et une arete AB/BC/CD/DA ?
-	// si oui il est dans le quad
+    Vec3 n1 = glm::cross(B-A,C-B) ;
+    Vec3 n2 = glm::cross(C-B,D-C) ;
+    Vec3 n3 = glm::cross(D-C,A-D) ;
+    Vec3 n4 = glm::cross(A-D,B-A) ;
+
+    float som1 = P.x*n1.x + P.y*n1.y + P.z*n1.z ; //dot
+    float som2 = P.x*n2.x + P.y*n2.y + P.z*n2.z ;
+    float som3 = P.x*n3.x + P.y*n3.y + P.z*n3.z ;
+    float som4 = P.x*n4.x + P.y*n4.y + P.z*n4.z ;
+
+    return som1 > 0 && som2 >0 && som3 > 0  && som4 > 0 ;
 
-    return true;
 }
 
 bool MeshQuad::intersect_ray_quad(const Vec3& P, const Vec3& Dir, int q, Vec3& inter)
 {
-	// recuperation des indices de points
-	// recuperation des points
+    // recuperation des indices de points
+    // recuperation des points
+    int i1,i2,i3,i4 ;
+    Vec3 p1,p2,p3,p4 ;
 
-	// calcul de l'equation du plan (N+d)
+    i1 = m_quad_indices.at(q) ;
+    i2 = m_quad_indices.at(q+1) ;
+    i3 = m_quad_indices.at(q+2) ;
+    i4 = m_quad_indices.at(q+3) ;
 
-    // calcul de l'intersection rayon plan
-	// I = P + alpha*Dir est dans le plan => calcul de alpha
+    p1 = m_points.at(i1) ;
+    p2 = m_points.at(i2) ;
+    p3 = m_points.at(i3) ;
+    p4 = m_points.at(i4) ;
 
-	// alpha => calcul de I
 
-	// I dans le quad ?
+    // calcul de l'equation du plan (N+d)
 
-    return false;
-}
+    Vec3 N = glm::cross(p2-p1,p3-p1) ;
+    float d = -N.x*p4.x - N.y*p4.y - N.z*p4.z ;
+    Vec3 D ;
+    // calcul de l'intersection rayon plan
+    // I = P + alpha*Dir est dans le plan => calcul de alpha
+
+     float alpha = (d - glm::dot(N, P)) / glm::dot(P,Dir);
+    // alpha => calcul de I
+
+     inter = P + alpha * Dir ;
+    // I dans le quad ?
+    return is_points_in_quad(inter,p1,p2,p3,p4) ;
+ }
 
 
 int MeshQuad::intersected_closest(const Vec3& P, const Vec3& Dir)
 {
-	// on parcours tous les quads
-	// on teste si il y a intersection avec le rayon
-	// on garde le plus proche (de P)
+    // on parcours tous les quads
+    // on teste si il y a intersection avec le rayon
+    // on garde le plus proche (de P)
 
-	int inter = -1;
+    int  i,inter = -1 ;
+    float min = MAX ;
+    Vec3 inters = Vec3() ;
 
-	return inter;
+    for (i = 0  ; i < m_quad_indices.size()/4 ; i+=4)
+    {
+        if(intersect_ray_quad(P,Dir,i,inters))
+        {
+            if(glm::length(P-inters) < min)
+            {
+                inter = i ;
+                min = glm::length(P-inters) ;
+            }
+        }
+    }
+
+    return inter;
 }
 
 
 Mat4 MeshQuad::local_frame(int q)
 {
-	// Repere locale = Matrice de transfo avec
-	// les trois premieres colones: X,Y,Z locaux
-	// la derniere colonne l'origine du repere
+    // Repere locale = Matrice de transfo avec
+    // les trois premieres colones: X,Y,Z locaux
+    // la derniere colonne l'origine du repere
+
+    // ici Z = N et X = AB
+    // Origine le centre de la face
+    // longueur des axes : [AB]/2
+
+    // recuperation des indices de points
+    // recuperation des points
+
+    int i1,i2,i3,i4 ;
+    Vec3 A,B,C,D ;
 
-	// ici Z = N et X = AB
-	// Origine le centre de la face
-	// longueur des axes : [AB]/2
+    i1 = m_quad_indices.at(q) ;
+    i2 = m_quad_indices.at(q+1) ;
+    i3 = m_quad_indices.at(q+2) ;
+    i4 = m_quad_indices.at(q+3) ;
 
-	// recuperation des indices de points
-	// recuperation des points
+    A = m_points.at(i1) ;
+    B = m_points.at(i2) ;
+    C = m_points.at(i3) ;
+    D = m_points.at(i4) ;
 
-	// calcul de Z:N / X:AB -> Y
+    // calcul de Z:N / X:AB -> Y
 
-	// calcul du centre
+    Vec3 Z = glm::cross(B-A,C-A) ;
+    Vec3 X = B - A ;
+    Vec3 Y = Z / X  ;
 
-	// calcul de la taille
+    // calcul du centre
+      C = normal_of(X,Y,Z) ;
+    // calcul de la taille
 
-	// calcul de la matrice
+      float t = glm::length(B-A) ;
+    // calcul de la matrice
 
-    return Mat4();
+    Mat4 transfo = Mat4(Vec4(X,t),Vec4(Y,t),Vec4(Z,t),Vec4(C,t)) ;
+    return transfo;
 }
 
 void MeshQuad::extrude_quad(int q)
 {
-	// recuperation des indices de points
+    // recuperation des indices de points
 
-	// recuperation des points
+    // recuperation des points
 
-	// calcul de la normale
+    // calcul de la normale
 
-	// calcul de la hauteur
+    // calcul de la hauteur
 
-	// calcul et ajout des 4 nouveaux points
+    // calcul et ajout des 4 nouveaux points
 
-	// on remplace le quad initial par le quad du dessu
+    // on remplace le quad initial par le quad du dessu
 
-	// on ajoute les 4 quads des cotes
+    // on ajoute les 4 quads des cotes
 
    gl_update();
 }
 
 void MeshQuad::transfo_quad(int q, const glm::mat4& tr)
 {
-	// recuperation des indices de points
-	// recuperation des (references de) points
+    // recuperation des indices de points
+    // recuperation des (references de) points
 
-	// generation de la matrice de transfo globale:
-	// indice utilisation de glm::inverse() et de local_frame
+    // generation de la matrice de transfo globale:
+    // indice utilisation de glm::inverse() et de local_frame
 
-	// Application au 4 points du quad
+    // Application au 4 points du quad
 }
 
 void MeshQuad::decale_quad(int q, float d)
@@ -278,99 +330,99 @@ void MeshQuad::tourne_quad(int q, float a)
 
 
 MeshQuad::MeshQuad():
-	m_nb_ind_edges(0)
+    m_nb_ind_edges(0)
 {}
 
 
 void MeshQuad::gl_init()
 {
-	m_shader_flat = new ShaderProgramFlat();
-	m_shader_color = new ShaderProgramColor();
-
-	//VBO
-	glGenBuffers(1, &m_vbo);
-
-	//VAO
-	glGenVertexArrays(1, &m_vao);
-	glBindVertexArray(m_vao);
-	glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
-	glEnableVertexAttribArray(m_shader_flat->idOfVertexAttribute);
-	glVertexAttribPointer(m_shader_flat->idOfVertexAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0);
-	glBindVertexArray(0);
-
-	glGenVertexArrays(1, &m_vao2);
-	glBindVertexArray(m_vao2);
-	glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
-	glEnableVertexAttribArray(m_shader_color->idOfVertexAttribute);
-	glVertexAttribPointer(m_shader_color->idOfVertexAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0);
-	glBindVertexArray(0);
-
-	//EBO indices
-	glGenBuffers(1, &m_ebo);
-	glGenBuffers(1, &m_ebo2);
+    m_shader_flat = new ShaderProgramFlat();
+    m_shader_color = new ShaderProgramColor();
+
+    //VBO
+    glGenBuffers(1, &m_vbo);
+
+    //VAO
+    glGenVertexArrays(1, &m_vao);
+    glBindVertexArray(m_vao);
+    glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
+    glEnableVertexAttribArray(m_shader_flat->idOfVertexAttribute);
+    glVertexAttribPointer(m_shader_flat->idOfVertexAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0);
+    glBindVertexArray(0);
+
+    glGenVertexArrays(1, &m_vao2);
+    glBindVertexArray(m_vao2);
+    glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
+    glEnableVertexAttribArray(m_shader_color->idOfVertexAttribute);
+    glVertexAttribPointer(m_shader_color->idOfVertexAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0);
+    glBindVertexArray(0);
+
+    //EBO indices
+    glGenBuffers(1, &m_ebo);
+    glGenBuffers(1, &m_ebo2);
 }
 
 void MeshQuad::gl_update()
 {
-	//VBO
-	glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
-	glBufferData(GL_ARRAY_BUFFER, 3 * m_points.size() * sizeof(GLfloat), &(m_points[0][0]), GL_STATIC_DRAW);
-	glBindBuffer(GL_ARRAY_BUFFER, 0);
-
-	std::vector<int> tri_indices;
-	convert_quads_to_tris(m_quad_indices,tri_indices);
-
-	//EBO indices
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo);
-	glBufferData(GL_ELEMENT_ARRAY_BUFFER,tri_indices.size() * sizeof(int), &(tri_indices[0]), GL_STATIC_DRAW);
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
-	std::vector<int> edge_indices;
-	convert_quads_to_edges(m_quad_indices,edge_indices);
-	m_nb_ind_edges = edge_indices.size();
-
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo2);
-	glBufferData(GL_ELEMENT_ARRAY_BUFFER,m_nb_ind_edges * sizeof(int), &(edge_indices[0]), GL_STATIC_DRAW);
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    //VBO
+    glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
+    glBufferData(GL_ARRAY_BUFFER, 3 * m_points.size() * sizeof(GLfloat), &(m_points[0][0]), GL_STATIC_DRAW);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+    std::vector<int> tri_indices;
+    convert_quads_to_tris(m_quad_indices,tri_indices);
+
+    //EBO indices
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo);
+    glBufferData(GL_ELEMENT_ARRAY_BUFFER,tri_indices.size() * sizeof(int), &(tri_indices[0]), GL_STATIC_DRAW);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+    std::vector<int> edge_indices;
+    convert_quads_to_edges(m_quad_indices,edge_indices);
+    m_nb_ind_edges = edge_indices.size();
+
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo2);
+    glBufferData(GL_ELEMENT_ARRAY_BUFFER,m_nb_ind_edges * sizeof(int), &(edge_indices[0]), GL_STATIC_DRAW);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 }
 
 
 
 void MeshQuad::set_matrices(const Mat4& view, const Mat4& projection)
 {
-	viewMatrix = view;
-	projectionMatrix = projection;
+    viewMatrix = view;
+    projectionMatrix = projection;
 }
 
 void MeshQuad::draw(const Vec3& color)
 {
-	glEnable(GL_CULL_FACE);
-	glEnable(GL_POLYGON_OFFSET_FILL);
-	glPolygonOffset(1.0f, 1.0f);
-
-	m_shader_flat->startUseProgram();
-	m_shader_flat->sendViewMatrix(viewMatrix);
-	m_shader_flat->sendProjectionMatrix(projectionMatrix);
-	glUniform3fv(m_shader_flat->idOfColorUniform, 1, glm::value_ptr(color));
-	glBindVertexArray(m_vao);
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,m_ebo);
-	glDrawElements(GL_TRIANGLES, 3*m_quad_indices.size()/2,GL_UNSIGNED_INT,0);
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
-	glBindVertexArray(0);
-	m_shader_flat->stopUseProgram();
-
-	glDisable(GL_POLYGON_OFFSET_FILL);
-
-	m_shader_color->startUseProgram();
-	m_shader_color->sendViewMatrix(viewMatrix);
-	m_shader_color->sendProjectionMatrix(projectionMatrix);
-	glUniform3f(m_shader_color->idOfColorUniform, 0.0f,0.0f,0.0f);
-	glBindVertexArray(m_vao2);
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,m_ebo2);
-	glDrawElements(GL_LINES, m_nb_ind_edges,GL_UNSIGNED_INT,0);
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
-	glBindVertexArray(0);
-	m_shader_color->stopUseProgram();
-	glDisable(GL_CULL_FACE);
+    glEnable(GL_CULL_FACE);
+    glEnable(GL_POLYGON_OFFSET_FILL);
+    glPolygonOffset(1.0f, 1.0f);
+
+    m_shader_flat->startUseProgram();
+    m_shader_flat->sendViewMatrix(viewMatrix);
+    m_shader_flat->sendProjectionMatrix(projectionMatrix);
+    glUniform3fv(m_shader_flat->idOfColorUniform, 1, glm::value_ptr(color));
+    glBindVertexArray(m_vao);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,m_ebo);
+    glDrawElements(GL_TRIANGLES, 3*m_quad_indices.size()/2,GL_UNSIGNED_INT,0);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
+    glBindVertexArray(0);
+    m_shader_flat->stopUseProgram();
+
+    glDisable(GL_POLYGON_OFFSET_FILL);
+
+    m_shader_color->startUseProgram();
+    m_shader_color->sendViewMatrix(viewMatrix);
+    m_shader_color->sendProjectionMatrix(projectionMatrix);
+    glUniform3f(m_shader_color->idOfColorUniform, 0.0f,0.0f,0.0f);
+    glBindVertexArray(m_vao2);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,m_ebo2);
+    glDrawElements(GL_LINES, m_nb_ind_edges,GL_UNSIGNED_INT,0);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
+    glBindVertexArray(0);
+    m_shader_color->stopUseProgram();
+    glDisable(GL_CULL_FACE);
 }
 
-- 
GitLab