Seamlessly Combining 2D and 3D in Flash with Planes, Part 1 [AS3] · Jun 22, 03:50 PM
Integrating Papervision3D in a useful way can be tricky. Suppose you’ve created some useful website widget. When the user clicks the settings button, the widget does a 3D-flip and shows the settings controls on the other side. To achieve this in AS3 and Papervision3D, temporarily transfer both display components into a plane, using MovieMaterial. Hide the component, spin the plane by tweening rotationY (or rotationX), and when the tween is complete make the settings component visible.
In the case where you’re transferring only one display component to one Papervision3D viewport, it’s pretty simple to implement this kind of functionality. It starts to get tricky when you want to transfer multiple display components to one viewport and have those components interact in some way with a 3D world.
To make this task easier, confine 2d to 3d transfers to planes placed in the XY plane where Z=0. Also, lets not move the camera. With these constrains in mind, set up your camera like so:
var camera_z:Number = -500;
camera = new FreeCamera3D(2);
camera.z = camera_z;
camera.focus = -camera.z;
With this camera, when a plane is added with Z=0, it should appear to-scale.
Now, how do you properly transfer a display component (MovieClip or Sprite) to the viewport? What we are talking about here is transferring something from the Flash coordinate system where the top-left corner is coordinate (0,0); right and down are positive, up and left are negative. We are transferring to a system where the center of the space is coordinate (0,0); up and right are positive, down and left are negative.
To complicate matters further, my characterization of 2D and 3D coordinate systems is not the whole store. You can in fact work in multiple coordinate systems. To illustrate this concept in 2D, we aren’t actually always working in a coordinate system where the top-left (TL) corner is (0,0). For example, by adding an onResize function to the stage that positions a Sprite called mainContainer in the exact center whenever the stage is resized, we can create a 2d coordinate system where the exact center is (0,0). If you add another Sprite called spriteContent as a child of mainContainer, it will appear in the center of the screen. To position spriteContent at the left of the screen you would do something like this:
spriteContent.x = - spriteContent.stage.stageWidth/2;
In both 2D and 3D, it is possible to create new coordinate systems by nesting instances of DisplayObject (in 2D) and by nesting instances of DisplayObject3D (in Papervision3D). For the rest of this article, I will only be using the default TL coordinate system for 2D. The reason for this is that in AS3, the DisplayObject class (and all subclasses of DisplayObject) has a getBounds() function which returns the position of the object relative to any other DisplayObject. Therefore, to get the position of a sprite in relation to your Papervision3D viewport you can do:
positionRect:Rectangle = sprite.getBounds( viewport );
At this point, remember that positionRect is in terms of the TL 2D coordinate system where the (0,0) coordinate is the TL corner of your Papervision3D viewport. In order to use this position information, we must perform some math to transfer the sprite to the 3D scene.
First, a pretty illustration to visualize what we’re trying to do:

In the illustration, each box represents a different coordinate system. I’ve just discussed the coordinate systems on the left and the right. The system in the middle is a 3D coordinate system where the origin is at the top-left corner of the viewport. In order to maintain this coordinate system, the DisplayObject3D used as the system’s container needs to be translated to the new origin every time the viewport is resized. In my application, I have a render function that loops through an array of containers and aligns each at this origin point:
private function render():void {// static TL 3d containersfor each (var cont:DisplayObject3D in static3dContainers) {cont.x = camera.x - viewport.viewportWidth / 2;cont.y = camera.y + viewport.viewportHeight / 2;}renderer.renderScene(scene, camera, viewport);}- Download this code: /files/3dCoordFunctions-render.txt
Without further ado, here is the set of utility functions that I’m currently using to transfer an object from one coordinate space to another:
/*** Place a DisplayObject3D inside a new DisplayObject3D container,* and align the top-left corner of the do3d to the origin of the container;* apply the plane's orignal transformation to the container* @paramplane* @paramwwidth of do3d (or nested plane)* @paramhheight of do3d (or nested plane)* @returna DisplayObject3D container with plane as child*/private function do3dAlignTL3d(do3d:DisplayObject3D, w:Number, h:Number):DisplayObject3D {var cont:DisplayObject3D = new DisplayObject3D();cont.x = do3d.x - w/2; //cont.x = plane.x - w / 2;cont.y = do3d.y + h/2; //cont.y = plane.y + h / 2;cont.z = do3d.z;cont.addChild(do3d);do3d.x = w / 2;do3d.y = -h / 2;do3d.z = 0;return cont;}/*** Place a DisplayObject3D inside a new DisplayObject3D container,* and align the top-center of the do3d to the origin of the container;* apply the plane's orignal transformation to the container* @paramplane* @paramwwidth of do3d (or nested plane)* @paramhheight of do3d (or nested plane)* @returna DisplayObject3D container with plane as child*/private function do3dAlignTC3d(do3d:DisplayObject3D, w:Number, h:Number):DisplayObject3D {var cont:DisplayObject3D = new DisplayObject3D();cont.x = do3d.x;cont.y = do3d.y + h/2;cont.z = do3d.z;cont.addChild(do3d);do3d.y = -h / 2;do3d.z = 0;return cont;}/*** Transforms (from Normal Flash Coordinate system) a TL2d point to a StaticTL3d point.* @parampoint in TL2d coord system* @return point transformed to TLStatic3d coord system*/private function TL2dtoTLStatic3d(point:Point):Point {return new Point(point.x, -point.y);}/*** Transforms a TL3d point, to a StaticTL3d point.* @parampoint in TL3d coord system* @return point transformed to TLStatic3d coord system*/private function TL3dtoTLStatic3d(point:Point):Point {return new Point(point.x + viewport.width / 2, point.y - viewport.height/2 );}/*** Transforms a StaticTL3d point, to a TL3d point.* @parampoint in StaticTL3d coord system* @return point transformed to TL3d coord system*/private function TLStatic3dtoTL3d(point:Point):Point {return new Point(point.x - viewport.width / 2, point.y + viewport.height/2 );}/*** Transforms a TL2d point, to a TL3d point.* @parampoint in TL2d coord system* @return point transformed to TL3d coord system*/private function TL2dtoTL3d(point:Point):Point {return new Point(point.x - viewport.width/2, -point.y + viewport.height/2 );}- Download this code: /files/3dCoordFunctions.txt
I’m thinking about integrating some of this functionality into the upcoming AS3 version of the AFW Template. I’d love to get some feedback from people on this. Part 2 of this article series will provide a working example of when you would do this stuff. I know I’ve really glossed over some stuff in this article, so if you have any questions, please post a comment.
— Pickle
Comment
How-To: Rockstar Flash Programming [AS3] Publish And Exclude: Flash CS3 Plugin for Optimizing File Size

unsaluted guayaba dependent mythopoem calorigenic oceanican goosy splenunculus
<a href= http://www.mojospage.8m.com >Mojo Racing</a> http://www.fchd.info/MARSKEU.HTM
<a href= http://cnn.com/2003/LAW/08/27/otsc.toobin/ >Jeffrey Toobin: Federal courts have last word in Alabama</a> http://www.sugarnspicedaycare.org
<a href= http://www.chase-company.com/ >Chase & Company</a> http://www.sankukaikarate.co.uk/
<a href= http://www.newadvent.org/cathen/01660b.htm >Apsidiole</a> http://www.fly-fishing-tackle.co.uk
— Byron Joseph · Aug 18, 05:18 PM · #