https://www.jpct.net/wiki/index.php?title=MultiTouch_camera_controls&feed=atom&action=history
MultiTouch camera controls - Revision history
2024-03-29T06:01:10Z
Revision history for this page on the wiki
MediaWiki 1.23.15
https://www.jpct.net/wiki/index.php?title=MultiTouch_camera_controls&diff=606&oldid=prev
Ruben: /* MultiTouch camera controls */
2014-09-10T18:59:07Z
<p><span dir="auto"><span class="autocomment">MultiTouch camera controls</span></span></p>
<table class='diff diff-contentalign-left'>
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr style='vertical-align: top;'>
<td colspan='2' style="background-color: white; color:black; text-align: center;">← Older revision</td>
<td colspan='2' style="background-color: white; color:black; text-align: center;">Revision as of 18:59, 10 September 2014</td>
</tr><tr><td colspan="2" class="diff-lineno">Line 366:</td>
<td colspan="2" class="diff-lineno">Line 366:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>}</div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>}</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></pre></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"><pre></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> @Override</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> public boolean onTouchEvent(MotionEvent event) {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> _movementHandler.handleMotionEvent(event);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> return true;</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> }</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> private void moveCamera() {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> Movement movement = _movementHandler.getMovement();</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> if (movement.hasMovement()) {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> Camera camera = world.getCamera();</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> Matrix rot = camera.getBack();</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> rot.rotateAxis(rot.getYAxis(), -(float) movement.cameraRotationY);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> worldObject.rotateX(movement.worldRotationX);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> float angle = worldObject.getYAxis().calcAngle(</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> new SimpleVector(0, 1, 0));</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> float crossAngle = worldObject.getYAxis().calcCross(</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> new SimpleVector(0, 1, 0)).x;</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> if (crossAngle > 0) {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> worldObject.rotateX(-angle);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> } else {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> float delta = (float) (angle - (Math.PI / 2));</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> if (delta > 0) {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> worldObject.rotateX(delta);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> }</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> }</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> camera.moveCamera(Camera.CAMERA_MOVELEFT, movement.cameraMovementX);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> camera.moveCamera(Camera.CAMERA_MOVEUP, movement.cameraMovementY);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> camera.moveCamera(Camera.CAMERA_MOVEIN, movement.cameraMovementZ);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> }</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"> }</ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div></pre></div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div></pre></div></td></tr>
</table>
Ruben
https://www.jpct.net/wiki/index.php?title=MultiTouch_camera_controls&diff=598&oldid=prev
Ruben: Created page with '=== MultiTouch camera controls === This code will handle control from 1 or 2 fingers, it was made for a tablet showing 3D objects, so it's made for navigating not for FPS gaming…'
2014-08-14T12:35:35Z
<p>Created page with '=== MultiTouch camera controls === This code will handle control from 1 or 2 fingers, it was made for a tablet showing 3D objects, so it's made for navigating not for FPS gaming…'</p>
<p><b>New page</b></p><div>=== MultiTouch camera controls ===<br />
<br />
This code will handle control from 1 or 2 fingers, it was made for a tablet showing 3D objects, so it's made for navigating not for FPS gaming.<br />
<br />
'''Usage'''<br />
Call MovementHandler.handleMotionEvent for every motionEvent you receive.<br />
CAll MovementHandler.getMovement for every tick or whenever you can to update the movement.<br />
<br />
<pre><br />
<br />
import android.util.Log;<br />
import android.view.MotionEvent;<br />
<br />
/**<br />
* <br />
* @author Ruben.Hesselbaek@beumergroup.com<br />
*<br />
*/<br />
public class MovementHandler {<br />
<br />
/**<br />
* Logs a lot of stuff<br />
*/<br />
public static final boolean DEBUG_MOVEMENT = false;<br />
<br />
/**<br />
* Min 0.25 degrees<br />
*/<br />
public static final float MIN_ANGLE_XMOVEMENT = (float) (Math.PI / 720);<br />
<br />
/**<br />
* Max 15 degrees<br />
*/<br />
public static final float MAX_ANGLE_XMOVEMENT = (float) MIN_ANGLE_XMOVEMENT * 60;<br />
<br />
/**<br />
* Pixels->Angle ratio on the X-axis<br />
*/<br />
public static final float XANGLE_FACTOR = 360;<br />
<br />
/**<br />
* Min 0.25 degrees<br />
*/<br />
public static final float MIN_ANGLE_YMOVEMENT = (float) (Math.PI / 720);<br />
<br />
/**<br />
* Max 15 degrees<br />
*/<br />
public static final float MAX_ANGLE_YMOVEMENT = (float) MIN_ANGLE_YMOVEMENT * 60;<br />
<br />
/**<br />
* Pixels->Angle ratio on the Y-axis<br />
*/<br />
public static final float YANGLE_FACTOR = 360;<br />
<br />
/**<br />
* Pixels->Distance ratio<br />
*/<br />
public static final float DISTANCE_FACTOR = 10;<br />
<br />
/**<br />
* Pixels->Movement ratio<br />
*/<br />
public static final float MOVEMENT_X_FACTOR = 10;<br />
<br />
/**<br />
* Pixels->Movement ratio<br />
*/<br />
public static final float MOVEMENT_Y_FACTOR = 10;<br />
<br />
public static final float MIN_MOVEMENT_DELTA = 0.1f;<br />
public static final float MAX_MOVEMENT_DELTA = 5;<br />
<br />
private int _firstPointerId = MotionEvent.INVALID_POINTER_ID;<br />
private float startMovementx1;<br />
private float startMovementy1;<br />
private float lastMovementx1;<br />
private float lastMovementy1;<br />
<br />
private int _secondPointerId = MotionEvent.INVALID_POINTER_ID;<br />
private float startMovementx2;<br />
private float startMovementy2;<br />
private float lastMovementy2;<br />
private float lastMovementx2;<br />
<br />
private float startDistance;<br />
private float lastDistance;<br />
<br />
private float startAngle;<br />
private float lastAngle;<br />
<br />
public synchronized Movement getMovement() {<br />
Movement movement = new Movement();<br />
<br />
if (_secondPointerId != MotionEvent.INVALID_POINTER_ID) {<br />
float movementX1 = lastMovementx1 - startMovementx1;<br />
float movementY1 = lastMovementy1 - startMovementy1;<br />
float movementX2 = lastMovementx2 - startMovementx2;<br />
float movementY2 = lastMovementy2 - startMovementy2;<br />
<br />
if ((movementX1 > 0 && movementX2 > 0)<br />
|| (movementX1 < 0 && movementX2 < 0)) {<br />
float movementX = Math.min(Math.abs(movementX1),<br />
Math.abs(movementX2))<br />
/ MOVEMENT_X_FACTOR;<br />
if (movementX > MIN_MOVEMENT_DELTA<br />
&& movementX < MAX_MOVEMENT_DELTA) {<br />
if (movementX1 > 0) {<br />
movement.cameraMovementX = movementX;<br />
} else {<br />
movement.cameraMovementX = -movementX;<br />
}<br />
} else {<br />
if (DEBUG_MOVEMENT) {<br />
Log.d("MovementHandler",<br />
"getMovement(): Invalid movement: movementX=<"<br />
+ movementX + ">, movementX1=<"<br />
+ movementX1 + ">, movementX2=<"<br />
+ movementX2 + ">");<br />
}<br />
}<br />
}<br />
<br />
if ((movementY1 > 0 && movementY2 > 0)<br />
|| (movementY1 < 0 && movementY2 < 0)) {<br />
float movementY = Math.min(Math.abs(movementY1),<br />
Math.abs(movementY2))<br />
/ MOVEMENT_Y_FACTOR;<br />
if (movementY > MIN_MOVEMENT_DELTA<br />
&& movementY < MAX_MOVEMENT_DELTA) {<br />
if (movementY1 > 0) {<br />
movement.cameraMovementY = movementY;<br />
} else {<br />
movement.cameraMovementY = -movementY;<br />
}<br />
} else {<br />
if (DEBUG_MOVEMENT) {<br />
Log.d("MovementHandler",<br />
"getMovement(): Invalid movement: movementY<"<br />
+ movementY + ">, movementY1=<"<br />
+ movementY1 + ">, movementY2=<"<br />
+ movementY2 + ">");<br />
}<br />
}<br />
}<br />
float distanceDelta = lastDistance - startDistance;<br />
float distance = distanceDelta / DISTANCE_FACTOR;<br />
float absoluteDistance = Math.abs(distance);<br />
if (absoluteDistance > MIN_MOVEMENT_DELTA<br />
&& absoluteDistance < MAX_MOVEMENT_DELTA) {<br />
movement.cameraMovementZ = distance;<br />
} else {<br />
if (DEBUG_MOVEMENT) {<br />
Log.d("MovementHandler",<br />
"getMovement(): Invalid movement: distanceDelta=<"<br />
+ distanceDelta + ">, distance=<"<br />
+ distance + ">");<br />
}<br />
}<br />
<br />
float angleDelta = lastAngle - startAngle;<br />
float absoluteAngle = Math.abs(angleDelta);<br />
if (absoluteAngle > MIN_ANGLE_XMOVEMENT<br />
&& absoluteAngle < MAX_ANGLE_XMOVEMENT) {<br />
movement.cameraRotationY = angleDelta;<br />
} else {<br />
if (DEBUG_MOVEMENT) {<br />
Log.d("MovementHandler",<br />
"getMovement(): Invalid movement: absoluteAngle=<"<br />
+ absoluteAngle + ">, startAngle=<"<br />
+ Math.toDegrees(startAngle)<br />
+ ">, lastAngle=<"<br />
+ Math.toDegrees(lastAngle) + ">");<br />
}<br />
}<br />
} else if (_firstPointerId != MotionEvent.INVALID_POINTER_ID) {<br />
float movementX1 = lastMovementx1 - startMovementx1;<br />
float angle = (float) ((movementX1) / XANGLE_FACTOR);<br />
float absoluteAngle = Math.abs(angle);<br />
if (absoluteAngle > MIN_ANGLE_XMOVEMENT<br />
&& absoluteAngle < MAX_ANGLE_XMOVEMENT) {<br />
movement.cameraRotationY = angle;<br />
} else {<br />
if (DEBUG_MOVEMENT) {<br />
Log.d("MovementHandler",<br />
"getMovement(): Invalid movement: movementX=<"<br />
+ movementX1 + ">, angle=<" + absoluteAngle<br />
+ ">");<br />
}<br />
}<br />
<br />
float movementY1 = lastMovementy1 - startMovementy1;<br />
angle = (float) ((movementY1) / YANGLE_FACTOR);<br />
absoluteAngle = Math.abs(angle);<br />
if (absoluteAngle > MIN_ANGLE_YMOVEMENT<br />
&& absoluteAngle < MAX_ANGLE_YMOVEMENT) {<br />
movement.worldRotationX = angle;<br />
} else {<br />
if (DEBUG_MOVEMENT) {<br />
Log.d("MovementHandler",<br />
"getMovement(): Invalid movement: movementY=<"<br />
+ movementY1 + ">, angle=<" + absoluteAngle<br />
+ ">");<br />
}<br />
}<br />
}<br />
startMovementx1 = lastMovementx1;<br />
startMovementy1 = lastMovementy1;<br />
startMovementx2 = lastMovementx2;<br />
startMovementy2 = lastMovementy2;<br />
startDistance = lastDistance;<br />
startAngle = lastAngle;<br />
return movement;<br />
}<br />
<br />
public synchronized void handleMotionEvent(MotionEvent event) {<br />
final int pointerIndex = event.getActionIndex();<br />
final int pointerId = event.getPointerId(pointerIndex);<br />
<br />
if (DEBUG_MOVEMENT) {<br />
Log.d("MovementHandler", "handleMotionEvent(pointerIndex=<"<br />
+ pointerIndex + ">, pointerId=<" + pointerId<br />
+ ">, event=<" + event.getActionMasked()<br />
+ ">, pointerCount=<" + event.getPointerCount() + ">");<br />
}<br />
switch (event.getActionMasked()) {<br />
case MotionEvent.ACTION_DOWN: {<br />
_firstPointerId = pointerId;<br />
_secondPointerId = MotionEvent.INVALID_POINTER_ID;<br />
startMovementx1 = event.getX(_firstPointerId);<br />
startMovementy1 = event.getY(_firstPointerId);<br />
lastMovementx1 = startMovementx1;<br />
lastMovementy1 = startMovementy1;<br />
if (DEBUG_MOVEMENT) {<br />
Log.d("MovementHandler", "ACTION_DOWN(firstPointerId=<"<br />
+ _firstPointerId + ">(" + startMovementx1 + ","<br />
+ startMovementy1 + ")");<br />
}<br />
break;<br />
}<br />
case MotionEvent.ACTION_UP: {<br />
_firstPointerId = MotionEvent.INVALID_POINTER_ID;<br />
_secondPointerId = MotionEvent.INVALID_POINTER_ID;<br />
if (DEBUG_MOVEMENT) {<br />
Log.d("MovementHandler", "ACTION_UP(firstPointerId=<"<br />
+ _firstPointerId + ">)");<br />
}<br />
break;<br />
}<br />
case MotionEvent.ACTION_POINTER_DOWN:<br />
if (event.getPointerCount() == 2) {<br />
_secondPointerId = pointerId;<br />
startMovementx2 = event.getX(_secondPointerId);<br />
startMovementy2 = event.getY(_secondPointerId);<br />
lastMovementx2 = startMovementx2;<br />
lastMovementy2 = startMovementy2;<br />
startDistance = calcDistance();<br />
startAngle = calcAngle();<br />
if (DEBUG_MOVEMENT) {<br />
Log.d("MovementHandler",<br />
"ACTION_POINTER_DOWN(secondPointerId=<"<br />
+ _secondPointerId + ">)");<br />
}<br />
}<br />
break;<br />
case MotionEvent.ACTION_POINTER_UP:<br />
if (pointerId == _firstPointerId) {<br />
// This was our active pointer going up. Choose a new<br />
// active pointer and adjust accordingly.<br />
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;<br />
_firstPointerId = event.getPointerId(newPointerIndex);<br />
int oldPointerId = _firstPointerId;<br />
if (DEBUG_MOVEMENT) {<br />
Log.d("MovementHandler",<br />
"ACTION_POINTER_UP(_firstPointerId=<"<br />
+ _firstPointerId + ">, oldPointerId=<"<br />
+ oldPointerId + ">)");<br />
}<br />
startMovementx1 = event.getX(newPointerIndex);<br />
startMovementy1 = event.getY(newPointerIndex);<br />
} else if (pointerId == _secondPointerId) {<br />
if (event.getPointerCount() > 2) {<br />
// This was our active secondpointer going up. Choose a new<br />
// active pointer and adjust accordingly.<br />
final int newPointerIndex = pointerIndex == 1 ? 2 : 1;<br />
_secondPointerId = event.getPointerId(newPointerIndex);<br />
int oldPointerId = _secondPointerId;<br />
if (DEBUG_MOVEMENT) {<br />
Log.d("MovementHandler",<br />
"ACTION_POINTER_UP(secondPointerId=<"<br />
+ _secondPointerId<br />
+ ">, oldPointerId=<" + oldPointerId<br />
+ ">)");<br />
}<br />
startMovementx2 = event.getX(newPointerIndex);<br />
startMovementy2 = event.getY(newPointerIndex);<br />
} else {<br />
_secondPointerId = MotionEvent.INVALID_POINTER_ID;<br />
if (DEBUG_MOVEMENT) {<br />
Log.d("MovementHandler",<br />
"ACTION_POINTER_UP(secondPointerId=<"<br />
+ _secondPointerId + ">)");<br />
}<br />
}<br />
}<br />
break;<br />
case MotionEvent.ACTION_MOVE: {<br />
int firstPointerIndex = event.findPointerIndex(_firstPointerId);<br />
int secondPointerIndex = event.findPointerIndex(_secondPointerId);<br />
if (event.getPointerCount() > 0) {<br />
lastMovementx1 = event.getX(firstPointerIndex);<br />
lastMovementy1 = event.getY(firstPointerIndex);<br />
}<br />
if (event.getPointerCount() > 1) {<br />
lastMovementx2 = event.getX(secondPointerIndex);<br />
lastMovementy2 = event.getY(secondPointerIndex);<br />
lastDistance = calcDistance();<br />
lastAngle = calcAngle();<br />
}<br />
break;<br />
}<br />
}<br />
}<br />
<br />
private float calcDistance() {<br />
float deltaX = lastMovementx2 - lastMovementx1;<br />
float deltaY = lastMovementy2 - lastMovementy1;<br />
return (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY);<br />
}<br />
<br />
private float calcAngle() {<br />
return (float) Math.atan2(lastMovementx1 - lastMovementx2,<br />
lastMovementy1 - lastMovementy2);<br />
}<br />
}<br />
</pre><br />
<br />
<pre><br />
/**<br />
* <br />
* @author Ruben.Hesselbaek@beumergroup.com<br />
*<br />
*/<br />
public class Movement {<br />
<br />
public float worldRotationX;<br />
public float cameraRotationY;<br />
public float cameraMovementX;<br />
public float cameraMovementY;<br />
public float cameraMovementZ;<br />
<br />
public boolean hasMovement() {<br />
return worldRotationX != 0f || cameraRotationY != 0f<br />
|| cameraMovementX != 0f || cameraMovementY != 0f<br />
|| cameraMovementZ != 0f;<br />
}<br />
<br />
@Override<br />
public String toString() {<br />
return "Movement (hasMovement=<"+hasMovement()+">, worldRotationX=" + worldRotationX<br />
+ ", cameraRotationY=" + cameraRotationY + ", cameraMovementX="<br />
+ cameraMovementX + ", cameraMovementY=" + cameraMovementY<br />
+ ", cameraMovementZ=" + cameraMovementZ + ")";<br />
}<br />
<br />
}<br />
<br />
</pre></div>
Ruben