package com.publicreative.pv.interaction
{
import flash.display.Sprite;
import flash.display.Stage;
import flash.geom.Point;
import org.papervision3d.view.layer.util.ViewportLayerSortMode;
import com.publicreative.utils.MathUtils;
import flash.display.DisplayObject;
import org.papervision3d.objects.DisplayObject3D;
import flash.events.MouseEvent;
/**
* ...
* @author Mark Stewart :: http://www.publicreative.com
*/
public class MouseGrab
{
public static const X:String = "x";
public static const Y:String = "y";
public static const Z:String = "z";
public static const XY:String = "xy";
public static const XZ:String = "xz";
public static const YZ:String = "yz";
public static const HORIZONTAL:String = "horiz";
public static const VERTICAL:String = "vert";
private var _do :DisplayObject3D;
private var _base:DisplayObject;
private var _init:Boolean = false;
private var _currentPoint:Point;
private var _startPoint:Point;
private var _mouseDown:Boolean = false;
private var _camRx:Number = 0;
private var _camRy:Number = 0;
private var _downPoint:Point;
private var _percentX:Number;
private var _percentY:Number;
private var _horizontalType:String;
private var _verticalType:String;
private var _vMultiplier:Number;
private var _vEase:Number;
private var _vLow:Number;
private var _vHigh:Number;
private var _vRadius:Number;
private var _hMultiplier:Number;
private var _hEase:Number;
private var _hLow:Number;
private var _hHigh:Number;
private var _hRadius:Number;
public function MouseGrab( displayObject3d:DisplayObject3D , base:DisplayObject )
{
super();
_do = displayObject3d;
_base = base;
}
public function addSingleAxis( movement:String , axis:String , multiplier:Number = 1000, ease:Number = 10, lowLimit:Number = -2000 , highLimit:Number = 2000 , startOffset:Number = 90 ):void
{
if (axis == XY || axis == XZ || axis == YZ) throw new Error("For multiple axis movement use addDoubleAxis function");
if (!_init) addListeners();
if (movement == HORIZONTAL)
{
_horizontalType = axis;
_hMultiplier = multiplier;
_hEase = ease;
_hLow = lowLimit;
_hHigh = highLimit;
_downPoint.offset(startOffset, 0);
}
else
{
_verticalType = axis;
_vMultiplier = multiplier;
_vEase = ease;
_vLow = lowLimit;
_vHigh = highLimit;
_downPoint.offset(0, startOffset);
}
}
public function addDoubleAxis( movement:String ,axis:String ,radius:Number= 1000,multiplier:Number = 1000, ease:Number = 10 , startOffset:Number = 90):void
{
if (axis == X || axis == Z || axis == Y) throw new Error("For single axis movement use addSingleAxis function");
if (!_init) addListeners();
if (movement == HORIZONTAL)
{
_horizontalType = axis;
_hMultiplier = multiplier;
_hEase = ease;
_hRadius = radius;
_downPoint.offset(startOffset, 0);
}
else
{
_verticalType = axis;
_vMultiplier = multiplier;
_vEase = ease;
_vRadius = radius;
_downPoint.offset(0, startOffset);
}
}
private function addListeners():void
{
_init = true;
_currentPoint = new Point(0,0);
_startPoint = new Point(0,0);
_downPoint = new Point( 0,0 );
_base.addEventListener( MouseEvent.MOUSE_DOWN, mouseDown , false , 0 , true);
_base.addEventListener( MouseEvent.MOUSE_UP , mouseUp , false , 0 , true);
}
private function mouseDown(ev:MouseEvent):void
{
_startPoint = new Point(_base.stage.mouseX , _base.stage.mouseY);
_downPoint = new Point(_camRx , _camRy);
_mouseDown = true;
}
private function mouseUp(ev:MouseEvent):void
{
_mouseDown = false;
}
public function processFrame():void
{
if(_mouseDown)
{
_currentPoint.x = _base.mouseX;
_currentPoint.y = _base.mouseY;
}
switch( _verticalType)
{
case X:
{
_percentY = (_currentPoint.y - _startPoint.y) / _base.stage.stageHeight;
_camRy = _downPoint.y + (_percentY * _vMultiplier);
if (_camRy < _vLow) _camRy = _vLow;
if (_camRy > _vHigh) _camRy = _vHigh;
_do.x += (_camRy - _do.x) / _vEase;
break;
}
case Y:
{
_percentY = (_currentPoint.y - _startPoint.y) / _base.stage.stageHeight;
_camRy = _downPoint.y + (_percentY * _vMultiplier);
if (_camRy < _vLow) _camRy = _vLow;
if (_camRy > _vHigh) _camRy = _vHigh;
_do.y += (_camRy - _do.y) / _vEase;
break;
}
case Z:
{
_percentY = (_currentPoint.y - _startPoint.y) / _base.stage.stageHeight;
_camRy = _downPoint.y + (_percentY * _vMultiplier);
if (_camRy < _vLow) _camRy = _vLow;
if (_camRy > _vHigh) _camRy = _vHigh;
_do.z += (_camRy - _do.z) / _vEase;
break;
}
case XY:
{
_percentY = (_currentPoint.y - _startPoint.y)/_base.stage.stageHeight;
_camRy = _downPoint.y + (_percentY * _vMultiplier / 5);
_do.x += ((Math.cos( MathUtils.toRadians( _camRy )) * _vRadius) - _do.x) / _vEase;
_do.y += ((Math.sin( MathUtils.toRadians( _camRy )) * -_vRadius) - _do.y) / _vEase;
break;
}
case XZ:
{
_percentY = (_currentPoint.y - _startPoint.y)/_base.stage.stageHeight;
_camRy = _downPoint.y + (_percentY * _vMultiplier / 5);
_do.x += ((Math.cos( MathUtils.toRadians( _camRy )) * _vRadius) - _do.x) / _vEase;
_do.z += ((Math.sin( MathUtils.toRadians( _camRy )) * -_vRadius) - _do.z) / _vEase;
break;
}
case YZ:
{
_percentY = (_currentPoint.y - _startPoint.y)/_base.stage.stageHeight;
_camRy = _downPoint.y + (_percentY * _vMultiplier / 5);
_do.y += ((Math.cos( MathUtils.toRadians( _camRy )) * _vRadius) - _do.y) / _vEase;
_do.z += ((Math.sin( MathUtils.toRadians( _camRy )) * -_vRadius) - _do.z) / _vEase;
break;
}
}
switch( _horizontalType)
{
case X:
{
_percentX = (_currentPoint.x - _startPoint.x) / _base.stage.stageWidth;
_camRx = _downPoint.x + (_percentX * _hMultiplier);
if (_camRx < _hLow) _camRx = _hLow;
if (_camRx > _hHigh) _camRx = _hHigh;
_do.x += (_camRx - _do.x) / _hEase;
break;
}
case Y:
{
_percentX = (_currentPoint.x - _startPoint.x) / _base.stage.stageWidth;
_camRx = _downPoint.x + (_percentX * _hMultiplier);
if (_camRx < _hLow) _camRx = _hLow;
if (_camRx > _hHigh) _camRx = _hHigh;
_do.y += (_camRx - _do.y) / _hEase;
break;
}
case Z:
{
_percentX = (_currentPoint.x - _startPoint.x) / _base.stage.stageWidth;
_camRx = _downPoint.x + (_percentX * _hMultiplier);
if (_camRx < _hLow) _camRx = _hLow;
if (_camRx > _hHigh) _camRx = _hHigh;
_do.z += (_camRx - _do.z) / _hEase;
break;
}
case XY:
{
_percentX = (_currentPoint.x - _startPoint.x)/_base.stage.stageWidth;
_camRx = _downPoint.x + (_percentX * _hMultiplier / 5);
_do.x += ((Math.cos( MathUtils.toRadians( _camRx )) * _hRadius) - _do.x) / _hEase;
_do.y += ((Math.sin( MathUtils.toRadians( _camRx )) * _hRadius) - _do .y) / _hEase;
break;
}
case XZ:
{
_percentX = (_currentPoint.x - _startPoint.x)/_base.stage.stageWidth;
_camRx = _downPoint.x + (_percentX * _hMultiplier / 5);
_do.x += ((Math.cos( MathUtils.toRadians( _camRx )) * _hRadius) - _do.x) / _hEase;
_do.z += ((Math.sin( MathUtils.toRadians( _camRx )) * -_hRadius) - _do.z) / _hEase;
break;
}
case YZ:
{
_percentX = (_currentPoint.x - _startPoint.x)/_base.stage.stageWidth;
_camRx = _downPoint.x + (_percentX * _hMultiplier / 5);
_do.y += ((Math.cos( MathUtils.toRadians( _camRx )) * _hRadius) - _do.y) / _hEase;
_do.z += ((Math.sin( MathUtils.toRadians( _camRx )) * -_hRadius) - _do.z) / _hEase;
break;
}
}
}
}
}