Camera classes

Away3D includes a number of camera classes. We have already used the Camera3D class, which is referenced by the Away3DTemplate class introduced in Chapter 1, Building Your First Away3D Application. The Camera3D class can be positioned and transformed within the scene, but it does not have the ability to easily track, follow, or slide around a 3D object. Instead, this functionality is provided by the TargetCamera3D, HoverCamera3D, and SpringCam classes.

To demonstrate these additional camera classes we will create an application called CameraDemo. This application will allow us to use these cameras to view a sphere primitive that can be moved around within the scene in response to keyboard input.

package
{

The camera classes are found in the away3d.cameras package.

  import away3d.cameras.HoverCamera3D;
  import away3d.cameras.SpringCam;
  import away3d.cameras.TargetCamera3D;
  import away3d.core.clip.FrustumClipping;
  import away3d.core.render.Renderer;
  import away3d.core.utils.Cast;
  import away3d.materials.BitmapMaterial;
  import away3d.primitives.Plane;
  import away3d.primitives.Sphere;

  import flash.events.Event;
  import flash.events.KeyboardEvent;
  import flash.events.MouseEvent;

  public class CameraDemo extends Away3DTemplate
  {

This embedded texture file will be applied to the ground (represented by a plane primitive) to provide a reference point for the moving sphere.

    [Embed(source="checkerboard.jpg")] 
    protected var CheckerBoardTexture:Class;

The sphere property will reference the sphere primitive that will be added to the scene.

    protected var sphere:Sphere;

The three cameras demonstrated by this application (the hover camera, target camera and spring camera) are each referenced by their own similarly named property.

    protected var hoverCamera:HoverCamera3D;
    protected var springCamera:SpringCam;
    protected var targetCamera:TargetCamera3D;

The lastStageX and lastStageY properties are used to store the position of the mouse during the last frame. This will allow us to find out how far the mouse has moved in any given frame.

    protected var lastStageX:Number;
    protected var lastStageY:Number;

The mouseButtonDown property will be set to true when the mouse button has been pressed, and false when it has been released.

    protected var mouseButtonDown:Boolean;

The spring and target cameras are best demonstrated tracking a moving target. These four properties will be true when the corresponding arrow keys on the keyboard are pressed, and false when they are released. That in turn allows us to move and turn the sphere by a small amount every frame in response to keyboard input.

    protected var moveForward:Boolean;
    protected var moveBackward:Boolean;
    protected var turnLeft:Boolean;
    protected var turnRight:Boolean;

    public function CameraDemo()
    {
      super();
    }

    protected override function initEngine():void
    {
      super.initEngine();

In this demo, the default renderer can introduce some z-sorting issues between the sphere and the ground plane. Using the Quadtree renderer (which was covered in Chapter 4, Z-Sorting) provides a simple fix for this problem.

      view.renderer = Renderer.CORRECT_Z_ORDER; 

We can also run into some trouble where the ground plane is culled when it is still visible on the screen. Assigning a new FrustumClipping object to the view's clipping property ensures that only those parts of the ground plane that are not visible are culled.

      view.clipping = new FrustumClipping();
    }

The initScene() function is used to create a sphere primitive, a plane primitive to represent the ground, and add both 3D objects to the scene. A checkerboard material is applied to the plane primitive, which gives us a point of reference as the sphere primitive is moved around the scene.

    protected override function initScene():void
    {
      super.initScene();
      sphere = new Sphere(
        {
          radius: 10,
          y: 10
        }
      );
      scene.addChild(sphere);

      var plane:Plane = new Plane(
      {
       material: new BitmapMaterial(Cast.bitmap(CheckerBoardTexture)),
          width: 500,
          height: 500
        }
      );
      scene.addChild(plane);

The addHoverCamera() function is then called, configuring the hover camera as the initial camera.

      addHoverCamera();
    }

The initListeners() function contains code to register functions against several different events. For this demo, we need to listen for when keys on the keyboard are pressed (KeyboardEvent.KEY_DOWN ) and released (KeyboardEvent.KEY_UP), when the mouse button is pressed (MouseEvent.MOUSE_DOWN) and released (MouseEvent.MOUSE_UP), and also for when the mouse is moved (MouseEvent.MOUSE_MOVE).

    protected override function initListeners():void
    {
      super.initListeners();
      stage.addEventListener(
        MouseEvent.MOUSE_DOWN, 
        onMouseDown
      );
      stage.addEventListener(
        MouseEvent.MOUSE_UP, 
        onMouseUp
      );
      stage.addEventListener(
        MouseEvent.MOUSE_MOVE, 
        onMouseMove
      );
      stage.addEventListener(
        KeyboardEvent.KEY_DOWN, 
        onKeyDown
      );
      stage.addEventListener(
        KeyboardEvent.KEY_UP, 
        onKeyUp
      );
    }

    protected override function onEnterFrame(event:Event):void
    {
      super.onEnterFrame(event);

If the hover camera is the current camera, we need to call its hover() function. This will update the position and orientation of the hover camera, moving it towards the target angles that we have given it in response to the movement of the mouse.

      if (hoverCamera != null) hoverCamera.hover();

Likewise if the spring camera is the current camera, we need to access the view property. This does much the same job as the hover() function on the hover camera, and will move the camera in response to the movement of the target 3D object it is following.

      if (springCamera != null) springCamera.view;

Depending on which arrow keys are currently pressed on the keyboard, the sphere will be moved using the moveForward() and moveBackward() functions, and rotated using the yaw() function.

      if (moveForward) sphere.moveForward(5);
      else if (moveBackward) sphere.moveBackward(5);
      if (turnLeft) sphere.yaw(-5);
      else if (turnRight) sphere.yaw(5);
    }

When the mouse button has been pressed down, the MouseEvent.MOUSE_DOWN event will be dispatched, and the onMouseDown() function is called.

    protected function onMouseDown(event:MouseEvent):void
    {

We set the mouseButtonDown property to true to indicate that the mouse button is currently pressed.

      mouseButtonDown = true;

We store the current position of the mouse in the lastStageX and lastStageY properties, which will allow us to calculate how far the mouse has moved next frame.

      lastStageX = event.stageX;
      lastStageY = event.stageY;
    }

When the mouse button is released the MouseEvent.MOUSE_UP event is dispatched, and the onMouseUp() function is called.

    protected function onMouseUp(event:MouseEvent):void
    {

The mouseButtonDown property is set to false to indicate that the mouse button has been released.

      mouseButtonDown = false;
    }

When a key is pressed on the keyboard, the KeyboardEvent.KEY_DOWN event is dispatched, and the onKeyDown() function is called. It is here that we set the moveForward, moveBackward, turnLeft, and turnRight properties to true, if their corresponding arrow key was pressed.

    protected function onKeyDown(event:KeyboardEvent):void
    {
      switch (event.keyCode)
      {
        case 38: // UP ARROW
          moveForward = true;
          break;
        case 40: // DOWN ARROW
          moveBackward = true;
          break;
        case 37: // LEFT ARROW
          turnLeft = true;
          break;
        case 39: // RIGHT ARROW
          turnRight = true;
          break;
      }
    }

When a key is released on the keyboard, the KeyboardEvent.KEY_UP event is dispatched, and the onKeyUp() function is called. It is here that we set the moveForward, moveBackward, turnLeft, and turnRight properties to false, if their corresponding arrow key was released.

    protected function onKeyUp(event:KeyboardEvent):void
    {
      switch (event.keyCode)
      {
        case 38: // UP ARROW
          moveForward = false;
          break;
        case 40: // DOWN ARROW
          moveBackward = false;
          break;
        case 37: // LEFT ARROW
          turnLeft = false;
          break;
        case 39: // RIGHT ARROW
          turnRight = false;
          break;

We also watch for the 1, 2, or 3 keys on the keyboard being released. In response to these keys being released, we call the addHoverCamera(), addSpringCamera(), or addTargetCamera() functions. Each of these functions initializes a new type of camera through which the scene is viewed.

        case 49: // 1
          addHoverCamera();
          break;
        case 50: // 2
          addSpringCamera();
          break;
        case 51: // 3
          addTargetCamera();
          break;
      }
    }

The remaining code deals with the creation and updating of the three different camera classes.

Target camera

The target camera acts just like the regular camera, with the exception that it will orient itself to always keep a particular 3D object in the centre of its view. Releasing the 3 key on the keyboard will cause the addTargetCamera() function to be called, which will create and activate the target camera.

    protected function addTargetCamera():void
    {

When a new camera is added to the scene, the references to the other two cameras are set to null.

      hoverCamera = null;
      springCamera = null;

The target camera is represented by the TargetCamera3D class. In the following code, we create a new instance of the TargetCamera3D class, supplying an init object to the constructor that defines the target 3D object for the camera, as well as placing the camera 100 units up along the Y-axis, giving it a global position of (0, 100, 0).

The target init object parameter is the only one recognized by the TargetCamera3D class. However, like all cameras, the TargetCamera3D class extends the Camera3D class, and init object parameters for the Camera3D class can also be passed to the TargetCamera3D constructor.

        targetCamera = new TargetCamera3D(
        {
          target: sphere,
          y: 100
        }
      );

To view the scene through the new camera, we assign it to the View3D camera property.

      view.camera = targetCamera;
    }

The following table lists the init object parameters recognized by the TargetCamera3D class:

Parameter

Data Type

Default Value

Description

target

Object3D

new Object3D()

Defines the 3D object targeted by the camera.

Hover camera

Like the target camera, the hover camera always looks at a target 3D object, but it can also move around it as if it were sliding across the surface of an ellipsoid that surrounds the target. This provides an easy way to view a 3D object from all angles, and by responding to the movement of the mouse can be used to create a natural interface to manipulate how the scene is viewed.

    protected function addHoverCamera():void
    {
      springCamera = null;
      targetCamera = null;

The hover camera is represented by the HoverCamera3D class. Here, we create a new instance of the class, and supply an init object to define the target 3D object that the camera will always look at, the distance that the camera will be placed from the 3D object, the minimum tilt angle that the camera will be able to use, and the initial target tilt angle. The table below lists all the init object parameters that can be passed to the HoverCamera3D constructor.

      hoverCamera = new HoverCamera3D(
        {
          target: sphere,
          distance: 100,
          mintiltangle: 5,
          tiltAngle: 45
        }
      );

      view.camera = hoverCamera;
    }

In this application, the position of the hover camera is controlled using the mouse. We have already seen that the mouseButtonDown property is set to true or false by the onMouseDown() and onMouseUp() functions in response to the mouse button being pressed or released. Now, when the onMouseMove() function is called in response to the MouseEvent.MOUSE_MOVE event, we can modify the position of the hover camera.

    protected function onMouseMove(event:MouseEvent):void
    {

If the mouseButtonDown property is set to true, indicating the mouse button is being held down, and the hoverCamera property is not null, indicating that the hover camera is the current camera, we will use the movement of the mouse to modify the angle of the hover camera.

      if (mouseButtonDown && hoverCamera != null)
      {

The angle to pan (which is rotation around the Y-axis) the hover camera by is calculated using the distance the mouse has moved horizontally across the screen. By subtracting the current horizontal position of the mouse (event.stageX) from the horizontal position of the mouse from the last frame (lastStageX), we can work out how far the mouse has moved during the last frame.

        var pan:int = (event.stageX - lastStageX);

The angle to tilt (which is rotation around the X-axis) the hover camera by is calculated in a similar way, only this time we use the current and last vertical position of the mouse to find its vertical movement over the last frame.

        var tilt:int = (event.stageY - lastStageY); 

The hover camera has two properties that define how it should be positioned around the target 3D object. The first is panAngle. This property defines the desired angle around the Y-axis that the hover camera should have. The second property, tiltAngle, defines the desired angle around the X-axis that the camera should have.

Assigning a value to either of these properties will not immediately jump the camera to a new position. Instead, the camera will incrementally update its position and orientation with each call to the hover() function. So by calling the hover() function once each frame in the onEnterFrame() function, the hover camera will eventually reach the desired position specified by the panAngle and tiltAngle properties.

        hoverCamera.panAngle += pan;
        hoverCamera.tiltAngle += tilt;

The position of the mouse is then stored in the lastStageX and lastStageY properties.

        lastStageX = event.stageX;
        lastStageY = event.stageY;
      }
    }

The following table below lists the init object parameters recognized by the HoverCamera3D class:

Parameter

Data Type

Default Value

Description

yfactor

Number

2

Fractional difference in distance between the horizontal camera orientation and vertical camera orientation. Higher values mean the camera will be placed further from the target 3D object as the camera moves above or below it.

distance

Number

800

The distance from the camera to the target 3D object when the tiltangle is zero. The yfactor property can be used to change this distance with the vertical movement of the camera.

wrapPanAngle

Boolean

false

Defines whether the value of the pan angle wraps when over 360 degrees or under 0 degrees.

panAngle

Number

0

The desired rotation of the camera around the Y axis, measured in degrees.

tiltAngle

Number

90

The desired rotation of the camera around the X axis, measured in degrees.

minTiltAngle

Number

-90

Minimum bounds for the tiltAngle property.

maxTiltAngle

Number

90

Maximum bounds for the tiltAngle property.

steps

int

8

Fractional step taken each time the hover function is called. Larger values result in the camera moving smaller distances with each call to the hover function.

Spring camera

The spring camera, represented by the SpringCam class, provides a camera that will follow a 3D object as it moves around the scene as if it were attached by a spring.

    protected function addSpringCamera():void
    {
      hoverCamera = null;
      targetCamera = null;

      springCamera = new SpringCam();
      springCamera.target = sphere;
      view.camera = springCamera;

    }
  }
}

The SpringCam class is unusual in that its initial properties cannot be specified via an init object. The constructor will accept an init object, which is passed to the base Camera3D constructor, but all of the properties specific to the SpringCam class have to be set individually once a new SpringCam object has been created. The following table lists all of the public properties exposed by the SpringCam class:

Parameter

Data Type

Default Value

Description

target

Object3D

null

The target 3D object that the camera should follow. If this property is null, the camera will behave like a standard Camera3D.

stiffness

Number

1

The stiffness of the spring, which defines how hard it is to extend. Higher values for this property mean the camera will trail the target at a more fixed distance.

damping

Number

4

Defines the internal friction of the spring, which affects how quickly the spring will snap back. Higher values will reduce how much the camera will bounce. This value should be between 1 and 20.

mass

Number

40

The mass of the camera. Higher values will increase the resistance of the camera to the pull of the target 3D object, and give it more momentum when it is moving.

positionOffset

Vector3D

Vector3D(0,5,-50)

The resting position of the camera relative to the position of the target 3D object.

lookOffset

Vector3D

Vector3D (0,2,10)

The position relative to the target 3D object that the camera should look at.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.147.131