Google Maps 3D Overlay

February 3rd, 2010 2 comments

The Flash Google Maps API offers what they call a 3D map. It’s nothing more than a component that enables a perspective view of a classic 2D map with the associated controls. Here is how it works:

  1. The 3D view is engine independant and uses Flash 10 3D maths and “drawTriangles” method if available
  2. The API provides everything one needs to integrate 3D graphics as an overlay using the library of its choice
  3. It works just the same as the good old 2D Google Maps API

The first point is very important. It ensures the library is lightweight and does not include any third party software you wouldn’t want to use.

The second is what makes the magic possible: the API exposes the viewport and camera data and provides methods to convert latitude/longitude into 3D world coordinates. With a little math and a few hours of debugging it is then easy to wrap it with the 3D engine of your choice.

The Experiment

You can use CTRL + mouse drag or SHIFT + mouse drag to look around.

The Code

You might want to read the official Google Maps Flash API documentation first, including the dedicated 3D maps section.

The Viewport

The Google Maps API provides the viewport width and height and the focal length. I use the field-of-view instead of the focal length but there is a simple formula to convert from one to the other:

var fieldOfView : Number = 2. * Math.atan(viewportWidth / (2. * focalLength));

Another issue is to find proper values for the near and far clipping planes. I chose 0.000001 for the near plane and 0.2 for the far plane. Those values are extremely low and might cause floating point inconsistencies. The best thing to do would be to scale the whole scene to be able to use reasonable clipping values. Maybe for a later version! This problem does not seem to affect the experiment though…
The following function presents how to get the relevant viewport values from the Google Maps API:

public function buildViewport(myMap : Map3D) : void
{
	var g : TransformationGeometry = myMap.camera.getTransformationGeometry();
	var width : Number = g.viewportSize.x;
	var height : Number = g.viewportSize.y;
	var fieldOfView : Number = 2. * Math.atan(g.viewportSize.y / (2. * g.focalLength));
 
	// build viewport...
}
The Camera

The following function retrieves the camera position and look-at vectors from the Google Maps API:

public function buildCamera(myMap : Map3D) : void
{
	var cam : ICamera = myMap.camera;
	var mapCenter : Point = cam.latLngToWorld(cam.center);
	var g : TransformationGeometry = cam.getTransformationGeometry();
	var pos : Point3D = g.cameraPosition;
	var zAxis : Point3D = g.cameraZAxis;
	var yaw : Number = cam.attitude.yaw * (Math.PI / 180.);
	var lookAt : Vector3D = new Vector3D();
	var eye : Vector3D = new Vector3D();
 
	eye.x = pos.x - 128;
	eye.y = pos.z;
	eye.z = 128 - pos.y;
 
	if (!zAxis.x && !zAxis.y)
	{
		lookAt.x = eye.x + EPSILON * Math.sin(yaw);
		lookAt.z = eye.z + EPSILON * Math.cos(yaw);
	}
	else
	{
		lookAt.x = eye.x - zAxis.x;
		lookAt.z = eye.z + zAxis.y;
	}
 
	lookAt.y = eye.y - zAxis.z;
 
	// build camera using eye position, look-at and Vector3D.Y_AXIS as the up vector
}

I prefer computing the eye position and look-at vectors and using them to create the transform matrix rather than just creating the matrix directly. This way, you can expose the actual camera parameters (even if in read-only) and still use the transform matrix to do the math.

The Scene

The last step is to make it possible to position 3D objects on the map. What you actually want to do is to be able to add objects specifying their latitude/longitude instead of their actual (x, y, z) coordinates. Then again, the Google Maps API does it just fine:

public function computePosition(myLatitude : Number, myLongitude : Number) : Vector3D
{
	var pos : Point = _map.camera.latLngToWorld(new LatLng(myLatitude, myLongitude));
 
	return new Vector3D(pos.x - 128., 0., 128. - pos.y);
}

Know Issues

As said previously, the extremely low far and near clipping plane values might introduce float point inconsistencies. Therefore, some clipping glitches might appear and frustum culling is performed only on the far clipping plane.

Credits

Credits goes to Marc Fahmi for the low-polygon 3D model of the Eiffel Tower.

Categories: Flash, Snippets Tags:

BSP Tree Optimization in Flash 10

December 18th, 2009 3 comments

Binary Space Partitioning trees are the new trend to cure the lack of Z-Buffer when building 3D applications for the Flash Platform. Thus, building a fast and robust BSP system is one of the key for a successful 3D API targeting Flash. I won’t discuss BSP theory here because it’s very easy to find good documentation. I’ll rather let you play with a little experiment and discuss what it actually features…

The Experiment

BSP tree optimization experiment

BSP tree optimization experiment

What It Does…

  • load a *.3DS file and use it as a mesh
  • load a *.PNG texture and use it as a material
  • display the mesh using a BSP tree

The vertical slider enables you to play with what I called the BSP precision. This value represents the thickness of the partition planes used to build the BSP tree: the lower the precision, the better the final rendering. When the precision is higher, the BSP is less deep and a lot faster to render. But if the precision is too high, some artifacts occur and the rendering is corrupted. The idea is to find the best rendering quality/number of artifacts ratio.

When checked , the “Optimized BSP” checkbox enables the build BSP where each partition plane will be chosen carefully. This very choice is based on the number of polygons that would have to be cut if that plane was ever used as a partition plane. This way, the final BSP tree features a lot less polygons and is faster to walk through/render.

And the “Wireframe” checkbox speaks for itself I guess… Anyway, wireframe rendering makes it possible to see how the BSP tree actually divides more or less polygons depending on the settings you chose.

And The Good News Is…

Keep an eye on the Triangles Per Second counter (TPS, on the top-left corner of the screen) as you play with the precision slider/optimization checkbox. Changing those values of the BSP tree has a huge impact on the amount of rendered polygons (and the overall performances of course!).

Categories: Flash Tags:

AIR 2.0 HTTP Web Server

December 17th, 2009 No comments

AIR 2.0 brings a lot of new features. Among them is the new ServerSocket class. The Socket class exists since Flash 9 and enabled a lot of new client/server applications. But it has always been limited to client side sockets as long as AIR (and the Flash Platform as a whole for that matter) is concerned. Therefor, this new server socket feature makes it possible to build actual server software using AIR!

Rich of this new and incredible ability, Christophe Coenraets posted a small but yet very powerful code snippet to build an HTTP web server using AIR 2.0!

Voice Recognition in Flash 10

December 16th, 2009 No comments

The following video demonstrates a new “voice gesture” library targeting the Flash Platform. As you might have guessed, those “voice gestures” are pretty much like “mouse gestures” but they are activated by voice only. I guess it uses some kind of voice learning/recognition algorithm. I can’t stress enough how trhilled I am to see this kind of new and powerful software coming to Flash. This enables a whole new kind of usages and applications…


Voice Gesture from didier.brun on Vimeo.

Flex SDK 3.5 released

December 15th, 2009 No comments

A new milestone version of the Flex SDK has just been released and is available on:

Categories: Uncategorized Tags:

Frustum Culling in Flash 10

December 13th, 2009 1 comment

Update: corrected a few glitches in the bounding sphere creation routine.

Optimization is always important. But when it comes to 3D for the Flash Platform, it’s an everyday battle. The first ideas that come to mind are to avoid:

  1. redrawing the same regions : each pixel value must be set once and only once
  2. rendering invisible objects : objects that are out of sight still take a lot of CPU horsepower

While Flash takes care of the first one in its very renderer, the second one is not handled. But that is something we can easily address!

The Technic

The method is called “frustum culling”. The big picture is that every mesh is approximated using a bounding volume (typically a sphere or a box). If the bounding volume is visible, the corresponding mesh is rendered. The two following pictures show the frustum culling caught in action:

The mesh is visible

The mesh is visible: TPS counter indicates 18900 triangles per seconds

Frustum culling in action (TPS counter indicates 0!)

The mesh is out of sight: frustum culling is acting and TPS counter indicates 0!

Code snippets and a live experiment right after the jump!

MadCompany: Coming Soon!

December 10th, 2009 2 comments



Flash 10.1 and AIR 2.0 beta released

November 18th, 2009 3 comments

Flash 10.1 and AIR 2.0 beta have been released yesterday. They are available for the Windows, Linux and MacOS X platform for now but mobile versions should be released before the end of the year.

You can find more info and downloads on Adobe Labs:

Categories: Uncategorized Tags:

Flash 10.1 beta released “in November”

November 13th, 2009 1 comment

This is what you can read on the Flash Platform issue tracker on the “Unacceptable CPU Use on Idle” thread:

Rick Winscot: “[...] is this fix going to make it into the up-and-coming 10.1 release?”

Charles Liss: “This will be fixed in our Beta release here in November.”

Not only a major bug is now fixed, but we also get a beta release date more precise than just the “before the end of the year” Adobe gave us during Max. It is now as short as before the end of the month!

You can read more about Flash 10.1 on the Adobe Labs Flash 10.1 page.

Categories: Uncategorized Tags:

rSoul v0.1b

November 5th, 2009 No comments

rSoul is my very first public AIR application. It is an open-source NetSoul client.  Since NetSoul is not a commonly used protocol it won’t be useful for many people. Still, the NetSoul protocol is mandatory when you want to have access to the PIE (Parc Informatique de l’EPITA). And the source might help anyone willing to build his very first AIR application. The user interface is very light and I tried to keep it as simple and as intuitive as possible.

Like any other AIR application, rSoul is cross-platform and works on Windows, Linux and Mac OS X. You can install it and get the sources from the rSoul website:

http://rsoul.promethe.net

Here are a few screenshots:

rsoul_chat

Features

This first release includes the following features:

  • Online/Away/Busy status
  • Location configuration
  • “Remember Password” option
  • Auto-connect option
  • Contacts list
  • Add/Remove contacts
  • Tabbed chat
  • Auto-update
  • Connection errors handling

Known issues

  • Some special characters are not handled correctly
  • The application does not (yet) minimize itself to the system tray
  • Contacts status is not updated

If you found any bug or have any suggestion please feel free to add a comment…

Categories: Uncategorized Tags: , ,