#!/usr/bin/gawk -f # reinhard@finalmedia.de # Public Domain # Mushroom Cloud als minimalistisches Partikelsystem BEGIN { if (!width) width=ENVIRON["SCREEN_WIDTH"]; if (!height) height=ENVIRON["SCREEN_HEIGHT"]; if (!width) width = 1920; if (!height) height = 1080; cx = width / 2; cy = height / 2; MAX_PARTICLES = 1200; cam_angle = 0.35; cosA = cos(cam_angle); sinA = sin(cam_angle); global_time = 0; while (1) { print "c 0 0 0"; print "m 0 0"; print "r " width " " height; global_time++; if (global_time < 90) { spawns = 0; for (i = 0; i < MAX_PARTICLES; i++) { if (p_active[i] == 0 && spawns < 10) { p_active[i] = 1; p_x[i] = (rand() - 0.5) * 6; p_y[i] = 0; p_z[i] = (rand() - 0.5) * 6; p_vy[i] = 9.0 + rand() * 5.0; p_angle[i] = rand() * 6.28; p_age[i] = 0; p_max_age[i] = 80 + rand() * 40; spawns++; } } } active_count = 0; for (i = 0; i < MAX_PARTICLES; i++) { if (p_active[i] == 0) continue; active_count++; p_age[i]++; if (p_age[i] >= p_max_age[i]) { p_active[i] = 0; continue; } life = p_age[i] / p_max_age[i]; if (life < 0.20) { p_y[i] += p_vy[i]; p_size[i] = 10 + (p_y[i] * 0.45); if (p_size[i] > 60) p_size[i] = 60; p_x[i] += cos(p_angle[i]) * (p_y[i] * 0.02); p_z[i] += sin(p_angle[i]) * (p_y[i] * 0.02); } else if (life < 0.70) { p_vy[i] *= 0.80; p_y[i] += p_vy[i] * 0.3; drift = 16.0 * sin((life - 0.20) * 3.14); p_x[i] += cos(p_angle[i]) * drift; p_z[i] += sin(p_angle[i]) * drift; p_size[i] = 60 + ((life - 0.20) * 320); } else { p_y[i] -= 1.0; p_x[i] += cos(p_angle[i]) * 1.5; p_z[i] += sin(p_angle[i]) * 1.5; p_size[i] = 220 + (1.0 - life) * 30; } total_progress = global_time / 220; if (total_progress > 1.0) total_progress = 1.0; x3d = p_x[i]; y3d = p_y[i] * cosA - p_z[i] * sinA; z3d = 850 + (p_y[i] * sinA + p_z[i] * cosA); K1 = width * 1.1; sx = int(x3d * K1 / z3d + cx); sy = int(-y3d * K1 / z3d + cy) + int(height * 0.40); if (sx >= 0 && sx < width && sy >= 0 && sy < height) { depth_shade = (1200 - z3d) / 500; if (depth_shade < 0.2) depth_shade = 0.2; if (depth_shade > 1.0) depth_shade = 1.0; if (life < 0.08 && total_progress < 0.4) { r = int(255 * (1.0 - total_progress)); g = int(240 * (1.0 - total_progress)); b = int(160 * (1.0 - total_progress)); } else if (life < 0.40) { r = int(255 * depth_shade * (1.0 - total_progress * 0.5)); g = int(190 * depth_shade * (1.0 - (life - 0.08) * 1.8)); if (g < 40) g = 40; b = int(30 * depth_shade); } else { fade = 1.0 - (life - 0.40) * 1.6; fade *= (1.0 - total_progress); if (fade < 0.0) fade = 0.0; r = int(120 * fade * depth_shade); g = int(45 * fade * depth_shade); b = int(5 * fade); } sz = int(p_size[i] * K1 / z3d); if (sz < 6) sz = 6; sx_offset = int(sx - sz / 2); sy_offset = int(sy - sz / 2); if (r > 5) { print "c " r " " g " " b; print "m " sx_offset " " sy_offset; print "r " sz " " sz; } } } if (global_time > 90 && active_count == 0) { global_time = 0; } print "s 16666"; fflush(); } }