123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- package hide.view.l3d;
- class CameraController2D extends h2d.Object {
- public var friction = 0.4;
- public var zoomAmount = 1.15;
- public var panSpeed = 1.;
- public var smooth = 0.6;
- var scene : h2d.Scene;
- var pushing = -1;
- var pushX = 0.;
- var pushY = 0.;
- var pushStartX = 0.;
- var pushStartY = 0.;
- var moveX = 0.;
- var moveY = 0.;
- var pushTime : Float;
- var curPos = new h3d.col.Point(0,0,1);
- var targetPos = new h3d.col.Point(0,0,1);
- public function new(?parent) {
- super(parent);
- name = "CameraController";
- }
- /**
- Set the controller parameters.
- Distance is ray distance from target.
- Theta and Phi are the two spherical angles
- Target is the target position
- **/
- public function set( x : Float, y : Float, ?zoom : Float ) {
- targetPos.x = x;
- targetPos.y = y;
- if( zoom != null ) targetPos.z = zoom;
- }
- /**
- Load current position from current camera position and target.
- Call if you want to modify manually the camera.
- **/
- public function loadFromScene( animate = false ) {
- var scene = if( scene == null ) getScene() else scene;
- if( scene == null ) throw "Not in scene";
- targetPos.set( (scene.width*0.5-parent.x) / parent.scaleX, (scene.height*0.5-parent.y) / parent.scaleX, parent.scaleX);
- if( !animate )
- toTarget();
- else
- syncCamera(); // reset camera to current
- }
- /**
- Initialize to look at the whole scene, based on reported scene bounds.
- **/
- public function initFromScene() {
- var scene = getScene();
- if( scene == null ) throw "Not in scene";
- var bounds = parent.getBounds(parent);
- var center = bounds.getCenter();
- var scale = Math.min(1, Math.min(scene.width / bounds.width, scene.height / bounds.height));
- parent.setScale(scale);
- parent.x = scene.width * 0.5 - center.x;
- parent.y = scene.height * 0.5 - center.y;
- loadFromScene();
- }
- /**
- Stop animation by directly moving to end position.
- Call after set() if you don't want to animate the change
- **/
- public function toTarget() {
- curPos.load(targetPos);
- syncCamera();
- }
- override function onAdd() {
- super.onAdd();
- scene = getScene();
- scene.addEventListener(onEvent);
- targetPos.load(curPos);
- }
- override function onRemove() {
- super.onRemove();
- scene.removeEventListener(onEvent);
- scene = null;
- }
- public dynamic function onClick( e : hxd.Event ) {
- }
- function onEvent( e : hxd.Event ) {
- var p : h2d.Object = this;
- while( p != null ) {
- if( !p.visible ) {
- e.propagate = true;
- return;
- }
- p = p.parent;
- }
- switch( e.kind ) {
- case EWheel:
- zoom(e.wheelDelta);
- case EPush:
- @:privateAccess scene.events.startCapture(onEvent, function() pushing = -1, e.touchId);
- pushing = e.button;
- pushTime = haxe.Timer.stamp();
- pushStartX = pushX = e.relX;
- pushStartY = pushY = e.relY;
- case ERelease, EReleaseOutside:
- if( pushing == e.button ) {
- pushing = -1;
- @:privateAccess scene.events.stopCapture();
- if( e.kind == ERelease && haxe.Timer.stamp() - pushTime < 0.2 && hxd.Math.distance(e.relX - pushStartX,e.relY - pushStartY) < 5 )
- onClick(e);
- }
- case EMove:
- switch( pushing ) {
- case 1:
- pan((e.relX - pushX) * panSpeed, (e.relY - pushY) * panSpeed);
- pushX = e.relX;
- pushY = e.relY;
- default:
- }
- default:
- }
- }
- function zoom(delta:Float) {
- targetPos.z *= Math.pow(zoomAmount, -delta);
- }
- function rot(dx, dy) {
- moveX += dx;
- moveY += dy;
- }
- function pan(dx:Float, dy:Float) {
- targetPos.x -= dx / parent.scaleX;
- targetPos.y -= dy / parent.scaleY;
- }
- function syncCamera() {
- var scene = getScene();
- if( scene == null ) return;
- parent.setScale(curPos.z);
- parent.x = scene.width * 0.5 - curPos.x * parent.scaleX;
- parent.y = scene.height * 0.5 - curPos.y * parent.scaleY;
- }
- override function sync(ctx:h2d.RenderContext) {
- var p : h2d.Object = this;
- while( p != null ) {
- if( !p.visible ) {
- super.sync(ctx);
- return;
- }
- p = p.parent;
- }
- /*
- if( moveX != 0 ) {
- targetPos.y += moveX * 0.003 * rotateSpeed;
- moveX *= 1 - friction;
- if( Math.abs(moveX) < 1 ) moveX = 0;
- }
- if( moveY != 0 ) {
- targetPos.z -= moveY * 0.003 * rotateSpeed;
- var E = 2e-5;
- var bound = Math.PI - E;
- if( targetPos.z < E ) targetPos.z = E;
- if( targetPos.z > bound ) targetPos.z = bound;
- moveY *= 1 - friction;
- if( Math.abs(moveY) < 1 ) moveY = 0;
- }*/
- var dt = hxd.Math.min(1, 1 - Math.pow(smooth, ctx.elapsedTime * 60));
- curPos.lerp(curPos, targetPos, dt );
- syncCamera();
- super.sync(ctx);
- }
- }
|