Table of Contents
Lab 3 - Camera, Text, Sound and Outside Environment
Before You Start
- Download and unzip the Lab 3 Asset File into your working directory (same directory you used last week)
Continuing with your Virtual Room
- You should continue working where you left off last week on the Making a Virtual Room in Panda 3D exercise.
- Camera Lens:
Adjust your camera's field of view (FOV) and near clipping distance so that you see a bit more of the room as you move around in it. A field of view of 50 seems pretty good and a near clipping plane of 0.01.
base.camLens.setFov(<field of view in degrees>) base.camLens.setNear(<distance of near clipping plane - anything closer than this will disappear>) base.camLens.setFar(<distance to far clipping plane - anything further than this will disappear>)
- Onscreen Text:
Add a dynamic text label on your heads-up-display (HUD) simply by creating an OnscreenText object like this:
from direct.gui.OnscreenText import OnscreenText textobject = OnscreenText(pos = (0, -0.9), fg = (1,1,1,1), bg = (0.3, 0.3, 0.3, 0.5), align = TextNode.ACenter, scale = 0.07, mayChange = True)
You can look up the various creation parameters for OnscreenText. And then any time you want to display some text, just set the
textproperty for this object. The following code sets the text to the current camera location values using a python formatted string
textobject.setText("Your location is (%2.2f,%2.2f,%2.2f)" % (base.camera.getX(), base.camera.getY(), base.camera.getZ()))
Make your label show an updated camera position as you move around.
- Localized Sound:
Add some sound to the television broadcast which grows louder as you approach the television set and softer as you move away from it. First you need to create an instance of an Audio3DManager inside the World. You can use the camera object as the reference point for calculating how far the sound is traveling and therefore how much the volume should drop. Set the drop off factor to 10. Then load the sound glenn_launch.wav (from the assets file) and attach it to the television screen. Set the min distance of the sound to 1.2. Make sure to start the sound playing. Play with different drop off factors and min distance values and see how it affects the sound in the room as you move around. Note that for a sound to get localized, the sound has to be stored in a Mono format.
# HINT - Creating a 3D audio manager # Note that 'reference_point' could be the nodepath of a listener's location audio3d = Audio3DManager.Audio3DManager(base.sfxManagerList, <reference point>) audio3d.setDropOffFactor(<drop off factor>) # HINT - Loading a 3D sound and attaching it to an object sound = audio3d.loadSfx(<filename>) sound.setVolume(<volume between 0 and 1>) audio3d.attachSoundToObject(sound, <object> ) audio3d.setSoundMinDistance(sound, <distance>) sound.play()
- Transparent Windows:
Some of the wall panels have windows on them (namely the window and door panels). It would be nice to see through those windows to the world outside! To make the glass see-through in your panels, you need to use textures that store a transparency value for each pixel, as well as the Red/Green/Blue (RGB) information. This transparency information is stored in an image layer called an alpha channel. In this layer, the color white (maximum value) means a opaque surface but the color black (minimum value or 0) means fully transparent. Not all image formats can store an alpha channel along with RGB color information. A new version of the wall_tanned_door and wall_tanned_window with an alpha channel, has been created in the tiff format (extension *.tif). Load this version of those textures into your Room instead of the previous *.png ones. One more step is needed though. You will need to enable the transparency effect on the actual model that receives the texture. Call the following method on the wall panel NodePath the first time you load the model:
Now, let's create an actual outside world. First create the terrain. You can make your own heightmap (512×512 grayscale texture where white is highest and black is lowest) and colormap (512×512 color texture) like you saw in class, or you can use the supplied maps contained in the assets file. Add a
create_terrainmethod to your
Worldclass. Inside it, do the following:
- Create a Heightfield Tesselator and give it the heightmap you have chosen. For the supplied heightmap, set the tesselator's vertical scale to 5.0 and horizontal scale to 0.25. If you make your own, you may want to change these values for a better fit. Then use the tesselator to generate a terrain node that you can position anywhere you want in the world. The position (-64,64,-0.05) works well with the supplied heightmap. Place it directly under the root of your scene graph.
#HINT - Creating a Hightfield Tesselator and a Terrain Node tess = HeightfieldTesselator(<some name you choose>) tess.setHeightfield(Filename(<filename of hightmap>)) tess.setVerticalScale(<vertical scale>) tess.setHorizontalScale(<horizontal scale>) terrain = tess.generate() terrain.reparentTo(render)
- If you call base.toggleWireframe() in your code, you'll see the detail of the generated mesh. If you look carefully, you'll find that at a certain place in the landscape the detail is much greater (i.e. more polygons are generated). Typically you would want to generate more detail where the user is standing. You set this location before you generate the mesh, like this:
tess.setFocalPoint(<heightmap x coord>,<heightmap y coord>)
Note that the coordinates are in heightmap pixels (so 256,256 would place you in the center of a 512×512 map).
- Load the colormap texture and apply it to your terrain node. But first you must generate texture coordinates for your terrain geometry. You can generate texture coordinates for any geometry in a node by making the following call
<nodepath>.setTexGen(TextureStage.getDefault(),TexGenAttrib.MWorldPosition). You will also have to scale the texture and center it by using the
<nodepath>.setTexScale(<texture stage>, <u scale>, <v scale>)and
<nodepath>.setTexOffset(<texture stage>, <u offset>, <v offset>)methods. Good uniform scale would be 1/128 (this value is 1/(<horizontal scale of terrain>*<terrain size>), i.e. 1/(0.25*512)), and centering just involves an offset of -0.5 for both
The sky and the world beyond the terrain is still gray and gloomy. Surround your entire scene with a box that has textures facing the inside to replace the gray color with something interesting. A box like that, with textures depicting a sky already applied, can be found with the name “Models/skybox.egg”. As you can see, this sort of an object is called a skybox. Create a new
create_skyboxmethod in your
Worldclass. Use it to load the skybox model as the member variable self.skybox in your World class, attach it to render and scale it up 200 times. A skybox represents a horizon that the user should never be able to reach and pass through, and therefore it needs to move with the user, always keeping the user at its center. This is easy to do since World already has a move method that updates the camera position. Once the camera position has been updated in that method, give self.skybox the same position as the camera. Try moving outside of the room and notice how the clouds seems to stay put.
NOTE: The clouds textures of the skybox were rendered using the Terragen Tool with a handy skybox rendering script. You can create your own skies with this tool. You can replace the textures of
Models/skybox.eggsimply by opening the file in a text editor and changing the texture filenames to your files.
To add a little bit of an atmosphere (and to save the rendering engine from rendering objects that are very far away), add some fog to your whole scene and play with the values. Don't make the fog too dense or you won't see much through the windows of your house.
# HINT - Adding fog to a sub-tree starting at '<nodepath>' fog = Fog("Fog") fog.setColor(0.6,0.6,0.8) fog.setExpDensity(0.008) <nodepath>.setFog(fog)
/var/www/cadia.ru.is/wiki/data/pages/public/t-vien-11-1/lab3.txt · Last modified: 2011/05/04 21:11 by hannes