#!/usr/bin/perl # map2vrml.pl by Andrew Daviel, Vancouver Webpages, 1996 # # Converts NCSA style imagemap file to VRML # see http://Vancouver-Webpages.com/vrml/map2vrml.html # # Color map for mapping color names to RGB values %color = ("blue","0 0 1","red","1 0 0","green","0 1 0", "white","1 1 1", "black","0 0 0") ; $color = "blue" ; # default color for all objects $height = 30 ; # default height for all objects $base = 0 ; # default base (z-coordinate) for all objects $anchor = 0 ; # default is not to generate anchor $noroof = 0 ; # default is to roof in polygons $xscale = 1 ; $yscale = 1 ; # default x,y scaling $xoffset = 0 ; $yoffset = 0 ; $piby2 = atan2(1,0) ; $pi180 = $piby2 /90 ; if (@ARGV[0] =~ /-h/i) { print "Usage: $0 < mapfile > vrmlfile\n"; exit ; } # if supported, get X11 colors using "showrgb" # colors have names like "PaleGreen", "MediumTurquoise" $_ = `showrgb` ; @lines = split(/\n/) ; foreach $line (@lines) { $line =~ tr/\t//s ; @field = split(/\t/,$line) ; if (!($field[1] =~ / /)) { $field[0] =~ tr/ //s ; $field[0] =~ s/^ // ; @rgb = split(/ /,$field[0]) ; for ($i=0; $i<=2;$i++) { $rgb[$i] = $rgb[$i]/255 ; $RGB[$i] = sprintf("%5.3f",$rgb[$i]) ; } $color{$field[1]} = join(' ',@RGB) ; } } # # print standard header for standalone file. May be removed for # building more complex world. # print <) { chop ; $raw = $_ ; tr/ //s ; # squeeze spaces if (/^rect/) { # # process rectangle - create cuboid with current height, color # @f = split(/ /) ; $name = $f[1] ; @xy = split(/,/,$f[2]) ; $x1 = $xy[0] * $xscale + $xoffset ; $y1 = -$xy[1] * $yscale + $yoffset ; @xy = split(/,/,$f[3]) ; $x2 = $xy[0] * $xscale + $xoffset ; $y2 = -$xy[1] * $yscale + $yoffset ; print " Separator {\n"; if ($anchor) { print " WWWAnchor {\n name \"$name\"\n"; } if ($comment) {print " Info { string \"$comment\" }\n"; } if ($axis) { print " Rotation { rotation $axis $angle }\n"; } print " Material { diffuseColor $color{$color} }\n"; if($height != 0) { $xx = ($x1+$x2)/2 ; $yy = ($y1+$y2)/2 ; $width = ($x2-$x1) ; $depth = ($y1-$y2) ; $xx = sprintf("%7.1f",$xx) ; $yy = sprintf("%7.1f",$yy) ; $base2 = $base + $height/2 ; $base2 = sprintf("%7.1f",$base2) ; print " Translation { translation $xx $yy $base2 }\n"; print " Cube { height $depth width $width depth $height}\n"; } else { print " Coordinate3 { point [\n" ; print " $x1 $y1 $base, $x2 $y1 $base,\n"; print " $x2 $y2 $base, $x1 $y2 $base\n ] }\n"; print " IndexedFaceSet { coordIndex [\n"; print " 0, 1, 2, 3, -1\n ] }\n"; } if ($anchor) {print " }\n";} print " }\n"; $comment = "" ; $anchor = 0 ; $axis = "" ; $angle = "" ; } elsif (/^circle/) { # # process circle - create cylinder with current height and color # @f = split(/ /) ; $name = $f[1] ; @xy = split(/,/,$f[2]) ; $x1 = $xy[0] * $xscale + $xoffset ; $y1 = -$xy[1] * $yscale + $yoffset ; @xy = split(/,/,$f[3]) ; $x2 = $xy[0] * $xscale + $xoffset ; $y2 = -$xy[1] * $yscale + $yoffset ; $radius = sqrt(($x1-$x2)**2 + ($y1-$y2)**2) ; $radius = sprintf("%7.1f",$radius) ; $base2 = $base + $height/2 ; $base2 = sprintf("%7.1f",$base2) ; print " Separator {\n"; if ($anchor) { print " WWWAnchor {\n name \"$name\"\n"; } if ($comment) {print " Info { string \"$comment\" }\n"; } print " Material { diffuseColor $color{$color} }\n"; if ($axis) { print " Rotation { rotation $axis $angle }\n"; } if ($cone) { print " Translation { translation $x1 $y1 $base2 }\n"; print " Rotation { rotation 1 0 0 1.5707 }\n"; # pi/2 print " Cone { height $height bottomRadius $radius }\n" ; } elsif ($sphere) { $base2 = $base + $radius ; print " Translation { translation $x1 $y1 $base2 }\n"; print " Sphere { radius $radius }\n" ; } else { print " Translation { translation $x1 $y1 $base2 }\n"; print " Rotation { rotation 1 0 0 -1.5707 }\n"; # pi/2 print " Cylinder { height $height radius $radius }\n" ; } if ($anchor) {print " }\n";} print " }\n"; $anchor = 0 ; $comment = "" ; $cone = 0 ; $sphere = 0 ; $axis = "" ; $angle = "" ; } elsif (/^poly/) { # # process polygon - create polygonal prism with current height, color # @f = split(/ /) ; $np = @f - 2; $name = $f[1] ; undef (@x) ; undef (@y) ; for ($i=1; $i<=$np;$i++) { @xy = split(/,/,$f[$i+1]) ; $x1 = $xy[0] * $xscale + $xoffset ; $y1 = -$xy[1] * $yscale + $yoffset ; push (@x,$x1) ; push (@y,$y1) ; } print " Separator {\n"; if ($anchor) { print " WWWAnchor {\n name \"$name\"\n"; } if ($comment) { print " Info { string \"$comment\" }\n"; } if ($axis) { print " Rotation { rotation $axis $angle }\n"; } print " Material { diffuseColor $color{$color} }\n Coordinate3 { point [\n" ; $z1 = $base ; $z2 = $base + $height ; for ($i=0; $i<$np-1;$i++) { print " $x[$i] $y[$i] $z1, $x[$i] $y[$i] $z2,\n"; } print " $x[$np-1] $y[$np-1] $z1, $x[$np-1] $y[$np-1] $z2\n ] }\n"; # end of Coordinate3 print " IndexedFaceSet { coordIndex [\n"; for ($i=0; $i<$np-1;$i++) { $v1 = $i*2 ; $v2 = $i*2 + 1 ; $v3 = ($i+1)*2+1 ; $v4 = ($i+1)*2 ; print " $v1, $v2, $v3, $v4, -1,\n"; } $i = $np-1 ; $v1 = $i*2 ; $v2 = $i*2 + 1 ; $v3 = 1 ; $v4 = 0 ; if ($noroof) { # don't add roof & floor print " $v1, $v2, $v3, $v4, -1\n ]\n"; } else { print " $v1, $v2, $v3, $v4, -1,\n "; for ($i=0; $i<$np-1;$i++) { $v1 = $i*2 ; print "$v1,"; } $v1 = ($np-1)*2 ; print "$v1,-1,\n "; for ($i=0; $i<$np-1;$i++) { $v1 = $i*2+1 ; print "$v1,"; } $v1 = ($np-1)*2+1 ; print "$v1,-1\n ] }\n"; } if ($anchor) {print " }\n";} print " }\n"; $comment = "" ; $anchor = 0 ; $axis = "" ; $angle = "" ; $noroof = 0 ; # # process metainformation stored as comments in mapfile # } elsif (/^#\!color/) { @f = split(/ /) ; $color = $f[1] ; if (!$color{$color}) { print STDERR "Warning - color $color not defined\n"; } } elsif (/^#\!height/) { @f = split(/ /) ; $height = $f[1] ; } elsif (/^#\!base/) { @f = split(/ /) ; $base = $f[1] ; } elsif (/^#\!cone/) { $cone = 1 ; } elsif (/^#\!sphere/) { $sphere= 1 ; } elsif (/^#\!rotation/) { @f = split(/ /) ; $axis = join(' ',@f[1,2,3]) ; $angle = $f[4] *$pi180 ; $angle = sprintf("%5.4f",$angle) ; } elsif (/^#\!anchor/) { $anchor = 1 ; } elsif (/^#\!noroof/) { $noroof = 1 ; } elsif (/^#\!landscape/) { printf " # emulate noonday sun\n"; printf " DirectionalLight { direction 0 -0.5 -0.7 intensity 1 }\n"; printf " # emulate ambient daylight\n"; printf " DirectionalLight { direction 1 -0.3 0 intensity 0.5 }\n"; printf " DirectionalLight { direction -1 -0.3 0 intensity 0.5 }\n"; printf " DirectionalLight { direction 0 -0.3 0.7 intensity 0.4 }\n"; printf " # make Y axis up\n"; printf " Rotation { rotation 1 0 0 -1.57079 }\n"; } elsif (/^#\!offset/) { @f = split(/ /) ; $xoffset = $f[1] ; $yoffset = $f[2] ; if (!$yoffset) { $yoffset = $xoffset ; } } elsif (/^#\!scale/) { @f = split(/ /) ; $xscale = $f[1] ; $yscale = $f[2] ; if (!$yscale) { $yscale = $xscale ; } } elsif (/^#\!/) { print STDERR "Unknown metacommand $_\n"; } elsif (/^#/) { $comment = $raw ; $comment =~ s/^#// ; # unsqueezed version } else { print STDERR "Unknown command $_\n"; } } # # clean up # print "}\n";