Thanks. That is an quite simple but good idea! I created this code, but it is not yet tested for other screen resolutions. It allows you to zoom and scroll the camera with two fingers:
package de.jvhoffbauer.empire.game;
import com.jme3.input.InputManager;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.MouseAxisTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.input.controls.TouchListener;
import com.jme3.input.controls.TouchTrigger;
import com.jme3.input.event.TouchEvent;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import static de.jvhoffbauer.empire.game.StrategyCameraController.SCROLL_DOWN;
import static de.jvhoffbauer.empire.game.StrategyCameraController.SCROLL_LEFT;
import static de.jvhoffbauer.empire.game.StrategyCameraController.SCROLL_RIGHT;
import static de.jvhoffbauer.empire.game.StrategyCameraController.SCROLL_UP;
/**
*
* @author jvh
*/
public class StrategyCameraControllerAndroid extends StrategyCameraController implements TouchListener {
public static final int REFERENCE_WIDTH = 1920, REFERENCE_HEIGHT = 1080;
private float widthScale, heightScale;
private float speed = 0.001f;
private Vector2f prevPointerPos = new Vector2f();
private float prevScaleFactor = 0;
private float zoomSpeed = 1;
public StrategyCameraControllerAndroid(Camera cam, InputManager inputManager) {
super(cam, inputManager);
this.widthScale = cam.getWidth() / REFERENCE_WIDTH;
this.heightScale = cam.getHeight() / REFERENCE_HEIGHT;
}
protected void registerInputs() {
inputManager.addMapping(TRIGGER_DRAG, new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addMapping(SCROLL_DOWN, new MouseAxisTrigger(MouseInput.AXIS_Y, false));
inputManager.addMapping(SCROLL_UP, new MouseAxisTrigger(MouseInput.AXIS_Y, true));
inputManager.addMapping(SCROLL_LEFT, new MouseAxisTrigger(MouseInput.AXIS_X, true));
inputManager.addMapping(SCROLL_RIGHT, new MouseAxisTrigger(MouseInput.AXIS_X, false));
inputManager.addListener(this, new String[]{TRIGGER_DRAG, SCROLL_DOWN, SCROLL_UP, SCROLL_LEFT,
SCROLL_RIGHT});
inputManager.addMapping("Touch", new TouchTrigger(0));
inputManager.addListener(this, "Touch");
}
public void onTouch(String name, TouchEvent event, float tpf) {
if(event.getType() == TouchEvent.Type.SCALE_START) {
prevPointerPos = null;
prevScaleFactor = -1;
}
else if(event.getType() == TouchEvent.Type.SCALE_MOVE) {
if(prevPointerPos == null) {
prevPointerPos = new Vector2f(event.getX(), event.getY());
prevScaleFactor = event.getScaleFactor();
}
// Move camera
prevPointerPos.subtractLocal(event.getX(), event.getY()); // prevPointerPos now is delta between prev and current pointer pos
Vector3f cameraMovement = new Vector3f(prevPointerPos.x, 0, prevPointerPos.y);
cameraMovement.x *= -speed * cam.getLocation().y * widthScale;
cameraMovement.z *= speed * cam.getLocation().y * heightScale;
cam.setLocation(cam.getLocation().add(cameraMovement));
prevPointerPos.set(event.getX(), event.getY());
// Zoom
float deltaScaleFactor = prevScaleFactor - event.getScaleFactor();
prevScaleFactor = event.getScaleFactor();
setToZoom(getZoom() + deltaScaleFactor * zoomSpeed);
}
}
}
and:
package de.jvhoffbauer.empire.game;
import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.input.InputManager;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
/**
*
* @author jvh
*/
public abstract class StrategyCameraController extends AbstractAppState {
public static String
TRIGGER_DRAG = "TriggerDrag",
SCROLL_UP = "ScrollUp",
SCROLL_DOWN = "ScrollDown",
SCROLL_LEFT = "ScrollLeft",
SCROLL_RIGHT = "ScrollRight",
ZOOM_IN = "ZoomIn",
ZOOM_OUT = "ZoomOut";
protected Camera cam;
protected InputManager inputManager;
private float zoom = 1;
private float camMinY = 1.5f, camMaxY = 10;
public StrategyCameraController(Camera cam, InputManager inputManager) {
this.cam = cam;
this.inputManager = inputManager;
}
protected abstract void registerInputs();
@Override
public void initialize(AppStateManager stateManager, Application app) {
cam.setLocation(new Vector3f(0, camMaxY, 0));
cam.lookAt(Vector3f.ZERO, cam.getUp());
registerInputs();
}
/**
* Zooms the camera to a certaion value, which is in [0; 1].
*/
protected void setToZoom(float zoom) {
if(zoom > 1)
zoom = 1;
else if(zoom < 0)
zoom = 0;
this.zoom = zoom;
Vector3f camPos = cam.getLocation();
camPos.y = camMinY + (camMaxY - camMinY) * zoom;
cam.setLocation(camPos);
}
protected float getZoom() {
return zoom;
}
}