]> git.mxchange.org Git - flightgear.git/blob - utils/Modeller/ac3d-despeckle
initial commit for a python based terrasync client
[flightgear.git] / utils / Modeller / ac3d-despeckle
1 #!/usr/bin/perl -w
2 # $Id$
3 # Melchior FRANZ  < mfranz # aon : at >  Public Domain
4 #
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.
11 #
12 use strict;
13
14 my $SELF = $0;
15 $SELF =~ s,.*\/,,;
16
17 my $VERBOSE = 0;
18 my $NOOP = 0;
19 my $TEXPATH = ".";
20
21 my $help = <<EOF;
22 Usage:
23         $SELF [-v] [-n] [-t <path>] <infile.ac >outfile.ac
24
25 Options:
26         -h          this help
27         -v          verbose output (also shows line numbers if used twice: -v -v)
28         -n          dry run
29         -t <path>   texture directory (default $TEXPATH)
30
31 Output:
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)
35 EOF
36
37
38 my $OBJECTNAME;
39 my $TEXTURE;
40 my $PIXW = 0;
41 my $PIXH = 0;
42
43 sub fatal($) {
44         die shift;
45 }
46
47 sub report($) {
48         print STDERR shift;
49         print STDERR "[$.] " if $VERBOSE > 1;
50 }
51
52
53 sub parse_args() {
54         while (@ARGV) {
55                 my $arg = shift @ARGV;
56                 if ($arg eq '-h' or $arg eq '--help') {
57                         print STDERR $help;
58                         exit 0;
59
60                 } elsif ($arg eq '-v' or $arg eq '--verbose') {
61                         $VERBOSE++;
62
63                 } elsif ($arg eq '-n' or $arg eq '--dry-run') {
64                         $NOOP = 1;
65
66                 } elsif ($arg eq '-t') {
67                         $arg = shift @ARGV;
68                         defined $arg or fatal('-t option without <text> argument');
69                         $TEXPATH = $arg;
70                 }
71         }
72 }
73
74
75 sub sgisize($) {
76         my $name = shift;
77         my $i;
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': $!");
81         read(IMG, $i, 2);
82         unpack("n", $i) == 474 or fatal("'$name' cannot be an SGI image (wrong magic number)");
83
84         my ($x, $y);
85         seek(IMG, 6, 0);
86         read(IMG, $x, 2);
87         read(IMG, $y, 2);
88         close IMG or fatal("cannot close file '$name': $!");
89         return (unpack("n", $x), unpack("n", $y));
90 }
91
92
93
94
95 # main()
96
97 parse_args();
98 print STDERR "\033[35mTEXTURE PATH: $TEXPATH\033[m" if $VERBOSE;
99
100
101 while (<>) {
102         if (/^OBJECT /) {
103                 undef $TEXTURE;
104
105         } elsif (/^name\s+(.*)/) {
106                 $OBJECTNAME = $1;
107                 $OBJECTNAME =~ /"(.*)"/ and $OBJECTNAME = $1;
108                 print STDERR "\033[35;1m\nNAME: $OBJECTNAME\033[m " if $VERBOSE;
109
110         } elsif (/^texture\s+(.*)/) {
111                 $TEXTURE = $1;
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;
117
118         } elsif (/^SURF /) {
119                 print $_ unless $NOOP;
120
121                 my $mat = <>;
122                 $mat =~ /^mat / or fatal("line $.: mat entry missing");
123                 print $mat unless $NOOP;
124
125                 my $refs = <>;
126                 $refs =~ /^refs\s+(\d+)/ or fatal("line $.: refs entry missing");
127                 print $refs unless $NOOP;
128                 my $n = $1;
129
130                 if ($n < 3 or $n > 4) {
131                         report("?") if $VERBOSE;
132                         unless ($NOOP) {
133                                 print scalar(<>) foreach (1 .. $n);
134                         }
135                         next;
136                 }
137
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;
143
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]);
146
147
148                 if (defined $TEXTURE) {
149                         report("#") if $VERBOSE;
150
151                         my ($x, $y) = @ref0[1, 2];
152
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;
157
158                         $x = int($x / $PIXW) * $PIXW;
159                         $y = int($y / $PIXH) * $PIXH;
160
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;
165
166                 } else {
167                         report(".") if $VERBOSE;
168                 }
169
170
171 writeuv:
172                 unless ($NOOP) {
173                         print join " ", @ref0;
174                         print "\n";
175                         print join " ", @ref1;
176                         print "\n";
177                         print join " ", @ref2;
178                         print "\n";
179                         if ($n == 4) {
180                                 print join " ", @ref3;
181                                 print "\n";
182                         }
183                 }
184                 next;
185         }
186         print unless $NOOP;
187 }
188
189 print STDERR "\n" if $VERBOSE;
190 exit 0;
191
192
193