This repository has been archived on 2024-07-18. You can view files and clone it, but cannot push or open issues or pull requests.
lwb5/planetgen/generate.pl

270 lines
6.7 KiB
Raku
Executable file

#!/usr/bin/perl
#
# Planet Generator
#
# Syntax: ./generate.pl <output>
#
# Generates a random POVRay script for a planet
#
sub genSingle
{
# Load template
open(TMPL, "<template.pov") or die "couldn't open template\n";
@tmpl = <TMPL>;
close TMPL;
# Generate texture
$pSize = sprintf("%.2f", 1 + rand() * 0.75);
@types = ("agate", "bozo", "granite", "wood");
$type = $types[int(rand() * @types)];
$ambient = rand() * .25;
$shining = rand() * .1;
$txt = "pigment {\n\t\t\t$type\n";
# Generate turbulence
@tm = (int(rand() * 3), int(rand() * 3), int(rand() * 3));
$toc = 1 + int(rand() * 3);
$tol = sprintf "%.2f", 1 + rand() * 2;
$too = sprintf "%.2f", 0.25 + rand() * 0.5;
$txt .= "\t\t\twarp { turbulence <" . join(",", @tm) . "> octaves $too lambda $tol omega $too }\n";
# Generate color map
$mainColor = int(rand() * 3);
$secColor = int(rand() * 3);
$nColors = int(rand() * 10) + 5;
$current = 0;
$txt .= "\t\t\tcolor_map {\n";
for ($i=0;$i<$nColors;$i++)
{
$mx = (1 - $current) / ($nColors - $i);
$cs = sprintf "%.2f", ($i == $nColors - 1) ? (1 - $current) : (rand() * $mx);
$cs += $current;
$txt .= "\t\t\t\t[$cs color rgb <";
@cg = map { sprintf "%.2f", $_ } (0.4 + rand() * 0.5, 0.2 + rand() * 0.5, rand() * 0.5);
@rc = ();
for ($j=0;$j<3;$j++)
{
$rc[$j] = ($mainColor == $j ? $cg[0] : ($secColor == $j ? $cg[1] : $cg[2]));
}
$txt .= join(",",@rc) . ">]\n";
$current = $cs;
}
$txt .= "\t\t\t}\n";
# Random pigment rotation
$txt .= "\t\t\trotate x * " . int(rand() * 360) . "\n";
$txt .= "\t\t\trotate y * " . int(rand() * 360) . "\n";
$txt .= "\t\t\trotate z * " . int(rand() * 360) . "\n";
$txt .= "\t\t}\n";
# Generate finish
$txt .= "\t\tfinish { ambient $ambient phong $shining }\n";
# Light source rotation
$lsr = int(rand() * 358);
open(TARGET, ">$ref") or die "couldn't create target file\n";
# Rings
if ($pSize < 1.25 && rand() < 0.5)
{
print TARGET "#declare RINGS = 1;\n";
$rhrad = $pSize + 0.05 + sprintf("%.2f", rand() * 0.2);
$rrad = $rhrad + 0.3 + sprintf("%.2f", rand() * 0.2);
$t = rand();
$b = 0.6 + rand() * 0.2;
if ($t < 0.25)
{
@cg = map { sprintf "%.2f", $_ } ($b + rand() * 0.1, $b + rand() * 0.05, $b);
@rc = ();
for ($j=0;$j<3;$j++)
{
$rc[$j] = ($mainColor == $j ? $cg[0] : ($secColor == $j ? $cg[1] : $cg[2]));
}
($rr, $rg, $rb, $rt) = (@rc,sprintf("%.2f",0.2+rand()*0.15));
}
else
{
($rr, $rg, $rb, $rt) = map { sprintf "%.2f", $_ } ($b,$b,$b,0.2+rand()*0.15);
}
$rcmap = "\t\t\t\t[0.00 color rgbt <$rr,$rg,$rb,1>]\n";
$rcmap .= "\t\t\t\t[0.05 color rgbt <$rr,$rg,$rb,$rt>]";
$acc = 0;
$n = 0.05;
$oldlv = 1;
while ($n < 0.99)
{
$n += 0.05;
$acc += rand();
next if $acc < (.5/($rrad-$rhrad));
$acc = 0;
do { $lv = 1 + int(rand() * 3); } while ($lv == $oldlv);
$oldlv = $lv;
$lv *= $rt;
($lv > 1) && ($lv = 1);
$rcmap .= "\n\t\t\t\t[" . sprintf("%.2f", $n) . " color rgbt <$rr,$rg,$rb,$lv>]";
}
$rcmap .= "\t\t\t\t[1.00 color rgbt <$rr,$rg,$rb,1>]\n";
do { $rrot = int(rand() * 60) - 30; } while (abs($rrot) < 10);
do { $rrot2 = int(rand() * 60) - 30; } while (abs($rrot2) < 10);
}
foreach $l (@tmpl)
{
$l =~ s/PSIZE/$pSize/;
$l =~ s/TEXTURE/$txt/;
$l =~ s/LSROT/$lsr/;
$l =~ s/RRAD/$rrad/;
$l =~ s/RHRAD/$rhrad/;
$l =~ s/RROTZ/$rrot/;
$l =~ s/RROTY/$rrot2/;
$l =~ s/RR/$rr/;
$l =~ s/RG/$rg/;
$l =~ s/RB/$rb/;
$l =~ s/RT/$rt/;
$l =~ s/RCMAP/$rcmap/;
print TARGET $l;
}
close TARGET;
}
sub genCluster
{
# Load template
open(TMPL, "<template2.pov") or die "couldn't open template\n";
@tmpl = <TMPL>;
close TMPL;
$nPlanets = 2 + int(rand() * 2);
$psBase = 1.2 / $nPlanets;
$psRand = 0.55 / $nPlanets;
$mainColor = int(rand() * 3);
@ps = @tx = @cx = @cy = @cz = ();
for ($p=0;$p<$nPlanets;$p++)
{
$pSize = sprintf("%.2f", $psBase + rand() * $psRand);
# Generate texture
@types = ("agate", "bozo", "granite", "wood");
$type = $types[int(rand() * @types)];
$ambient = rand() * .25;
$shining = rand() * .1;
$txt = "pigment {\n\t\t\t$type\n";
# Generate turbulence
@tm = (int(rand() * 3), int(rand() * 3), int(rand() * 3));
$toc = 1 + int(rand() * 3);
$tol = sprintf "%.2f", 1 + rand() * 2;
$too = sprintf "%.2f", 0.25 + rand() * 0.5;
$txt .= "\t\t\twarp { turbulence <" . join(",", @tm) . "> octaves $too lambda $tol omega $too }\n";
# Generate color map
$secColor = int(rand() * 3);
$nColors = int(rand() * 10) + 5;
$current = 0;
$txt .= "\t\t\tcolor_map {\n";
for ($i=0;$i<$nColors;$i++)
{
$mx = (1 - $current) / ($nColors - $i);
$cs = sprintf "%.2f", ($i == $nColors - 1) ? (1 - $current) : (rand() * $mx);
$cs += $current;
$txt .= "\t\t\t\t[$cs color rgb <";
@cg = map { sprintf "%.2f", $_ } (0.4 + rand() * 0.5, 0.2 + rand() * 0.5, rand() * 0.5);
@rc = ();
for ($j=0;$j<3;$j++)
{
$rc[$j] = ($mainColor == $j ? $cg[0] : ($secColor == $j ? $cg[1] : $cg[2]));
}
$txt .= join(",",@rc) . ">]\n";
$current = $cs;
}
$txt .= "\t\t\t}\n";
# Random pigment rotation
$txt .= "\t\t\trotate x * " . int(rand() * 360) . "\n";
$txt .= "\t\t\trotate y * " . int(rand() * 360) . "\n";
$txt .= "\t\t\trotate z * " . int(rand() * 360) . "\n";
$txt .= "\t\t}\n";
# Generate finish
$txt .= "\t\tfinish { ambient $ambient phong $shining }\n";
push @ps, $pSize;
push @tx, $txt;
}
# Generate coordinates
if ($nPlanets == 2)
{
$e = 1.5 - ($ps[0] + $ps[1]);
$w = ($e + rand() * $e) / 2;
@cx = ($w+$ps[0], -$w-$ps[1]);
@cy = @cz = (0, 0);
}
else
{
$e1 = $ps[0] + $ps[1];
$e2 = $ps[2] + $ps[1];
$e3 = $ps[0] + $ps[2];
$m = (($e1>$e2 && $e1>$e3) ? $e1 : (($e2>$e1 && $e2>$e3) ? $e2 : $e3));
$e = 1.3 - $m;
$w = ($e + rand() * $e) / 2;
$rw = $w + $m;
$d = $rw * cos(3.1415926535/6);
@cx = ($d, $d * cos(2*3.1415926535/3), $d * cos(4*3.1415926535/3));
@cy = (0, $d * sin(2*3.1415926535/3), $d * sin(4*3.1415926535/3));
@cz = (0, 0, 0);
}
$rotx = int(rand() * 360);
$roty = int(rand() * 360);
$rotz = int(rand() * 360);
print join(',', @cx) . "\n";
print join(',', @cy) . "\n";
# Light source rotation
$lsr = int(rand() * 358);
open(TARGET, ">$ref") or die "couldn't create target file\n";
foreach $l (@tmpl)
{
$l =~ s/LSROT/$lsr/;
$l =~ s/ROTX/$rotx/;
$l =~ s/ROTY/$roty/;
$l =~ s/ROTZ/$rotz/;
$l =~ s/NP;/$nPlanets;/;
for ($i=0;$i<$nPlanets;$i++)
{
$pSize = $ps[$i];
$txt = $tx[$i];
$x = $cx[$i];
$y = $cy[$i];
$z = $cz[$i];
$np = $i + 1;
$l =~ s/PSIZE$np/$pSize/;
$l =~ s/TEXTURE$np/$txt/;
$l =~ s/X$np/$x/;
$l =~ s/Y$np/$y/;
$l =~ s/Z$np/$z/;
}
print TARGET $l;
}
close TARGET;
}
$ref = $ARGV[0];
die "Syntax: $0 <output>\n" if $ref eq "";
if (rand() < 0.9) { genSingle(); }
else { genCluster(); }