3 # Melchior FRANZ < mfranz # aon : at > Public Domain
5 # Older nVidia cards like the GF4 MX440 don't like UV faces
6 # where all coordinates are equal, and thus don't have an area.
7 # This leads to grey spots that are constantly going on and off.
8 # The script fixes UV faces with 3 and 4 references by assigning
9 # a one (half)pixel sized area, and moves coordinates into the
10 # texture area if necessary.
23 $SELF [-v] [-n] [-t <path>] <infile.ac >outfile.ac
27 -v verbose output (also shows line numbers if used twice: -v -v)
29 -t <path> texture directory (default $TEXPATH)
32 # BAD (face with identical UV coords; will be fixed)
33 ? CHECK (only two UV coordinates or more than 4; could be a problem)
34 . OK (wrong coordinates, but no texture assigned; ignore)
49 print STDERR "[$.] " if $VERBOSE > 1;
55 my $arg = shift @ARGV;
56 if ($arg eq '-h' or $arg eq '--help') {
60 } elsif ($arg eq '-v' or $arg eq '--verbose') {
63 } elsif ($arg eq '-n' or $arg eq '--dry-run') {
66 } elsif ($arg eq '-t') {
68 defined $arg or fatal('-t option without <text> argument');
78 -f $name or fatal("cannot find texture '$name'");
79 -s $name > 512 or fatal("'$name' cannot be an SGI image (too small)");
80 open(IMG, "<$name") || fatal("cannot open file '$name': $!");
82 unpack("n", $i) == 474 or fatal("'$name' cannot be an SGI image (wrong magic number)");
88 close IMG or fatal("cannot close file '$name': $!");
89 return (unpack("n", $x), unpack("n", $y));
98 print STDERR "\033[35mTEXTURE PATH: $TEXPATH\033[m" if $VERBOSE;
105 } elsif (/^name\s+(.*)/) {
107 $OBJECTNAME =~ /"(.*)"/ and $OBJECTNAME = $1;
108 print STDERR "\033[35;1m\nNAME: $OBJECTNAME\033[m " if $VERBOSE;
110 } elsif (/^texture\s+(.*)/) {
112 $TEXTURE =~ /"(.*)"/ and $TEXTURE = $1;
113 my ($WIDTH, $HEIGHT) = sgisize($TEXPATH . '/' . $TEXTURE);
114 print STDERR "\033[33;1m\nTEXTURE: $TEXTURE ($WIDTH x $HEIGHT)\033[m " if $VERBOSE;
115 $PIXW = 1.0 / $WIDTH;
116 $PIXH = 1.0 / $HEIGHT;
119 print $_ unless $NOOP;
122 $mat =~ /^mat / or fatal("line $.: mat entry missing");
123 print $mat unless $NOOP;
126 $refs =~ /^refs\s+(\d+)/ or fatal("line $.: refs entry missing");
127 print $refs unless $NOOP;
130 if ($n < 3 or $n > 4) {
131 report("?") if $VERBOSE;
133 print scalar(<>) foreach (1 .. $n);
138 my (@ref0, @ref1, @ref2, @ref3);
139 @ref0 = split /\s+/, <>;
140 @ref1 = split /\s+/, <>;
141 @ref2 = split /\s+/, <>;
142 @ref3 = split /\s+/, <> if $n == 4;
144 goto writeuv if $ref0[1] != $ref1[1] or $ref0[2] != $ref1[2] or $ref1[1] != $ref2[1] or $ref1[2] != $ref2[2];
145 goto writeuv if $n == 4 and ($ref2[1] != $ref3[1] or $ref2[2] != $ref3[2]);
148 if (defined $TEXTURE) {
149 report("#") if $VERBOSE;
151 my ($x, $y) = @ref0[1, 2];
153 $x = 0.0 if $x < 0.0;
154 $x = 1.0 - $PIXW if $x > 1.0 - $PIXW;
155 $y = 0.0 if $y < 0.0;
156 $y = 1.0 - $PIXH if $y > 1.0 - $PIXH;
158 $x = int($x / $PIXW) * $PIXW;
159 $y = int($y / $PIXH) * $PIXH;
161 $ref0[1] = $x, $ref0[2] = $y;
162 $ref1[1] = $x + $PIXW;
163 $ref2[1] = $x + $PIXW, $ref2[2] = $y + $PIXH;
164 $ref3[2] = $y + $PIXH if $n == 4;
167 report(".") if $VERBOSE;
173 print join " ", @ref0;
175 print join " ", @ref1;
177 print join " ", @ref2;
180 print join " ", @ref3;
189 print STDERR "\n" if $VERBOSE;