The Group Kaleidoscope Project

Last issue I explored VRML’s External Authoring Interface in an article that documented an old Kaleidoscope project of mine. While re-reading the article, I kept thinking about how unnecessarily lonely doing such a project alone became. We live in a networked world and the design of VRML begs for collaboration on VRML content. This issue’s article requests you to participate in the design of a Kaleidoscope that will be created by folks all around the globe. In this article, I lay out the specifications for a Kaleidoscope piece template which I will ask you to use creatively in designing your own piece or pieces. You can send me your content by email complete with texturing and I will accumulate all the pieces I receive into one big Kaleidoscope. Next issue, I will write about the pieces I receive from everyone and provide specifics on the most intriguing designs. I will also show off our Kaleidoscopes in full color. To assist your learning through participation in this project, I will focus this article on using VRML prototypes, creating transparency in bitmap images and writing intranode JavaScript behaviors.

The Group Development Opportunity with VRML

Upon returning from the VRML 98 conference in Monterey, CA, I felt a renewed enthusiasm for working with the VRML community. So many interesting and creative people involved with VRML. So many people interested in sharing ideas and working together to create better VRML related technologies. The VRML community has certainly come together to build a functional specification. The time is ripe now for coming together to create content. The hierarchical nature of the VRML scene graph makes group projects easy to slap together. I can terraform a new terrain. You can add trees or roads. A mutual friend can add a house and a fourth friend can furnish it. Surely, a VRML modeling effort is easy to divide and conquer. But, as we wish to add behaviors to our worlds and move objects about naturally in close quarters, we may want to take advantage of another VRML feature: PROTOtyping.

A Kaleidoscope is an example of a very doable group project that benefits from a little planning up front. Without planning, the movement of the Kaleidoscope pieces will likely be chaotic if each designer independently provides behaviors for each piece. Quite possibly two people might design their pieces to follow similar paths with one designer’s piece covering up an other designer’s piece. Someone could write some Java classes to determine piece collisions and provide a natural system for intelligently determining how the pieces should respond to collisions. I hope you have a sense for the amount of work involved in creating Java classes from reading about the External Authoring Interface (EAI) last issue. Creating the necessary Java classes would not be too hard and the result may well be worth the effort if realism were what we craved. The computing power required to run such a fully simulated Kaleidoscope would be significantly more than what I had in mind for a worldwide project. I do not want to limit the potential audience.

The design of the Kaleidoscope I presented last issue provided an adequate structure for moving the pieces in harmony as a whole. More importantly, that Kaleidoscope’s movement is more efficient compared to other possible designs. Let’s keep that basic high-level structure in place for our group project. I think each piece designer will have enough freedom within that structure to design interesting pieces and demonstrate novel solutions. To help provide additional consistency within our lower level design, I will provide you with a KPAnimation PROTO node from which you can build your pieces. I next provide an overview of VRML’s PROTO node and then demonstrate a piece I designed by using the KPAnimation node prototype.

The PROTO Node

The PROTO and EXTERNPROTO VRML keywords together provide important design benefits: Compact file sizes plus design speed and consistency. By using prototypes, one person can create a PROTO node that contains sophisticated VRML nodes, fields, and scripts while a second person can use the PROTO node to create another similar VRML object without having to reinvent the details in common.. Should a third person come up with a better implementation of the details, the PROTO node can be changed and the two existing objects will continue to function. In many ways, VRML PROTO nodes are similar to word processing or spreadsheet templates that make reuse simple yet provide flexibility for the creation of anticipated differences. For our Kaleidoscope group project, we will use a PROTO node to make the development of your piece behaviors simple, flexible and consistent.

Take a look at the KPAnimation PROTOtype I propose in Listing 1. The KPAnimation node gives you control of which JavaScript script to use (I cover the scripts later on), the frequency of the script’s execution, and a way to change both the rotation and translation of your Kaleidoscope piece within the script.

The KPAnimation node interface contains the following four components

field MFString jsurl [ ]

field SFTime seconds 0

eventOut SFRotation kpRot

eventOut SFVec3f kpTrans

which let you vary the script filename (through the jsurl field), the timing cycle (through the seconds field), the piece’s rotation (through the kpRot eventOut), and the piece’s translation (through the kpTrans eventOut). The body of the PROTO contains the details of the loop timer, script fields, and necessary routes. These details should be the same for each designer’s piece. The KPAnimation PROTO node keeps these common details in one place instead of in each designer’s file. And, the PROTO node gets each designer thinking along the same lines.

PROTO nodes can be as rigid or flexible as you want. In the case of the KPAnimation PROTO node, the seconds field provides you with the freedom to adjust the frame loop duration. If you set the seconds field to .1, your Kaleidoscope piece will update its translation and rotation 10 times a second (every 1/10th of a second). Together with your JavaScript script, the seconds field will control the speed and/or smoothness of the animation.

The seconds field provides a little design freedom. In contrast, the jsurl field provides a lot of design freedom. You can write whatever behavior(s) you want and save them to your own JavaScript file. Your KPAnimation node will read your JavaScript file and use the behaviors at run time. To understand why your script functions must have specific names, you need to take a look at the implementation details of the KPAnimation PROTO node. Listing 2 shows the KPAnimation PROTO in its entirety. The syntax must be followed closely. The PROTO header provides a node name and lists the eventIns, fields, and eventOuts associated with the prototype [ within square brackets ]. The body of a PROTO node follows right after the header { within braces }.

The KPAnimation PROTO body includes a Timer, a Script, and ROUTE statements. All Kaleidoscope pieces need these three components. The Timer is a simple loop timer that runs continuously. The Script contains a ww field you will use to provide variability to your JavaScript functions, two eventIns you will use to kick off your JavaScript functions, and two eventOuts you will use to effect the scene graph with the results your JavaScript processing. The url field keeps a reference to where your JavaScript functions reside. Note the use of the IS keyword. The IS keyword connects the fields from the PROTO header (also called the interface) to the PROTO body. Design flexibility comes from this ability to defer body decisions until run time (when the actual KPAnimation node is instantiated based on the PROTO node’s guidelines).

Timer nodes contain a cycleTime eventOut which fires each time the Timer starts its loop. The KPAnimation node uses the cycleTime eventOut to regulate the execution timing of the JavaScript functions. A ROUTE is required for each JavaScript function in order to wire the cycleTime eventOut to the execution of JavaScript function. The JavaScript function name must be identical to the Script node’s eventIn name. The design comes together when you consider the JavaScript functions.

The JavaScript Behaviors

There are two script functions available that come with the necessary routing already in place: set_rotKP() and set_transKP(). Of the two, the set_rotKP() function is safer to implement since any rotation you perform will not effect where the Kaleidoscope piece appears within the higher-level positioning of the Kaleidoscope. You can freely change the rotation of your piece around any or all of the x, y, and z axes. You can use the ww field of the KPAnimation PROTO Script node to vary rotation from one script execution to the next. Take a look at a possible set_rotKP() function. The following set_rotKP() function contains valid JavaScript syntax.

function set_rotKP() {
ww = ww+1;
if(ww>19) {ww=0;}
kpRotation = new SFRotation(ww/40,ww/20,0,6.28*ww/20);
}

Each time the Timer loop starts, field ww increments by 1. Remember that field ww is of type SFFloat which gives you more flexibility than I use here. I am treating ww as an integer. Whenever ww exceeds 19, I reset it to 0. Then, I change the rotation of my Kaleidoscope around the x and y axes with some simple fractions that take advantage of the changing ww field. The fourth parameter of the SFRotation constructor is most important for providing a smooth animation. I want my rotation behavior to complete a full circle before starting over again. Since there are 2 * Pi radians in a circle, I multiple the constant 6.28 by a fraction that will smoothly vary from 0 to 1. I am hoping you will come up with other interesting ways to make your piece’s animation appear smooth.

The set_transKP() function requires some careful thought. The high-level positioning of Kaleidoscope pieces controls the translation of pieces in order to provide an attractive presentation. Yet, only the x and y axes are involved in the high-level PositionInterpolator nodes you saw last issue. In your set_transKP() function, you can change the z translation freely from -2 to +2 and can change the x and y translation by -.5 to +.5 and still take advantage of the high-level design. If you dynamically change your piece translations by more than these guidelines, I may have to tone them down when consolidating our group Kaleidoscopes.

Submitting a Kaleidoscope Piece

Now that you have seen the KPAnimation PROTO node in detail, you can focus on what to submit to me when your are satisfied with your piece. Listing 3 shows an example of a complete piece. Listing 3 begins with an EXTERNPROTO node. VRML’s EXTERNPROTO node allows you to use a PROTO node which exists as a separate .wrl file. I will put the KPAnimation PROTO node in a file named KPAnimation.wrl on my server in the same subdirectory as your piece file(s). Then, I will include the KPAnimation EXTERNPROTO node at the top of your piece file with a reference to the KPAnimation.wrl file.

Since the KPAnimation EXTERNPROTO node is the same for each Kaleidoscope piece, you do not need to submit that node to me. Instead, you need to deliver two nodes to me: A Shape node and a KPAnimation node. The Shape node can be anything you want to design. All I ask is that the (0,0,0) origin be inside of your shape, preferably at the center of gravity. I will scale your piece appropriately to fit with all the other pieces. Listing 3 shows a simple Shape with a Box geometry. I know you can do better than Listing 3. You can include the ROUTE statements if you wish, but I will figure them out if you do not.

Besides your .wrl file that follows the format in Listing 3, you need to send me your JavaScript functions contained in a file with a .js extension. If you are on an email system that uses strange file attachment standards, you can send the VRML syntax and JavaScript functions as email message body text with no attachments. An example of a complete .js file appears as Listing 4. Additionally, you can send me a bitmap image to be used as a texture for your piece. Send me textures that follow either the JPEG (.jpg) or GIF (.gif) file format.

A Word About Textures

When I remember back to the first cheap Kaleidoscope I received as a gift, the Kaleidoscope contained pretty glass pieces and trinkets such as shiny silver paper clips. Although you could create a paper clip through a sophisticated IndexedFaceSet node geometry, a more efficient method is to create a flat geometry and place a transparent bitmap image over the geometry. I do not want to limit your creativity by suggesting the second approach, but I think more people will enjoy our Kaleidoscopes if they performed better. Our Kaleidoscope pieces will perform better with simple polygons and textures than with 1000 polygon geometries.

Figure 1 - A transparent bitmap image in action.

The Shape node I provide in Listing 3 uses a texturing approach to create an oddly shaped piece. The texture in file tex04.gif contains a gray background which I make transparent using my GIF image editor. Then I slap it on the simple Box geometry and it appears as seen in Figure 1. The piece looks great at any angle as it rotates in place. If you do not have experience with a GIF editor, you can still send me your images with a note as to which color should be transparent.

Transmission Details

Gather your .wrl file, .js file, and texture file (or files if you are submitting more than one piece) and attach them to an email message that you send to me electronically at mailbox bdc@hitl.washington.edu. Anything you submit to me should be without copyright and not violate any trademarks as I will use it freely in the next issue’s article. For example, do not send me Mickey Mouse, corporate logos, or professional sports team insignias.

If you are feeling extra creative, you can send me a Kaleidoscope design in which we can imbed our pieces. I have been slow in creating one of my own. Consider a really funky virtual design. Your design can be a design that would not work in the real world. Send me email if you have any questions.

Conclusion

I sure hope we have fun creating a group Kaleidoscope. I have had a blast coming up with the concept and testing it out. You have seen some possible Kaleidoscopes in the images that are scattered throughout this article. I am very interested in participating in other group projects since I think group projects demonstrate the best use of cyberspace - as a place to use our imagination and interact with other people of all different backgrounds and cultures. There is no inherent language associated with a Kaleidoscope.

There are some very fascinating group projects already in the works. A group in Canada is developing a model for creating shared VRML theater to deliver Shakespeare’s works on-line and is opening the character and stage content creation to eager volunteers all around the globe. Another group in Germany is creating a butterfly world where we will be able to fly VRML butterflies of our own design using sophisticated butterfly behaviors they provide. We will be able to hold out a virtual rose and attract butterflies to come towards us.

The next step is to develop applications that allow us to actually design together in real-time over long distances. You saw how to create a Kaleidoscope design tool last issue. We can use those same Java classes to produce group design applications. But, I hope you have an appreciation for the magnitude of the programming effort such tools entail. The approach provided in this article of using VRML PROTO nodes, intranode JavaScript scripting, and simple VRML high-level interpolators is much simpler, yet may provide content which is just as compelling as content using all those Java classes. We will see what is possible in a couple of months when I put the Kaleidoscopes on line for all others to see. If I get enough content, I think I will even create a randomizing routine that will use a different combination of Kaleidoscope pieces each time you load the .wrl file. If I do follow that path, I will provide all the source code next issue. Speaking of next issue, I would also be interested in providing URLs to group VRML projects out there that want participation. Go ahead and send them to me. I look forward to your Kaleidoscope piece designs!

**** Listing 1 ****

PROTO KPAnimation [
field MFString jsurl [ ]
field SFTime seconds 0
eventOut SFRotation kpRot
eventOut SFVec3f kpTrans ]

**** end of Listing 1 ****

**** Listing 2 ****

#VRML V2.0 utf8

PROTO KPAnimation [
field MFString jsurl [ ]
field SFTime seconds 0
eventOut SFRotation kpRot
eventOut SFVec3f kpTrans ]
{
DEF Time_T1 TimeSensor {
cycleInterval IS seconds
startTime 0
loop TRUE
},
DEF KP1 Script {
directOutput TRUE
field SFFloat ww 0
eventIn SFTime set_transKP
eventIn SFTime set_rotKP
eventOut SFRotation kpRotation IS kpRot
eventOut SFVec3f kpTranslation IS kpTrans
url IS jsurl
}
ROUTE Time_T1.cycleTime TO KP1.set_rotKP
ROUTE Time_T1.cycleTime TO KP1.set_transKP
}

**** end of Listing 2 ****

Some files:
A single animated piece using the prototype node
One version of the Kaleidoscope
A second version of the Kaleidoscope
A third version of the Kaleidoscope

**** Listing 3 ****

#VRML V2.0 utf8

EXTERNPROTO KPAnimation [
field MFString jsurl
field SFTime seconds
eventOut SFRotation kpRot
eventOut SFVec3f kpTrans ]
"KPAnimation.wrl"

DEF S1 Transform {
children [
Transform {
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 1 1 1
}
texture ImageTexture { url "tex04.gif" }
}
geometry Box {size 2 2 .001 }
}
]
scale 1.5 1.5 1.5
},
DEF KP KPAnimation {
jsurl ["KPTransform.js"]
seconds .4
}
]
}
ROUTE KP.kpRot TO S1.set_rotation
ROUTE KP.kpTrans TO S1.set_translation

**** end of Listing 3 ****

**** Listing 4 ****

javascript:
function set_transKP() {
ww = ww+1;
if(ww>19) {ww=0;}
kpTranslation = new SFVec3f(0,0,1-ww/10);
}
function set_rotKP() {
ww = ww+1;
if(ww>19) {ww=0;}
kpRotation = new SFRotation(ww/40,ww/20,0,6.28*ww/20);
}

**** end of Listing 4 ****