3D camera view: TOP VIEW

Hello everybody,

Someone knows how to set the camera in processing in order to have the TOP view? and move It in x or y to find the object ?

Thanks!

2 Likes

The idea of 3D space

The idea of 3D space (with size(1600, 900, P3D);) is that you draw not on a canvas but inside a box / room where you can place stuff further away (away from you, into the screen depth) or nearer to you.

Imagine the room as the space on a table where you place your scene:

The idea is that

  • the first parameter is x (you move something left and right on the table surface e.g.),
  • the 2nd parameter (y) is the height (you move something up and down above the table) and
  • the 3rd parameter (z) is that you move something back and forth on the table surface (depth).

The camera

The camera has 9 parameters: 3 for position, 3 for lookAt, 3 for UP vector.

For Top Down view:
top down camera is

  • pos x = lookAt x,
  • pos y = 300 above lookAt y,
  • pos z = lookAt z,
  • and you have to change the UP vector, as I did below.

Chrisir

// house
float inc = 0;
int depth= 125;

void setup() {
  size(1600, 900, P3D);
  noStroke();
}

void draw() {
  //
  background(0);
  lights();

  if (!keyPressed) {
    // top down !!!!!!!!!!!!!!!!!!!!!!!!
    camera(width/2, height/2-300, 0, 
      width/2, height/2, 0, 
      0, 0, 1);
  } else {
    camera(width/2.0, height/2.0, (height/2.0) / tan(PI*30.0 / 180.0), 
      width/2.0, height/2.0, 0, 
      0, 1, 0);
  }

  translate(width/2, height/2);
  rotateY(inc);

  arrow();
  inc += .01;
}

// ------------------------------------------------------------------

void arrow() {

  // house

  fill(255);

  int[] x = {
    -50, 0, 50, 25
  };

  int[] y = {
    50, 0, 50, 50
    //
  };

  int[] xWalls = {  
    25, 25, -25, -25, -50
  };

  int[] yWalls = {  
    50, 100, 100, 50, 50
    }
    ;

  fill(255, 0, 0);
  beginShape();
  for (int i = 0; i<4; i++)
    vertex(x[i], y[i]);
  endShape(CLOSE);


  fill(255, 0, 0);
  beginShape();
  for (int i = 0; i<4; i++)
    vertex(x[i], y[i], depth+10);
  endShape(CLOSE);

  fill(0, 255, 255);
  fill(255, 0, 0);
  beginShape(QUAD_STRIP);
  for (int i = 0; i<4; i++) {
    vertex(x[i], y[i]);
    vertex(x[i], y[i], depth+10);
  }
  int i2 = 0;
  vertex(x[i2], y[i2]);
  vertex(x[i2], y[i2], depth);
  endShape(CLOSE);


  fill(0, 255, 255);
  beginShape(QUAD_STRIP);
  for (int i = 0; i<4; i++) {
    vertex(xWalls[i], yWalls[i]);
    vertex(xWalls[i], yWalls[i], depth);
  }
  i2 = 4;
  vertex(xWalls[i2], yWalls[i2]);
  vertex(xWalls[i2], yWalls[i2], depth);
  endShape(CLOSE);

  // ---------------------------------------
  fill(255, 0, 0);
  fill(0, 255, 255);
  beginShape();
  for (int i = 0; i<4; i++)
    vertex(xWalls[i], yWalls[i]);
  endShape(CLOSE);


  fill(255, 0, 0);
  fill(0, 255, 255);
  beginShape();
  for (int i = 0; i<4; i++)
    vertex(xWalls[i], yWalls[i], depth);
  endShape(CLOSE);
}
//
2 Likes

in this new version, use mouse to move the camera (not the objects) in x and z direction

(As discussed above, in top view when you search something, search in in x and z direction,
so mouseX and mouseY is used as x and y position of the camera)

  • The camera always looks straight down so you see objects that are far away from the side
  • Alternatively you could look at 0,0,0 or at your object always, then the camera would tilt towards the center or your object while moving

Chrisir

// house
float inc = 0;
int depth= 125;

PVector mousePV = new PVector(); 

void setup() {
  size(1600, 900, P3D);
  noStroke();
}

void draw() {
  //
  background(0);
  lights();

  if (!keyPressed) {
    // top down !!!!!!!!!!!!!!!!!!!!!!!!

    //mousePV.set(mouseX, mouseY);
    mousePV.set (
      map(mouseX, 0, width, -50, width+50), 
      map(mouseY, 0, height, -300, 300)
      );

    camera(mousePV.x, height/2-300, mousePV.y, 
      mousePV.x, height/2, mousePV.y, 
      0, 0, 1);
  } else {
    camera(width/2.0, height/2.0, (height/2.0) / tan(PI*30.0 / 180.0), 
      width/2.0, height/2.0, 0, 
      0, 1, 0);
  }

  translate(width/2, height/2);
  rotateY(inc);

  arrow();
  inc += .01;

  camera(); 
  fill(255); 
  text("camera is at "
    +int(mousePV.x)
    +", "
    +int(mousePV.y), 
    14, 17);
}

// ------------------------------------------------------------------

void arrow() {

  // house

  fill(255);

  int[] x = {
    -50, 0, 50, 25
  };

  int[] y = {
    50, 0, 50, 50
    //
  };

  int[] xWalls = {  
    25, 25, -25, -25, -50
  };

  int[] yWalls = {  
    50, 100, 100, 50, 50
    }
    ;

  fill(255, 0, 0);
  beginShape();
  for (int i = 0; i<4; i++)
    vertex(x[i], y[i]);
  endShape(CLOSE);


  fill(255, 0, 0);
  beginShape();
  for (int i = 0; i<4; i++)
    vertex(x[i], y[i], depth+10);
  endShape(CLOSE);

  fill(0, 255, 255);
  fill(255, 0, 0);
  beginShape(QUAD_STRIP);
  for (int i = 0; i<4; i++) {
    vertex(x[i], y[i]);
    vertex(x[i], y[i], depth+10);
  }
  int i2 = 0;
  vertex(x[i2], y[i2]);
  vertex(x[i2], y[i2], depth);
  endShape(CLOSE);


  fill(0, 255, 255);
  beginShape(QUAD_STRIP);
  for (int i = 0; i<4; i++) {
    vertex(xWalls[i], yWalls[i]);
    vertex(xWalls[i], yWalls[i], depth);
  }
  i2 = 4;
  vertex(xWalls[i2], yWalls[i2]);
  vertex(xWalls[i2], yWalls[i2], depth);
  endShape(CLOSE);

  // ---------------------------------------
  fill(255, 0, 0);
  fill(0, 255, 255);
  beginShape();
  for (int i = 0; i<4; i++)
    vertex(xWalls[i], yWalls[i]);
  endShape(CLOSE);


  fill(255, 0, 0);
  fill(0, 255, 255);
  beginShape();
  for (int i = 0; i<4; i++)
    vertex(xWalls[i], yWalls[i], depth);
  endShape(CLOSE);
}
//
2 Likes

another sketch with 5 different views:

/*

 New version with camera class AND smooth transitions (damping) ============================================================
 
 This sketch is based on the following assumptions:
 * in 3D the scene is on a table. So placing things left and right on the table is x, 
 * placing it more in front or in the back is Z and 
 * placing it above the scene (blue box) is Y.
 
 * The center of the scene is at width/2, height/2, 0
 
 https://discourse.processing.org/t/camera-how-top-down-view/1178/3
 
 wenn man von 2 auf 4 geht oder 1 auf 3, schiesst er durch den Würfel durch.
 besser wäre lerp auf einer Kreisbahn über einen radius 
 
 */

// demonstrates view from top down (above the sceen), 
// and from north, east, south and west. 

// The interesting part: the UP-vector when view from top.  

// default values are 
// camera(width/2.0, height/2.0, (height/2.0) / tan(PI*30.0 / 180.0),
// width/2.0, height/2.0, 0, 
// 0, 1, 0).

CameraMy cam;  

// view mode and its texts : 

int viewMode=3; // This var dictates how current camera mode!!!!!!!

String[] viewText={
  "top view", 
  "from north", 
  "from east", 
  "from south (processing default)", 
  "from west", 
  "rotating"
};

// -------------------------------------------------------

void setup() {
  size(1500, 600, P3D);
  stroke(255, 0, 0);
  cam = new CameraMy();
}

void draw() {
  background(0);
  lights();

  if (!mousePressed) {
    // apply view mode
    cam.apply();
    //
  } else {
    // default (from south)  
    camera();
  }//else 

  // draw scene 
  drawScene();

  // HUD : text
  camera();
  fill(255);
  text("Camera test: Hit 0..5 for top view (0, from top) / north (1) / east (2) / south (=3, processing default) / west view (4) / rotate (5). "
    +"\nClick and hold mouse to see processing default view."
    +"\nCurrent view: "
    +viewText[viewMode], 
    15, 15);
}//func

// ---------------------------------------------------------------------------

void drawScene() {

  // the sculpture

  translate(width/2, height/2, 0);

  fill(255); //white 
  box(100);  // big box 

  translate(100, 0, 0); // right 
  fill(255, 0, 0);  // red 
  box(50);

  translate(-200, 0, 0); // left
  fill(0, 255, 0);  // green 
  box(50);

  translate(100, -100, 0); // center above 
  fill(0, 0, 255);  // blue 
  box(50);

  translate(0, 100, 100); // center above 
  fill(0, 0, 255);  // blue 
  noStroke(); 
  sphere(12);

  translate(0, 0, -200); // center above 
  fill(0, 255, 0);  // green 
  noStroke(); 
  sphere(12);
}

//-----------------------------------------------------------------------------

void keyPressed() {
  // for keys from 0 to 5 
  if (key>='0'&&key<='5') {
    // apply as camera mode 
    viewMode=int(key+"");
    setViewFromViewMode();
  }//if
}

void setViewFromViewMode() {

  // radius = 400 

  cam.rotateFlag=false;

  switch (viewMode) {

  case 0:
    // top down 
    cam.setEye(width/2, height/2-400, 0); 
    cam.setUpVector(0, 0, 1); 
    break; 

  case 1: 
    //from north 
    cam.setEye(width/2, height/2, -400); 
    cam.setUpVectorToStandard();
    break; 

  case 2: 
    //from east 
    cam.setEye(width/2+400, height/2, 0); 
    cam.setUpVectorToStandard();
    break; 

  case 3:
    //from south // default 
    // cam.reset();
    cam.setEye(width/2, height/2, 400); 
    cam.setUpVectorToStandard();
    break; 

  case 4:
    //from west 
    cam.setEye(width/2-400, height/2, 0); 
    cam.setUpVectorToStandard();
    break;

  case 5:
    cam.setUpVectorToStandard();
    cam.rotate();
    break; 

  default:
    // Error 
    println("error 55 in switch");
    exit();
    return;
  }//switch
  //
}//func 

//===========================================================

class CameraMy {

  // to use the camera more easily 

  // standard values
  final PVector eyePV_Standard     = new PVector ( width/2.0, height/2.0, (height/2.0) / tan(PI*30.0 / 180.0)); // eye = camera position 
  final PVector lookAtPV_Standard  = new PVector ( width/2, height/2, 0 );  // look At or center
  final PVector upPV_Standard      = new PVector ( 0, 1, 0);  // the up vector for rotating the camera around itself 

  // the changing values: 
  PVector eyePV, lookAtPV, upPV;

  // old PVectors
  PVector eyePVold, lookAtPVold, upPVold;

  // for lerp
  float amt = 0;

  // for rotation 
  boolean rotateFlag=false; 
  float angle=0;

  // constr 
  CameraMy() {
    eyePV    = eyePV_Standard.copy(); 
    lookAtPV = lookAtPV_Standard.copy();
    upPV     = upPV_Standard.copy();

    eyePVold    = eyePV.copy(); 
    lookAtPVold = lookAtPV.copy();
    upPVold     = upPV.copy();
  }//constr 

  // -----
  // 3 set methods : 

  void setEye( float x, float y, float z) {
    eyePVold=eyePV.copy(); 
    eyePV=new PVector(x, y, z);
    amt=0;
  }
  void setLookAt( float x, float y, float z) {
    lookAtPVold=lookAtPV.copy();
    lookAtPV=new PVector(x, y, z);
    amt=0;
  }
  void setUpVector( float x, float y, float z) {
    upPVold=upPV.copy();
    // set UP vector 
    upPV=new PVector(x, y, z);
    amt=0;
  }

  // ----
  // 3 set methods for standard :

  void setEyeToStandard() {
    eyePVold=eyePV.copy(); 
    eyePV = eyePV_Standard.copy();
    amt=0;
  }
  void setLookAtToStandard() {
    lookAtPVold=lookAtPV.copy();
    lookAtPV = lookAtPV_Standard.copy();
    amt=0;
  }
  void setUpVectorToStandard() {
    upPVold=upPV.copy();
    upPV = upPV_Standard.copy();
    amt=0;
  }

  // ----

  void reset() {
    // reset 
    // store old values 
    eyePVold=eyePV.copy(); 
    lookAtPVold=lookAtPV.copy();
    upPVold=upPV.copy();
    // reset 
    eyePV    = eyePV_Standard.copy(); 
    lookAtPV = lookAtPV_Standard.copy();
    upPV     = upPV_Standard.copy();
    // set amt to 0 for lerp
    amt=0;
  }

  //----

  void rotate() {
    //init rotate
    rotateFlag = true;
    setLookAtToStandard();
  }

  // ----

  void apply() {

    // apply values

    // rotation mode ?
    if (rotateFlag) {
      // rotation mode 
      eyePV = new PVector ( width/2.0 + cos(angle) * 400, 
        height/2.0, 
        sin(angle) * 400  ); // eye = camera position
      angle+=.05;

      camera (eyePV.x, eyePV.y, eyePV.z, 
        lookAtPV.x, lookAtPV.y, lookAtPV.z, 
        upPV.x, upPV.y, upPV.z);

      return; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    }//if rotateFlag

    // normal modes : 

    // we don't use the new values (eyePV,lookAtPV,upPV) directly but with eyePVold etc. and lerp (and its amt) 

    PVector eyePV2, lookAtPV2, upPV2;

    eyePV2    = lerpPV ( eyePVold, eyePV, amt );
    lookAtPV2 = lerpPV ( lookAtPVold, lookAtPV, amt );
    upPV2     = lerpPV ( upPVold, upPV, amt );

    if (amt<1)
      amt+=.025;
    else 
    amt = 1.0; 

    camera (eyePV2.x, eyePV2.y, eyePV2.z, 
      lookAtPV2.x, lookAtPV2.y, lookAtPV2.z, 
      upPV2.x, upPV2.y, upPV2.z);
  } //method

  PVector lerpPV(PVector pvOld, PVector pvNew, float amt) {

    // help function: lerp for a PVector

    // lerp: 
    float x = lerp(pvOld.x, pvNew.x, amt);
    float y = lerp(pvOld.y, pvNew.y, amt);
    float z = lerp(pvOld.z, pvNew.z, amt);

    return new PVector (  x, y, z  );
  }//method
  //
}//class 
//

update version of the previous sketch.

Added a new view “From Below” and a Batch Mode.

/*
 New version with camera class AND smooth transitions (damping).
 Demonstrates view from top down (above the sceen), 
 and from north, east, south and west and bottom and rotation. 
 The interesting part: the UP-vector when view from top.  
 
 This sketch is based on the following assumptions:
 * in 3D the scene is on a table. So placing things left and right on the table is x, 
 * placing it more in front or in the back is Z and 
 * placing it above the scene (blue box) is Y. 
 * The center of the scene is at width/2, height/2, 0
 
 https://discourse.processing.org/t/camera-how-top-down-view/1178/3
 
 Remark:
 going from view 2 to 4 or 1 to 3 etc. it wasn't a nice transition. 
 To avoid this, we have a HashMap hmBatchList which is used to make 
 one inbetween-view between 2 and 4 (and 4 and 2, 1 and 3 etc.), so it looks nicer. 
 
 default values are 
 camera(width/2.0, height/2.0, (height/2.0) / tan(PI*30.0 / 180.0),
 width/2.0, height/2.0, 0, 
 0, 1, 0);
 */

// The core class 
CameraClass cam;  

// view mode and its texts : 

int viewMode=3; // This var dictates the current camera mode!

String[] viewText={
  "top view", 
  "from north", 
  "from east", 
  "from south (processing default)", 
  "from west", 
  "rotating", 
  "From below"
};

// keys to change views 
char oldKey=' ', 
  currentKey=' ';

// A HashMap hmBatchList and Batch variables: 
// Note the HashMap's "key" is a String and "value" is a String
HashMap<String, String> hmBatchList = new HashMap<String, String>();
String resultStringBatch=""; // Batch commands 
boolean inBatchMode=false;
int inBatchCounter=0; 

// -------------------------------------------------------

void setup() {
  size(1500, 600, P3D);
  stroke(255, 0, 0);

  // set cam 
  cam = new CameraClass();

  // set Batch list
  hmBatchList.put("from2to4", "34");
  hmBatchList.put("from4to2", "32");

  hmBatchList.put("from1to3", "23");
  hmBatchList.put("from3to1", "21");

  hmBatchList.put("from0to6", "36");
  hmBatchList.put("from6to0", "30");

  hmBatchList.put("from0to1", "21");
  hmBatchList.put("from1to0", "20");

  hmBatchList.put("from6to1", "21");
  hmBatchList.put("from1to6", "26");
}

void draw() {
  background(0);
  lights();

  if (!mousePressed) {
    // apply view mode
    cam.apply();
    //
  } else {
    // default (from south)  
    camera();
  }//else 

  // draw scene 
  drawScene();

  // HUD : text
  camera();
  fill(255);
  text("Camera test: Hit 0..6 for: top view (0) / north (1) / east (2) / south (=3, processing default) / west view (4) / rotate (5) / from below (6). "
    +"\nClick and hold mouse to see processing default view."
    +"\nCurrent view: "
    +viewText[viewMode], 
    15, 15);
}//func

// -------------------------------------------------------

void drawScene() {

  // the sculpture

  translate(width/2, height/2, 0);

  fill(255); // white 
  box(100);  // big box 

  // --- 

  translate(100, 0, 0); // right 
  fill(255, 0, 0);  // red box
  box(50);

  translate(-200, 0, 0); // left
  fill(0, 255, 0);  // green box
  box(50);

  translate(100, -100, 0); // center above 
  fill(0, 0, 255);  // blue box
  box(50);

  // --- 

  translate(0, 100, 100); // in front  
  fill(0, 0, 255);  // blue sphere
  noStroke(); 
  sphere(12);

  translate(0, 0, -200); // behind the white center box 
  fill(0, 255, 0);  // green sphere
  noStroke(); 
  sphere(12);

  // ---

  translate(0, 100, 100); // behind the white center box 
  fill(255, 0, 0);  // red sphere
  noStroke(); 
  sphere(12);
  //
}

//-----------------------------------------------------------------------------
// Inputs 

void keyPressed() {
  // for keys from 0 to 6 

  oldKey=currentKey;
  currentKey=key; 
  resultStringBatch=null;

  String searchString="from"
    + trim(str(oldKey)) 
    + "to" 
    + trim(str(currentKey));

  resultStringBatch = hmBatchList.get(searchString);

  // Did we get a Batch result?
  if (resultStringBatch==null) {
    // No
    // normal: just use the key 
    if (key>='0'&&key<='6') {
      // apply as camera mode 
      cam.amt=0; 
      viewMode=int(key+"");
      setViewFromViewMode();
      inBatchMode=false;
    }//if
  } else {
    // Yes
    // apply resultStringBatch as camera mode in Batch Mode
    inBatchMode=true;
    inBatchCounter=0; 
    cam.amt=0; 
    viewMode=int(resultStringBatch.charAt(inBatchCounter)+"");
    setViewFromViewMode();
  } // else
} //func 

//-----------------------------------------------------------------------------

void setViewFromViewMode() {

  float radius = 400.0; 

  cam.rotateFlag=false;

  switch (viewMode) {   

  case 0:
    // top down 
    cam.setEye(width/2, height/2-radius, 0);
    cam.setUpVector(0, 0, 1);  // Good: cam.setUpVector(0, 0, 1); 
    break; 

  case 1: 
    //from north 
    cam.setEye(width/2, height/2, -radius); 
    cam.setUpVectorToStandard();
    break; 

  case 2: 
    //from east 
    cam.setEye(width/2+radius, height/2, 0); 
    cam.setUpVectorToStandard();
    break; 

  case 3:
    //from south // default 
    cam.setEye(width/2, height/2, radius); 
    cam.setUpVectorToStandard();
    break; 

  case 4:
    //from west 
    cam.setEye(width/2-radius, height/2, 0); 
    cam.setUpVectorToStandard();
    break;

  case 5:
    // rotate 
    cam.setUpVectorToStandard();
    cam.rotate();
    break; 

  case 6:
    // from below
    cam.setEye(width/2, height/2+radius, 0); 
    cam.setUpVector(0, 0, -1); 
    break; 

  default:
    // Error 
    println("error 55 in switch");
    exit();
    return;
  } // switch
  //
}//func 

//===========================================================

class CameraClass {

  // class to use the camera more easily 

  // standard values
  final PVector eyePV_Standard     = new PVector ( width/2.0, height/2.0, (height/2.0) / tan(PI*30.0 / 180.0)); // eye = camera position 
  final PVector lookAtPV_Standard  = new PVector ( width/2, height/2, 0 );  // look At or center
  final PVector upPV_Standard      = new PVector ( 0, 1, 0);  // the up vector for rotating the camera around itself 

  // the changing values: 
  PVector eyePV, lookAtPV, upPV;

  // old PVectors
  PVector eyePVold, lookAtPVold, upPVold;

  // for lerp
  float amt = 0;

  // for rotation 
  boolean rotateFlag=false; 
  float angle=0;

  // -----
  // constr 
  CameraClass() {
    eyePV    = eyePV_Standard.copy(); 
    lookAtPV = lookAtPV_Standard.copy();
    upPV     = upPV_Standard.copy();

    eyePVold    = eyePV.copy(); 
    lookAtPVold = lookAtPV.copy();
    upPVold     = upPV.copy();
  }//constr 

  // -----
  // 3 set methods : 

  void setEye( float x, float y, float z) {
    eyePVold=eyePV.copy(); 
    eyePV=new PVector(x, y, z);
    amt=0;
  }
  void setLookAt( float x, float y, float z) {
    lookAtPVold=lookAtPV.copy();
    lookAtPV=new PVector(x, y, z);
    amt=0;
  }
  void setUpVector( float x, float y, float z) {
    upPVold=upPV.copy();
    // set UP vector 
    upPV=new PVector(x, y, z);
    amt=0;
  }

  // ----
  // 3 set methods for standard :

  void setEyeToStandard() {
    eyePVold=eyePV.copy(); 
    eyePV = eyePV_Standard.copy();
    amt=0;
  }
  void setLookAtToStandard() {
    lookAtPVold=lookAtPV.copy();
    lookAtPV = lookAtPV_Standard.copy();
    amt=0;
  }
  void setUpVectorToStandard() {
    upPVold=upPV.copy();
    upPV = upPV_Standard.copy();
    amt=0;
  }

  // ----

  void reset() {
    // reset 
    // store old values 
    eyePVold=eyePV.copy(); 
    lookAtPVold=lookAtPV.copy();
    upPVold=upPV.copy();
    // reset 
    eyePV    = eyePV_Standard.copy(); 
    lookAtPV = lookAtPV_Standard.copy();
    upPV     = upPV_Standard.copy();
    // set amt to 0 for lerp
    amt=0;
  }

  void resetPVOld() {
    eyePVold=eyePV.copy(); 
    lookAtPVold=lookAtPV.copy();
    upPVold=upPV.copy();
  }

  //----

  void rotate() {
    //init rotate
    rotateFlag = true;
    setLookAtToStandard();
  }

  // ----
  // Tools: 

  void apply() {

    // apply values

    // rotation mode ?
    if (rotateFlag) {
      // rotation mode 
      eyePV = new PVector ( width/2.0 + cos(angle) * 400, 
        height/2.0, 
        sin(angle) * 400  ); // eye = camera position
      angle+=.05;

      camera (eyePV.x, eyePV.y, eyePV.z, 
        lookAtPV.x, lookAtPV.y, lookAtPV.z, 
        upPV.x, upPV.y, upPV.z);

      return; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    }//if rotateFlag

    // normal modes : ------------------------------

    // we don't use the new values (eyePV,lookAtPV,upPV) directly but 
    // with eyePVold etc. and lerp (and its amt) we calculate eyePV2, lookAtPV2 and upPV2

    PVector eyePV2, lookAtPV2, upPV2;

    eyePV2    = lerpPV ( eyePVold, eyePV, amt );
    lookAtPV2 = lerpPV ( lookAtPVold, lookAtPV, amt );
    upPV2     = lerpPV ( upPVold, upPV, amt );

    if (amt<1) {
      amt += 0.025;
    } else {
      // amt is done 
      amt = 1.0;

      // When we are in Batch Mode we go to next batch command 
      if (inBatchMode) {

        inBatchCounter++; // go to next batch command  
        resetPVOld(); 

        // if we finished the Batch
        if (inBatchCounter >= resultStringBatch.length()) {
          //reset 
          inBatchMode=false; 
          inBatchCounter=0;
          resultStringBatch=null;
        } else { 
          viewMode=int(resultStringBatch.charAt(inBatchCounter)+"");
          setViewFromViewMode();
        }//else 
        amt=0;
      }
    }

    camera (eyePV2.x, eyePV2.y, eyePV2.z, 
      lookAtPV2.x, lookAtPV2.y, lookAtPV2.z, 
      upPV2.x, upPV2.y, upPV2.z);
  } // method

  PVector lerpPV(PVector pvOld, PVector pvNew, 
    float amt) {

    // help function: lerp for a PVector

    // lerp: 
    float x = lerp(pvOld.x, pvNew.x, amt);
    float y = lerp(pvOld.y, pvNew.y, amt);
    float z = lerp(pvOld.z, pvNew.z, amt);

    return new PVector (  x, y, z  );
  }//method
  //
}//class 
//
2 Likes