Monday, August 1, 2011

Animating perspectiveProjection AS3 (CS5)

I use TweenMax a lot, but sometimes you need to animate a complex object or 3D object.

In this case, it's the perspectiveProjection class of the native 3D features of flash player 10, in particular it's fieldOfView and focalLength properties.

Why bother with this at all? Well, although you probably can't do mesh, the native 3D features can be much faster than libraries like Away3D for simple 3D effects.

View demo. Download example.

And below is the code, just in case you want to jump right in... (sorry for the procedural code!)

import com.greensock.TweenMax;
import com.jibjub.quickZsort;, 10, {rotationX:700, rotationZ:400, rotationY:500, repeat:-1, yoyo:true});

//new PerspectiveProjection
var pers:PerspectiveProjection = new PerspectiveProjection();
//set the field of view - doesn't really do much
pers.fieldOfView = 1;//Default: 55, Range: 1 - 180
//set the focal length
pers.focalLength = 1000;//Default: 663
//set the projection center to stage center for a straight view
pers.projectionCenter = new Point(stage.stageWidth * 0.5, stage.stageHeight * 0.5);

// tween the perspective projection, 1, {fieldOfView:179, repeat:-1, yoyo:true});

// apply the perspective each frame (and also z-sort out clips)
addEventListener(Event.ENTER_FRAME, function(){
    //assign to target/DisplayObject
    cube_test.transform.perspectiveProjection = pers;

stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
addEventListener(Event.RESIZE, onResize);
stage.addEventListener(Event.RESIZE, onResize);

function onResize(e:Event) {
    // keep our vanishing point centred
    pers.projectionCenter = new Point(stage.stageWidth * 0.5, stage.stageHeight * 0.5);
    // keep our cube centred
    cube_test.x = stage.stageWidth * 0.5;
    cube_test.y = stage.stageHeight * 0.5;


vmedium said...

thanks for this. you should check out for all of your little snippets you post, it would be great to be able to look through all your snippets. It would also be cool if you expanded on this as well.

vmedium said...

noticed that it fails if i make a plane, and then make a plane at exactly the same z depth. my fix was to just add 1 extra pixel to z.

here is my class: