public class

ZoomCamera

extends BoundCamera
package org.andengine.engine.camera;

import org.andengine.input.touch.TouchEvent;
import org.andengine.util.Constants;
import org.andengine.util.math.MathUtils;



/**
 * (c) 2010 Nicolas Gramlich
 * (c) 2011 Zynga Inc.
 * 
 * @author Nicolas Gramlich
 * @since 15:48:11 - 24.06.2010
 * TODO min/max(X/Y) values could be cached and only updated once the zoomfactor/center changed.
 */
public class ZoomCamera extends BoundCamera {
	// ===========================================================
	// Constants
	// ===========================================================

	// ===========================================================
	// Fields
	// ===========================================================

	protected float mZoomFactor = 1.0f;

	// ===========================================================
	// Constructors
	// ===========================================================

	public ZoomCamera(final float pX, final float pY, final float pWidth, final float pHeight) {
		super(pX, pY, pWidth, pHeight);
	}

	// ===========================================================
	// Getter & Setter
	// ===========================================================

	public float getZoomFactor() {
		return this.mZoomFactor;
	}

	public void setZoomFactor(final float pZoomFactor) {
		this.mZoomFactor = pZoomFactor;

		if(this.mBoundsEnabled) {
			this.ensureInBounds();
		}
	}

	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================

	@Override
	public float getXMin() {
		if(this.mZoomFactor == 1.0f) {
			return super.getXMin();
		} else {
			final float centerX = this.getCenterX();
			return centerX - (centerX - super.getXMin()) / this.mZoomFactor;
		}
	}

	@Override
	public float getXMax() {
		if(this.mZoomFactor == 1.0f) {
			return super.getXMax();
		} else {
			final float centerX = this.getCenterX();
			return centerX + (super.getXMax() - centerX) / this.mZoomFactor;
		}
	}

	@Override
	public float getYMin() {
		if(this.mZoomFactor == 1.0f) {
			return super.getYMin();
		} else {
			final float centerY = this.getCenterY();
			return centerY - (centerY - super.getYMin()) / this.mZoomFactor;
		}
	}

	@Override
	public float getYMax() {
		if(this.mZoomFactor == 1.0f) {
			return super.getYMax();
		} else {
			final float centerY = this.getCenterY();
			return centerY + (super.getYMax() - centerY) / this.mZoomFactor;
		}
	}

	@Override
	public float getWidth() {
		return super.getWidth() / this.mZoomFactor;
	}

	@Override
	public float getHeight() {
		return super.getHeight() / this.mZoomFactor;
	}

	@Override
	protected void applySceneToCameraSceneOffset(final TouchEvent pSceneTouchEvent) {
		final float zoomFactor = this.mZoomFactor;
		if(zoomFactor != 1) {
			Camera.VERTICES_TMP[Constants.VERTEX_INDEX_X] = pSceneTouchEvent.getX();
			Camera.VERTICES_TMP[Constants.VERTEX_INDEX_Y] = pSceneTouchEvent.getY();

			MathUtils.scaleAroundCenter(Camera.VERTICES_TMP, zoomFactor, zoomFactor, this.getCenterX(), this.getCenterY()); // TODO Use a Transformation object instead!?!

			pSceneTouchEvent.set(Camera.VERTICES_TMP[Constants.VERTEX_INDEX_X], Camera.VERTICES_TMP[Constants.VERTEX_INDEX_Y]);
		}

		super.applySceneToCameraSceneOffset(pSceneTouchEvent);
	}

	@Override
	protected void applySceneToCameraSceneOffset(final float[] pSceneCoordinates) {
		final float zoomFactor = this.mZoomFactor;
		if(zoomFactor != 1) {
			MathUtils.scaleAroundCenter(pSceneCoordinates, zoomFactor, zoomFactor, this.getCenterX(), this.getCenterY()); // TODO Use a Transformation object instead!?!
		}

		super.applySceneToCameraSceneOffset(pSceneCoordinates);
	}

	@Override
	protected void unapplySceneToCameraSceneOffset(final TouchEvent pCameraSceneTouchEvent) {
		super.unapplySceneToCameraSceneOffset(pCameraSceneTouchEvent);

		final float zoomFactor = this.mZoomFactor;
		if(zoomFactor != 1) {
			Camera.VERTICES_TMP[Constants.VERTEX_INDEX_X] = pCameraSceneTouchEvent.getX();
			Camera.VERTICES_TMP[Constants.VERTEX_INDEX_Y] = pCameraSceneTouchEvent.getY();

			MathUtils.revertScaleAroundCenter(Camera.VERTICES_TMP, zoomFactor, zoomFactor, this.getCenterX(), this.getCenterY()); // TODO Use a Transformation object instead!?!

			pCameraSceneTouchEvent.set(Camera.VERTICES_TMP[Constants.VERTEX_INDEX_X], Camera.VERTICES_TMP[Constants.VERTEX_INDEX_Y]);
		}
	}

	@Override
	protected void unapplySceneToCameraSceneOffset(final float[] pCameraSceneCoordinates) {
		super.unapplySceneToCameraSceneOffset(pCameraSceneCoordinates);

		final float zoomFactor = this.mZoomFactor;
		if(zoomFactor != 1) {
			MathUtils.revertScaleAroundCenter(pCameraSceneCoordinates, zoomFactor, zoomFactor, this.getCenterX(), this.getCenterY()); // TODO Use a Transformation object instead!?!
		}
	}

	// ===========================================================
	// Methods
	// ===========================================================

	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================
}