/src/org/mt4j/util/camera/MTCamera.java
http://mt4j.googlecode.com/ · Java · 596 lines · 227 code · 80 blank · 289 comment · 5 complexity · de0719c1d01564d731c207a19e27c40f MD5 · raw file
- /***********************************************************************
- * mt4j Copyright (c) 2008 - 2009 C.Ruff, Fraunhofer-Gesellschaft All rights reserved.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- ***********************************************************************/
- package org.mt4j.util.camera;
-
-
- import org.mt4j.util.math.Matrix;
- import org.mt4j.util.math.Vector3D;
-
- import processing.core.PApplet;
- import processing.core.PGraphics3D;
- import processing.core.PMatrix3D;
-
- /**
- * The Class MTCamera.
- * @author Christopher Ruff
- */
- public class MTCamera implements Icamera{
-
- /** The pa. */
- private PApplet pa;
-
- /** The view center pos. */
- private Vector3D viewCenterPos;
-
- /** The cam pos. */
- private Vector3D camPos;
-
- /** The x axis up. */
- private float xAxisUp;
-
- /** The y axis up. */
- private float yAxisUp;
-
- /** The z axis up. */
- private float zAxisUp;
-
- /** The zoom min distance. */
- private float zoomMinDistance;
-
- private Frustum frustum;
-
- private boolean dirty;
-
- private PMatrix3D cameraMat;
- private PMatrix3D cameraInvMat;
-
- private Matrix cameraMatrix;
- private Matrix cameraInvMatrix;
-
- private PGraphics3D p3d;
-
- /**
- * Instantiates a new mT camera.
- *
- * @param processingApplet the processing applet
- */
- public MTCamera(PApplet processingApplet){
- this(processingApplet.width/2.0f, processingApplet.height/2.0f, processingApplet.height/2.0f / PApplet.tan(PApplet.PI*60.0f / 360.0f),
- processingApplet.width/2.0f, processingApplet.height/2.0f, 0, 0, 1,0, processingApplet);
- }
-
-
- /**
- * Instantiates a new mT camera.
- *
- * @param cameraPosX the camera pos x
- * @param cameraPosY the camera pos y
- * @param cameraPosZ the camera pos z
- * @param camEyePosX the cam eye pos x
- * @param camEyePosY the cam eye pos y
- * @param camEyePosZ the cam eye pos z
- * @param xAxisUp the x axis up
- * @param yAxisUp the y axis up
- * @param zAxisUp the z axis up
- * @param processingApplet the processing applet
- */
- public MTCamera(float cameraPosX, float cameraPosY, float cameraPosZ,
- float camEyePosX, float camEyePosY, float camEyePosZ,
- float xAxisUp, float yAxisUp, float zAxisUp,
- PApplet processingApplet){
-
- this.pa = processingApplet;
- this.camPos = new Vector3D(cameraPosX, cameraPosY, cameraPosZ);
- this.viewCenterPos = new Vector3D(camEyePosX, camEyePosY, camEyePosZ);
- this.xAxisUp = xAxisUp;
- this.yAxisUp = yAxisUp;
- this.zAxisUp = zAxisUp;
-
- this.zoomMinDistance = 0;
-
- this.frustum = new Frustum(pa);
- this.frustum.setCamDef(this.getPosition(), this.getViewCenterPos(), xAxisUp, -yAxisUp, zAxisUp); //new Vector3D(xAxisUp, -yAxisUp, zAxisUp));
-
- this.p3d = ((PGraphics3D)pa.g);
- this.dirty = true;
- this.cameraMat = new PMatrix3D();
- this.cameraInvMat = new PMatrix3D();
- this.cameraMatrix = new Matrix();
- this.cameraInvMatrix = new Matrix();
- }
-
- /**
- * Sets or updates the camera with the values specified in the camera.
- * <br> <b>Call this after changing any camera values to take effect!</b>.
- * <br><strong>Note:</strong> The current modelview matrices (=all transformations made up to this point) will be reset and replaced by the camera values!
- */
- public void update(){
- /*
- pa.camera(camPos.getX(), camPos.getY() , camPos.getZ(), //eyeposition
- viewCenterPos.getX(), viewCenterPos.getY(), viewCenterPos.getZ(), //view center
- xAxisUp, yAxisUp, zAxisUp); //which axis points up?
- this.frustum.setCamDef(this.getPosition(), this.getViewCenterPos(), xAxisUp, -yAxisUp, zAxisUp); //new Vector3D(xAxisUp, -yAxisUp, zAxisUp));
- */
-
- // /*
- if (this.dirty){
- // System.out.println("Calc new camera");
- this.calcCameraMatrix(camPos.getX(), camPos.getY() , camPos.getZ(), //eyeposition
- viewCenterPos.getX(), viewCenterPos.getY(), viewCenterPos.getZ(), //view center
- xAxisUp, yAxisUp, zAxisUp);//which axis points up?
- this.setCachedCamMatrices();
- this.frustum.setCamDef(this.getPosition(), this.getViewCenterPos(), xAxisUp, -yAxisUp, zAxisUp); //new Vector3D(xAxisUp, -yAxisUp, zAxisUp));
- }else{
- // System.out.println("Use Cached");
- this.setCachedCamMatrices();
- }
- // */
- }
-
-
- private void setCachedCamMatrices(){
- Matrix m = this.cameraMatrix;
- Matrix mi = this.cameraInvMatrix;
-
- cameraMat.set(
- m.m00, m.m01, m.m02, m.m03,
- m.m10, m.m11, m.m12, m.m13,
- m.m20, m.m21, m.m22, m.m23,
- m.m30, m.m31, m.m32, m.m33);
-
- cameraInvMat.set(
- mi.m00, mi.m01, mi.m02, mi.m03,
- mi.m10, mi.m11, mi.m12, mi.m13,
- mi.m20, mi.m21, mi.m22, mi.m23,
- mi.m30, mi.m31, mi.m32, mi.m33);
-
- //cant also set cameraInv..not visible
- p3d.camera.set(
- m.m00, m.m01, m.m02, m.m03,
- m.m10, m.m11, m.m12, m.m13,
- m.m20, m.m21, m.m22, m.m23,
- m.m30, m.m31, m.m32, m.m33);
-
- //FIXME cannot set p5 cameraInv because its not visible..problem?
-
- p3d.modelview.set(cameraMat);
- p3d.modelviewInv.set(cameraInvMat);
- }
-
-
- private void calcCameraMatrix(float eyeX, float eyeY, float eyeZ,
- float centerX, float centerY, float centerZ,
- float upX, float upY, float upZ
- ) {
- /*
- float z0 = eyeX - centerX;
- float z1 = eyeY - centerY;
- float z2 = eyeZ - centerZ;
- float mag = FastMath.sqrt(z0*z0 + z1*z1 + z2*z2);
-
- if (mag != 0) {
- z0 /= mag;
- z1 /= mag;
- z2 /= mag;
- }
-
- float y0 = upX;
- float y1 = upY;
- float y2 = upZ;
-
- float x0 = y1*z2 - y2*z1;
- float x1 = -y0*z2 + y2*z0;
- float x2 = y0*z1 - y1*z0;
-
- y0 = z1*x2 - z2*x1;
- y1 = -z0*x2 + z2*x0;
- y2 = z0*x1 - z1*x0;
-
- mag = FastMath.sqrt(x0*x0 + x1*x1 + x2*x2);
- if (mag != 0) {
- x0 /= mag;
- x1 /= mag;
- x2 /= mag;
- }
-
- mag = FastMath.sqrt(y0*y0 + y1*y1 + y2*y2);
- if (mag != 0) {
- y0 /= mag;
- y1 /= mag;
- y2 /= mag;
- }
-
- try {
- //just does an apply to the main matrix,
- //since that'll be copied out on endCamera
- // cameraMat.set(
- // x0, x1, x2, 0,
- // y0, y1, y2, 0,
- // z0, z1, z2, 0,
- // 0, 0, 0, 1);
- // cameraMat.translate(-eyeX, -eyeY, -eyeZ);
- // this.cameraMatrix.set(new float[]{
- // x0, x1, x2, -eyeX,
- // y0, y1, y2, -eyeY,
- // z0, z1, z2, -eyeZ,
- // 0, 0, 0, 1
- // });
-
- this.cameraMatrix.set(new float[]{
- x0, x1, x2, 0,
- y0, y1, y2, 0,
- z0, z1, z2, 0,
- 0, 0, 0, 1
- });
- this.cameraMatrix.mult(Matrix.getTranslationMatrix(-eyeX, -eyeY, -eyeZ), this.cameraMatrix);
- System.out.println("My cammatrix: " + this.cameraMatrix);
-
- // cameraInvMat.reset();
- // cameraInvMat.invApply(
- // x0, x1, x2, 0,
- // y0, y1, y2, 0,
- // z0, z1, z2, 0,
- // 0, 0, 0, 1);
- // cameraInvMat.translate(eyeX, eyeX, eyeZ);
- this.cameraInvMatrix = this.cameraMatrix.invert(this.cameraInvMatrix);
-
- // this.cameraInvMatrix.set(new float[]{
- // x0, x1, x2, eyeX,
- // y0, y1, y2, eyeX,
- // z0, z1, z2, eyeZ,
- // 0, 0, 0, 1
- // });
-
- this.dirty = false;
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- */
-
- // /*
- try {
- pa.camera(camPos.getX(), camPos.getY() , camPos.getZ(), //eyeposition
- viewCenterPos.getX(), viewCenterPos.getY(), viewCenterPos.getZ(), //view center
- xAxisUp, yAxisUp, zAxisUp); //which axis points up?
-
-
- this.cameraMatrix.set(new float[]{
- p3d.modelview.m00, p3d.modelview.m01, p3d.modelview.m02, p3d.modelview.m03,
- p3d.modelview.m10, p3d.modelview.m11, p3d.modelview.m12, p3d.modelview.m13,
- p3d.modelview.m20, p3d.modelview.m21, p3d.modelview.m22, p3d.modelview.m23,
- p3d.modelview.m30, p3d.modelview.m31, p3d.modelview.m32, p3d.modelview.m33
- });
-
- // System.out.println("p5 camMatrix: " + this.cameraMatrix);
-
- this.cameraInvMatrix.set(new float[]{
- p3d.modelviewInv.m00, p3d.modelviewInv.m01, p3d.modelviewInv.m02, p3d.modelviewInv.m03,
- p3d.modelviewInv.m10, p3d.modelviewInv.m11, p3d.modelviewInv.m12, p3d.modelviewInv.m13,
- p3d.modelviewInv.m20, p3d.modelviewInv.m21, p3d.modelviewInv.m22, p3d.modelviewInv.m23,
- p3d.modelviewInv.m30, p3d.modelviewInv.m31, p3d.modelviewInv.m32, p3d.modelviewInv.m33
- });
-
-
- this.dirty = false;
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- // */
- }
-
- /**
- * Gets the camera matrix.
- *
- * @return the camera matrix
- */
- public Matrix getCameraMatrix(){
- if (this.dirty){
- this.calcCameraMatrix(camPos.getX(), camPos.getY() , camPos.getZ(), //eyeposition
- viewCenterPos.getX(), viewCenterPos.getY(), viewCenterPos.getZ(), //view center
- xAxisUp, yAxisUp, zAxisUp);//which axis points up?
- this.setCachedCamMatrices();
- this.frustum.setCamDef(this.getPosition(), this.getViewCenterPos(), xAxisUp, -yAxisUp, zAxisUp); //new Vector3D(xAxisUp, -yAxisUp, zAxisUp));
- }else{
- this.setCachedCamMatrices();
- }
- return this.cameraMatrix;
- }
-
- /**
- * Gets the camera inv matrix.
- *
- * @return the camera inv matrix
- */
- public Matrix getCameraInvMatrix(){
- if (this.dirty){
- this.calcCameraMatrix(camPos.getX(), camPos.getY() , camPos.getZ(), //eyeposition
- viewCenterPos.getX(), viewCenterPos.getY(), viewCenterPos.getZ(), //view center
- xAxisUp, yAxisUp, zAxisUp);//which axis points up?
- this.setCachedCamMatrices();
- this.frustum.setCamDef(this.getPosition(), this.getViewCenterPos(), xAxisUp, -yAxisUp, zAxisUp); //new Vector3D(xAxisUp, -yAxisUp, zAxisUp));
- }else{
- this.setCachedCamMatrices();
- }
- return this.cameraInvMatrix;
- }
-
-
- /**
- * Zooms from the camera to the eye location by the given factor.
- *
- * @param factor the factor
- */
- public void zoomFactor(float factor){
- factor = 1/factor;
- Vector3D dirToCamVect = camPos.getSubtracted(viewCenterPos);
- dirToCamVect.scaleLocal(factor);
- if (dirToCamVect.length() > zoomMinDistance){
- Vector3D toCam = viewCenterPos.getAdded(dirToCamVect);
- camPos.setXYZ(toCam.getX(), toCam.getY(), toCam.getZ());
-
- this.dirty = true;
- }
- }
-
- /**
- * changes the distance from the eye to the camera location by the given amount
- * negative values will increase the distance, positive values will decrease it.
- *
- * @param amount the amount
- */
- public void zoomAmount(float amount){
- amount*=-1;
- //Get direction vector from eye to camera
- Vector3D dirToCamVect = camPos.getSubtracted(viewCenterPos);
- //get the length of that vector
- float mag = dirToCamVect.length();
- //normalize the vector
- dirToCamVect.normalizeLocal();
- //scale the normalized vector with the original amount + the zoom amount
- dirToCamVect.scaleLocal(mag + amount);
-
- if (dirToCamVect.length() > zoomMinDistance){
- //Get the Vector to the camera from origin
- Vector3D toCam = viewCenterPos.getAdded(dirToCamVect);
- //set the new camPos
- camPos.setXYZ(toCam.getX(), toCam.getY(), toCam.getZ());
-
- this.dirty = true;
- }
- }
-
- /**
- * prevent zooming the cam to the center too close
- * set the minimal distance between the cam and the center.
- *
- * @param minDistance the min distance
- */
- public void setZoomMinDistance(float minDistance){
- this.zoomMinDistance = minDistance;
- }
-
- /**
- * Gets the zoom min distance.
- *
- * @return the zoom min distance
- */
- public float getZoomMinDistance() {
- return zoomMinDistance;
- }
-
- // /**
- // * sets the position of the camera.
- // *
- // * @param x the x
- // * @param y the y
- // * @param z the z
- // */
- // public void setCamPosition(float x, float y, float z){
- // camPos.setXYZ(x, y, z);
- // this.dirty = true;
- // }
-
- /**
- * Move cam.
- *
- * @param directionX the direction x
- * @param directionY the direction y
- * @param directionZ the direction z
- */
- public void moveCam(float directionX, float directionY, float directionZ){
- camPos.setXYZ(camPos.getX() + directionX, camPos.getY() + directionY, camPos.getZ() + directionZ);
- this.dirty = true;
- }
-
- /**
- * sets the position of the center view point.
- *
- * @param x the x
- * @param y the y
- * @param z the z
- */
- public void setViewCenterPosition(float x, float y, float z){
- viewCenterPos.setXYZ(x, y, z);
- this.dirty = true;
- }
-
- /**
- * moves the view center location by the given values in the given directions.
- *
- * @param directionX the direction x
- * @param directionY the direction y
- * @param directionZ the direction z
- */
- public void moveViewCenter(float directionX, float directionY, float directionZ){
- viewCenterPos.setXYZ(viewCenterPos.getX() + directionX, viewCenterPos.getY() + directionY, viewCenterPos.getZ() + directionZ);
- this.dirty = true;
- }
-
-
- /**
- * moves both the view center and the camera location by the given values in the given directions.
- *
- * @param directionX the direction x
- * @param directionY the direction y
- * @param directionZ the direction z
- */
- public void moveCamAndViewCenter(float directionX, float directionY, float directionZ){
- moveCam(directionX, directionY, directionZ);
- moveViewCenter(directionX, directionY, directionZ);
- this.dirty = true;
- }
-
- /**
- * Gets the cam view center distance.
- *
- * @return the cam view center distance
- */
- public float getCamViewCenterDistance(){
- return Vector3D.distance(getPosition(), getViewCenterPos());
- }
-
- /**
- * Reset to default.
- */
- public void resetToDefault(){
- this.camPos = new Vector3D((float)(pa.width/2.0), (float)(pa.height/2.0), (float)(pa.height/2.0) / PApplet.tan((float)(PApplet.PI*60.0 / 360.0)));
- this.viewCenterPos = new Vector3D((float)(pa.width/2.0), (float)(pa.height/2.0), 0) ;
- this.xAxisUp = 0;
- this.yAxisUp = 1;
- this.zAxisUp = 0;
-
- this.dirty = true;
- }
-
- /* (non-Javadoc)
- * @see util.camera.Icamera#getPosition()
- */
- public Vector3D getPosition() {
- return new Vector3D(camPos);
- }
-
- /* (non-Javadoc)
- * @see util.camera.Icamera#setPosition(util.math.Vector3D)
- */
- public void setPosition(Vector3D camPos) {
- this.camPos = camPos;
- this.dirty = true;
- }
-
- /* (non-Javadoc)
- * @see util.camera.Icamera#getViewCenterPos()
- */
- public Vector3D getViewCenterPos() {
- return viewCenterPos;
- }
-
- /* (non-Javadoc)
- * @see util.camera.Icamera#setViewCenterPos(util.math.Vector3D)
- */
- public void setViewCenterPos(Vector3D eyePos) {
- this.viewCenterPos = eyePos;
- this.dirty = true;
- }
-
- /**
- * Gets the x axis up.
- *
- * @return the x axis up
- */
- public float getXAxisUp() {
- return xAxisUp;
- }
-
- /**
- * Sets the x axis up.
- *
- * @param axisUp the new x axis up
- */
- public void setXAxisUp(float axisUp) {
- xAxisUp = axisUp;
- this.dirty = true;
- }
-
- /**
- * Gets the y axis up.
- *
- * @return the y axis up
- */
- public float getYAxisUp() {
- return yAxisUp;
- }
-
- /**
- * Sets the y axis up.
- *
- * @param axisUp the new y axis up
- */
- public void setYAxisUp(float axisUp) {
- yAxisUp = axisUp;
- this.dirty = true;
- }
-
- /**
- * Gets the z axis up.
- *
- * @return the z axis up
- */
- public float getZAxisUp() {
- return zAxisUp;
- }
-
- /**
- * Sets the z axis up.
- *
- * @param axisUp the new z axis up
- */
- public void setZAxisUp(float axisUp) {
- zAxisUp = axisUp;
- this.dirty = true;
- }
-
-
- public Frustum getFrustum() {
- return frustum;
- }
-
-
- public int isSphereInFrustum(Vector3D p, float radius){
- return this.getFrustum().isSphereInFrustum(p, radius);
- }
-
- public int isPointInFrustum(Vector3D p) {
- return this.getFrustum().isPointInFrustum(p);
- }
-
-
- // public boolean contains(IBoundingShape bounds){
- // if (bounds != null){
- //
- //
- // }else{
- // return true;
- // }
- // }
-
- //TODO setFrustum(float near, float far, float left, float right, float top, float bottom);
- //TODO setFrustumPerspective(float fovY, float aspect, float near, float far);
-
- }