123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- class Camera {
- // camera's field of view
- float fov;
- // camera's position, look at point and axis
- PVector pos, center, axis;
- PVector init_pos, init_center, init_axis;
- float move_speed;
- float rot_speed;
- Camera(float fov, PVector pos, PVector center, PVector axis) {
- this.fov = fov;
- this.pos = pos;
- this.center = center;
- this.axis = axis;
- this.axis.normalize();
- move_speed = 0.001;
- rot_speed = 0.01 * PI;
- init_pos = pos.copy();
- init_center = center.copy();
- init_axis = axis.copy();
- }
- Camera copy() {
- Camera cam = new Camera(fov, pos.copy(), center.copy(), axis.copy());
- return cam;
- }
- PVector project(PVector pos) {
- PVector proj = MatxVec3(getCameraMat(), PVector.sub(pos, this.pos));
- proj.x = (float)height / 2.0 * proj.x / proj.z / tan(fov / 2.0f);
- proj.y = (float)height / 2.0 * proj.y / proj.z / tan(fov / 2.0f);
- proj.z = proj.z;
- return proj;
- }
- float[] getCameraMat() {
- float[] mat = new float[9];
- PVector dir = PVector.sub(center, pos);
- dir.normalize();
- PVector left = dir.cross(axis);
- left.normalize();
- // processing camera system does not follow right hand rule
- mat[0] = -left.x;
- mat[1] = -left.y;
- mat[2] = -left.z;
- mat[3] = axis.x;
- mat[4] = axis.y;
- mat[5] = axis.z;
- mat[6] = dir.x;
- mat[7] = dir.y;
- mat[8] = dir.z;
- return mat;
- }
- void run() {
- PVector dir, left;
- if (mousePressed) {
- float angleX = (float)mouseX / width * PI - PI / 2;
- float angleY = (float)mouseY / height * PI - PI;
- PVector diff = PVector.sub(center, pos);
- float radius = diff.mag();
- pos.x = radius * sin(angleY) * sin(angleX) + center.x;
- pos.y = radius * cos(angleY) + center.y;
- pos.z = radius * sin(angleY) * cos(angleX) + center.z;
- dir = PVector.sub(center, pos);
- dir.normalize();
- PVector up = new PVector(0, 1, 0);
- left = up.cross(dir);
- left.normalize();
- axis = dir.cross(left);
- axis.normalize();
- }
- if (keyPressed) {
- switch (key) {
- case 'w':
- dir = PVector.sub(center, pos);
- dir.normalize();
- pos = PVector.add(pos, PVector.mult(dir, move_speed));
- center = PVector.add(center, PVector.mult(dir, move_speed));
- break;
- case 's':
- dir = PVector.sub(center, pos);
- dir.normalize();
- pos = PVector.sub(pos, PVector.mult(dir, move_speed));
- center = PVector.sub(center, PVector.mult(dir, move_speed));
- break;
- case 'a':
- dir = PVector.sub(center, pos);
- dir.normalize();
- left = axis.cross(dir);
- left.normalize();
- pos = PVector.add(pos, PVector.mult(left, move_speed));
- center = PVector.add(center, PVector.mult(left, move_speed));
- break;
- case 'd':
- dir = PVector.sub(center, pos);
- dir.normalize();
- left = axis.cross(dir);
- left.normalize();
- pos = PVector.sub(pos, PVector.mult(left, move_speed));
- center = PVector.sub(center, PVector.mult(left, move_speed));
- break;
- case 'r':
- dir = PVector.sub(center, pos);
- dir.normalize();
- float[] mat = getRotationMat3x3(rot_speed, dir.x, dir.y, dir.z);
- axis = MatxVec3(mat, axis);
- axis.normalize();
- break;
- case 'b':
- pos = init_pos.copy();
- center = init_center.copy();
- axis = init_axis.copy();
- break;
- case '+': move_speed *= 2.0f; break;
- case '-': move_speed /= 2.0; break;
- case CODED:
- if (keyCode == UP) {
- pos = PVector.add(pos, PVector.mult(axis, move_speed));
- center = PVector.add(center, PVector.mult(axis, move_speed));
- } else if (keyCode == DOWN) {
- pos = PVector.sub(pos, PVector.mult(axis, move_speed));
- center = PVector.sub(center, PVector.mult(axis, move_speed));
- }
- }
- }
- }
- void open() {
- perspective(fov, float(width) / height, 1e-6, 1e5);
- camera(pos.x, pos.y, pos.z, center.x, center.y, center.z, axis.x, axis.y,
- axis.z);
- }
- void close() {
- ortho(-width, 0, -height, 0);
- camera(0, 0, 0, 0, 0, 1, 0, 1, 0);
- }
- }
|