www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 235e150ee960d628922c5a16c785fca7003c1d74
parent e9a2a6d4a8fdc439024cdb54c1c1fc301b684e46
Author: Georges Dupéron <jahvascriptmaniac+github@free.fr>
Date:   Sat,  1 Oct 2011 18:45:36 +0200

Perlin noise + démo. Il y a un bug lors du split sur les triangles à gauche.

Diffstat:
Abugs/new/2011-10-01-1846-split.txt | 1+
Mdisplay.c | 30++++++++++++++++--------------
Mroam.c | 87++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Mroam.h | 1+
4 files changed, 87 insertions(+), 32 deletions(-)

diff --git a/bugs/new/2011-10-01-1846-split.txt b/bugs/new/2011-10-01-1846-split.txt @@ -0,0 +1 @@ +Quand on fait un split récursif sur au moins 4-5 niveaux, on voit que le côté gauche des triangles est malformé. diff --git a/display.c b/display.c @@ -81,9 +81,9 @@ void displayTree(Triangle *t) { if(t->tLeftChild == NULL) { glBegin(GL_LINE_LOOP); glColor3ub(255,255,255); - glVertex3d(t->vLeft->x,t->vLeft->y,1); - glVertex3d(t->vApex->x,t->vApex->y,1); - glVertex3d(t->vRight->x,t->vRight->y,1); + glVertex3d(t->vLeft->x,t->vLeft->y,t->vLeft->z); + glVertex3d(t->vApex->x,t->vApex->y,t->vApex->z); + glVertex3d(t->vRight->x,t->vRight->y,t->vRight->z); glEnd(); } else { @@ -93,17 +93,19 @@ void displayTree(Triangle *t) { } int main() { - /* initWindow(); */ - /* t = initDefaultExample(); */ + initWindow(); + t = initDefaultExample(); - /* mainLoop(); */ - int x; - int y; - printf("P5 %d %d 255\n", 256, 256); - for (y = 0; y < 256; y++) { - for (x = 0; x < 256; x++) { - printf("%c", interpolation(x, y, 0, 0, 256, 256, 0, 255, 255, 255)); - } - } + mainLoop(); + + // Pour afficher le terrain : + /* int x; */ + /* int y; */ + /* printf("P5 %d %d 255\n", 256, 256); */ + /* for (y = 0; y < 256; y++) { */ + /* for (x = 0; x < 256; x++) { */ + /* printf("%c", get_z(x, y));//interpolation(256+x, 256+y, 256, 256, 512, 512, 0, 255, 255, 255)); */ + /* } */ + /* } */ return 0; } diff --git a/roam.c b/roam.c @@ -41,12 +41,37 @@ int getFirstTriangleSize(Triangle* t) { return sqrt(((t->vRight->x - t->vLeft->x)^2) + ((t->vRight->y - t->vLeft->y)^2)); } +// TODO : à supprimer. unsigned int getValueForSeed(unsigned int seed) { unsigned int primeA = 65521; // Plus grand premier < 2^16 unsigned int primeB = 4294967291U; // Plus grand premier < 2^32 return ((seed * primeA) ^ ((seed+1) * primeB)) + seed; // + seed pour éviter d'avoir uniquement des nombres impairs. } +// Donne des mauvais résultats (en faisant & 0xff…, on obtient des valeurs répétitives). +/* unsigned int hash2(unsigned int a, unsigned int b) { */ +/* unsigned int primeA = 65521; // Plus grand premier < 2^16 */ +/* unsigned int primeB = 4294967291U; // Plus grand premier < 2^32 */ +/* return ((a * primeA) + (b * primeB) + a + 43) ^ ((a * primeB) + (b * primeA) + b + 57); */ +/* } */ + +int hash2(int a, int b) { + int i; + for (i = 0; i < 5; i++) { // repeat five times + b += a; // b = a + b + a *= b; // a = a * (a + b) + b ^= a; // b = (a + b) ^ (a * (a + b)) + a += 211; // a = (a * (a + b)) + 5 + b /= 2; // b = ((a + b) ^ (a * (a + b))) / 2 + } + return (a >> 3); // high bits are never set… +} + +// Un hachage certes un peu primaire mais bon… +unsigned int hash(unsigned int seed, int x, int y) { + return hash2(seed,hash2(x, y)); +} + /* Interpolation linéaire entre deux points. * (x,y) est le point dont on veut connaître la valeur * (x1,y1)--(x2,y2) est le carré dont on connaît les valeurs @@ -55,19 +80,13 @@ unsigned int getValueForSeed(unsigned int seed) { // Optimiser aussi le fait que la distance entre xy1 et xy2 est une puissance de 2, donc on peut faire un simple décalage. // Peut être réalisé par une multiplication de matrice (donc sur le GPU) : http://en.wikipedia.org/wiki/Bilinear_interpolation int interpolation(int x, int y, int x1, int y1, int x2, int y2, int ne, int se, int so, int no) { - int gaucheBas = so * -(x-x2) / (x2-x1); - int droiteBas = se * (x-x1) / (x2-x1); - int gaucheHaut = no * -(x-x2) / (x2-x1); - int droiteHaut = ne * (x-x1) / (x2-x1); - - int pointBas = gaucheBas + droiteBas; - int pointHaut = gaucheHaut + droiteHaut; - - int bas = pointBas * -(y-y1) / (y1-y2); - int haut = pointHaut * (y-y2) / (y1-y2); - int ret = bas+haut; - ret = ret; - return ret; + int ret = 0; + // on multiplie chaque coin par la superficie du rectangle formé par (x,y) et ce coin. + ret += so * (x2-x) * (y-y1); + ret += no * (x2-x) * (y2-y); + ret += ne * (x-x1) * (y2-y); + ret += se * (x-x1) * (y-y1); + return ret / ((x2-x1) * (y2-y1)); } short** PerlinNoise(Triangle* t) { @@ -93,10 +112,33 @@ short** PerlinNoise(Triangle* t) { return values; } +// renvoie un z entre 0 et 255 int get_z(int x, int y) { + unsigned int seed = 45; x = x; /* Unused */ y = y; /* Unused */ - return 0; + int z = 0; + int level; + int maxlevel = 7; + for (level = maxlevel; level > 0; level--) { + int step = (1 << level); + int mask = step - 1; + int zmax = mask; + int x1 = x & ~mask; + int y1 = y & ~mask; + int x2 = x1 + step; + int y2 = y1 + step; + z += interpolation(x, y, x1, y1, x2, y2, hash(seed, x2, y1) & zmax, hash(seed, x2, y2) & zmax, hash(seed, x1, y2) & zmax, hash(seed, x1, y1) & zmax); + //fprintf(stderr, "x=%d y=%d x1=%d y1=%d x2=%d y2=%d hash(seed, x2, y1)=%d ans&zmax=%d\n", x, y, x1, y1, x2, y2, hash(seed, x2, y1), hash(seed, x2, y1) & zmax); + //break; + } + // ici le résultat est entre 0 (inclues) et 2^(1+maxlevel) (non inclus) + // On normalise sur [0,256[ sachant que 256 == 2^8 + if (maxlevel > 7) + z = z >> (-7+maxlevel); + else if (maxlevel != 7) + z = z << (7-maxlevel); + return z; } void triangle_split(Triangle* t) { @@ -294,6 +336,14 @@ Triangle* maxheap_pop_max(Triangle** heap, unsigned int n) { return ret; } +// t must not already be split ! +void recursiveSplit(Triangle* t, int n) { + if (n == 0) return; + triangle_split(t); + recursiveSplit(t->tLeftChild, n-1); + recursiveSplit(t->tRightChild, n-1); +} + Triangle* initDefaultExample() { Triangle* t = (Triangle*)malloc(sizeof(Triangle)); Vertex* vApex = (Vertex*)malloc(sizeof(Vertex)); @@ -314,10 +364,11 @@ Triangle* initDefaultExample() { t->tRightNeighbor = NULL; t->tParent = NULL; - triangle_split(t); - triangle_split(t->tLeftChild); - triangle_split(t->tLeftChild->tLeftChild); - triangle_split(t->tLeftChild->tRightChild); + recursiveSplit(t, 10); + /* triangle_split(t); */ + /* triangle_split(t->tLeftChild); */ + /* triangle_split(t->tLeftChild->tLeftChild); */ + /* triangle_split(t->tLeftChild->tRightChild); */ return t; } diff --git a/roam.h b/roam.h @@ -23,3 +23,4 @@ typedef struct Triangle { Triangle* initDefaultExample(); int interpolation(int x, int y, int x1, int y1, int x2, int y2, int ne, int se, int so, int no); +int get_z(int x, int y);