r5149 - trunk/misc

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Tue Dec 2 08:27:17 EST 2008


Author: div0
Date: 2008-12-02 08:27:17 -0500 (Tue, 02 Dec 2008)
New Revision: 5149

Modified:
   trunk/misc/bsptool.pl
   trunk/misc/dependencies.pl
   trunk/misc/jpeg-if-not-alpha.sh
Log:
simple lightmap decimator


Modified: trunk/misc/bsptool.pl
===================================================================
--- trunk/misc/bsptool.pl	2008-12-01 14:53:32 UTC (rev 5148)
+++ trunk/misc/bsptool.pl	2008-12-02 13:27:17 UTC (rev 5149)
@@ -29,7 +29,6 @@
 	read $fh, my $lump, 8;
 	my ($offset, $length) = unpack "VV", $lump;
 
-	print STDERR "BSP lump $_ ($lumpname[$_]): offset $offset length $length\n";
 	push @bsp, [$offset, $length, undef];
 }
 
@@ -95,12 +94,91 @@
 	@decoded;
 }
 
+sub EncodeLump($@)
+{
+	my ($items, @fields) = @_;
+	my @decoded;
+
+	my @encoders;
+
+	my $item;
+	my @data;
+	my $idx;
+	my $data = "";
+
+	for(@fields)
+	{
+		if(/^(\w*)=(.*?)(\d*)$/)
+		{
+			my $spec = "$2$3";
+			my $f = $1;
+			my $n = $3;
+			if($n eq '')
+			{
+				push @encoders, sub { $data .= pack $spec, $item->{$f}; };
+			}
+			else
+			{
+				push @encoders, sub { $data .= pack $spec, @{$item->{$f}}; };
+			}
+		}
+	}
+
+	for my $i(@$items)
+	{
+		$item = $i;
+		$_->() for @encoders;
+	}
+
+	$data;
+}
+
+sub EncodeDirection(@)
+{
+	my ($x, $y, $z) = @_;
+
+	return [
+		map { ($_ / 0.02454369260617025967) & 0xFF }
+		(
+			atan2(sqrt($x * $x + $y * $y), $z),
+			atan2($y, $x)
+		)
+	];
+}
+
+sub DecodeDirection($)
+{
+	my ($dir) = @_;
+
+	my ($pitch, $yaw) = map { $_ * 0.02454369260617025967 } @$dir; # maps 256 to 2pi
+
+	return (
+		cos($yaw) * sin($pitch),
+		sin($yaw) * sin($pitch),
+		cos($pitch)
+	);
+}
+
 # OPTIONS
 
 for(@ARGV)
 {
-	if(/^-d(.+)$/) # delete a lump
+	if(/^-i$/) # info
 	{
+		my $total = 17 * 8 + 8 + length($msg);
+		my $max = 0;
+		for(0.. at bsp-1)
+		{
+			my $nl = length $bsp[$_]->[2];
+			$total += $nl;
+			print "BSP lump $_ ($lumpname[$_]): offset $bsp[$_]->[0] length $bsp[$_]->[1] newlength $nl\n";
+			my $endpos = $bsp[$_]->[0] + $bsp[$_]->[1];
+			$max = $endpos if $max < $endpos;
+		}
+		print "BSP file size will change from $max to $total bytes\n";
+	}
+	elsif(/^-d(.+)$/) # delete a lump
+	{
 		my $id = $lumpid{$1};
 		die "invalid lump $1 to remove"
 			unless defined $id;
@@ -155,8 +233,9 @@
 		# nullify the lightmap lump
 		$bsp[$lumpid{lightmaps}]->[2] = "";
 	}
-	elsif(/^-g$/) # decimate light grid
+	elsif(/^-g(.+)$/) # export light grid as an image (for debugging)
 	{
+		my $filename = $1;
 		my @models = DecodeLump $bsp[$lumpid{models}]->[2],
 			qw/mins=f3 maxs=f3 face=V n_faces=V brush=V n_brushes=V/;
 		my $entities = $bsp[$lumpid{entities}]->[2];
@@ -178,8 +257,155 @@
 		die "Cannot decode light grid"
 			unless $isize == @gridcells;
 
-		# TODO now decimate it and reinsert the lump (and the changed entity lump for the new size)
+		# sum up the "ambient" light over all pixels
+		my @pixels;
+		my $max = 1;
+		for my $y(0..$isize[1]-1)
+		{
+			for my $x(0..$isize[0]-1)
+			{
+				my ($r, $g, $b) = (0, 0, 0);
+				for my $z(0..$isize[2]-1)
+				{
+					my $cell = $gridcells[$x + $y * $isize[0] + $z * $isize[0] * $isize[1]];
+					$r += $cell->{ambient}->[0];
+					$g += $cell->{ambient}->[1];
+					$b += $cell->{ambient}->[2];
+				}
+				push @pixels, [$r, $g, $b];
+				$max = $r if $max < $r;
+				$max = $g if $max < $g;
+				$max = $b if $max < $b;
+			}
+		}
+		my $pixeldata = "";
+		for my $p(@pixels)
+		{
+			$pixeldata .= pack "CCC", map { 255 * $p->[$_] / $max } 0..2;
+		}
+
+		my $img = Image::Magick->new(size => sprintf("%dx%d", $isize[0], $isize[1]), depth => 8, magick => 'RGB');
+		$img->BlobToImage($pixeldata);
+		$img->Write($filename);
+		print STDERR "Wrote $filename\n";
 	}
+	elsif(/^-G(.+)$/) # decimate light grid
+	{
+		my $decimate = $1;
+		my $filter = 0.5;
+
+		my @models = DecodeLump $bsp[$lumpid{models}]->[2],
+			qw/mins=f3 maxs=f3 face=V n_faces=V brush=V n_brushes=V/;
+		my $entities = $bsp[$lumpid{entities}]->[2];
+		my @entitylines = split /\r?\n/, $entities;
+		my $gridsize = "64 64 128";
+		my $gridsizeindex = undef;
+		for(0.. at entitylines-1)
+		{
+			my $l = $entitylines[$_];
+			last if $l eq '}';
+			if($l =~ /^\s*"gridsize"\s+"(.*)"$/)
+			{
+				$gridsize = $1;
+				$gridsizeindex = $_;
+			}
+		}
+		my @scale = map { 1 / $_ } split / /, $gridsize;
+		my @imins = map { ceil($models[0]{mins}[$_] * $scale[$_]) } 0..2;
+		my @imaxs = map { floor($models[0]{maxs}[$_] * $scale[$_]) } 0..2;
+		my @isize = map { $imaxs[$_] - $imins[$_] + 1 } 0..2;
+		my $isize = $isize[0] * $isize[1] * $isize[2];
+		my @gridcells = DecodeLump $bsp[$lumpid{lightgrid}]->[2],
+			qw/ambient=C3 directional=C3 dir=C2/;
+		die "Cannot decode light grid"
+			unless $isize == @gridcells;
+
+		# get the new grid size values
+		my @newscale = map { $_ / $decimate } @scale;
+		my $newgridsize = join " ", map { 1 / $_ } @newscale;
+		my @newimins = map { ceil($models[0]{mins}[$_] * $newscale[$_]) } 0..2;
+		my @newimaxs = map { floor($models[0]{maxs}[$_] * $newscale[$_]) } 0..2;
+		my @newisize = map { $newimaxs[$_] - $newimins[$_] + 1 } 0..2;
+
+		# do the decimation
+		my @newgridcells = ();
+		for my $z($newimins[2]..$newimaxs[2])
+		{
+			# the coords are MIDPOINTS of the grid cells!
+			my @oldz = grep { $_ >= $imins[2] && $_ <= $imaxs[2] } floor(($z - 0.5) * $decimate + 0.5) .. ceil(($z + 0.5) * $decimate - 0.5);
+			my $innerz_raw = $z * $decimate;
+			my $innerz = floor($innerz_raw + 0.5);
+			$innerz = $imins[2] if $innerz < $imins[2];
+			$innerz = $imaxs[2] if $innerz > $imaxs[2];
+			for my $y($newimins[1]..$newimaxs[1])
+			{
+				my @oldy = grep { $_ >= $imins[1] && $_ <= $imaxs[1] } floor(($y - 0.5) * $decimate + 0.5) .. ceil(($y + 0.5) * $decimate - 0.5);
+				my $innery_raw = $y * $decimate;
+				my $innery = floor($innery_raw + 0.5);
+				$innery = $imins[1] if $innery < $imins[1];
+				$innery = $imaxs[1] if $innery > $imaxs[1];
+				for my $x($newimins[0]..$newimaxs[0])
+				{
+					my @oldx = grep { $_ >= $imins[0] && $_ <= $imaxs[0] } floor(($x - 0.5) * $decimate + 0.5) .. ceil(($x + 0.5) * $decimate - 0.5);
+					my $innerx_raw = $x * $decimate;
+					my $innerx = floor($innerx_raw + 0.5);
+					$innerx = $imins[0] if $innerx < $imins[0];
+					$innerx = $imaxs[0] if $innerx > $imaxs[0];
+
+					my @vec = (0, 0, 0);
+					my @dir = (0, 0, 0);
+					my @amb = (0, 0, 0);
+					my $weight = 0;
+					my $innercell = $gridcells[($innerx - $imins[0]) + $isize[0] * ($innery - $imins[1]) + $isize[0] * $isize[1] * ($innerz - $imins[2])];
+					for my $Z(@oldz)
+					{
+						for my $Y(@oldy)
+						{
+							for my $X(@oldx)
+							{
+								my $cell = $gridcells[($X - $imins[0]) + $isize[0] * ($Y - $imins[1]) + $isize[0] * $isize[1] * ($Z - $imins[2])];
+								$dir[$_] += $cell->{directional}->[0] for 0..2;
+								$amb[$_] += $cell->{ambient}->[0] for 0..2;
+								my @norm = DecodeDirection $cell->{dir};
+								$vec[$_] += $norm[$_] for 0..2;
+								++$weight;
+							}
+						}
+					}
+					if($weight)
+					{
+						$amb[$_] /= $weight for 0..2;
+						$amb[$_] *= $filter for 0..2;
+						$amb[$_] += (1 - $filter) * $innercell->{ambient}->[$_] for 0..2;
+
+						$dir[$_] /= $weight for 0..2;
+						$dir[$_] *= $filter for 0..2;
+						$dir[$_] += (1 - $filter) * $innercell->{directional}->[$_] for 0..2;
+
+						my @norm = DecodeDirection $innercell->{dir};
+						$vec[$_] /= $weight for 0..2;
+						$vec[$_] *= $filter for 0..2;
+						$vec[$_] += (1 - $filter) * $norm[$_] for 0..2;
+
+						$innercell = {
+							ambient => \@amb,
+							directional => \@dir,
+							dir => EncodeDirection @norm
+						};
+					}
+
+					push @newgridcells, $innercell;
+				}
+			}
+		}
+
+		$bsp[$lumpid{lightgrid}]->[2] = EncodeLump \@newgridcells,
+			qw/ambient=C3 directional=C3 dir=C2/;
+		splice @entitylines, $gridsizeindex, 1, ()
+			if defined $gridsizeindex;
+		splice @entitylines, 1, 0, qq{"gridsize" "$newgridsize"};
+		$bsp[$lumpid{entities}]->[2] = join "\n", @entitylines;
+	}
 	elsif(/^-x(.+)$/) # extract lump to stdout
 	{
 		my $id = $lumpid{$1};

Modified: trunk/misc/dependencies.pl
===================================================================
--- trunk/misc/dependencies.pl	2008-12-01 14:53:32 UTC (rev 5148)
+++ trunk/misc/dependencies.pl	2008-12-02 13:27:17 UTC (rev 5149)
@@ -231,6 +231,7 @@
 	AddFile "maps/$b.jpg";
 	AddFile "maps/$b.cfg";
 	AddFile "maps/$b.waypoints";
+	AddFile "maps/$b.rtlights";
 	AddTexture "gfx/$b\_radar.tga";
 	AddTexture "gfx/$b\_mini.tga";
 

Modified: trunk/misc/jpeg-if-not-alpha.sh
===================================================================
--- trunk/misc/jpeg-if-not-alpha.sh	2008-12-01 14:53:32 UTC (rev 5148)
+++ trunk/misc/jpeg-if-not-alpha.sh	2008-12-02 13:27:17 UTC (rev 5149)
@@ -7,13 +7,13 @@
 for X in "$@"; do
 	case "$X" in
 		*.jpg)
-			jpegoptim --strip-all "$X"
+			jpegoptim --strip-all -m$qual "$X"
 			;;
 		*.png|*.tga)
 			if convert "$X" -depth 16 RGBA:- | perl -e 'local $/ = \8; while(<>) { substr($_, 6, 2) eq "\xFF\xFF" or exit 1; ++$pix; } END { exit not $pix; }'; then
 				echo "$X has no alpha, converting"
-				convert "$X" -quality $qual "${X%.*}.jpg"
-				jpegoptim --strip-all "${X%.*}.jpg"
+				convert "$X" -quality 100 "${X%.*}.jpg"
+				jpegoptim --strip-all -m$qual "${X%.*}.jpg"
 				rm -f "$X"
 			else
 				echo "$X has alpha, not converting"




More information about the nexuiz-commits mailing list