Table of Contents

Lab 3 - Camera, Text, Sound and Outside Environment

In-Class Exercises

Before You Start

Continuing with your Virtual Room

  1. 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>) 
  2. 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 text property 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.

  3. 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.
    # HINT - Creating a 3D audio manager
    # Note that 'reference_point' could be the pathnode of a listener's location 
    audio3d = Audio3DManager.Audio3DManager(base.sfxManagerList[0], <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()
  4. 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:
    <NodePath>.setTransparency(TransparencyAttrib.MAlpha) 
  5. Terrain:
    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_terrain method to your World class. Inside it, do the following:
    1. Create a Heightfield Tesselator and give it the heightmap you have chosen. Set the tesselator's vertical scale to 5.0 and horizontal scale to 0.25. Then use the tesselator to generate a terrain node that you place at (-64,64,-0.05) 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) 
    2. 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, and centering just involves an offset of -0.5 for both u and v.
  6. Skybox:
    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_skybox method in your World class. 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.egg simply by opening the file in a text editor and changing the texture filenames to your files.
  7. Fog:
    To add a little bit of an atmosphere, 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)