139 lines
4.2 KiB
Plaintext
139 lines
4.2 KiB
Plaintext
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);
|
|
}
|
|
}
|