// Cylindre float cylindre(in vec3 p, in vec3 a, in vec3 b, float rayon, float e, float R){ vec3 ab = normalize(b-a); vec3 pa = p-a; float ph = dot(pa,-ab); //en dessous du disque de centre a if(ph > 0.0){ //algo du disque if(ph >= R) return 0.0; float ch2 = dot(pa, pa) - ph*ph; if(ch2 < rayon*rayon) return e*falloff(ph,R); else if(ch2 >= (rayon+R)*(rayon+R)) return 0.0; else{ float qh = sqrt(ch2) - rayon; float d2 = qh*qh + ph*ph; return e*falloff2(d2,R); } } else{ vec3 pb = p-b; float ph = dot(pb, ab); //en dessus du disque de centre b if(ph>0.0){ if(ph >= R) return 0.0; float ch2 = dot(pb, pb) - ph*ph; if(ch2 < rayon*rayon) return e*falloff(ph,R); else if(ch2 >= (rayon+R)*(rayon+R)) return 0.0; else{ float qh = sqrt(ch2) - rayon; float d2 = qh*qh + ph*ph; return e*falloff2(d2,R); } } //entre les deux disque else{ vec3 tmp = b+ph*ab-p; float dist2 = dot(tmp,tmp); if(dist2 <= rayon*rayon) return e; else if(dist2 >= (rayon+R)*(rayon+R)) return 0.0; float d = sqrt(dist2)-rayon; return e*falloff(d,R); } } }
void plantTrees() { printf("planting trees: "); init_noise(treeSeed); srand(treeSeedPos); int i = 0; int j = 0; while(i < treeNumber) { if(j++ > 1024 * 1024 * 8) break; int x = rand() % 1024; int y = rand() % 1024; if(material[y][x] != GRASS) continue; double val = scaled_octave_noise_2d(treeOctaves, treeOctavePersistence, treeOctaveScale, 0.0, 1.0, (x - 512) * treeScale / 1024, (y - 512) * treeScale / 1024); if(treeFalloff) val *= falloff(x, y); if(treeValueInvert) val = 1.0 - val; if(val > treeDensity) { trees[i++] = ((top[y][x] - 1) << 20) + (y << 10) + x; material[y][x] = DIRT; } } if(i < treeNumber) { printf("\ncould only plant %d trees\n", i); treeNumber = i; } printf(" done.\n"); }
// r < R in [0, 1] inline double bump(double r, double R, double x, double y, double z) { double dx = x - 0.5; double dy = y - 0.5; double dz = z - 0.5; double t = std::sqrt(dx * dx + dy * dy + dz * dz); return falloff(r / 2, R / 2, t); }
// clou // p : point // a : extrémité 1 du segment // b : extrémité 2 du segment // e : energy associated to skeleton // R : segment radius float clou(in vec3 p, in vec3 a, in vec3 b, float r, float e, float R){ float d; vec3 ab = (b-a)/length(b-a); if(dot(p-a,ab)<-r){d=length(p-a)-r;} else if(dot(p-b,ab)>r){d=length(p-b);} else{ float t = dot(p-a,ab); d = length(a+t*ab-p); } return e*falloff(d,R); }
float SI_Sphere::potentiel(const Vector3D &p) const { float dist2 = p.Squaredistance(centre); if(dist2 >= englob.getRayon()*englob.getRayon()) return 0.f; else if(dist2 <= rayon*rayon) return e; float r = sqrt(dist2)-rayon;//interp::interp_linear1D(sqrt(dist2), 0.f, R, rayon, englob.getRayon()); return e*falloff(r,R); }
void generateIsland() { printf("generating island outline: "); init_noise(islandSeed); for(int y = 0; y < 1024; ++y) { for(int x = 0; x < 1024; ++x) { double val = scaled_octave_noise_2d(islandOctaves, islandOctavePersistence, islandOctaveScale, 0.0, 1.0, (x - 512) * islandScale / 1024, (y - 512) * islandScale / 1024); val *= falloff(x, y); if(val > (1.0 - islandDensity)) material[y][x] = GRASS; } } printf(" done.\n"); }
float vague(in vec3 p, in vec3 c, float rayon, float periode, float amplitude, float e, float R) { float d = 0.0; vec3 pos = vec3(c.x,0,c.z)-vec3(p.x,0,p.z); float dist2 = dot(pos,pos); if(dist2 > (rayon+R)*(rayon+R)) return 0.0; else if(dist2 > rayon*rayon) d += sqrt(dist2)-rayon; float val = sin(sqrt(dist2)/periode+iGlobalTime)*amplitude; //float val = cos(pos.x)+sin(pos.z); d += abs((p.y-c.y)-val); return e*falloff(d,R); }
// Disque // p : point // c : centre du disque // n : normal du disque // rayon : rayon du disque // e : energy associated to skeleton // R : segment radius float disque(in vec3 p, in vec3 c, in vec3 n, float rayon, float e, float R){ //n = normalize(n); vec3 pc = p-c; float ph = dot(n, pc); float ch = sqrt(dot(pc, pc) - ph*ph); float d; if(ch < rayon){ //le point est en dessus ou en dessous du disque d = abs(ph); } else{ float qh = ch - rayon; d = sqrt(qh*qh + ph*ph); } return e*falloff(d,R); }
// Cube // p : point // c : center of cube // e : energy associated to skeleton // R : distance au cube // cote : largeur cube float cube(vec3 p, vec3 c, vec3 cote, float e, float R) { p = abs(p - c); cote = cote/2.0; float val = 0.0; if(p.x > cote.x) val += (cote.x - p.x)*(cote.x - p.x); if(p.y > cote.y) val += (cote.y - p.y)*(cote.y - p.y); if(p.z > cote.z) val += (cote.z - p.z)*(cote.z - p.z); return e * falloff(val, R); }
//plus lent, tentative d'amélioration de la vitesse ratée. float disque2(in vec3 p, in vec3 c, in vec3 n, float rayon, float e, float R){ vec3 pc = p-c; float ph = abs(dot(n, pc)); if(ph >= R) return 0.0; float ch2 = dot(pc, pc) - ph*ph; if(ch2 <= rayon*rayon) //le point est en dessus ou en dessous du disque return e*falloff(ph,R); else if(ch2 >= (rayon+R)*(rayon+R)) return 0.0; else{ float qh = sqrt(ch2) - rayon; //le point est en dehors du rayon du disque if(qh >= R) return 0.0; float d2 = qh*qh + ph*ph; return e*falloff2(d2,R); } }
void generateTop() { printf("generating island top layer: "); init_noise(heightSeed); for(int y = 0; y < 1024; ++y) { for(int x = 0; x < 1024; ++x) { double val = scaled_octave_noise_2d(heightOctaves, heightOctavePersistence, heightOctaveScale, 0.0, 1.0, (x - 512) * heightScale / 1024, (y - 512) * heightScale / 1024); if(heightFalloff) val *= falloff(x, y); if(heightValueInvert) val = 1.0f - val; double height = pow(val, heightExponent); height = heightBase + (heightTop - heightBase) * height; if(material[y][x] != 0) { top[y][x] = height; fraction[y][x] = (height - top[y][x]) * 3.0 + 1.0; bottom[y][x] = top[y][x] - bottomMinThick; } } } printf(" done.\n"); }