static void add_bump(union vec3 p, float r, float h) { struct bump *b; const union vec3 right_at_ya = { { 0.0f, 0.0f, 1.0f } }; const union vec3 up = { { 0.0f, 1.0f, 0.0f } }; if (totalbumps >= MAXBUMPS) return; b = &bumplist[totalbumps]; b->p = p; b->r = r; b->h = h; b->tx = (int) ((float) samplew / RADII + 0.5 * snis_random_float() * (RADII - 2.0f) / RADII * (float) samplew); b->ty = (int) ((float) sampleh / RADII + 0.5 * snis_random_float() * (RADII - 2.0f) / RADII * (float) sampleh); if (samplew < sampleh) b->ts = samplew / RADII; else b->ts = sampleh / RADII; b->sampledata = sampledata; b->samplew = samplew; b->sampleh = sampleh; b->sample_bytes_per_row = sample_bytes_per_row; b->is_crater = 0; quat_from_u2v(&b->texelq, &p, &right_at_ya, &up); totalbumps++; }
static void add_crater(int i, union vec3 p, float r, float h) { struct bump *b; const union vec3 right_at_ya = { { 0.0f, 0.0f, 1.0f } }; const union vec3 up = { { 0.0f, 1.0f, 0.0f } }; float crater_r; b = &craterlist[i]; b->is_crater = 1; b->p = p; b->r = r; b->h = h; b->tx = 512; b->ty = 512; b->ts = 512; b->sampledata = malloc(3 * 1024 * 1024); memset(b->sampledata, crater_base_level, 3 * 1024 * 1024); b->samplew = 1024; b->sampleh = 1024; b->sample_bytes_per_row = 3 * b->samplew; crater_r = (0.5 * (snis_random_float() + 1.0) * 5.5) * (0.5 * (snis_random_float() + 1.0) * 5.5) + 2.5; create_crater_heightmap((unsigned char *) b->sampledata, 1024, 1024, 512, 512, (int) crater_r, 3); quat_from_u2v(&b->texelq, &p, &right_at_ya, &up); }
static void __attribute__((unused)) uniform_random_point_in_spehere(float r, float *x, float *y) { float a = M_PI * snis_random_float(); r = r * sqrt(fabs(snis_random_float())); *x = r * cos(a); *y = r * sin(a); }
/* return a random point in an annulus on a plane in 3d, r1=inner radius, r2=outer radius, c=center, n=normal */ void random_point_in_3d_annulus(float r1, float r2, const union vec3 *center, const union vec3 *u, const union vec3 *v, union vec3 *point) { float angle = snis_random_float() * M_PI; float r = fabs(snis_random_float()) * (r2 - r1) + r1; point->v.x = center->v.x + r * cos(angle) * u->v.x + r * sin(angle) * v->v.x; point->v.y = center->v.y + r * cos(angle) * u->v.y + r * sin(angle) * v->v.y; point->v.z = center->v.z + r * cos(angle) * u->v.z + r * sin(angle) * v->v.z; }
struct mesh *init_burst_rod_mesh(int streaks, double h, double r1, double r2) { struct mesh *my_mesh = malloc(sizeof(*my_mesh)); if (!my_mesh) return my_mesh; memset(my_mesh, 0, sizeof(*my_mesh)); my_mesh->geometry_mode = MESH_GEOMETRY_PARTICLE_ANIMATION; my_mesh->nlines = streaks; my_mesh->nvertices = my_mesh->nlines * 2; my_mesh->ntriangles = 0; my_mesh->t = 0; my_mesh->v = malloc(sizeof(*my_mesh->v) * my_mesh->nvertices); my_mesh->l = malloc(sizeof(*my_mesh->l) * my_mesh->nlines); my_mesh->tex = 0; my_mesh->radius = fmax(sqrt(h * h / 4.0 + r1 * r1), sqrt(h * h / 4.0 + r2 * r2)); my_mesh->graph_ptr = 0; int line_index; for (line_index = 0; line_index < streaks; line_index++) { float p = fabs(snis_random_float()); float pr = p * (r2 - r1) + r1; float ph = p * h - h / 2.0; float pa = fabs(snis_random_float()) * 2.0 * M_PI; int v_index = line_index * 2; my_mesh->v[v_index + 0].x = ph; my_mesh->v[v_index + 0].y = 0; my_mesh->v[v_index + 0].z = 0; my_mesh->v[v_index + 1].x = ph; my_mesh->v[v_index + 1].y = sin(pa) * pr; my_mesh->v[v_index + 1].z = cos(pa) * pr; my_mesh->l[line_index].start = &my_mesh->v[v_index + 0]; my_mesh->l[line_index].end = &my_mesh->v[v_index + 1]; my_mesh->l[line_index].flag = 0; my_mesh->l[line_index].additivity = 1.0; my_mesh->l[line_index].opacity = 1.0; my_mesh->l[line_index].tint_color.red = 1.0; my_mesh->l[line_index].tint_color.green = 1.0; my_mesh->l[line_index].tint_color.blue = 1.0; my_mesh->l[line_index].time_offset = fabs(snis_random_float()); } mesh_graph_dev_init(my_mesh); return my_mesh; }
static void create_particle(float h, float r1, struct particle *particles, int i) { particles[i].offset = fabs(snis_random_float()); particles[i].lifetime = fabs(snis_random_float()); particles[i].decay = 0.1; particles[i].xpos = 0.0; particles[i].ypos = 0.0; particles[i].zpos = 0.0; /* uniform_random_point_in_spehere(r1 * 0.1, &particles[i].yspeed, &particles[i].zspeed); */ particles[i].xspeed = -fabs(snis_random_float()) * h * 0.1; particles[i].yspeed = 0; particles[i].zspeed = 0; particles[i].active = 1; }
void create_crater_heightmap(unsigned char *image, int imagew, int imageh, int x, int y, int r, int h) { int i, npoints = (int) (1.7 * (M_PI * 2.0 * r)); float angle; crater_dimple(image, imagew, imageh, x, y, r * 0.95, base_level); for (i = 0; i < npoints; i++) { int tx, ty; angle = (2.0 * M_PI * i) / (float) npoints + snis_random_float() * 10.0 * M_PI / 180.0; tx = x + cos(angle) * r + snis_random_float() * snis_random_float() * r * 3.9; ty = y - sin(angle) * r + snis_random_float() * snis_random_float() * r * 3.9; add_cone(image, imagew, imageh, tx, ty, (0.2 + 0.50 * zerotoone()) * r, h); } add_rays(image, imagew, imageh, x, y, r, h * 2.75, 50 + snis_randn(350)); }
static void recursive_add_bump(union vec3 pos, float r, float h, float shrink, float rlimit) { float hoffset; add_bump(pos, r, h); if (r * shrink < rlimit) return; for (int i = 0; i < nbumps; i++) { union vec3 d; d.v.x = snis_random_float() * r * scatterfactor; d.v.y = snis_random_float() * r * scatterfactor; d.v.z = snis_random_float() * r * scatterfactor; vec3_add_self(&d, &pos); vec3_normalize_self(&d); hoffset = snis_random_float() * h * shrink * 0.5; recursive_add_bump(d, r * shrink, h * (shrink + 0.5 * (1.0 - shrink)) + hoffset, shrink, rlimit); } }
static void add_ray(unsigned char *image, int imagew, int imageh, int x, int y, int r, int h) { int i; int npoints = snis_randn(100); float angle = snis_random_float() * 2.0 * M_PI; float radius = r; float con_rad = radius * 0.1; float tx, ty; float height = h; for (i = 0; i < npoints; i++) { tx = x + cos(angle) * radius; ty = y - sin(angle) * radius; add_cone(image, imagew, imageh, tx, ty, (int) con_rad, height); con_rad = con_rad * 0.98; height = height * (0.9 + 0.08 * zerotoone()); radius = radius + zerotoone() * r * 0.3; } }
static void add_bumps(const int initial_bumps) { int i; float h; if (nbumps == 1) /* If we're not doing any recursive bumps, then make the bumps taller */ h = 0.3; else h = 0.1; printf("adding bumps:"); for (i = 0; i < initial_bumps; i++) { union vec3 p; float r = 0.5 * (snis_random_float() + 1.0f) * initial_bump_size; random_point_on_sphere(1.0, &p.v.x, &p.v.y, &p.v.z); recursive_add_bump(p, r, h, shrink_factor, rlimit); printf("."); fflush(stdout); } printf("\n"); }
static float zerotoone() { return 0.5 * (1.0 + snis_random_float()); }