Skip to content

Away3D 3.6.0: TargetCamera3D spiralling problem fix

August 24, 2011

View/download the Source files for this tutorial here, and view the main swf here. The tutorial also assumes you have a working build of Away3D 3.6.0.

Due to the recent developments with Molehill for Flash Player, I’ve finally decided it’s time to start playing with 3D in Flash. After a brief look around I decided that Away3D seemed to be a good bet; it looks to be pretty actively developed, has some great examples online and critically, will support Molehill.

Cameras are one of the initial concepts you need to get your head around. After a quick search I found this great tutorial which gives an exceptionally clear and concise overview of the main ideas. One thing did bug me a little however; if you scroll down to the TargetCamera3D example, click on the Flash example to gain focus and press the up arrow key on your keyboard until the red sphere fills your screen. Now hold down the A key so that the camera spins around the sphere. Notice how the camera is gradually drifting away from the target object.

If we look at the code for this example, line 69 in ExTargetCamera3D.as tells the camera to move left by 10 units when the A key is pressed:

case 65 : cam.moveLeft(10); break;

moveLeft() is a method of Object3D, which TargetCamera3D extends. The description for this method is as follows: “Moves the 3d object backwards along it’s local x axis”. Next, the code within the getter function for away3d.cameras.TargetCamera3D.viewMatrix forces the camera to lookAt() it’s target when the position is updated. So in summary, move left, perpendicular to the direction you are facing, then at the end of the move, turn to face the target object.

The following diagram demonstrates how this behaviour causes the camera to quickly drift out of the circular orbit you may expect into a spiral pattern, first moving directly to it’s left, then turning to face the sphere.

cam3d_drift

In order to resolve this, I’ve made a few small changes to the tutorial. You can find all the code you’ll need in the first sentence of this tutorial.

The following lines in our main app class contain the first important difference from the previous tutorial:

// create a basic camera
cam = new TargetCamera3D2();
cam.movePivotBackward(1000);
// add cam to scene!
view.scene.addChild(cam);

Instead of moving the camera backward via the line:

cam.z = -1000;

We are now using the newly defined function:

cam.movePivotBackward(1000);

Also, just as critically we’re now adding the camera to the 3D scene. If we don’t do this our movePivotBackward() and movePivotForward() functions won’t work as our camera object will never be forced to validate by the scene graph, so will never get around to updating the position of the pivot.

The next key difference in the app code is that instead of using the moveUp(), moveDown(), moveLeft() and moveRight() functions on Object3D in order to move the camera, we are now using it’s rotation functions pitch() and yaw():

private function update(e:Event):void
{
  var distance:uint = 5;
  var rotateStep:uint = 1;

  if(keyIsDown){
    // if the key is still pressed, just keep on moving
    switch(lastKey){
      case KEY_W: cam.pitch(rotateStep); break;
      case KEY_S: cam.pitch(-rotateStep); break;
      case KEY_A: cam.yaw(rotateStep); break;
      case KEY_D: cam.yaw(-rotateStep); break;
      case Keyboard.UP: cam.movePivotForward(distance); break;
      case Keyboard.DOWN: cam.movePivotBackward(distance); break;
      case Keyboard.LEFT: cam.roll(rotateStep); break;
      case Keyboard.RIGHT: cam.roll(-rotateStep); break;
    }
  }
  // render the view
  view.render();
}

You’ll notice I’ve also introduced the ability to roll the camera using the left and right keys, as well as defining my own functions on the camera class for the up and down keys. Using the W,A,S,D and UP, DOWN, LEFT, RIGHT keys to navigate, have a play with the version below. Try zooming into the sphere as far as you can go as before by pressing the UP key, then hold the A key down. You’ll notice that it no longer displays the spiralling behaviour.

targ_cam_clickToOpen

You may also notice another subtle change in behaviour from the previous tutorial.

targ_cam_rotate

In the previous tutorial’s swf, If you move the camera to the top of the sphere by holding the W key, then hold the A key, you’ll notice the camera quickly spirals around the topmost point of the sphere (see 1. in the above diagram), then gradually drifts outwards and downwards in a path similar to the apple peel above . This is due to the fact that we are telling the camera to “move left” rather than “rotate left”, and after moving directly left it turns to face the centre of the target object again. In our new tutorial, the camera orbits around the object on the designated axis (see 2.).

Finally, one other point worth mentioning is the difference in implementation regarding the TargetCamera3D2.target property.

public function set target( value:Object3D ):void
{
  if ( _target == value )  return;
  _target = value;
  position = _target.position;
}

When our new camera’s target is set, we update the position of our camera to be the centre of the target object. When we move the camera’s internal pivot point backward using movePivotBackward(), it continues to look at the 0,0,0 point in it’s own coordinate space; it just so happens that it’s internal zero point is exactly aligned with the zero point of the target object’s coordinate space, hence rotating the camera within it’s internal coordinate space rotates it perfectly around the target object.

Hope that makes sense and is of some use to someone! :-)

Advertisement

From → Away3D, Flash, Tutorials

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.