March 96 - Generating QuickTime VR Movies From QuickDraw 3D
Generating QuickTime VR Movies From QuickDraw
Philip McBride
QuickTime VR is a new technology from Apple that provides users with a virtual
reality experience through interactive panoramic and object movies. You can generate
images for QuickTime VR movies with either a real camera or a three-dimensional
rendering system such as QuickDraw 3D. Here you'll learn how to create images from
QuickDraw 3D models and generate movies from these images with the QuickTime VR
Authoring Tools Suite version 1.0.
QuickTime VR lets you create two kinds of interactive virtual reality
movies:panoramic movies and object movies. In a panoramic movie, users can
interactively view a scene at nearly all camera angles from a particular point in
space, which gives them the impression of being there and looking around. In an object
movie, users can interactively spin an object around and thereby see it from all sides.
Panoramic and object movies can be linked together or used separately.
QuickTime VR has several advantages over three-dimensional modeling systems for
making interactive movies. Its movie files are much smaller than complex 3D models
in situations where complete interactivity with the scene isn't necessary, or where
the scene contains complex objects or large numbers of textures. With QuickTime VR,
the complexity of the scene and the number of textures used are irrelevant to runtime
performance, so even users with lower-end machines can effectively interact with the
scene. Finally, a QuickTime VR scene needs only a few megabytes of free space in
memory, much less than the enormous amount of RAM usually taken up by complex 3D
scenes.
You can create QuickTime VR movies using either digitized images captured from a real
camera or synthetic images generated by a 3D rendering system, such as QuickDraw
3D. In this article, you'll learn how to generate images with QuickDraw 3D and
convert them to QuickTime VR movies. To make a panoramic movie, you create a
panoramic image from a 3D scene, generate a linear QuickTime movie from the image,
and convert the linear movie to an interactive panoramic movie using the QuickTime
VR Authoring Tools Suite (ATS). (The ATS is a set of tools that you use from within
MPW, the Macintosh Programmer's Workshop.) To create an object movie, you
generate a series of images from a 3D model, add the images to a linear QuickTime
movie, and then use the QuickTime VR ATS to convert the linear movie to an interactive
object movie.
Before we get into the specifics of making movies, we'll explore the basic concepts of
QuickTime VR. We assume you have a general understanding of QuickDraw 3D, which
you can get by reading "QuickDraw 3D: A New Dimension for Macintosh Graphics" in
develop Issue 22 and "The Basics of QuickDraw 3D Geometries" in develop Issue 23.
You can learn all about QuickDraw 3D in the book 3D Graphics Programming With
QuickDraw 3D.
This issue's CD contains all the code necessary to generate panoramic images and linear
object movies from QuickDraw 3D models. For brevity, the listings in the article omit
error handling; the code on the CD includes the complete versions of these functions.
QUICKTIME VR BASICS
The basic components of QuickTime VR movies are panoramas, nodes, objects, and
scenes.
• A panorama is an image spanning 360deg. or less in a real or virtual
scene. The image is viewed from a particular location in the scene, called
anode. A single-node panoramic movie enables a user to look in all directions
from that location.
• An object is an interactive item that can be viewed from all angles. Object
movies can be linked to panoramic movies in a scriptable authoring
environment, enabling a user to pick up and turn the objects from within a
panorama. Object movies can also be used independently of panoramic movies.
• In our case, the object of the movie is generated from a QuickDraw 3D
model, which contains a single geometric object (or group of objects); we'll
use the term model in this article to refer to the object in a QuickTime VR
object movie.
• A scene is a collection of several panoramas or nodes, a panorama with
one or more objects, or several panoramas and objects all linked together by
interactive hot spots. In a multinode scene, a user can navigate from node to
node to move about the scene.
SHOOTING AN OBJECT
For object movies, you need to photograph the model (or the real object) from all
directions, as shown in Figure 1. All vertical camera positions above the center of the
model are considered positive, and all positions below it are considered negative. The
vertical position with the camera directly above the model looking down at it is called
vertical pan 90deg.; the vertical position directly below and looking up is called
vertical pan -90deg.. Vertical pan 0deg. is at the model's center (equator). Horizontal
positions are measured in degrees from horizontal pan 0deg. to 360deg.. Horizontal
pan 0deg. is typically at the back of the model.
Figure 1. Shooting a model (or a real object)
Images must be stored as frames in row order from top to bottom in a linear
QuickTime movie. For best results, we (along with the QuickTime VR documentation)
recommend that you have a frame every 10deg. between positions in both the
horizontal and vertical direction. If you shoot at increments greater than 10deg., the
motion of the model in the QuickTime VR movie will be choppier when the user turns
it. If you shoot at increments of less than 10deg., the motion will be smoother, but
you'll need more disk space to store all the frames. Whatever increment you choose, it
should be consistent between all horizontal and vertical frames for the object and
divide evenly into the horizontal and vertical pan ranges.
Your first frame at each horizontal position should be of the back of the model, so that
the frame showing the front of the model is halfway through the series at that
horizontal position. This improves disk access time at run time since the user will
most likely be looking at the front of the model.
SHOOTING A PANORAMA
If you're using a real camera to shoot a panorama, you need to take the appropriate
number of equally spaced pictures in a circle, as shown in Figure 2.
Figure 2. Shooting a panorama
Although this sounds simple, there are a few things you must be aware of. First, you
need to make sure you're taking the right number of shots for the lens you're using
(see Chapter 6 in Volume 1 of the QuickTime VR ATS documentation for a full
explanation of this). The entire camera rig should be level at all times, and the nodal
point of the lens should be directly over the point of rotation of the rig. For best
results, you should also have a consistent overlap between images; the more overlap,
the better (30% to 50% is recommended). Finally, you should maintain consistency
between images in each panorama by using similar exposure and a fixed focus.
Because this can get quite complicated, Apple strongly recommends the use of a
professional photographer for making any production-quality titles. However, one way
around this is to use rendered data, as we do in this article. The programmatic control
we have over the "virtual" camera in a 3D environment such as QuickDraw 3D
eliminates all of the problems just mentioned.
MAKING MOVIES WITH THE SAMPLE CODE
The sample code on this issue's CD enables you to make object and panoramic movies
from any 3DMF file (a file that conforms to the QuickDraw 3D Object Metafile
standard). For either type of movie, the code creates a new document record structure,
reads in the model from a 3DMF file, renders the images, and writes out the images in
a form that the QuickTime VR tools can work with. Here we'll look at the first few
steps, which are common to both types of movies. The other steps for making
QuickTime VR movies -- rendering and writing out the images and converting linear
movies to interactive movies -- are different for object and panoramic moviemaking
and are described later.
CREATING A NEW DOCUMENT
All of our scene information is stored in a document record structure, shown in Listing
1.
Listing 1. The document record structure for a scene
typedef struct _DocumentRecord {
CWindowPtr theWindow; // Display window
FSSpec theFileSpec; // Model file specification
short fRefNum; // and reference
GWorldPtr drawContextOffScreen; // Offscreen buffer
TQ3GroupObject documentGroup; // Main group for the document
TQ3ViewObject theView; // The document's view object
TQ3Matrix4x4 modelRotation; // The model transform
TQ3Point3D documentGroupCenter; // Center of the model
... // Miscellaneous view, model, and QuickTime file details
} DocumentRecord, *DocumentPtr, **DocumentHandle;
The MyNewDocument function (Listing 2) creates the document record structure and
sets up the view, camera, and other elements associated with the scene. It also adds the
background buffer and window used to display the rendered images of the scene.
Listing 2. Creating a new document record structure
DocumentPtr MyNewDocument()
DocumentPtr theDocument;
CWindowPtr theWindow;
TQ3DrawContextObject theDrawContext;
Rect myBounds = kMyBoundsRect;
TQ3CameraObject camera = NULL;
RGBColor blackColor = kMyBlackColor;
...
theDocument = (DocumentPtr)NewPtrClear(sizeof(DocumentRecord));
// Create the window for the document record and add references to
// the document record.
theWindow = (CWindowPtr)NewCWindow(0L, &myBounds,
"\pRendering Window", true, documentProc, (WindowPtr)-1L,
true, NULL);
theDocument->theWindow = theWindow;
// Create and set up the offscreen GWorld/context.
// ** Notice that QuickDraw 3D prefers direct color. **
NewGWorld(&theDocument->drawContextOffScreen, 32,
&theWindow->portRect, nil, nil, 0L);
...
SetGWorld(theDocument->drawContextOffScreen, nil);
EraseRect(&theDocument->drawContextOffScreen->portRect);
...
// Create the new pixmap draw context.
theDrawContext = MyNewDrawContext(theDocument);
// Create the view and set up the view attributes.
...
// Initialize the model rotation and transitions used for object
// movie rotations.
Q3Matrix4x4_SetIdentity(&theDocument->modelRotation);
// Add more model and view properties to the document record.
...
// Create the camera and add it to the view.
camera = MyNewCamera(theDocument->theWindow);
Q3View_SetCamera(theDocument->theView, camera);