📄 freecamera3dcontroller.as
字号:
package zephyr.cameracontrol
{
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.geom.Point;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.cameras.FreeCamera3D;
import flash.ui.Keyboard;
import org.papervision3d.view.Viewport3D;
import org.papervision3d.materials.MovieMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.core.proto.MaterialObject3D;
import org.papervision3d.render.BasicRenderEngine;
public class FreeCamera3DController extends EventDispatcher
{
public var camera:FreeCamera3D;
public var scene:Scene3D;
public var viewport:Viewport3D;
private var startPoint:Point;
public var panVelocity:Number = 0;
public var tiltVelocity:Number = 0;
public var sensitivity:Number = 10;
public var friction:Number = 0.1;
public var threshold:Number = 0.0000001;
private var _autoRotation:Boolean = true;
private var autoRotateTimer:Timer;
private var _autoRotateDelay:Number = 15000;
public var autoRotateIncrement:Number = 15;
public var isAutoRotating:Boolean = false;
private var isMouseDown:Boolean = false;
public var panoCubeTree:Array;
public var materials:MaterialsList;
private var isKeyDown:Boolean = false;
public var keyIncrement:Number = 75;
public var keyZoomIncrement:Number = 0.2;
private var keyUp:Boolean = false;
private var keyDown:Boolean = false;
private var keyLeft:Boolean = false;
private var keyRight:Boolean = false;
private var keyZoomIn:Boolean = false;
private var keyZoomOut:Boolean = false;
public var renderer:BasicRenderEngine;
private var _parent:Object;
//public function FreeCamera3DController( scene:Scene3D, camera:FreeCamera3D, viewport:Viewport3D, panoCubeTree:Array, materials:MaterialsList, renderer:BasicRenderEngine, autoRotation:Boolean = true )
public function FreeCamera3DController( _parent:Object, autoRotation:Boolean = true )
{
this._parent = _parent;
this.camera = _parent.camera;
this.scene = _parent.scene;
this.viewport = _parent.viewport;
this.panoCubeTree = _parent.panoCubeTree;
this.materials = _parent.materials;
this.renderer = _parent.renderer;
viewport.stage.addEventListener( MouseEvent.MOUSE_DOWN,mouseDownEvent, false, 1, true );
viewport.stage.addEventListener( MouseEvent.MOUSE_UP,mouseUpEvent, false, 0, true );
viewport.stage.addEventListener( Event.DEACTIVATE, mouseUpEvent, false, 0, true );
viewport.stage.addEventListener( KeyboardEvent.KEY_DOWN, keyDownEvent, false, 0, true );
viewport.stage.addEventListener( KeyboardEvent.KEY_UP, keyUpEvent, false, 0, true);
// start the autorotator
if (autoRotation)
{
this.autoRotation = true;
//override the auto on feature and make it wait for its delay
//isAutoRotating = false;
}
}
protected function mouseDownEvent( event:MouseEvent ):void
{trace("mouse down");
for each( var o:Object in panoCubeTree )
{
try {
var mo3d:MaterialObject3D = materials.getMaterialByName(o.name);
//much better performance with animation off
//turn back on smoothing (which was off during the transition
(mo3d as MovieMaterial).smooth = false;
}
catch(e:Error){}
}
isMouseDown = true;
//reset autorotator on account of user input
autoRotateTimer.reset();
autoRotateTimer.stop();
isAutoRotating = false;
_autoRotation = false;
startPoint = new Point( viewport.mouseX,viewport.mouseY );
viewport.addEventListener( Event.ENTER_FRAME,enterFrameEvent );
//remove interface render loop
_parent.viewportInterface.removeEventListener( Event.ENTER_FRAME, _parent.interfaceOnEnterFrame );
}
protected function keyDownEvent( event:KeyboardEvent ):void
{
switch( event.keyCode )
{
case Keyboard.UP:
keyUp = true;
startKeyMovement();
break;
case Keyboard.DOWN:
keyDown = true;
startKeyMovement();
break;
case Keyboard.LEFT:
keyLeft = true;
startKeyMovement();
break;
case Keyboard.RIGHT:
keyRight = true;
startKeyMovement();
break;
case Keyboard.SHIFT:
keyZoomIn = true;
startKeyMovement();
break;
case Keyboard.CONTROL:
keyZoomOut = true;
startKeyMovement();
break;
}
}
protected function startKeyMovement():void
{
for each( var o:Object in panoCubeTree )
{
try {
var mo3d:MaterialObject3D = materials.getMaterialByName(o.name);
//much better performance with animation off
//turn back on smoothing (which was off during the transition
(mo3d as MovieMaterial).smooth = false;
}
catch(e:Error){}
}
//reset autorotator on account of user input
autoRotateTimer.reset();
autoRotateTimer.stop();
isAutoRotating = false;
_autoRotation = false;
isKeyDown = true;
viewport.addEventListener( Event.ENTER_FRAME,enterFrameEvent );
_parent.viewportInterface.removeEventListener( Event.ENTER_FRAME, _parent.interfaceOnEnterFrame );
}
protected function mouseUpEvent( event:Event ):void
{
isMouseDown = false;
_parent.viewportInterface.addEventListener( Event.ENTER_FRAME, _parent.interfaceOnEnterFrame );
for each( var o:Object in panoCubeTree )
{
try {
var mo3d:MaterialObject3D = materials.getMaterialByName(o.name);
//much better performance with animation off
//turn back on smoothing (which was off during the transition
(mo3d as MovieMaterial).smooth = true;
}
catch(e:Error){}
}
}
protected function keyUpEvent(event:KeyboardEvent):void
{
switch( event.keyCode )
{
case Keyboard.UP:
keyUp = false;
break;
case Keyboard.DOWN:
keyDown = false;
break;
case Keyboard.LEFT:
keyLeft = false;
break;
case Keyboard.RIGHT:
keyRight = false;
break;
case Keyboard.SHIFT:
keyZoomIn = false;
break;
case Keyboard.CONTROL:
keyZoomOut = false;
break;
}
if ( !keyUp && !keyDown && !keyLeft && !keyRight && !keyZoomIn && !keyZoomOut )
{
isKeyDown = false;
_parent.viewportInterface.addEventListener( Event.ENTER_FRAME, _parent.interfaceOnEnterFrame );
for each( var o:Object in panoCubeTree )
{
try {
var mo3d:MaterialObject3D = materials.getMaterialByName(o.name);
//much better performance with animation off
//turn back on smoothing (which was off during the transition
(mo3d as MovieMaterial).smooth = true;
}
catch(e:Error){}
}
}
}
protected function enterFrameEvent( event:Event ):void
{
// while mouse is down we calculate new velocities, when it is up we just slow with friction
if (isMouseDown || isAutoRotating || isKeyDown)
{
if (isAutoRotating)
{
//if isAutoRotating, spoof the next lines by moving the startpoint
startPoint = new Point( viewport.stage.mouseX - autoRotateIncrement, viewport.stage.mouseY - camera.rotationX );
//remove interface rendering loop
_parent.viewportInterface.removeEventListener( Event.ENTER_FRAME, _parent.interfaceOnEnterFrame );
}
else if (isKeyDown)
{
if ( keyUp ) { startPoint = new Point( viewport.stage.mouseX, viewport.stage.mouseY + keyIncrement ); }
if ( keyDown ) { startPoint = new Point( viewport.stage.mouseX, viewport.stage.mouseY - keyIncrement ); }
if ( keyLeft) { startPoint = new Point( viewport.stage.mouseX + keyIncrement, viewport.stage.mouseY ); }
if ( keyRight ) { startPoint = new Point( viewport.stage.mouseX - keyIncrement, viewport.stage.mouseY ); }
if ( keyZoomIn ) { camera.zoom += keyZoomIncrement }
if ( keyZoomOut ) { camera.zoom -= keyZoomIncrement }
}
// calculate new velocities
panVelocity = (panVelocity - (((startPoint.x - viewport.stage.mouseX) * sensitivity) / 15000));
tiltVelocity = (tiltVelocity + (((startPoint.y - viewport.stage.mouseY) * sensitivity) / 15000));
}
// motion is still over the threshold, so apply friction
if ( ( (panVelocity * panVelocity) + (tiltVelocity * tiltVelocity) ) > threshold ) {
// always apply friction so that motion slows AFTER mouse is up
panVelocity = (panVelocity * (1 - friction) );
tiltVelocity = (tiltVelocity * (1 - friction) );
}
else
{
if ( !(isMouseDown) )
{
// motion is under threshold, stop and remove enter frame listener
panVelocity = 0;
tiltVelocity = 0;
viewport.removeEventListener( Event.ENTER_FRAME,enterFrameEvent );
//turn on the autoRotator
autoRotateTimer.reset();
autoRotateTimer.start();
}
}
// apply new velocities to the camera
camera.rotationX = camera.rotationX + tiltVelocity;
camera.rotationY = camera.rotationY + panVelocity;
renderer.renderScene( scene, camera, viewport );
}
// handler fires after autoRotateTimer successfully completes its delay, which is reset by any user input
private function autoRotateTimerHandler(event:TimerEvent):void
{
viewport.addEventListener( Event.ENTER_FRAME,enterFrameEvent, false, 9 );
isAutoRotating = true;
autoRotateTimer.reset();
autoRotateTimer.stop();
}
public function set autoRotation(autoRotation:Boolean):void
{
if (autoRotation)
{
autoRotateTimer = new Timer(_autoRotateDelay);
autoRotateTimer.addEventListener("timer", autoRotateTimerHandler, false, 0, true);
autoRotateTimer.start();
//isAutoRotating = true;
_autoRotation = true;
}
else
{
viewport.stage.removeEventListener( Event.ENTER_FRAME,enterFrameEvent);
autoRotateTimer.reset();
autoRotateTimer.stop();
isAutoRotating = false;
_autoRotation = false;
}
}
public function get autoRotation():Boolean
{
return _autoRotation;
}
public function autoRotateNow():void
{trace("auto now");
autoRotateTimer = new Timer(_autoRotateDelay);
isAutoRotating = true;
_autoRotation = true;
}
public function set autoRotateDelay(autoRotateDelay:Number):void
{
if (autoRotateTimer != null)
{
autoRotateTimer.delay = autoRotateDelay;
}
}
public function get autoRotateDelay():Number
{
return _autoRotateDelay;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -