in this new version you can either
- look around (FPS) with mouse and “wasd” keys OR
- let the camera fly around a spot in front of you (denoted by a green sphere)
Toggle with r
Chrisir
// CONSTANT: the floor / field (y value)
final int GENERAL_Y_HEIGHT = 500;
// rotate around itself (player, FPS) OR around a point
boolean modeCamRotatesAroundPoint = false;
// Classes: The camera
CameraClass cam;
// The scene (background, field, boxes...)
Scene scene = new Scene();
// minor tools
Tools tools = new Tools();
// angles
float angleLeftRight;
float angleUpDown=GENERAL_Y_HEIGHT-66; // not a real angle!!!
float modeCamRotatesAroundPointAngle;
PVector spherePosPV=new PVector(0, GENERAL_Y_HEIGHT-500, 0);
float prevAngle;
// -----------------------------------------------------
void setup() {
size (1400, 800, P3D);
// setup camera
cam = new CameraClass (313,
GENERAL_Y_HEIGHT - 66,
113);
// avoid clipping : https : // forum.processing.org/two/discussion/4128/quick-q-how-close-is-too-close-why-when-do-3d-objects-disappear
perspective(PI/3.0, (float) width/height, 1, 1000000);
} // func
void draw() {
// set Canvas and Environment
scene.setCanvasAndEnvironment();
if (modeCamRotatesAroundPoint) {
// show Cam Rotates Around Point
showModeCamRotatesAroundPoint();
} else {
// first person shooter perspective (FPS)
showFPS();
}//else
// display the scene with the boxes and HUD text
scene.displayScene();
//
} // func draw
// ---------------------------------------------------
void showModeCamRotatesAroundPoint() {
// rotate around a point
cam.setPosAngle(modeCamRotatesAroundPointAngle);
cam.set(); // apply the values of the class cam to the real camera
tools.mySphere(spherePosPV.x, spherePosPV.y, spherePosPV.z,
7);
if (spherePosPV.y >= GENERAL_Y_HEIGHT) {
spherePosPV.y=GENERAL_Y_HEIGHT;
modeCamRotatesAroundPointAngle+=.032;
} else {
// sphere falls
spherePosPV.y+=10;
}//
}
void showFPS() {
// rotate around itself (player, FPS)
angleLeftRight=map(mouseX, 0, width, 0, 3*PI);
// angleUpDown=map(mouseY, 0, height, GENERAL_Y_HEIGHT-150, GENERAL_Y_HEIGHT+150);// not a real angle!!!
if (pmouseY<mouseY-5)
angleUpDown += .21;
else if (pmouseY>mouseY+5)
angleUpDown += -.21;
// camera
cam.setLookAtAngle(angleLeftRight); //
cam.set(); // apply the values of the class cam to the real camera
// sphere disappears
if (spherePosPV.y < GENERAL_Y_HEIGHT-310) {
// do nothing
} else {
// sphere
spherePosPV.y-=10;
tools.mySphere(spherePosPV.x, spherePosPV.y, spherePosPV.z,
7);
}//else
cam.keyPressedThroughout();
}//func
// ---------------------------------------------------
void keyPressed() {
//
if (key=='r') {
// Toggle: FPS OR cam rotates AROUND a point
modeCamRotatesAroundPoint =
! modeCamRotatesAroundPoint; // toggle
// modeCamRotatesAroundPoint has a new value now,
// it's a new mode so we can set some start conditions for the new mode.
if (modeCamRotatesAroundPoint) {
// starting mode: modeCamRotatesAroundPoint
prevAngle=angleLeftRight;
modeCamRotatesAroundPointAngle=angleLeftRight-PI;
// define camera
float x1 = cam.camPos.x + cos(angleLeftRight) *300;
float y1 = angleUpDown; // GENERAL_Y_HEIGHT;
float z1 = cam.camPos.z + sin(angleLeftRight) *300;
cam.setLookAt(x1, y1, z1);
// define sphere
spherePosPV=cam.camLookAt.copy();
spherePosPV.y=GENERAL_Y_HEIGHT-310;
} else {
// starting mode PVS
angleLeftRight=modeCamRotatesAroundPointAngle;
float x1 = cam.camLookAt.x - cos(prevAngle) *300;
float y1 = angleUpDown; // GENERAL_Y_HEIGHT;
float z1 = cam.camLookAt.z - sin(prevAngle) *300;
cam.camPos.set(x1, y1, z1); // =cam.camLookAt.copy();
}
//
} else if (key==ESC) {
modeCamRotatesAroundPoint = false;
key=0; // kill ESC
}// else if
}//func
// =================================================================
// classes
class Scene {
// cubes
float angleLeftRightCubes=45; // angleLeftRight for the cubes in the scene
void setCanvasAndEnvironment() {
// set Canvas and Environment
// clear canvas
background(111);
// apply lights
lights();
}
void displayScene() {
// Drawing of the scene / decoration
// Drawing of the red field ----
fill(255, 2, 2);//RED
noStroke();
tools.mySphere(500, GENERAL_Y_HEIGHT, 500, 20);
tools.mySphere(100, GENERAL_Y_HEIGHT, 100, 20);
tools.mySphere(100, GENERAL_Y_HEIGHT, 500, 20);
tools.mySphere(500, GENERAL_Y_HEIGHT, 100, 20);
// rect of lines / floor / field
stroke(255, 2, 2);//RED
// using 3D lines:
line(500, GENERAL_Y_HEIGHT, 500, 500, GENERAL_Y_HEIGHT, 100); // up |
line(500, GENERAL_Y_HEIGHT, 100, 100, GENERAL_Y_HEIGHT, 100); // left <-
line(100, GENERAL_Y_HEIGHT, 100, 100, GENERAL_Y_HEIGHT, 500 ); // down |
line(100, GENERAL_Y_HEIGHT, 500, 500, GENERAL_Y_HEIGHT, 500 ); // right ->
// one small wall of boxes
stroke(0);
int z = -60;
for (int x = 10; x < 600; x+= 100) {
fill(map(x, 10, 600, 111, 255), 2, 2);
for (int y = 410; y < 600; y+= 100) {
tools.myBox(x, y, z, 24, angleLeftRightCubes);
}
}
// a few additional blue boxes
fill(0, 0, 255);
z=-400;
tools.myBox(220, 10, z, 24, angleLeftRightCubes);
tools.myBox(600, 10, z, 24, angleLeftRightCubes);
z=-400;
tools.myBox(220, 510, z, 24, angleLeftRightCubes);
tools.myBox(600, 510, z, 24, angleLeftRightCubes);
z=399;
tools.myBox(220, 510, z, 24, angleLeftRightCubes);
tools.myBox(600, 510, z, 24, angleLeftRightCubes);
z=900;
tools.myBox(220, 510, z, 24, angleLeftRightCubes);
tools.myBox(600, 510, z, 24, angleLeftRightCubes);
angleLeftRightCubes++;
//
// text upper left corner (HUD)
fill(0, 255, 0);
cam.HUD_text("Use Mouse. Click r to toggle mode. " ); //
}
//
} // class
// =================================================================
class CameraClass {
// capsules the normal camera() command and its vectors
PVector camPos; // its vectors
PVector camLookAt;
PVector camUp;
PVector camPosInitial; // its vectors - the default (unchanged)
PVector camLookAtInitial;
PVector camUpInitial;
// float angleLeftRightForCamerasUpAndDownMovement=0; // angleLeftRight for the slight up and down movement of the camera
// constructor I - without parameters
CameraClass() {
// constr
// set vectors
camPos = new PVector(width/2.0, height/2.0, 990);
camLookAt = new PVector(width/2.0, height/2.0, -600);
camUp = new PVector( 0, 1, 0 );
// save the initial values
camPosInitial = camPos.copy();
camLookAtInitial = camLookAt.copy();
camUpInitial = camUp.copy();
} // constr I
// constructor II - with parameters for POS
CameraClass (float x1, float y1, float z1) {
// constr
// set vectors
camPos = new PVector(x1, y1, z1);
camLookAt = new PVector(width/2.0, height/2.0, -600);
camUp = new PVector( 0, 1, 0 );
// save the initial values
camPosInitial = camPos.copy();
camLookAtInitial = camLookAt.copy();
camUpInitial = camUp.copy();
camPos = new PVector(x1, y1, z1);
} // constr II
// ----------------------------------------
void set() {
// apply internal class vectors to actual camera
camera (camPos.x, camPos.y, camPos.z,
camLookAt.x, camLookAt.y, camLookAt.z,
camUp.x, camUp.y, camUp.z);
}
// ----------------------------------------
void setPos (float x1, float y1, float z1) {
camPos.set(x1, y1, z1);
}
void setLookAt (float x1, float y1, float z1) {
camLookAt.set(x1, y1, z1);
}
// ----------------------------------------
void setPosAngle (float angle_) {
// look to point while rotating around it
//
float x1 = camLookAt.x + cos(angle_) *300;
float y1 = angleUpDown; // GENERAL_Y_HEIGHT;
float z1 = camLookAt.z + sin(angle_) *300;
camPos.set(x1, y1, z1);
}
void setLookAtAngle (float angleLeftRight) {
// FPS
// from angleLeftRight
float x1 = camPos.x + cos(angleLeftRight) *10;
float y1 = angleUpDown; // GENERAL_Y_HEIGHT;
float z1 = camPos.z + sin(angleLeftRight) *10;
camLookAt.set(x1, y1, z1);
}
// ----------------------------------------
void keyPressedThroughout() {
if (!keyPressed)
return;
switch(key) {
case 'w':
// run forward / running towards lookat
float x1 = camPos.x + cos(angleLeftRight) *1;
float z1 = camPos.z + sin(angleLeftRight) *1;
camPos.set(x1, camPos.y, z1);
break;
case 's':
// run backward
x1 = camPos.x - cos(angleLeftRight) *1;
z1 = camPos.z - sin(angleLeftRight) *1;
camPos.set(x1, camPos.y, z1);
break;
case 'a':
// left / sideways
x1 = camPos.x + cos(angleLeftRight-HALF_PI) * 1;
z1 = camPos.z + sin(angleLeftRight-HALF_PI) * 1;
camPos.set(x1, camPos.y, z1);
break;
case 'd':
// right
x1 = camPos.x - cos(angleLeftRight-HALF_PI) * 1;
z1 = camPos.z - sin(angleLeftRight-HALF_PI) * 1;
camPos.set(x1, camPos.y, z1);
break;
}//switch
}// method
void HUD_text (String text_) {
// HUD text upper left corner - this must be called at the very end of draw()
// this is a 2D HUD
camera();
hint(DISABLE_DEPTH_TEST);
noLights();
// ------------------
textSize(16);
text (text_, 20, 20);
// ------------------
// reset all parameters to defaults
textAlign(LEFT, BASELINE);
rectMode(CORNER);
textSize(32);
hint(ENABLE_DEPTH_TEST); // no HUD anymore
lights();
} // method
//
} // class
// ======================================
class Tools {
// tools
void myBox(float x, float y, float z,
float size1,
float angleLeftRightCube) {
// one nice wrapper for build in box-command
pushMatrix();
translate(x, y, z);
rotateY(radians(angleLeftRightCube));
rotateX(radians(45));
box(size1);
popMatrix();
}
void mySphere(float x, float y, float z,
float size1) {
// one nice wrapper for build in sphere-command
pushMatrix();
noStroke();
translate(x, y, z);
sphere(size1);
popMatrix();
}
}//class
//