microgoodies

By Johnnie Rose, Jr.

It Shall Be Scaled

The first and second lessons of this Transform tutorial taught about moving and rotating things, respectively.  Amazingly, the power of the Transform node extends further than those two functions.  It can also scale its coordinate systems.

Remember that each time the Transform node is used, it creates a new coordinate system, which has your basic X, Y, and Z coordinates.  By using the scale and scaleOrientation fields, you can manipulate the Transform node's children by warping them in the X, Y, or Z directions, or any combination of each.  Scaling an object could make it shrink, grow, expand, or do a number of other things; it can mean the difference between a sphere and a flat oval.  So, to get some kind of basis of what we're talking about, here's the fully-expanded Transform node, with the fields we'll be using highlighted:

Transform {
   children	     []			# exposedField MFNode
   translation 	     0.0 0.0 0.0	# exposedField SFVec3f
   rotation	     0.0 0.0 0.0 0.0 	# exposedField SFRotation
   scale	     1.0 1.0 1.0	# exposedField SFVec3f
   scaleOrientation  0.0 0.0 1.0 0.0    # exposedField SFRotation
   bboxCenter	     0.0 0.0 0.0	# field	       SFVec3f
   bboxSize	     0.0 0.0 0.0	# field	       SFVec3f
   center	     0.0 0.0 0.0	# exposedField SFVec3f
   addChildren				# eventIn      MFNode
   removeChildren			# eventIn      MFNode
}

Using the scale field of the node requires just one concept: scale factor.  To shrink a beach ball down to half size, you'd use a scale factor of one half, or 0.5.  If you wanted to make a pea ten times as big to make a boulder, you'd use a scale factor of 10.  To make anything twice its size, use a scale factor of 2.0, and so on.  You may have noticed, however, that there are three specific values to go in the field.  Those are the directions in which you want to scale; simply plug-in your scale factor and you'll scale your coordinate system in that particular direction.  For example, to lengthen a sphere horizontally to twice its size, the scale factor would be 2.0 in the X axis.  Your finished scale field would be 2.0 1.0 1.0.  (Remember that you must use a scale factor of 1.0 in directions you're not using to keep the object normal in those axes.)  See this particular world in action here, and the corresponding code:

#VRML V2.0 utf8

Transform {
   children [   # Build the sphere
      Shape {
	 appearance Appearance {
	    material Material {} # Microsoft-like greyish color
	 }
         geometry Sphere {
	    radius 2.0
	 }
      }
   ]
   scale 2.0 1.0 1.0
}
  • The majority of the code is dedicated to building the sphere and settings its attributes, such as its radius and color.
  • scale 2.0 1.0 1.0
    This is where the real action takes place.  This line tells the browser to stretch the sphere horizontally to twice its original size.  What you get is an horizontal oval.
If we wanted to stretch the sphere to twice its size vertically, the scale factor would be 2.0, and the direction would be the Y axis: scale 1.0 2.0 1.0.  Likewise, to make the sphere longer going back and forth, you'd manipulate the Z axis: scale 1.0 1.0 2.0.  Remember that scale factors can be anything.  As explained before, you can scale all or any combination of the axes at once.

Using Scale Orientation

Simply scaling around the three axes is great, but there is a point where you find you can only do so much.  To remedy this problem, VRML includes the convenient scaleOrientation field, which allows you to put in a specific axis and a radian measure to tell the browser exactly how you want to scale your objects.  It's much like using the rotation field; in fact, both are of the same field type--SFRotation.

When you define a custom orientation, the browser performs three steps to build the children of that particular Transform node:

  1. It takes the measurements from the scale field to appropriately scale the object.
  2. The browser rotates the entire coordinate system to whatever is in the scaleOrientation field.  As you might have guessed, if it isn't defined, there's no rotation.
  3. Finally, the browser goes through any code dealing with rotation; using scaleOrientation reorients the direction of the scaling, and leaves the coordinate system open to further rotation.
So, you want to scale that sphere forty-five degress around the Z axis.  This will result in the ends of the sphere pointing diagonally from the top-left to the bottom-right.  (If you need to see how this is true, just take a glance at the rotation tutorial and scroll down to the Right Hand Rule.)  Like the rotation field, first you need to define which axis you'll be manipulating.  For the example above, you'll use the Z axis: scaleOrientation 0.0 0.0 1.0.  Now, rotate around that axis by forty-five degrees (view a Javascript degree/radian converter).  Your finished code is scaleOrientation 0.0 0.0 1.0 0.785.  From there, all you have to do is plug it in to a world and see if it works.

#VRML V2.0 utf8

Transform {
   children [
      Shape {
         appearance Appearance {
            material Material {} # Grey!
	 }
	 geometry Sphere { # The sphere
	    radius 2.0
 	 }
      }
   ]
   scale 1.0 3.0 1.0	# To show the difference, make the sphere 3 times taller
   scaleOrientation 0.0 0.0 1.0 0.785	# Then, it's rotated to what's in here
}

And, as expected, the resulting world.  The sphere is three times as tall as it was originally, and it's rotated around the Z axis by forty-five degrees (0.785 radians) so that it's tilted.  You could also add a line to rotate the coordinate system that just got finished scaling:

rotation 0.0 1.0 0.0 1.571

The result is a scaled sphere, like the one above, that has been rotated ninety degrees around the Y axis so that the upper end points towards you.

Scale Around the Center

Scaling around a center point other than the coordinate system's origin is a very easy concept.  You can use it on objects where some point should stay fixed while the rest of the system is scaled.  For example, a tree:

#VRML V2.0 utf8
# Help us build a tree.  Recycle your bytes.

Transform {
   children [
      Transform {
         children [
            Shape { # The trunk
               appearance Appearance {
                  material Material {}
               }
               geometry Cylinder {
                  radius 1.0
                  height 3.0
               }
            }
	 ]
         translation 0.0 -3.0 0.0   # A little underground
      },
      Shape { # The tree's upper portion
         appearance Appearance {
            material Material {}
         }
         geometry Cone {
            bottomRadius 4.0
            height 5.0
         }
      }
   ]
}

Now here's the same tree, with this additional line added to the parent Transform node so the whole thing is scaled to three times as tall as its original height.

scale 1.0 3.0 1.0   # Three times as tall as it was

Trees, however, grow upwards from the trunk as the trunk stays where it is.  So, we need to add a center field so the scale is applied to everything above the trunk:

center 0.0 -5.0 0.0

To view the full effect of this change, load this centered tree, which is three times as tall as its original height, and then load a tree seven times its original height.  As you can see, the bottom of the trunk remains stationary, and the scaling is applied to everything above the lowest point.

Another mystery of the Transform node unveiled.

back to the basics page

johnnie2 AT hal-pc DOT org

This site and all contents herein are Copyright ©1998-2006 Johnnie Rose, Jr. and may not be copied or reposted without written permission from the founder.
View the Microgoodies Privacy Policy. Fight Spam!