This site is now just an archive over the rise and fall of Flash. The domain flashmagazine.com is available for sale
Login | Register
Away3D Basics 3 - The Camera(s)

Away3D Basics 3 - The Camera(s)

The camera is what you view the 3D world through. Just as a real camera, the virtual 3D camera applies perspective to your models by adjusting properties such as zoom, focus and position. In this tutorial you'll learn how to use the 3 cameras available in Away3D.

No matter what you want to do in Away3D, there's some things that you'll always need to set up. The "Basic" tutorials will explain the Scene, View, Camera, Primitives, Textures and explore some of the possibilities. Each example in the series will be organized as Actionscript Classes so they can be used in both Flash and Flex.

If you are new to 3D on computers, you might want to read our introduction that explains the core 3D concepts. This tutorial also contains the source for 6 other Away3D projects that may be worth checking out. To run the example files, you will first need to set up Away3D on your computer. When you have the Away3D source files and your software is set up, you can open, explore and export the examples in this tutorial by just placing them in your project directory.

Away3D Cameras

Away3D offers 3 different cameras: Camera3D, TargetCamera3D and HoverCamera3D. All the cameras offer settings for zoom, focus, depth of field, pan, tilt and position.

All of these cameras have properties that can be set in the constructor like this:

var cam:Camera3D = new Camera3D({zoom:5,focus:200});

They can also be set or changed using the properties directly like this:

var cam:Camera3D = new Camera3D({zoom:5,focus:200});
cam.zoom = 5;
cam.focus = 200;

If you have a SLR camera or even a simple camera that has a proper lens, you will know how the zoom works. The focus property on the other hand decides the focal length of the camera (angle of view). To try this out, take a look at this example:

This content requires Flash Player 9 (or a more recent version). You need to upgrade your Flash Player

movie: Camera.as

Here you can see that the focus works together with the zoom to decide how you view the Scene. Lower focus values will move the "rendering plane" closer to the camera. Higher values wil move it away from it. Tartiflop has written a great tutorial that explains zoom and focus settings for Papervision. For Away3D it's the same, so if you want to learn more, check it out.

cam.pan = 45;
cam.tilt = -10;

Pan and Tilt will do as they say, they will rotate the camera around what it is looking at in either horisontal or vertical direction. You can set both positive and negative values. I initially  mentioned the Depth Of Field. When combined with 2D sprites, this can be used to create depth effects. We'll look closer at this in a later tutorial.

All these properties are all considered when rendering the View. The process of figuring out what triangles are visible though the View/Camera is called Culling. Calculating how something should look in 3D requires a lot of CPU and culling make sure only what is visible to the Camera is calculated.

The 3 cameras work a little differently, so here's a breakdown of each of them and how you use them.

Camera3D

Camera3D is the basic, free form camera. You can move and point it in any direction.

This content requires Flash Player 9 (or a more recent version). You need to upgrade your Flash Player

movie: ExCamera3D.as

Use the keys A, D, W, S and arrow up/down to navigate the 3D space. In this movie, we use a set of standard movement methods available to all Away3D objects:

camera.moveUp(10);
camera.moveDown(10);
camera.moveLeft(10);
camera.moveRight(10);
camera.moveForward(10);
camera.moveBackward(10);

These functions are pretty self explanatory. Note that a new Camera3D is by default positioned in the centre of the 3D world (0,0,0), meaning that if you add a Sphere you will not see anything since the camera is actually inside it. By default, a sphere is only viewable from the outside, so to see the sphere, we either have to invert the sphere ( sphere.invertFaces(); ) or move the camera outside the sphere by setting the cameras Z property like this:

camera.z = -1000;

Here we pull the camera back one thousand units, towards us. Setting the x/y/z properties of the camera will make it move, but remember that any camera must also point to a certain location. By default, the camera will look at the center coordinates of our 3D Scene. To point the camera somewhere else, we use the "lookAt" command:

camera.lookAt( new Vector3D(x,y,z) );

This tells the camera to look at the coordinate x/y/z in our virtual 3D world. You can also make the camera Pan, Tilt and rotate along any of the three axes.

A word of warning about setting the x/y/z properties - make sure you always set the camera position before asking it to "lookAt" something. If you first "lookAt" something and then change the position, the camera will still be looking in the direction set initially. To solve this, always update your "lookAt" reference after positioning the camera or use one of the other cameras that make targeting objects much easier.

TargetCamera3D

TargetCamera3D has all the properties of Camera3D, but it has a special ability to "target" other objects or positions in the 3D world:

This content requires Flash Player 9 (or a more recent version). You need to upgrade your Flash Player

movie: ExTargetCamera3D.as

Use the navigation keys as for the above movie. Using a TargetCamera3D, the methods for moving the camera about get a new meaning. Here the camera is always looking at the target object, so camera.moveLeft actually rotates the camera around the targeted object.

By default, this camera is looking at the center of the coordinate system, but we can change this to any other position by changing the target:

camera.target = sphere;

To see how the targeting works, just click any of the primitives in the example above.

HoverCamera3D

HoverCamera3D has all the properties that TargetCamera3D has, but adds methods that are useful for circling around an object by setting the desired pan and tilt. It also hovers the camera, so that it moves softly from one position to another. You are not limited to circle around objects though, so this is maybe the most versatile camera of them all.

This content requires Flash Player 9 (or a more recent version). You need to upgrade your Flash Player

movie: ExHoverCamera3D.as

Instead of using the move-methods, we now use two custom properties in the HoverCamera3D:

camera.panAngle = 0;
camera.tiltAngle = 0;

These are the angles from 0 to 360 that the camera will Pan and Tilt to. When you set these values, the camera won't move there right away. What is special with the HoverCam is that it will do a tween of the position over a predefined number of "steps":

camera.steps = 16;

By increasing this from the default 8 steps, we'll get a slower and smoother transition from one angle to another. You can also reduce this number, all the way down to zero steps. This will move the camera instantly to it's new position. Note that for the HoverCamera3D to actually "hover", we need to add a little something to our EnterFrame method:

camera.hover();
view.render();

Unless you call camera.hover() the camera will just stand still. There will also be occasions where you want the HoverCam to move to a position instantly. To do that, just pass true to the camera.hover method:

camera.hover(true);

Now it's time to put these properties to use and see how they work.

Orbiting your scene using the Mouse

One of the most classic ways to display a 3D scene is to just move the camera back from the scene center and let the user rotate around the scene using the mouse as in the example below.

This content requires Flash Player 9 (or a more recent version). You need to upgrade your Flash Player

movie: Triaxe.as

I'll now explain what happens in this code. We start by defining some variables that we'll need later.

private var View:View3D;

// HoverCam controls
private var camera:HoverCamera3D;
private var lastMouseX:Number;
private var lastMouseY:Number;
private var lastPanAngle:Number;
private var lastTiltAngle:Number;
private var move:Boolean = false;

We then add a HoverCamera3D and set our view to use that rather than the default camera.

camera = new HoverCamera3D({zoom:2, focus:100, distance:250});
View = new View3D({camera:camera,x:250, y:200});

We set some pan and tilt values on the camera so it opens at an angle a little different from the default:

camera.panAngle = 45;
camera.tiltAngle = 20;
camera.minTiltAngle = -90;
camera.hover(true);

Note that we also call hover(true). If we did not, the camera would start by rotating towards the desired pan/tilt angle. Also note that we set 'minTiltAngle' to minus ninety. This allows us to rotate below the scene, something that is prevented by default.

Next, we add some objects to our Scene and set the scene to render on EnterFrame.

addEventListener(Event.ENTER_FRAME, onEnterFrame);

To grab the values from the Mouse, we define two more listeners and tell these to call functions when they occur:

this.stage.addEventListener(MouseEvent.MOUSE_DOWN, MouseDown);
this.stage.addEventListener(MouseEvent.MOUSE_UP, MouseUp);

In our MouseDown handler, we'll need to save the current pan and tilt values of the camera as well as the position of the mouse. We'll use these to calculate the speed of the camera later.

private function MouseDown(event:MouseEvent):void
{
 lastPanAngle = camera.panAngle;
 lastTiltAngle = camera.tiltAngle;
 lastMouseX = stage.mouseX;
 lastMouseY = stage.mouseY;
 move = true;
}

Note that we're also setting the boolean variable 'move' to true. This variable will tell us if the mouse is down or up, so when the mouse is released, we'll unset it.

private function MouseUp(event:MouseEvent):void
{
 move = false;
}

The last bit we need is where 'the magic' happens, in the EnterFrame handler.

private function onEnterFrame(e:Event):void
{
 // rerender viewport
 var cameraSpeed:Number = 0.3; // Approximately same speed as mouse movement.
 if (move) {
 camera.panAngle = cameraSpeed*(stage.mouseX - lastMouseX) + lastPanAngle;
 camera.tiltAngle = cameraSpeed*(stage.mouseY - lastMouseY) + lastTiltAngle;
 }
 camera.hover();
 View.render();
}

The goal of this function is to calculate a small value that we can add to the target pan and tilt values. We know the previous mouse position ('lastMouseX/lastMouseY') since we saved these in our MouseDown handler. By subtracting the current values, we'll know how far the Mouse have moved. We multiply this with a speed factor ('cameraSpeed') and add the result to the existing values (lastPanAngle/lastTiltAngle). We finish off by calling the hover and render functions to make the view update.

If you want the inverse of this - so the mouse moves in the opposite direction of dragging, you just swap the parameters around:

camera.panAngle = lastPanAngle - cameraSpeed*(stage.mouseX - lastMouseX);
camera.tiltAngle = lastTiltAngle - cameraSpeed*(stage.mouseY - lastMouseY);

This is just one of many possible solutions to rotating around an object and there's many ways you can improve on this. How about adding scrollwheel support for zooming (camera.zoom)? We'll get back to camera movement in many of the following tutorials, so just keep reading to learn more.

 

About Jens C Brynildsen

Jens has been working with Flash since version 3 came out. Since then, he's been an active member of the Flash community. He's created more than a hundred Flash games (thus the name of his blog) but he also creates web/standalone applications, does workshops and other consulting. He loves playing with new technology and he is convinced that the moment you stop learning you die (creatively speaking). Jens is also the Editor of this website.

Get new stories first

Click to follow us on Twitter!

 

Comments


Posted by kat3D on 01/08 at 07:42 PM

I appreciate these tutorials… but why show keyboard interaction with cameras when 99.99% of webdesigners need MOUSE interaction with the scene. It would be wonderful if a camera tutorial was added showing an example of how to control the cameras’ x y and z (and limitting movement) through mouse interaction.
Thank you


Posted by Jens C Brynildsen on 01/09 at 10:10 AM

@kat3D - a good point indeed! I’m kind of covering this in later tutorials, but I don’t explain it at all. I’ll add it asap!

J


Posted by John Brightman on 03/16 at 05:00 AM

I really appreciate these tutorials,in the exmaple Basic05HoverCamera3D and Basic06HoverCamera3D, when I clicked the different object, the camera just focus on it immediantely,now I am wondering if you could tell me how to add some effect when camera changing it’s target, like camera move to the next target smoothly,thanks in advance!


Posted by Jens C Brynildsen on 03/16 at 01:32 PM

@john Just keep reading, it’s in the next tutorial under the heading “Tweening 3D objects”:
http://www.flashmagazine.com/Tutorials/detail/away3d_basics_4_-_manipulating_3d_objects/

J


Posted by pbohny on 04/14 at 11:58 AM

Great tutorials, but having huge problems.

Tested on Flash CS4/Flex3 IDE with 2.3 and 3.3.3 target Player 9 and 10:

a) the big yellow circle does not show on either one

b) suddenly get 2099 error

Error: Error #2099: Das ladende Objekte ist noch nicht weit genug geladen, um diese Informationen zu liefern.
  at flash.display::LoaderInfo/get width()
  at away3d.containers::View3D/updateScreenClipping()
  at away3d.cameras::Camera3D/update()
  at away3d.containers::Scene3D/update()
  at away3d.containers::Scene3D/onUpdate()
  at flash.events::EventDispatcher/dispatchEventFunction()
  at flash.events::EventDispatcher/dispatchEvent()
  at away3d.containers::View3D/notifySceneUpdate()
  at away3d.containers::View3D/render()
  at Basic04Camera3D()
TypeError: Error #1009: Der Zugriff auf eine Eigenschaft oder eine Methode eines null-Objektverweises ist nicht möglich.
  at away3d.core.project::MeshProjector/primitives()
  at away3d.core.traverse::PrimitiveTraverser/apply()
  at away3d.core.base::Object3D/traverse()
  at away3d.containers::ObjectContainer3D/traverse()
  at away3d.containers::View3D/render()
  at Basic04Camera3D()


Posted by Jens C Brynildsen on 04/16 at 08:33 AM

@pbohny Your first problem is easy to reproduce. The Sphere fails to show in all the 2.3 versions, but it is now fixed in the version that is in the Subversion (SVN) repository on Google Code (http://code.google.com/p/away3d/source).

Your other problem is worse since I can’t reproduce it. I’ve tried the code with all versions from 2.0 to 2.3 without seeing the error. Did you make any changes to the code?

J


Posted by Tekorobo on 04/17 at 08:04 PM

Just wanted to say that the HoverCamera example has the following code:

Keyboard.UP : cam.moveForward(10); break;
Keyboard.DOWN : cam.moveBackward(10); break;

which does absolutely nothing.
Currently trying to figure out how to move a hoverCamera in space, including it’s target, so the direction it’s looking at remains the same. And it needs to move forward/backward towards the direction it’s looking at.

(i’m trying to make a simple maze type game to learn all of this)


Posted by Jens C Brynildsen on 04/18 at 09:40 PM

@Tekorobo Good point. I should have cleaned that :)

About moving a HoverCamera - there’s two ways to do this. I’ve formerly used a TargetCam and done the hovering using a Tween Class.

Another good solution is to use the new SpringCam. It’s not documented in this tutorial, but it’s in the Away3D Source files. This camera is next to perfect for chase-cam usage and probably the way I’d do stuff like that now.

J


Posted by shone on 05/20 at 05:08 AM

Hi!

I copied the code Basic04TargetCamera3D.as and Basic05TargetCamera3D.as and Cover.as as they are and tried both of them on my machine, but could not see the largeSphere object in the view as the background. Did anyone else get this same problem?
I checked the code, largeSphere did invoked invertFaces(), anything else could be wrong? What should I do to make the background visible? Thanks in advance!

Shone


Posted by Jens C Brynildsen on 05/20 at 11:08 PM

@shone That is indeed a bug in the Away3D engine. It’s been fixed, but have now re-appeared. I’ve logged it as a bug and I’m also working on preventing such errors in the future.

J


Posted by Jens C Brynildsen on 05/20 at 11:24 PM

... and I should add - you can get around this by using ‘sphere.scaleX = -1;’ instead.

J


Posted by shone on 05/21 at 01:54 AM

Hi Jens,

The ‘sphere.scaleX = -1;’ just works well, amazing.. thanks a lot for your help.

Shone


Posted by turbino on 12/30 at 11:17 AM

At least I want to say that you have to be carful which code you use. Because with the latest version of the code of Away3d the some camera functions like invert.faces doesn’t work!

Maybe you have an idea how to change the code of the “BasicCamera"s to have the same result like the in the old code?


Posted by Jens C Brynildsen on 01/02 at 10:31 PM

@turbino The team is aware of the issue with invertFaces. It’s been on the bug-list for quite some time and hopefully it’ll be fixed soon: http://code.google.com/p/away3d/issues/list

I’d use the scaleX-trick mentioned above to get around it in the meantime.

J


Posted by turbino on 01/03 at 10:22 AM

@ jens C Brynildsen

i have found another trick to get around this problem. you could use bothside() instead of invert.faces. I found that very interesting :D

turbino


Posted by Jens C Brynildsen on 01/03 at 11:23 AM

@turbino That’ll work too, but be aware that bothsides has some side-effects (hehe). It makes the model more heavy to render as it will have more visible faces, so don’t use that on large models.

J


Posted by turbino on 01/04 at 11:19 AM

@ Jens C Brynildsen
Now I have another question. I’ve tried to load a object-data with the .mtl-file to a away3d scene. And I’ve tried a lot things but all of them didn’t work. So maybe you have the “best” idea to load it in a away3d scene!

turbino


Posted by Jens C Brynildsen on 01/04 at 12:14 PM

@turbino The best place to get questions like this answered is really on the Away3D dev-list (http://groups.google.com/group/away3d-dev). It’s really active with more than a thousand members and you’ll get your answers quicker than by posting here :)

That said - the most common problem with .mtl files are that the paths to the texture files are wrong. Have you opened the file and had a look at it?

J


Posted by turbino on 01/04 at 07:45 PM

@Jens C Brynildsen
Yeah that’s a great side! there are a lot of the same problems I have!
Thanks a lot! :D

turbino


Posted by turbino on 01/17 at 04:20 PM

@ Jens C Brynildsen

You were talking about scrolling with the mouse. Can you give me an expamle. I’ve tried the last days to do that but it doesn’t work.
Maybe you can help me!

turbino


Posted by Jens C Brynildsen on 02/05 at 11:16 AM

@turbino yup, but post it at the Away3D dev-list?

J


Posted by evampire on 03/19 at 10:53 PM

I’m not sure if its an error on your part or if its just due to changes in Away3D but the invertFaces(); has to be added after adding the object to the scene =)


Posted by zqshadowzm on 07/18 at 10:39 AM

camera.hover(true);

1137: Incorrect number of parameters. Not more than 0.

why?


Posted by Jens C Brynildsen on 07/19 at 09:51 PM

@zqshadowzm All the tutorials are now updated for the 3.5 version of Away3D. You will get this error if you are using an older version. Go here to get the latest version: http://away3d.com/downloads


Posted by EXIT on 08/04 at 12:45 PM

thanks your tutorial. It’s make me clear about away3D faster.

I just change version to away3_5_0. It makes error about HoverCamera3D. So I change to version 2_5_0, it’s still have the same error.
It’s work in version 2.4. T T

i am so confuse. !!!!


Posted by Jens C Brynildsen on 08/15 at 10:39 AM

@EXIT did you check the syntax in the code above? If you have a problem like that, please make a post on the official Away3D list (http://groups.google.com/group/away3d-dev) and I’ll answer your question there?

Seeing the error message would also be helpful :-D

J


Posted by Bertie on 12/25 at 01:32 AM

I have a question about the hovercamera.

You can turn around the triaxe above to infinity around the green axe.
Around the red and blue axe you can only turn to 90 degrees up and down (you can watch under the model and above the model).
Is it also possible to turn around the triaxe to infinity around the red and blue axe? So you can turn your model in any direction to infinity?

I know you can change minTiltAngle to -Infinity but if you do that, the model is flipping when you turn it around.

Submit a comment

Only registered members can comment. Click here to login or here to register