Papervision3D 2.0 (Great White) in Flex 3 (Part II & III combined) with source code

YahooMap in PV3D

The purpose of this demonstration is to use Yahoo Map and Papervision3D as a base for creating/importing 3D Objects with reference to actual locations on planet Earth using the Adobe Flex framework.

In this post I will be covering how to integrate Yahoo Maps AS3 API as an Interactive Material in PV3D 2.0 and solutions to the following problems:

- Security sandbox violation when using Yahoo Map as MovieMaterial (i.e. BitmapData.draw problem)
- Mapping Longitude and Latitude values to X and Y coordinates of a PV3D material
- Dragging Yahoo Map in PV3D (avoiding the map panning collision with PV3D)
- Simple gauge component from the ground up using basic trigonometry
- Simple tilt component again using basic trigonometry
- Making a visual component using Degrafa

Demonstrations of these solutions are packed in this air application for which you can also see and download fully functioning source code.

The application was built in Flex 3 using following API's:

Yahoo Maps AS3
You can download it here.
Also don't forget to acquire a free API key to run your app online. It is not necessary for local testing in debugger through Flex.

Papervision3D 2.0 (Great White)
You can find excellent tutorials here.
Source is available as a SVN repository here.

Official site:
SWC is available here.

Security sandbox violation when using Yahoo Map as MovieMaterial i.e. BitmapData.draw() problem

When processing a MovieMaterial, PV3D uses the infamous BitmapData.draw method in MovieMaterial/bitmapDraw. This is a problem because the method will not yield a result if the origin of BitmapData is not in the same domain.
In case you have access to the server that you are loading the image data from, you can solve this problem by adding an appropriate crossdomain.xml file to that server.

This article from Adobe’s Deneb Meketa covers security updates in Flash Player 9 including very important changes to the crossdomain.xml structure. Whenever you have a Flash security based headache, this is a good starting point.

In case you can’t put crossdomain.xml on the image origin server, as is the case with Yahoo severs, you are supposed to use the checkPolicyFile property of the LoaderContext class, but that works only if we are directly loading the image data ourselves.

In our case image (map tiles) loading is being handled by YahooMap.swc and we don't have access to the aforementioned process. We could do an override, if we knew where the darn thing was, which I don't.

Sadly, the only solution for this problem that I could implement was by using Air, which is why I'm sharing this as an Air app rather than via a browser version - Air is much easier to deal with when it comes to security. As far as I'm concerned, problem solved for now.

I did hear some gossip that this will be sorted out in Flash Player 10, but who's going to wait for that?

I still haven't quite given up on this issue, as it is highly annoying roadblock to some cool browser based projects.

Mapping Longitude and Latitude values to X and Y coordinates of a PV3D material

This is done very straightforwardly by capturing the YahooMapEvent. It goes something like this:

private function getAllCoordinates(e:YahooMapEvent):void


You add a listener with this line:

yahooMap.addEventListener(YahooMapEvent.MAP_MOUSE_CLICK, handleMapClick);

Although this is a very simple thing, it allows you to convert Latitude and Longitude to the X and Y coordinates of the referring Material and you can play with it from then on. For instance, I used it to map flight trajectories based on GPS data (including GPS altitude) in 3D space. Fun stuff!
Dragging Yahoo Map in PV3D (avoiding the map panning collision with PV3D)

Dragging a YahooMap is super simple using the Yahoo Map API. It’s a convenient single line:


When the map is processed by PV3D and you try to drag it, it starts jumping all over the screen, probably because of some event collision with PV3D. Luckily, we can get around this one by making our own custom dragging method as follows (note that this only describes the concept, the working version is in source):

private function mMove( e:InteractiveScene3DEvent ):void
// This code is run when the mouse is moved on the plane.
movieParent.x = mouseX -e.x;
movieParent.y = mouseY -e.y;

else if(Application.application.stopMovingMap==true && Application.application.isAnythingBeingDragged==false)
oldX = e.x;
oldY = e.y;


xDiff= newX-oldX;
yDiff= newY-oldY;

Application.application.yahooMap.setCenterByPixels(new Point(xDiff,yDiff));

flightsContainer.x = flightsContainer.x-xDiff;
flightsContainer.y = flightsContainer.y-yDiff;


You can look at the missing variables and event listeners in the source.

Simple gauge component from ground up using basic trigonometry

What I wanted to achieve was to rotate the 3D cube on which the map rests around the Z axis. Simple, right? So I used a VSlider component and gave it a range from 0 to 360 to capture the angle of rotation. And that’s where problems started. When the 3D map is under VSlider, both start acting up and jumping across the screen. All the issues in this app smell of the same thing - something to do with Mouse Down and Mouse Move events in PV3D. I’m still looking.

Being annoyed by the problem I started thinking about other approaches and a gauge component came to mind as the best visual representation of the functionality I was trying to achieve.

I naturally tried using some of the ready made gauge components available online, but with all of them I had some kind of issue. Either it was the inability to skin them properly, or to set the scope to full 360 degrees.

In the end I decided to refresh my trigonometry knowledge and made the component myself.

At the same time, this solved the VSlider going crazy issue. Why? I’ll post it when I find out.

Simple tilt component again using basic trigonometry

When in Rome... I used the same principle as in simple gauge component to add to user experience and visually show the angle that the 3D map is tilted by.

Making a visual component using Degrafa

Degrafa is such a priceless framework. Just in case you don’t know, it’s used for manipulating SVG’s (vector based graphics) in Flex 3, giving you a lot of power in customizing your visual components. It is the best solution for mapping in Flex that I have ever seen!

In this particular app it wasn’t absolutely necessary but it’s there to visually enhance the arrow button. I really wanted the arrow to look like it does in the example. Look at the source to see the details. Actual SVG data was created in Illustrator.

All in all, combining API’s is certainly going to get you into trouble. But combining ideas can amount to a sum greater than it’s parts. I love it.

If anything is not clear to you, look at the code to see all the in’s and out’s. If it’s still not clear, shoot me a message.

Related Services:
Flex, Flash and Air, Custom Software Development