Hi there, I’ve got a globe which I’m adding markers too and then I allow the user to spin the globe by click-dragging it. Actually, the globe and markers don’t move, the camera moves around them. Anyways, what I need is to be able to spin the camera around to a markers position when it’s clicked on. I’m close but I just can’t figure out the formula! If you can help, that’d be great. Here’s my source code (shortened)…
package
{
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLRequest;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.events.InteractiveScene3DEvent;
import org.papervision3d.materials.BitmapMaterial;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.view.BasicView;
import com.atticmedia.console.C;
import gs.TweenLite;
public class DocumentClass extends BasicView
{
protected var latitudeDegreeOffset:Number = 90;
protected var longitudeDegreeOffset:Number = 15;
protected var cameraTarget:DisplayObject3D;
protected var globe:Sphere;
protected var globeMouseDiffX:Number = 0;
protected var globeMouseDiffY:Number = 0;
protected var mouseDown:Boolean = false;
private var _texture : Loader;
private var _marker : Marker;
private var markerVector : Number3D;
public function DocumentClass( viewportWidth:Number=1024, viewportHeight:Number=768, scaleToStage:Boolean=true, interactive:Boolean=true, cameraType: String = "FREE" )
{
//Setup the basic view.
super( viewportWidth, viewportHeight, scaleToStage, interactive, cameraType);
var urlRequest : URLRequest = new URLRequest("assets/earthmap1k.jpg");
_texture = new Loader();
_texture.contentLoaderInfo.addEventListener(Event.COMPLETE, init);
_texture.load(urlRequest);
}
protected function init(e : Event):void
{
var bitmapData : BitmapData = new BitmapData(_texture.width, _texture.height);
bitmapData.draw(_texture);
var earthMaterial:BitmapMaterial = new BitmapMaterial(bitmapData);
startRendering();
//Create a null object for the camera to copy.
cameraTarget = new DisplayObject3D();
scene.addChild( cameraTarget );
//Rotate the camera target to have the camera face America.
cameraTarget.yaw( 180 );
camera.focus = 1100;
camera.zoom = 1;
//Create the globe.
globe = new Sphere(earthMaterial, 320, 32, 32);
globe.y = 0;
scene.addChild( globe );
//Listen for mouse events.
addEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler );
addEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
addEventListener( MouseEvent.ROLL_OUT, mouseUpHandler );
// Add a marker
addMarker();
}
protected override function onRenderTick( event:Event=null ):void
{
if( mouseDown )
{
//Set the target rotation properties for the camera based on the mouse position.
var rotationY:Number = -( -mouseX - globeMouseDiffX );
var rotationX:Number = -( mouseY - globeMouseDiffY );
//Tween the null object.
TweenLite.to(cameraTarget, 2, {rotationY: rotationY, rotationX: rotationX});
}
//Copy the null object's transform into the camera.
camera.copyTransform( cameraTarget );
//Reposition the camera away from the globe and null object.
camera.moveBackward( 1300 );
//Render as usual
super.onRenderTick( event );
}
protected function mouseDownHandler( evt:MouseEvent ):void
{
//Track the amount the mouse has moved.
globeMouseDiffX = -mouseX + cameraTarget.rotationY;
globeMouseDiffY = mouseY + cameraTarget.rotationX;
mouseDown = true;
}
protected function mouseUpHandler( evt:MouseEvent ):void
{
mouseDown = false;
}
private function markerClickHandler( e:InteractiveScene3DEvent ):void
{
}
private function addMarker() : void
{
_marker = new Marker();
placeMarker( _marker, 54, 5 );
}
private function translateGeoCoords( latitude:Number, longitude:Number, radius:Number ):Number3D
{
//Convert latitude and longitude to radians.
latitude = Math.PI * latitude / 180;
longitude = Math.PI * longitude / 180;
//Adjust latitude and longitude by radians.
latitude -= ( latitudeDegreeOffset * ( Math.PI/180 ) ); // offset latitude by n degrees (in radians).
longitude -= ( longitudeDegreeOffset * ( Math.PI/180 ) ); // offset longitude by n degrees (in radians).
var x:Number = radius * Math.sin( latitude ) * Math.cos( longitude );
var y:Number = radius * Math.sin( latitude ) * Math.sin( longitude );
var z:Number = radius * Math.cos( latitude );
//Switch z and y (since z is forward) (see the right-hand rule).
return new Number3D( x, z, y );
}
protected function placeMarker( marker:Marker, latitude:Number, longitude:Number ):void
{
//Translate the geo coordinates to 3D coordinates.
markerVector = translateGeoCoords( latitude, longitude, 320 );
marker.x = markerVector.x;
marker.y = markerVector.y;
marker.z = markerVector.z;
//Align the marker with the globe's surface.
marker.lookAt( DisplayObject3D.ZERO );
globe.addChild( marker );
C.add("ADD LISTENER");
marker._cube.addEventListener( InteractiveScene3DEvent.OBJECT_PRESS, markerClickHandler );
}
}
}