• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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