diff --git a/bugs/closed/2011-10-02-0237-hash.txt b/bugs/closed/2011-10-02-0237-hash.txt new file mode 100644 index 0000000..7ee89f0 --- /dev/null +++ b/bugs/closed/2011-10-02-0237-hash.txt @@ -0,0 +1,4 @@ +TODO : trouver une fonction unsigned int hash(uint x, uint y) telle que +hash(x,y) renvoie toujours la même chose pour les mêmes x et y, et sans +artefact visuel. + diff --git a/bugs/new/2011-10-02-0237-interpolation.txt b/bugs/new/2011-10-02-0237-interpolation.txt new file mode 100644 index 0000000..4c11688 --- /dev/null +++ b/bugs/new/2011-10-02-0237-interpolation.txt @@ -0,0 +1 @@ +TODO : faire une interpolation autre que linéaire. diff --git a/bugs/new/2011-10-02-0237-shadeTriangles.txt b/bugs/new/2011-10-02-0237-shadeTriangles.txt new file mode 100644 index 0000000..e7fc0f3 --- /dev/null +++ b/bugs/new/2011-10-02-0237-shadeTriangles.txt @@ -0,0 +1 @@ +TODO : Remplir et shade les triangles pour que ça soit plus lisible. diff --git a/display.c b/display.c index 03e3f6d..27e932b 100644 --- a/display.c +++ b/display.c @@ -102,10 +102,16 @@ int main() { // 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)); */ + /* #define SIZE 256 */ + /* printf("P5 %d %d 255\n", SIZE, SIZE); */ + /* for (y = 0; y < SIZE; y++) { */ + /* for (x = 0; x < SIZE; x++) { */ + /* //int bit = y / (SIZE/32); */ + /* //int h = hash2(t,hash2(x, y)); */ + /* //if (y % (SIZE/32) == 0) h = 0; */ + /* //printf("%c", ((h >> (31-bit)) & 1) * 255); */ + /* //printf("%c", interpolation(256+x, 256+y, 256, 256, 512, 512, 0, 255, 255, 255)); */ + /* printf("%c", get_z(x,y)); */ /* } */ /* } */ return 0; diff --git a/roam.c b/roam.c index 532cc11..e1edaf5 100644 --- a/roam.c +++ b/roam.c @@ -48,27 +48,21 @@ unsigned int getValueForSeed(unsigned int seed) { 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) { +// Ce hash donne des bons résultats sur tous les bits de l'entier +// généré (pas d'artefacts, répartition homogène des 0 et des 1). +unsigned int hash2(unsigned int a, unsigned int b) { + unsigned int h = 1; 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 + for (i = 0; i < 32; i+=8) { + a *= h; + b *= h; + h = h * 65599 + ((a >> i) & 0xff); + h = h * 65599 + ((b >> i) & 0xff); } - return (a >> 3); // high bits are never set… + return h; } -// Un hachage certes un peu primaire mais bon… -unsigned int hash(unsigned int seed, int x, int y) { +unsigned int hash3(unsigned int seed, int x, int y) { return hash2(seed,hash2(x, y)); } @@ -114,28 +108,27 @@ short** PerlinNoise(Triangle* t) { // renvoie un z entre 0 et 255 int get_z(int x, int y) { - unsigned int seed = 45; x = x; /* Unused */ y = y; /* Unused */ int z = 0; int level; - int maxlevel = 7; - for (level = maxlevel; level > 0; level--) { + int maxlevel = 6; + for (level = maxlevel; level >= 0; level--) { int step = (1 << level); int mask = step - 1; - int zmax = mask; + int zmax = 2*step - 1; 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); + z += interpolation(x, y, x1, y1, x2, y2, hash3(level, x2, y1) & zmax, hash3(level, x2, y2) & zmax, hash3(level, x1, y2) & zmax, hash3(level, x1, y1) & zmax); } - // 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); + // ici le résultat est entre 0 (inclus) et 2^(2+maxlevel) (non inclus) + // On normalise sur [0,256[ sachant que 256 == 2^8. + if (maxlevel > 6) + z = z >> (-6+maxlevel); + else if (maxlevel != 6) + z = z << (6-maxlevel); return z; } diff --git a/roam.h b/roam.h index e6dea85..ac9fd5a 100644 --- a/roam.h +++ b/roam.h @@ -23,4 +23,5 @@ 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); +unsigned int hash2(unsigned int a, unsigned int b); int get_z(int x, int y);