Browse Source

revert ef5e5ddddde7b8bedde9832d1f541027ebfcd6aa (regression spotted, reopen #281)

ncannasse 8 years ago
parent
commit
59af6cbc08
2 changed files with 94 additions and 98 deletions
  1. 89 61
      h2d/Scene.hx
  2. 5 37
      samples/Interactive.hx

+ 89 - 61
h2d/Scene.hx

@@ -76,33 +76,21 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 			posChanged = true;
 		}
 	}
-	
-	inline function relMouseX() {
-		return stage.mouseX * width / stage.width;
+
+	inline function screenXToLocal(mx:Float) {
+		return mx * width / (stage.width * scaleX) - x;
 	}
-	
-	inline function relMouseY() {
-		return stage.mouseY * height / stage.height;
+
+	inline function screenYToLocal(my:Float) {
+		return my * height / (stage.height * scaleY) - y;
 	}
 
 	function get_mouseX() {
-		if (rotation == 0) {
-			return relMouseX() / scaleX - absX;
-		}
-		var mx = relMouseX() - absX;
-		var my = relMouseY() - absY;
-		var invDet = 1 / (matA * matD - matB * matC);
-		return (mx * matD - my * matC) * invDet;
+		return screenXToLocal(stage.mouseX);
 	}
 
 	function get_mouseY() {
-		if (rotation == 0) {
-			return relMouseY() / scaleY - absY;
-		}
-		var mx = relMouseX() - absX;
-		var my = relMouseY() - absY;
-		var invDet = 1 / (matA * matD - matB * matC);
-		return (-mx * matB + my * matA) * invDet;
+		return screenYToLocal(stage.mouseY);
 	}
 
 	public function dispatchListeners( event : hxd.Event ) {
@@ -122,17 +110,34 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 		return true;
 	}
 
-	/**
-	 * Return first Interactive which overlaps with x,y coordinates (Scene space) or null
-	 */
 	public function getInteractive( x : Float, y : Float ) {
-		var rx = x * matA + y * matC + absX;
-		var ry = x * matB + y * matD + absY;
-		for ( i in interactive ) {
+		var rx = x * matA + y * matB + absX;
+		var ry = x * matC + y * matD + absY;
+		for( i in interactive ) {
+
+			var dx = rx - i.absX;
+			var dy = ry - i.absY;
+
+			var w1 = i.width * i.matA;
+			var h1 = i.width * i.matC;
+			var ky = h1 * dx + w1 * dy;
+
+			// up line
+			if( ky < 0 )
+				continue;
 
-			// check bounds
-			var local = toInteractiveLocal(i, rx, ry);
-			if (local.x < 0 || local.x > i.width || local.y < 0 || local.y > i.height)
+			var w2 = i.height * i.matB;
+			var h2 = i.height * i.matD;
+			var kx = w2 * dy + h2 * dx;
+
+			// left line
+			if( kx < 0 )
+				continue;
+
+			var max = w1 * h2 - h1 * w2;
+
+			// bottom/right
+			if( ky >= max || kx >= max )
 				continue;
 
 			// check visibility
@@ -151,51 +156,74 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 		}
 		return null;
 	}
-	
-	inline function applyFixedSizeScale( e: hxd.Event ) {
-		if (fixedSize) {
-			e.relX *= width / stage.width;
-			e.relY *= height / stage.height;
-		}
-	}
 
 	function screenToLocal( e : hxd.Event ) {
-		applyFixedSizeScale(e);
-		var px = e.relX - absX;
-		var py = e.relY - absY;
-		var invDet = 1 / (matA * matD - matB * matC);
-		e.relX = (px * matD - py * matC) * invDet;
-		e.relY = ( -px * matB + py * matA) * invDet;
-	}
-	
-	static inline function toInteractiveLocal( i : Interactive, x : Float, y : Float ) {
-		var px = x - i.absX;
-		var py = y - i.absY;
-		var invDet = 1 / (i.matA * i.matD - i.matB * i.matC);
-		var lx = (px * i.matD - py * i.matC) * invDet;
-		var ly = ( -px * i.matB + py * i.matA) * invDet;
-		return new h2d.col.Point(lx, ly);
+		var x = screenXToLocal(e.relX);
+		var y = screenYToLocal(e.relY);
+		var rx = x * matA + y * matB + absX;
+		var ry = x * matC + y * matD + absY;
+		e.relX = rx;
+		e.relY = ry;
 	}
 
 	public function dispatchEvent( event : hxd.Event, to : hxd.SceneEvents.Interactive ) {
 		var i : Interactive = cast to;
-		applyFixedSizeScale(event);
-		var local = toInteractiveLocal(i, event.relX, event.relY);
-		event.relX = local.x;
-		event.relY = local.y;
+		screenToLocal(event);
+
+		var rx = event.relX;
+		var ry = event.relY;
+
+		var dx = rx - i.absX;
+		var dy = ry - i.absY;
+
+		var w1 = i.width * i.matA;
+		var h1 = i.width * i.matC;
+		var ky = h1 * dx + w1 * dy;
+
+		var w2 = i.height * i.matB;
+		var h2 = i.height * i.matD;
+		var kx = w2 * dy + h2 * dx;
+
+		var max = w1 * h2 - h1 * w2;
+
+		event.relX = (kx / max) * i.width;
+		event.relY = (ky / max) * i.height;
+
 		i.handleEvent(event);
 	}
 
 	public function handleEvent( event : hxd.Event, last : hxd.SceneEvents.Interactive ) : hxd.SceneEvents.Interactive {
-		applyFixedSizeScale(event);
+		screenToLocal(event);
+		var rx = event.relX;
+		var ry = event.relY;
 		var index = last == null ? 0 : interactive.indexOf(cast last) + 1;
 		for( idx in index...interactive.length ) {
 			var i = interactive[idx];
 			if( i == null ) break;
 
-			// check bounds
-			var local = toInteractiveLocal(i, event.relX, event.relY);
-			if (local.x < 0 || local.x > i.width || local.y < 0 || local.y > i.height)
+			var dx = rx - i.absX;
+			var dy = ry - i.absY;
+
+			var w1 = i.width * i.matA;
+			var h1 = i.width * i.matC;
+			var ky = h1 * dx + w1 * dy;
+
+			// up line
+			if( ky < 0 )
+				continue;
+
+			var w2 = i.height * i.matB;
+			var h2 = i.height * i.matD;
+			var kx = w2 * dy + h2 * dx;
+
+			// left line
+			if( kx < 0 )
+				continue;
+
+			var max = w1 * h2 - h1 * w2;
+
+			// bottom/right
+			if( ky >= max || kx >= max )
 				continue;
 
 			// check visibility
@@ -210,8 +238,8 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 			}
 			if( !visible ) continue;
 
-			event.relX = local.x;
-			event.relY = local.y;
+			event.relX = (kx / max) * i.width;
+			event.relY = (ky / max) * i.height;
 			i.handleEvent(event);
 
 			if( event.cancel ) {

+ 5 - 37
samples/Interactive.hx

@@ -1,5 +1,3 @@
-import h2d.Graphics;
-import hxd.Event;
 //PARAM=-D resourcesPath=../../skin_res
 
 class Interactive extends hxd.App {
@@ -80,22 +78,16 @@ class Interactive extends hxd.App {
 			initInteract(i, m);
 		}
 
-		s2d.setPos(10, 10);
-		s2d.scaleY = 1.2;
-		s2d.rotation = 0.3;
-		// s2d.setFixedSize(600, 600);
-
-		
 		b = new h2d.Interactive(150, 100, s2d);
-		b.backgroundColor = 0xC0204060;
+		b.backgroundColor = 0x80204060;
 		b.rotation = Math.PI / 3;
-		b.scaleX = 1.2;
+		//b.scaleX = 1.5; // TODO
 
 		var pix = null;
 		b.onOver = function(e) {
-			var t = h2d.Tile.fromColor(0xFF0000, 5, 5);
-			t.dx = -2;
-			t.dy = -2;
+			var t = h2d.Tile.fromColor(0xFF0000, 3, 3);
+			t.dx = -1;
+			t.dy = -1;
 			pix = new h2d.Bitmap(t, b);
 			pix.x = e.relX;
 			pix.y = e.relY;
@@ -109,22 +101,6 @@ class Interactive extends hxd.App {
 			pix.remove();
 			pix = null;
 		};
-		b.onClick = function(e) {
-			// Dispatch back a move event. Check that pix doesn't move on click
-			var stage = hxd.Stage.getInstance();
-			e.kind = EMove;
-			e.relX = stage.mouseX;
-			e.relY = stage.mouseY;
-			s2d.dispatchEvent(e, b);
-		}
-		s2d.addEventListener(function (e) {
-			if (e.kind == EPush) {
-				var g  = new Graphics(s2d);
-				g.beginFill(0xff0000);
-				g.drawRect(e.relX, e.relY, 4, 4);
-				g.endFill();
-			}
-		});
 
 		onResize();
 	}
@@ -136,14 +112,6 @@ class Interactive extends hxd.App {
 
 	override function update(dt:Float) {
 		obj.rotate(0, 0, 0.002 * dt);
-		
-		var i = s2d.getInteractive(s2d.mouseX, s2d.mouseY);
-		if (i != null) {
-			b.alpha = 0.5;
-		}
-		else {
-			b.alpha = 1.0;
-		}
 	}