Package org.mt4j.util.camera

Source Code of org.mt4j.util.camera.MTCamera

/***********************************************************************
* 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, IFrustum{
 
  /** 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((float)(processingApplet.width/2.0f), (float)(processingApplet.height/2.0f), (float)(processingApplet.height/2.0f) / PApplet.tan((float)(PApplet.PI*60.0f / 360.0f)),
        (float)(processingApplet.width/2.0f), (float)(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);
 
}
TOP

Related Classes of org.mt4j.util.camera.MTCamera

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.