1class Camera { 2 // camera's field of view 3 float fov; 4 // camera's position, look at point and axis 5 PVector pos, center, axis; 6 PVector init_pos, init_center, init_axis; 7 float move_speed; 8 float rot_speed; 9 Camera(float fov, PVector pos, PVector center, PVector axis) { 10 this.fov = fov; 11 this.pos = pos; 12 this.center = center; 13 this.axis = axis; 14 this.axis.normalize(); 15 move_speed = 0.001; 16 rot_speed = 0.01 * PI; 17 init_pos = pos.copy(); 18 init_center = center.copy(); 19 init_axis = axis.copy(); 20 } 21 22 Camera copy() { 23 Camera cam = new Camera(fov, pos.copy(), center.copy(), axis.copy()); 24 return cam; 25 } 26 27 PVector project(PVector pos) { 28 PVector proj = MatxVec3(getCameraMat(), PVector.sub(pos, this.pos)); 29 proj.x = (float)height / 2.0 * proj.x / proj.z / tan(fov / 2.0f); 30 proj.y = (float)height / 2.0 * proj.y / proj.z / tan(fov / 2.0f); 31 proj.z = proj.z; 32 return proj; 33 } 34 35 float[] getCameraMat() { 36 float[] mat = new float[9]; 37 PVector dir = PVector.sub(center, pos); 38 dir.normalize(); 39 PVector left = dir.cross(axis); 40 left.normalize(); 41 // processing camera system does not follow right hand rule 42 mat[0] = -left.x; 43 mat[1] = -left.y; 44 mat[2] = -left.z; 45 mat[3] = axis.x; 46 mat[4] = axis.y; 47 mat[5] = axis.z; 48 mat[6] = dir.x; 49 mat[7] = dir.y; 50 mat[8] = dir.z; 51 52 return mat; 53 } 54 55 void run() { 56 PVector dir, left; 57 if (mousePressed) { 58 float angleX = (float)mouseX / width * PI - PI / 2; 59 float angleY = (float)mouseY / height * PI - PI; 60 PVector diff = PVector.sub(center, pos); 61 float radius = diff.mag(); 62 pos.x = radius * sin(angleY) * sin(angleX) + center.x; 63 pos.y = radius * cos(angleY) + center.y; 64 pos.z = radius * sin(angleY) * cos(angleX) + center.z; 65 dir = PVector.sub(center, pos); 66 dir.normalize(); 67 PVector up = new PVector(0, 1, 0); 68 left = up.cross(dir); 69 left.normalize(); 70 axis = dir.cross(left); 71 axis.normalize(); 72 } 73 74 if (keyPressed) { 75 switch (key) { 76 case 'w': 77 dir = PVector.sub(center, pos); 78 dir.normalize(); 79 pos = PVector.add(pos, PVector.mult(dir, move_speed)); 80 center = PVector.add(center, PVector.mult(dir, move_speed)); 81 break; 82 case 's': 83 dir = PVector.sub(center, pos); 84 dir.normalize(); 85 pos = PVector.sub(pos, PVector.mult(dir, move_speed)); 86 center = PVector.sub(center, PVector.mult(dir, move_speed)); 87 break; 88 case 'a': 89 dir = PVector.sub(center, pos); 90 dir.normalize(); 91 left = axis.cross(dir); 92 left.normalize(); 93 pos = PVector.add(pos, PVector.mult(left, move_speed)); 94 center = PVector.add(center, PVector.mult(left, move_speed)); 95 break; 96 case 'd': 97 dir = PVector.sub(center, pos); 98 dir.normalize(); 99 left = axis.cross(dir); 100 left.normalize(); 101 pos = PVector.sub(pos, PVector.mult(left, move_speed)); 102 center = PVector.sub(center, PVector.mult(left, move_speed)); 103 break; 104 case 'r': 105 dir = PVector.sub(center, pos); 106 dir.normalize(); 107 float[] mat = getRotationMat3x3(rot_speed, dir.x, dir.y, dir.z); 108 axis = MatxVec3(mat, axis); 109 axis.normalize(); 110 break; 111 case 'b': 112 pos = init_pos.copy(); 113 center = init_center.copy(); 114 axis = init_axis.copy(); 115 break; 116 case '+': move_speed *= 2.0f; break; 117 case '-': move_speed /= 2.0; break; 118 case CODED: 119 if (keyCode == UP) { 120 pos = PVector.add(pos, PVector.mult(axis, move_speed)); 121 center = PVector.add(center, PVector.mult(axis, move_speed)); 122 } else if (keyCode == DOWN) { 123 pos = PVector.sub(pos, PVector.mult(axis, move_speed)); 124 center = PVector.sub(center, PVector.mult(axis, move_speed)); 125 } 126 } 127 } 128 } 129 void open() { 130 perspective(fov, float(width) / height, 1e-6, 1e5); 131 camera(pos.x, pos.y, pos.z, center.x, center.y, center.z, axis.x, axis.y, 132 axis.z); 133 } 134 void close() { 135 ortho(-width, 0, -height, 0); 136 camera(0, 0, 0, 0, 0, 1, 0, 1, 0); 137 } 138} 139