One of my most complex works yet. This 3D planet maps several
of the Earth (courtesy Nasa). You'll notice a reflection on the surface. (not really necessary but I like the effect).
That is achieved through a papervision EnvMap or Environment Map. A subtle glow effect is added around the earth to add atmosphere.
. You type in any address in the world (include the city name) and it sends it off to google, who kindly returns me a latitude and longitude coordinates. I then project those coordinates using a sphere and placing it at the correct location, thus highlighting the exact address you typed in. (I had help with the formula from
//i've already loaded bitmap data from external jpg files into local variables cloud_texture, earth_texture, and bump_texture
var earth_Shader:GouraudShader = new GouraudShader(light, 0xFFFFFF, 0x111111, 30);
//EnvMap gives us our reflection, the bump_texture gives us the small peaks and valleys on the earth
var earth_env:EnvMapShader = new EnvMapShader(light, cloud_texture, earth_texture, 0x0034c1, bump_texture);
var earth_mat:ShadedMaterial = new ShadedMaterial(new BitmapMaterial(earth_texture), earth_env, 0);
//let there be stars!!
var stars:ParticleField = new ParticleField(new ParticleMaterial(0xFFFFFF, .4, 1), 500);
scene.addChild(stars);
var earth:Sphere = new Sphere(earth_mat, 50, 25, 25);
scene.addChild(earth);
//this accomplishes the blurred glow effect around our 3D Earth
var bfx:BitmapEffectLayer = new BitmapEffectLayer(viewport, 1000, 1000, true, 0, "CLEAR_POST", false, true);//very important to set the last param to true! Otherwise the glow will continue to concatenate to itself! AHHH!
var gf:GlowFilter = new GlowFilter(0x00aaf6, .2, 5, 30, 2, 1, false);
var ble:BitmapLayerEffect = new BitmapLayerEffect(gf);
bfx.addEffect(ble);
viewport.containerSprite.addLayer(bfx);
bfx.addDisplayObject3D(earth);
//GeoCoding Functions
//I have this built into its own separate class
//Google makes you use their API. I tried over and over to make a simple URLRequest to get the coords...it worked just great locally, but as soon as I posted it to the server..nothin.
import com.google.maps.Map;
import com.google.maps.MapEvent;
import com.google.maps.services.*
//You only get access to the geocoder once a new Map Object has been instantiated
public function GPS(stage:*){
map = new Map();
map.key = "my_google_maps_api_key_here";
map.addEventListener(MapEvent.MAP_READY, onMapReady);
map.visible = false;
stage.addChild(map);
function onMapReady(event:Event):void {
trace(map);
}
}
//when user clicks on the find button, receive address as string, and call back function for when processing is complete.
public function Get_Coords_From_Address(address:String, callBack:Function) {
//format the address for google maps api
var temp:Array = address.split(" ");
address = temp.join("+").toString();
//call their geocoder, it just makes a URLRequest with special params
var geocoder:ClientGeocoder = new ClientGeocoder();
geocoder.addEventListener(GeocodingEvent.GEOCODING_SUCCESS, handleGeocodingSuccess);
geocoder.geocode(address);
//geocode received successfully now parse out latitude and longitude and return for mapping!
function handleGeocodingSuccess(e:GeocodingEvent) {
var t1:int = e.response.placemarks.toString().indexOf("@(") + 2;
var t2:int = e.response.placemarks.toString().indexOf(")");
var data:String = e.response.placemarks.toString().substring(t1, t2);
callBack(data);
}
//here is the callback function
function callBack(data:String){
trace(coords);
var lat:Number = parseInt(coords[0]);
var lon:Number = parseInt(coords[1]);
//convert_coords_to_rotation(lat, lon);
var phi:Number = (90-lat)*(Math.PI/180);
var theta:Number = (lon+180)*(Math.PI/180);
//create the marker
var marker:Sphere = new Sphere(new ShadedMaterial(new BitmapMaterial(new BitmapData(20,20,false,0x00aaf6)), new PhongShader(light, 0x00aaf6)),1,5,5);
//figure the spatial coords in which the sphere should be placed (will be placed directly over the address that the user entered..code courtesy
http://blog.zupko.info/?p=221)
var fx:Number = (earth_radius+3) * Math.sin(phi)*Math.cos(theta);
var fz:Number = (earth_radius+3) * Math.sin(phi)*Math.sin(theta);
var fy:Number = (earth_radius+3) * Math.cos(phi);
earth.addChild(marker);
bfx.addDisplayObject3D(marker);
marker.x = 0;
marker.y = 300;
marker.z = 0;
marker.alpha = 0;
//animate the sphere into place from 300 pixels north
TweenMax.to(marker, 2, { x:fx, y:fy, z:fz, ease:Regular.easeOut, alpha:1 } );
}