#include "sphere.h" #define M_PI 3.14159265358979323846 #define MAGIC_RATIO 0.37139f Sphere::Sphere(int n) { // icosahedron : // top cap createVertex(0, 1); for(int i=0; i<5; i++) createVertex(i/5.f, 1-MAGIC_RATIO); // bottom cap createVertex(0, 0); for(int i=0; i<5; i++) createVertex((i+0.5f)/5.f, MAGIC_RATIO); // Compute faces for(int i=0; i<5; i++){ int top = 1; int bottom = 7; int offset = (i+1)%5; // top cap addFace(0, top+i, top+offset); // bottom cap addFace(6, bottom+i, bottom+offset); // middle ribbon addFace(bottom+i, top+offset, top+i); addFace(top+offset, bottom+offset, bottom+i); } // geodesic subdivisions : for(int i=0; i idB ? idA : idB; vid[k] = getEdge(a, b); } for(int k=0; k<3; k++) addFace(indices[j*3 + k], vid[k], vid[(k+2)%3]); addFace(vid[0], vid[1], vid[2]); } delete[](edges); indices.erase(indices.begin(), indices.begin()+nb_triangles*3); } } int Sphere::getEdge(int a, int b) { Edge* current = edges+a; int vid = -1; while(vid == -1) { if(current->b == b) vid = current->vertex; else if(current->next == NULL) { // creating subdivision vertex Vertex v; Vertex v0 = vertices[a]; Vertex v1 = vertices[b]; v.position = glm::normalize((v0.position + v1.position)/2.f); v.normal = v.position; // u/v sphériques, cohérents sur toute la sphère sauf des artefacts au niveau des u==0 float newU = (v.position.x < 0 ? 1.5f : 1.f) + atan(v.position.z/v.position.x)/(2*M_PI); float newV = acos(v.position.y)/M_PI; v.texCoord = glm::vec2(newU - floor(newU), newV); // alternative, u/v moyennés : //v.texcoord_ = (v0.texcoord_ + v1.texcoord_)/2.f; vid = vertices.size(); addVertex(v); // inserting the new vertex in the edge collection if(current->b == -1) { current->vertex = vid; current->b = b; } else current->next = new Edge(b, vid); } else current = current->next; } return vid; } void Sphere::createVertex(float u, float v) { Vertex vert; vert.position = glm::vec3(cos(u*2*M_PI)*sin(v*M_PI), cos(v*M_PI), sin(u*2*M_PI)*sin(v*M_PI)); vert.normal = vert.position; vert.texCoord = glm::vec2(u, v); addVertex(vert); }