For example, what if you wanted a pyramid, or a doughnut shape? What if you wanted to model the floor plan of a proposed building? What if you want to include text? Or stars? Or a wire-frame model of something? The primitive shapes are easy and powerful, but there are things they cannot model easily. They are also a little inflexible when being colored, as they have an "all-or-nothing" coloring scheme. For example, what if you wanted a cube with different colors on all six sides? It would be nice if we could work with the individual faces sometimes.
Today we will focus on some other types of geometry nodes, that will help us with these problems. A geometry node, as you remember, lives inside a shape node, and describes the physical appearance of the given object. So far, we have used only 'primitive' shapes. These are the sphere, box, cylinder, and cone. We will see some much more complex and powerful geometries in this session. Specifically, we will examine the text node and extrusions. In a later lesson, we will learn some other powerful geometry objects, including pointsets, linesets, and facesets.
#VRML V2.0 utf8
#text.wrl
#demonstrates using text in a geometry node
Shape {
appearance Appearance {
material Material {
diffuseColor 1 1 0
} # end material
} # end appearance
geometry Text {
string "Hi there!!"
} # end text
} # end shape
As you can see, this allows us to place a text value in the
environment. Obviously, this is a nice capability, but it would be
interesting to see what options we have in terms of typeface and
positioning.
The next example illustrates some of these options:
fancyText.wrl
#VRML V2.0 utf8
#Fancytext.wrl
#demonstrates various features of text
# This is the generic text node
Transform {
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 1 1 0
} # end material
} # end appearance
geometry Text {
string "default"
} # end text
} # end shape
] # end children
}
# Here we've translated the shape node
# and and changed the length of the text node
Transform {
translation 0 1 0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 1 1 0
} # end material
} # end appearance
geometry Text {
string "narrow"
length 1
} # end text
} # end shape
] # end children
}
# Here we made the text node length longer
Transform {
translation 0 2 0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 1 1 0
} # end material
} # end appearance
geometry Text {
string "wide"
length 8
} # end text
} # end shape
] # end children
}
# Now we add a fontStyle element, and make the
# style "ITALIC"
Transform {
translation 0 -1 0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 1 1 0
} # end material
} # end appearance
geometry Text {
string "italic"
fontStyle FontStyle {
style "ITALIC"
} # end fontstyle
} # end text
} # end shape
] # end children
}# end transform
# Here I changed the size inside the fontStyle node
# This gives me better performance than changing
# the width of the Text node.
Transform {
translation 0 -2.5 0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 1 1 0
} # end material
} # end appearance
geometry Text {
string "Big"
fontStyle FontStyle {
size 2
} # end fontstyle
} # end text
} # end shape
] # end children
}# end transform
# size is a scaling node.
# The default size is being multiplied by 0.5, which
# also means divide by two.
Transform {
translation 0 -3.5 0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 1 1 0
} # end material
} # end appearance
geometry Text {
string "Small"
fontStyle FontStyle {
size .5
} # end fontstyle
} # end text
} # end shape
] # end children
}# end transform
# By setting horizontal FALSE, we made this a vertical
# text field. topToBottom determines the direction of
# the text.
Transform {
translation -2 4 0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 1 1 0
} # end material
} # end appearance
geometry Text {
string "going down"
fontStyle FontStyle {
size .5
horizontal FALSE
topToBottom TRUE
} # end fontstyle
} # end text
} # end shape
] # end children
}# end transform
# This is the same as the previous example, but we
# set topToBottom to FALSE.
Transform {
translation -4 -4 0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 1 1 0
} # end material
} # end appearance
geometry Text {
string "going up"
fontStyle FontStyle {
horizontal FALSE
topToBottom FALSE
} # end fontstyle
} # end text
} # end shape
] # end children
}# end transform
#VRML V2.0 utf8
#extrude1
#a very simple example of extrusion
Shape {
appearance Appearance {
material Material {
diffuseColor 0 0.5 1
} # end material
} # end appearance
geometry Extrusion {
crossSection [
0 1,
-1 -1,
1 -1,
0 1,
] # end cross section
spine [
0 0 0,
0 .2 0,
] # end spine
} # end extrusion
} # end shape
# force browser into 'examine mode'
NavigationInfo{
type "EXAMINE"
}
As you can see, this object appears to be a triangle with 'thickness.'
It is obviously not one of the primitive types, as those are quite
well defined. It is a very simple example of an 'extrusion.'
Bakers use the principle of extrusion when they decorate a cake.
You've probably done this; you take frosting, and put it in a tube
with a special tip. You can place different tips in the tube, and
they will cause different streams of frosting to come out. If you use
a small round tip, you will get a thin round stream of frosting. If
you use a flat tip, you will get a ribbon. If you use a fancy
serrated tip, you will get a different kind of ribbon.
You can apply this ribbon anywhere on the cake.
Basically, you generate an extrusion by the same process. You define a two-dimensional cross-section of your object, and then you tell the browser to apply that section across a three-dimensional spine. The cross section is the 'tip' in our frosting example. The spine would be like the path we are following on the cake.
CrossSection is a template designed in two dimensions. For this
project I wanted a triangular cross-section, so I sketched a
triangle. My original sketch looked something like this:
Note how this relates to the node format
crossSection [
0 1,
-1 -1,
1 -1,
0 1,
] # end cross section
I thought in X-Y coordinates for now. This defines the general
section of the object. It does NOT necessarily reflect X and Y
coordinates in the eventual model!! When we sketch a cross section,
we are NOT working in the 3D coordinate system! Notice also that I
'closed off' the shape by returning to my first point. This is
necessary, if I want all three sides to be drawn.
The other node, Spine looks like this in the code:
spine [
0 0 0,
0 .2 0,
] # end spine
As you can see, the spine node appears to contain 3D coordinates.
This is a very simple object. The spine is a virtual line running
from (0, 0, 0) to (0, 0.2, 0). I am now defining a line in the
coordinate system of the model (or an appropriate group or transform).
My extrusion will essentially draw a series of representations of
itself with that line as its origin.
#VRML V2.0 utf8
#extrude2
#a more complex example of extrusion
Shape {
appearance Appearance {
material Material {
diffuseColor 1 1 1
} # end material
} # end appearance
geometry Extrusion {
crossSection [
0 1,
-1 -1,
1 -1,
0 1,
] # end cross section
spine [
-5 5 0,
-5 -5 0,
5 -5 0,
5 5 0,
-5 5 0,
] # end spine
} # end extrusion
} # end shape
# force browser into 'examine mode'
NavigationInfo{
type "EXAMINE"
}
You'll probably need to spin this thing around a little bit to get the
full effect. Essentially, it's a kind of 'picture frame' effect. We
have taken that simple triangular cross-section and twisted it into a
3-dimensional shape. The browser will do its best to conform to the
cross section everywhere on the shape. Some browsers are better at
this than others, and simpler cross sections definitely seem to give
better results than more complex ones.
#VRML V2.0 utf8
#twist
#Using orientation node in an extrusion
Shape {
appearance Appearance {
material Material {
diffuseColor 0 0.5 1
} # end material
} # end appearance
geometry Extrusion {
solid FALSE
# same crossSection as before
crossSection [
0 1,
-1 -1,
1 -1,
0 1
] # end cross section
spine [
0 0 0,
0 1 0,
0 2 0,
0 3 0,
0 4 0,
0 5 0,
0 6 0,
] # end spine
orientation [
# for each spine point, I will define a rotation angle.
# most of the time, you will translate around Y axis (0 1 0)
# here I'm going in 10 degree increments, converted to radians
0 1 0 0,
0 1 0 .175,
0 1 0 .349,
0 1 0 .524,
0 1 0 .700,
0 1 0 .875,
0 1 0 1.05,
] # end orientation
} # end extrusion
} # end shape
# force browser into 'examine mode'
NavigationInfo{
type "EXAMINE"
}
Again, you see that many things are the same. I have added the
orientation node to the extrusion. This node has exactly the same
number of values as the spine. Each element will relate directly to
the corresponding spine coordinate. The orientation node describes
any orientation changes (twists) that we want the model to follow at
this point. The browser will try to make smooth transitions from one
orientation to the next.
Remember that orientations are basically rotations. They consist of a vector and an angle in radians. We will almost always be rotating around the LOCAL Y axis. I specified local, because this is the direction the spine is currently going, NOT necessarily the Y axis of the model in general. You will almost always use 0 1 0 as the axis of rotation in an orientation node of an extrusion.
The angle will be expressed in radians. You can convert them from degrees, or remember these general guidelines (which are good enough for many applications)