Hello,
I am working on a project where I use a cylinder to show the user a panorama of a room. This is no problem but around the inside of this cylinder I need hotspots that can be moved by the user on click.
Below you can see the code that I am using. I have removed some of the code for the panorama cylinder to make everything easier to understand. This code and a CS5 flash file is also attached.
Each hotspot is placed in its own ObjectContainer3D, rotated and moved on Z to the radius of the cylinder.
When the user clicks and drags the hotspot, I would like to move the container up and down on the y-axis and rotate the container around the y-axis so that the hotspot and be placed on the correct object.
I tried many diferent aproches and finaly came up with this sollution:
One thing to be aware of in this example is that the mousemove event is only fired when you are over an object in the view. So you will have to move the mouse slowly over the point or have another object behind it at the same distance so that the event is fired and then points still work out.
Greg
package{
import away3d.cameras.Camera3D;
import away3d.containers.ObjectContainer3D;
import away3d.containers.Scene3D;
import away3d.containers.View3D;
import away3d.core.base.Object3D;
import away3d.events.MouseEvent3D;
import away3d.materials.MovieMaterial;
import away3d.primitives.Plane;
import flash.display.Sprite;
import flash.events.Event;
public class ViewManager extends Sprite {
private var scene:Scene3D;
private var camera:Camera3D;
private var view:View3D;
private var hotSpotContainer:ObjectContainer3D;
private var hotSpotContainerDrag:Object3D = null;
private var hotSpot:Plane = null;
public function ViewManager() {
addEventListener(Event.ADDED_TO_STAGE, draw);
}
private function draw($e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, draw);
initPanorama();
initListeners();
}
private function initPanorama():void {
scene = new Scene3D();
camera = new Camera3D();
view = new View3D();
view.x = stage.stageWidth / 2;
view.y = stage.stageHeight / 2;
view.scene = scene;
view.camera = camera;
addChild(view);
hotSpotContainer = new ObjectContainer3D();
hotSpotContainer.ownCanvas = true;
scene.addChild(hotSpotContainer);
var tempHotSpotContainer:ObjectContainer3D = new ObjectContainer3D();
hotSpotContainer.addChild(tempHotSpotContainer);
var tempMaterial:MovieMaterial = new MovieMaterial(new HotSpot());
tempMaterial.autoUpdate = true;
tempMaterial.interactive = true;
tempMaterial.smooth = true;
var tempHotSpot:Plane = new Plane();
tempHotSpot.addEventListener(MouseEvent3D.MOUSE_DOWN, onHotSpotDown);
tempHotSpot.alpha = .5;
tempHotSpot.ownCanvas = true;
tempHotSpot.width = 20;
tempHotSpot.height = 20;
tempHotSpot.material = tempMaterial;
tempHotSpot.rotationX = 90;
tempHotSpot.z = 300;
tempHotSpotContainer.addChild(tempHotSpot);
}
private function onHotSpotDown($e:MouseEvent3D):void {
hotSpotContainerDrag = ObjectContainer3D($e.target.parent);
hotSpot = Plane($e.target);
view.addEventListener(MouseEvent3D.MOUSE_UP, onHotSpotUp);
view.addEventListener(MouseEvent3D.MOUSE_MOVE, onHotSpotMove);
}
private function onHotSpotMove($e:MouseEvent3D):void{
hotSpotContainerDrag.y = $e.sceneY
var radians:Number = Math.atan2($e.sceneZ - hotSpotContainerDrag.z, $e.sceneX - hotSpotContainerDrag.x);
var degrees:Number = radians * 180 / Math.PI;
hotSpotContainerDrag.rotationY = -(degrees - 90);
}
private function onHotSpotUp($e:MouseEvent3D):void {
hotSpotContainerDrag = null
hotSpot = null;
view.removeEventListener(MouseEvent3D.MOUSE_UP, onHotSpotDown);
view.removeEventListener(MouseEvent3D.MOUSE_MOVE, onHotSpotDown);
}
private function initListeners():void {
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e:Event):void {
view.render();
}
}
}