Camera.pde 4.2 KB

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