Understanding the 3D Member
In this section, we'll walk through the 3D cast member by creating some primitive models and texture mapping them using a bitmap image, as shown here:[View full size image]Director's 3D cast member isn't like other members, in that it is not just a single, discrete, piece of media. A 3D member contains a complete three-dimensional world and can consist of models, shaders, textures, cameras, lightseven animations.When a 3D member is instanced onto the Stage as a sprite, the view of the world you see is through a particular camera in that world. There can be one camera or many, and you can switch between them any time you like. You can even have several 3D sprites on the Stage, all instances of the same 3D member, and have each sprite show a different view.You're even able to create animated particle systems to create effects like smoke, rain, and snow. And while you will normally create your models using an external 3D package, Director offers primitive models such as cubes, spheres, and cylinders. You can even generate meshes directly from Lingo, though that's an advanced topic and beyond the scope of this book.Let's begin by creating a 3D cast member, then making and texturing a primitive sphere.
Creating a 3D Sprite
Primitives are simple 3D models and Director offers several different ones such as the plane, sphere, cube, and cylinder, as well as the particle system primitive.
|1. ||Start Director and choose to create a new movie. If you're already in Director choose File > New > Movie. Set the Stage size to 640 x 480, with a gray background.We'll use a gray background to contrast with the default black background of the 3D sprite you will place next.|
|2. ||Choose Insert > Media Element > Shockwave 3D.The 3D viewer window will open, displaying an empty 3D world. Notice in the status bar at the bottom of the 3D window that even though the world is empty, a default camera and lights have been created:|
|3. ||Enter test in the Cast Member Name field at the top of the window, then close the window.You must enter a name for the member, or it won't appear in the cast when you close the window.|
|4. ||Drag the 3D member from the internal cast into channel 1 of the Score. Be sure the sprite's span begins at frame 1.The 3D sprite appears, centered in the Stage.|
|5. ||Use the Sprite tab of the Property inspector to set the sprite's width to 640 and its height to 480.The 3D sprite now fills the Stage, and stays centered. Now, let's create a primitive sphere model within the 3D world.|
Models, within the 3D world, have what is known as a resource. Think of a resource as a cast member, and a model as a sprite or instance of that member. Once a resource has been created you can create many model instances from that single resource.Press Play in the toolbar, then open the Message window. Enter the following:
wrld = member("test")
This creates a reference to the 3D cast member.
spRes = wrld.newModelResource("sphere", #sphere)
This line creates a model resource of type sphere and gives it the name "sphere". You can now create a model from the resource:
This creates a model named sphere, from the model resource referenced by spRes. As soon as you hit Enter, a sphere model appears within the 3D sprite with a default red-and-white checker texture map applied to it:[View full size image]You can increase the size of the sphere by modifying the radius property of the sphere's resource:
The sphere's default radius is 25 units. To make it twice as big, increase the radius to 50 units:
spRes.radius = 50
Now, let's look at replacing the default texture board pattern with an image of our choosing.
Creating a Shader
Before placing a new bitmap image on the sphere model, you need to understand the concept of the shader. A shader defines how the surface of a model responds to light. Its reflectivity, shininess, color, and texture are all affected by the model's shader.There are four different types of shaders that you can create, and each has its own properties: standard, painter, engraver, and newsprint. The standard shader is the most common type and is used when you want to apply a bitmap image to a model. The following image compares the different shader styles:[View full size image]For our purposes, we'll use the standard shader. But feel free to experiment once you know how to create and apply shaders to a model.
|1. ||Within the Message window, enter the following Lingo to create a standard shader:|
ps = wrld.newShader("picShader", #standard)
|2. ||A new, standard, shader named picShader is created within the 3D member, referenced by wrld. The shader itself is referenced by the ps variable. You can now apply the shader to the model. Enter the following:|
wrld.model("sphere").shader = ps
The shader referenced by ps is assigned to the model, replacing the default shader. Notice that although the sphere's checker pattern remains, a shiny spot appears. This is due to the default settings of the standard shader.Now we'll replace the checker pattern with something a little more interesting.
Assigning a Texture
Each texture used in your 3D world is stored within the world. Textures are just bitmap images, and you must pay attention to two things when creating textures for use in 3D.First is the resolution of the images. The length and width of any texture map must be a power of 2. That is, 64x64, 128x128, 128x256, 512x512, 512x256, etc. The length and width can be different, but each needs to be a power of 2. If they aren't, Director will scale the image for you, to the nearest power of 2, typically producing less than desirable results.NoteThe power of 2 rule arises from the way textures are accessed from video memory. By having this requirement the renderer can access specific pixels within the texture, known as texels, using very fast bitshifting operations, instead of slow multipy and divide operations. This requirement came about in order to optimize the texture access speed and was necessary on older graphics cards. Although the rule still applies today, newer generation renderers, such as OpenGL2 will break with this tradition.The second thing to consider is that of your user's video RAM (VRAM). The memory on a video card must be able to accept all your textures, to be able to use hardware acceleration.Director's 3D engine will happily use DirectX or OpenGL for hardware-accelerated rendering, but only if the textures fit in the card's VRAM. If they don't, your scene will still render, but will use a much slower non-hardware accelerated software rendering. Memory is cheap and newer video cards contain 128 MB of RAM and more, so this is less and less a factor. But if you're creating a large 3D scene, it's something to consider.Now, let's import a bitmap image and use it to create a texture on our sphere.
|1. ||Import house.jpg from the Lesson15\media folder on the CD. When prompted, choose a color depth of 24 bits.There's no alpha channel information with JPEG images, so importing at 24 bits will save some space.|
|2. ||Enter the following in the Message window:|
tex = wrld.newTexture("house", #fromCastMember, member("house"))
You just created a new texture named "house" from the cast member of the same name. The texture is referenced by the tex variable. Note the use of the #fromCastMember symbol. This parameter can also be #fromImageObject, allowing you to create textures directly from imaging Lingo objects. Now let's assign the texture to the picShader that is assigned to the sphere.
|3. ||Enter the following in the Message window:|
ps.texture = tex
When you press Enter the house image appears, wrapped around the sphere, as shown here:As you can see, the bottom and edges of the sphere are black. This is due to the default scene lighting. A quick way to make the texture easier to see is to change the emissive property of the model's shader. The emissive property uses a color to alter the brightness of the object. By changing the emissive property to bright white the texture will appear at full brightness, regardless of the lightning.
|4. ||Enter the following in the Message window:|
ps.emissive = rgb(255, 255, 255)
The sphere now appears at full brightness, allowing you to see the bottom:
|5. ||Stop the movie and double-click the 3D sprite, in the Score, to open the 3D viewer window. Click the Rotate Camera button, then click and drag within the viewer window to move the camera around the sphere model:With the shader's emissive property set to bright white, you can see all around the sphere as you rotate the camera. Using the 3D viewer window is a quick way to preview your scene and examine individual models.Note that you can switch between the Rotate, Zoom, and Pan tools on the fly using hotkeys. Press and hold Ctrl/Command to switch to the Zoom tool, and press the Spacebar to pan. The Alt/Option key lets you switch to the Rotate tool if you have another tool selected.Notice that as you move about the sphere, the sprite on the Stage doesn't change unless you want it to. Using the Set Camera Transform button, you can update the camera within the sprite to show the same view as the one in the viewer window:|
|6. ||Move the camera to an interesting view and click the Set Camera Transform button.Clicking the button causes the camera view within the sprite on Stage to change to the view you have in the window.|
|7. ||Close the viewer window when you're finished examining the sphere.Now let's take a look at moving models within the world.|
Translating a Model
Translating a model includes moving, rotating, and scaling the model along one or more axes. As you can see from the following image you can translate your models along either the X, Y, or Z axis:To move a model using Lingo, you use the translate command. For instance, to move the sphere up 10 units, you'd translate it by 10 in the Y axis. Entering the following in the Message window would move the sphere up and right by 10 units each:
wrld.model("sphere").translate(10, 10, 0)
If you wanted to rotate the sphere 45 degrees around its vertical (Y) axis, you would use:
wrld.model("sphere").rotate(0, 45, 0)
If you wanted to turn the sphere into a kind of egg shape, you could scale it along its Y axis like so:
wrld.model("sphere").scale(1, 2, 1):
This has the effect of scaling the model by two times in Y and not scaling at all in either X or Z. To turn the scaled sphere back into a sphere, you would scale it by one-half in Y, like so:
wrld.model("sphere").scale(1, .5, 1)
Before moving on to the next section, let's look at how you might move your camera around the sphere to create an animation.
Moving the Camera
The camera can be moved and rotated, like any other object in your 3D world. By moving the camera on a per-frame basis, you create an animation. Using just a single line of Lingo, you can have the scenes camera orbit the sphere.
|1. ||Double-click the Score's behavior channel at frame 10 to open a Script window. Modify the default exitFrame behavior so it appears as follows:|
on exitFrame me
sprite(1).camera.rotate(vector(0,0,0), vector(0,1,0), 5, #world)
What you're doing is telling the camera to rotate about the vector point (0, 0, 0), which is the center of the world, and where the sphere is created by default. The second vector defines the axis of rotation. Using vector(0, 1, 0) causes the camera to rotate around the Y axis only, keeping it in a level plane. The third parameter, 5, is the number of degrees to rotate. Finally, the #world symbol tells the camera to rotate relative to the world's coordinate system. Without the #world parameter the camera would rotate relative to itself and simply spin about its own center.
|2. ||Rewind and play the movie.The camera orbits the sphere, at 5 degrees per frame. Now that you have a basic understanding of the 3D world, let's start work on the memory game.|
|3. ||Stop the movie before continuing.This was just a test, so there's no reason to save the movie, unless you want to experiment with it further later.|