📄 ch21.htm
字号:
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #VRML V1.0 ascii<BR>
2 #<BR>
3 # Created by VRML.pm<BR>
4 #<BR>
5 Separator {<BR>
6 Separator {<BR>
7 Material {<BR>
8 ambientColor .1 .1 .1<BR>
9 # End Material<BR>
10 Transform {<BR>
11 } # End Transform<BR>
12 Cube {<BR>
13 width .8<BR>
14 height .8<BR>
15 depth .8<BR>
16 }<BR>
17 } # End Separator<BR>
18 Separator {<BR>
19 Material {<BR>
20 ambientColor .1 1 1<BR>
21 } # End Material<BR>
22 Transform {<BR>
23 translation 0 0 .4<BR>
24 } # End Transform<BR>
25 Cube {<BR>
26 width .8<BR>
27 height .1<BR>
28 depth .8<BR>
29 }<BR>
30 } # End Separator<BR>
31 Separator {<BR>
32 Material {<BR>
33 diffuseColor .1 .1 .1<BR>
34 } # End Material<BR>
35 Transform {<BR>
36 translation 0 0 .5<BR>
37 } # End Transform<BR>
38 Cube {<BR>
39 width .8<BR>
40 height .1<BR>
41 depth .8<BR>
42 }<BR>
43 } # End Separator<BR>
44 } # End Separator</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
Lines 1 through 4 are comments generated from the <TT><FONT FACE="Courier">VRML.pm</FONT></TT>
module. In line 5, we define a separator which will contain the
object just about to be defined in our virtual world. The ambient
color for this object is defined in lines 6 through 9. More color,
luminance, and reflectivity definitions could be defined in the
Materials section. No transformation to move the object is applied
in lines 10 and 11; however, the section is defined so that you
can manually edit it. Lines 12 through 16 define the dimensions
of a cube. The dimensions are given in a normalized coordinate
scheme, i.e. ranging from 0 to 1. (To use a different reference
for the size, you would have to apply a scaling transformation.)
Line 17 ends the definition of this cube.
<P>
The process of defining the material type, transformation, and
object type of two more objects are repeated in lines 18-30 and
31-42. The process is repetitive: start a separator, define its
type of material, apply a transformation to move, scale, or rotate
it, and then define its normalized dimensions.
<P>
The separator we opened in line 5 was terminated at line 43. This
completes the definition of all the objects in our little world.
<P>
The code required to generate the <TT><FONT FACE="Courier">VRML</FONT></TT>
script is shown in Listing 21.2.
<P>
Admittedly, the number of lines in the Perl script are about the
same as the number in the <TT><FONT FACE="Courier">VRML</FONT></TT>
script. As your models become more and more complex, this ratio
should change to very few lines of Perl code per 100 lines of
definitions in the <TT><FONT FACE="Courier">VRML</FONT></TT> output.
<HR>
<BLOCKQUOTE>
<B>Listing 21.2. The code to generate two cubes.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #!/usr/bin/perl<BR>
2 use VRML;<BR>
3 use VRML::Cube;<BR>
4 my $header = VRML::new();<BR>
5 $header->VRML::startHeader;<BR>
6 $header->VRML::startSeparator;<BR>
7 my $cubeb = $header->VRML::putCube(<BR>
8 'width'
=> 0.5, 'height' => 0.5 , 'depth' => 0.5 ,<BR>
9 'translation'
=> [1,0,0]<BR>
10 );
<BR>
11 my $cubed = $header->VRML::putCube(<BR>
12 'width'
=> 1, 'height' => 1 , 'depth' => 1 ,<BR>
13 'translation'
=> [1,1,0],<BR>
14 );
<BR>
15 $header->VRML::stopSeparator;</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
Let's look at the code shown in Listing 21.2. Lines 2 and 3 indicate
that the <TT><FONT FACE="Courier">VRML</FONT></TT> package and
the <TT><FONT FACE="Courier">Cube</FONT></TT> object are being
used. Line 4 creates the <TT><FONT FACE="Courier">VRML</FONT></TT>
object, which will (eventually) contain all the definitions for
the objects. Line 5 starts the required header for all <TT><FONT FACE="Courier">VRML</FONT></TT>
output.
<P>
Line 6 starts a separator node, which will house all the current
changes. In Lines 7 through 9, we create one cube by giving its
width, height, and depth. The cube is placed at coordinates <TT><FONT FACE="Courier">[1,0,0]</FONT></TT>.
A second cube is placed at <TT><FONT FACE="Courier">[1,1,0]</FONT></TT>,
via code in lines 11-14. All changes to the current separator
node are ended at line 15. At this point, the script could start
a completely different separator.
<P>
It would be a good idea to examine the code in Listing 21.2 with
the VRML output generated in Listing 21.1. By looking at how each
line of Perl code generates each section of VRML, you should be
able to see how to apply the <TT><FONT FACE="Courier">VRML.pm</FONT></TT>
module for your own programs.
<H2><A NAME="BuildingtheVRMLPerlModule"><B><FONT SIZE=5 COLOR=#FF0000>Building
the </FONT></B><TT><B><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">VRML</FONT></B></TT><B><FONT SIZE=5 COLOR=#FF0000>
Perl Module</FONT></B></A></H2>
<P>
The <TT><FONT FACE="Courier">VRML</FONT></TT> module is composed
of several components. The main component is the <TT><FONT FACE="Courier">VRML.pm</FONT></TT>
file, and the rest of the components are shape object creators
in the <TT><FONT FACE="Courier">VRML</FONT></TT> directory. The
<TT><FONT FACE="Courier">VRML.pm</FONT></TT> file is located in
the <TT><FONT FACE="Courier">PERLLIBDIR</FONT></TT> directory
(<TT><FONT FACE="Courier">/usr/lib/perl5</FONT></TT>), and the
shape creation files are located in the <TT><FONT FACE="Courier">${PERLLIBDIR}/VRML</FONT></TT>
subdirectory. There are no extension files to worry about just
yet.
<H3><A NAME="WheretoGettheSourceforthePerlto"><B>Where to Get
the Source for the </B><TT><B><FONT SIZE=4 FACE="Courier">Perl
to VRML</FONT></B></TT><B><FONT SIZE=4> Package</FONT></B></A>
</H3>
<P>
The source of the <TT><FONT FACE="Courier">Perl to VRML</FONT></TT>
package is still in beta and resides at the ftp location <TT><FONT FACE="Courier"><A HREF="ftp://ikra.com/pub/perl5/modules" tppabs="ftp://ikra.com/pub/perl5/modules">ftp://ikra.com/pub/perl5/modules</A></FONT></TT>.
No warranty of any sort applies in any terms whatsoever. You may
copy, modify, and even use the contents of the package in commercial
applications just as long as you credit me as the author and keep
a note about there being absolutely no warranty. The same disclaimer
and warranty for Perl is used for <TT><FONT FACE="Courier">VRML.pm</FONT></TT>.
<P>
Currently, only the following shape nodes are supported: <TT><FONT FACE="Courier">Cube</FONT></TT>,
<TT><FONT FACE="Courier">Cone</FONT></TT>, <TT><FONT FACE="Courier">Cylinder</FONT></TT>,
and <TT><FONT FACE="Courier">Sphere</FONT></TT>. All <TT><FONT FACE="Courier">color</FONT></TT>,
<TT><FONT FACE="Courier">transform</FONT></TT>, <TT><FONT FACE="Courier">PerspectiveCamera</FONT></TT>,
and <TT><FONT FACE="Courier">Material</FONT></TT> nodes are supported
for shapes. As time progresses and the need arises, I will add
more node definitions to this package. For comments, updates,
and patches, please send me e-mail directly at <TT><FONT FACE="Courier">khusain@ikra.com</FONT></TT>.
If you have a better way of rewriting this module and would like
to contribute, please let me know.
<H2><A NAME="UsingVRMLpm"><B><FONT SIZE=5 COLOR=#FF0000>Using
</FONT></B><TT><B><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">VRML.pm</FONT></B></TT></A>
</H2>
<P>
You have already seen a use of the VRML package in placing two
cubes in a 3D world. That's nice, but not very useful. Why not
use the power of Perl to do your expression for you? Look at Listing
21.3, which illustrates how to generate a staircase of values
to show in 3D.
<HR>
<BLOCKQUOTE>
<B>Listing 21.3. Using </B><TT><B><FONT FACE="Courier">VRML.pm</FONT></B></TT><B>
to represent 3D data.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #!/usr/bin/perl<BR>
2<BR>
3 use VRML;<BR>
4 use VRML::Cube;<BR>
5<BR>
6 my $header = VRML::new();<BR>
7 $header->VRML::startHeader;<BR>
8<BR>
9 $header->VRML::startSeparator;<BR>
10<BR>
11 $header->VRML::setPointLight('location' => [1,1,1],<BR>
12 'color'
=> [0.2, 0.2, 0.5]);<BR>
13<BR>
14 $width = 0.1;<BR>
15 my @cubeb;<BR>
16<BR>
17 for ($i= 0; $i< 9; $i++) {<BR>
18 $j
= $width / 2 + $i * $width;<BR>
19 $ht
= $i * 0.1 + 0.1;<BR>
20 $cubeb[$i]
= $header->VRML::putCube(<BR>
21 'width'
=> $width, 'height' => $ht , 'depth' => 0.1 ,<BR>
22 'translation'
=> [$j,$ht/2,0],<BR>
23 'ambientColor'
=> [$i/10, $i/10,$i/10]<BR>
24 );
<BR>
25 }
<BR>
26 $header->VRML::stopSeparator;</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
In Listing 21.3, ten boxes are created to represent data. The
height, width, and color of the cubes could be used to represent
different features of each box. For the moment, we are stretching
the cube to represent the box. The height of the box is a function
of a value of an indexed item in an array. Each cube is placed
next to each other along the X axis. The output from this script
is shown in Listing 21.4.
<P>
The point light sets a light source for illuminating the figures.
(See Figure 21.1.) Note that I will use only the wireframe model
rendering on my VRML viewer to display data because the colors
and shading will not allow the models to be reproduced faithfully
on paper.
<P>
<A HREF="f21-1.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f21-1.gif" ><B>Figure 21.1 : </B><I>Using boxes to represent data.</I></A>
<HR>
<BLOCKQUOTE>
<B>Listing 21.4. Using boxes to represent data.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #VRML V1.0 ascii<BR>
2 #<BR>
3 # Created by VRML.pm flag<BR>
4 #<BR>
5<BR>
6 Separator {<BR>
7 PointLight {<BR>
8 location 1 1 1<BR>
9 color .2 .2 .5<BR>
10 } # End PointLight<BR>
11 Separator {<BR>
12 Material {<BR>
13 ambientColor 0 0 0<BR>
14 } # End Material<BR>
15 Transform {<BR>
16 translation .05 .05 0<BR>
17 } # End Transform<BR>
18 Cube {<BR>
19 width .1<BR>
20 height .1<BR>
21 depth .1<BR>
22 }<BR>
23<BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -