Accessibility

Director Article

Creating Interactive Virtual Objects with Shockwave 3D

Marty Plumbo

Marty Plumbo

www.martyplumbo.com.

Interactive Objects

The ability to present a view object from an infinite number of angles is one of the best things about real-time 3D—everything looks better from six degrees of freedom! Add to this the ability to alter the 3D object being viewed in response to user interaction, and you've got some serious "wow-factor" on your hands. Practically any project—from product demos to educational software—stands to benefit from this sort of interactive 3D treatment. The best part: It's not really all that hard to get started doing real-time 3D using Shockwave 3D.

Requirements

To complete this tutorial, install the following software and files:

Director MX



3DPI Xtra

Tutorials and sample files:

Project Overview

In this article, I show you how to create the functional shell of an interactive 3D product demo. But, in a larger sense, these techniques are fundamental in creating any project with interactive objects that need to be manipulated in first person, either as a group or as separate "subobjects." To that end, I cover several key concepts, including grouping strategies, picking, gesturing and interactive property manipulation, all through practical examples in Shockwave 3D.

Note: To complete this tutorial successfully, you should already be familiar with the basics of using and programming Shockwave 3D. Also, since the code in the finished example is somewhat lengthy, I present the code in several graduated revisions, rather than explaining it line by line, so you can study and read it in stages as you go along. Look to this text for explanation of the overall strategy and conceptual framework of the programming.

Functional Goals

In any interactive project, a good first step is to outline the functional goals that you need to accomplish. In this project, first and foremost, the user should be able to grab and rotate the 3D phone by clicking on its body and then moving the mouse. The user should also be able to reset the orientation of the phone by clicking a reset button—just in case he gets disoriented while spinning it around. Several of the component parts of the phone should elicit their own functionality:

  • All buttons will press and unpress when clicked.
  • Button presses should be accompanied by a sound.
  • Pressing the power button should cause the phone's antenna to extend and retract.
  • Pressing the A-B-C function buttons should change the display on the phone's screen.

Getting Started

Download the sample files for the project, which are linked at the beginning of this article. Before beginning the exercise, examine and run a completed version of the exercise, finished.dir.

The final product demo exercise, brimming with interactive 3D.

Figure 1. The final product demo exercise, brimming with interactive 3D

To begin the exercise, open the step_01.dir file in Director. This file is a Director movie that contains template code for the exercise, including an imported 3D cast member. Using 3DPI, examine the 3D scene in this starter movie, paying particular attention to the naming conventions used for the various models that make up the mobile phone. If you don't already have the 3DPI Xtra installed on your copy of Director, go to http://www.3dpi-director.com/ to get it before starting. 3DPI is truly the 3D property inspector that Macromedia forgot to include in Director 8.5; it lets you literally look inside 3D cast members and manipulate their contents and properties visually and in real time.

Looking inside the 3D world with the 3DPI Xtra.

Figure 2. Looking inside the 3D world with the 3DPI Xtra

The two-frame structure of the template movie is based on the need to ensure that the 3D cast member is fully initialized and ready, before executing any 3D Lingo. The playhead will loop in the init frame until the 3D member is ready. Once the 3D member is ready, a block of initialization code executes, and then the playhead advances to the main frame, where it loops for the remainder of the program. This is a good, basic template for all Shockwave 3D projects.

I'll build everything inside a basic, two-frame template movie.

Figure 3. A basic, two-frame template movie

Creating a Group

Load the file step_02.dir.

As you saw in 3DPI, the mobile phone model actually consists of 17 different models. The ultimate functional goals for this exercise require that these 17 model sometimes act independently, like when a user presses an individual button. Other times, they act as a whole, for example, when the user rotates entire phone in space. You can accommodate the former because each of the seventeen parts of the phone is indeed a separate model, and you can accomplish the latter by grouping all of the separate models together. I do this in Lingo here, although you can do it in most modeling programs as well.

Grouping lets you create a new node in the 3D world that has no geometry of its own, but rather acts as a container for other geometry. I have done this by adding a block of code to the enterFrame handler in the Initialization behavior, which creates the group node phone and then adds all of the models, that is, the various phone parts, in the 3D world to it. Grouping is a subtle but important aspect of interactive 3D. By grouping all of the parts of the phone in this way, I now have two levels of control over them: I can manipulate them one at a time or as a group.

Picking and Gesturing

Load the file step_03.dir.

The first functional goal is to allow the user to click, or "pick," the body of the phone, and then rotate it on two axes by gesturing with his mouse. The user can view the phone from any perspective—a very useful thing in product demos. This functionality rests in the Tracker behavior, which I have attached to the 3D world sprite instance in the main frame of the movie. The structure of this behavior is fairly straightforward: The mouseDown and mouseUp handlers toggle the rotation functionality on and off and leave the actual processing to the exitFrame handler.

Here's how it all works:

  1. Since the object should only rotate when the user clicks it, the mouseDown handler initializes and initiates the rotating of the object. It uses the modelUnderLoc function to determine if the user has just clicked on a model in the 3D world.
  2. If the value returned by modelUnderLoc is void, there is no model under the cursor and the mouseDown processing is done.
  3. If the modelUnderLoc value is not void, the user has picked a model in the scene.
  4. When this happens, the code sets the flag variable pTracking to TRUE, toggling execution of the code in the exitFrame handler.
  5. This transforms the entire "phone" group on two of its axes in response to the user's mouse gestures, which are inherently on two axes.
  6. Likewise, when the user releases the mouse, the mouseUp handler sets pTracking back to FALSE so that the code that transforms the "phone" group" cannot not execute.

Notice that the behavior lets you specify the model picked and group gestured as properties. This gives you allow greater flexibility in formulating the user interactions. For instance, while the interface utilizes a "first person" interaction wherein the user manipulates the phone itself to change its orientation, alternatively, the scene could feature geometry separate from the phone which serves as a navigation instrument, such as a sphere serving as a virtual trackball. This behavior could easily accommodate such configurations as well.

Resetting the Scene

Load the file step_04.dir.

Next, I add the "Reset" behavior to the reset button, which allows the user to return the phone to its initial orientation. As you will recall, after creating the "phone" group in the "Initialization" behavior, I stored the group's transform in the global variable gInitTransform. Thus, here I need only set the group's transform back to the value in gInitTransform to return all of the models that make up the phone back to their start position. This kind of functionality is particularly important in interactive 3D. Interacting with 3-dimensional content via 2-dimensional interface devices, such as a computer screen and mouse, isn't the most intuitive of tasks, and one that is still entirely new to many users. The need to establish and allow easy access to reference points, such as the initial position of the phone in our demo, is crucial to minimizing their frustration as they become accustomed to this new kind of interaction. Note that I have also provided a sound cue for the reset button in this behavior.

Pressing the Buttons

Load the file step_05.dir.

All of the remaining functionality in this exercise results from pressing buttons on the phone. Since the power and function buttons are a little more involved, I start by "wiring" the buttons that make up the keypad, which simply depress and make sound when clicked.

In this latest revision of the program, I have added a new behavior, Picker, to the 3D-world sprite instance in the main frame of the movie. In this behavior, the mouseDown and mouseUp handlers translate any button model in the 3D world picked by the user on its Z-axis and play a sound cue, creating the impression that the user is actually pressing the buttons.

The first few lines of code in the mouseDown handler should look somewhat familiar. Just as in the Tracking behavior, I have used the modelUnderLoc function here to determine if the user has clicked on a model in the 3D world. However, instead of using the mouseDown and mouseUp behaviors to toggle ongoing functionality (as I did with the rotation of the phone through mouse gesturing in the Tracking behavior), here I simply translate the button picked in one direction on its Z-axis in the mouseDown handler and then back in the opposite direction in the mouseUp handler. Note that the logic of this handler relies in part on the fact that I have strategically named all of the buttons in the phone with the string "button" to differentiate button clicks from clicks on other models. Note also that the mouseUp handler is much leaner than in the "Tracking" behavior, since it does not need to check for models picked or play any sounds.

The Function Buttons

Load the file step_06.dir.

Aside from acting like buttons, the three function buttons (those labeled A, B, and C) need to make the phone's screen change when they are pressed. You can use this to show that the phone's mode of operation is changing, say from calling mode to paging mode to phonebook book; you get the idea. Since the screen is itself a separate model, complete with its own shader, you make this happen by changing the screen shader texture as each button is pressed.

The first step is to create three custom textures from the bitmap cast members, screen_a, screen_b and screen_c, in the first three lines of code in the enterFrame handler within the Initialization behavior. I then use one of the new textures to change the screen to its initial display state. Run the movie to see the new screen display on the phone. The advantage of using bitmap cast members for the screen textures is that you can easily update them by importing new bitmaps. In fact, feel free to substitute your own bitmaps for those supplied here.

he screen textures are derived conveniently from three bitmap cast members.

Figure 4. The screen textures are derived conveniently from three bitmap cast members

Load the file step_07.dir.

The next step in changing the screen when the function buttons are pressed requires enhancing the logic of the Picker behavior. Specifically, the mouseDown handler now features a CASE statement block that differentiates function buttons A, B, C, and the keypad buttons, executing a unique outcome for each. In the case of the function buttons, you switch the texture used by the screen model's shader to the texture the user picked with the function button and play a function button sound.

The Power Button

Load the file final.dir.

The final step in the exercise is to make the phone's antenna extend and retract in response to the power button being pressed. Since I am adding yet another form of button functionality, this requires the addition of a yet another condition to the Picker behavior's CASE block. Now, when the model picked is named "button_on" (the power button), the CASE block executes a two-part IF-THEN-ELSE block which transforms the position of the antenna model based on the value in the flag variable, pAntennaFlag. This code adds bit of realism by handling the power button's own positional transformation, so that it toggles up and down between key presses, instead of with each key press. Note that the mouseUp handler had to be changed slightly to accommodate the fact that the power button's transform is now being handled entirely within the mouseDown handler.

Conclusion

That's it! The next step for you is to start flexing your programming muscles and use the foundational concepts covered here as a starting point for creating even richer and more complex interactions. The techniques that I examined in this product demo exercise only hint at the power of interactive 3D to engage an audience with content that not only looks real, but that acts real as well. Have fun!


About the author

Marty Plumbo is an assistant professor of design at the College of DAAP School of Design in Cincinnati, Ohio where he teaches courses in interactive design and programming for various mediums, 3D modeling and animation, and information design.

He has published and presented on subjects including the design, development and use of interactive 3-dimensional content; interactive educational software development; and the use of networked multi-user environments for teaching and collaboration.

Feel free to e-mail any questions or comments directly to Marty at Marty at martyp at martyplumbo dot com.