Camera.hx 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. package arm;
  2. import iron.system.Input;
  3. import iron.system.Time;
  4. import iron.math.Vec4;
  5. import iron.math.Mat4;
  6. import arm.Viewport;
  7. import arm.Enums;
  8. class Camera {
  9. public static var inst: Camera;
  10. public var origins: Array<Vec4>;
  11. public var views: Array<Mat4>;
  12. var redraws = 0;
  13. var first = true;
  14. var dir = new Vec4();
  15. var ease = 1.0;
  16. var controlsDown = false;
  17. public function new() {
  18. inst = this;
  19. var mouse = Input.getMouse();
  20. var kb = Input.getKeyboard();
  21. var camera = iron.Scene.active.camera;
  22. iron.App.notifyOnUpdate(function() {
  23. if (first) {
  24. first = false;
  25. reset();
  26. }
  27. if (mouse.viewX < 0 ||
  28. mouse.viewX > iron.App.w() ||
  29. mouse.viewY < 0 ||
  30. mouse.viewY > iron.App.h()) {
  31. if (Config.raw.wrap_mouse && controlsDown) {
  32. if (mouse.viewX < 0) {
  33. @:privateAccess mouse.x = mouse.lastX = iron.App.x() + iron.App.w();
  34. Krom.setMousePosition(0, Std.int(mouse.x), Std.int(mouse.y));
  35. }
  36. else if (mouse.viewX > iron.App.w()) {
  37. @:privateAccess mouse.x = mouse.lastX = iron.App.x();
  38. Krom.setMousePosition(0, Std.int(mouse.x), Std.int(mouse.y));
  39. }
  40. else if (mouse.viewY < 0) {
  41. @:privateAccess mouse.y = mouse.lastY = iron.App.y() + iron.App.h();
  42. Krom.setMousePosition(0, Std.int(mouse.x), Std.int(mouse.y));
  43. }
  44. else if (mouse.viewY > iron.App.h()) {
  45. @:privateAccess mouse.y = mouse.lastY = iron.App.y();
  46. Krom.setMousePosition(0, Std.int(mouse.x), Std.int(mouse.y));
  47. }
  48. }
  49. else {
  50. return;
  51. }
  52. }
  53. var modifKey = kb.down("alt") || kb.down("shift") || kb.down("control");
  54. var modif = modifKey || Config.keymap.action_rotate == "middle";
  55. if (Operator.shortcut(Config.keymap.action_rotate, ShortcutStarted) ||
  56. Operator.shortcut(Config.keymap.action_zoom, ShortcutStarted) ||
  57. Operator.shortcut(Config.keymap.action_pan, ShortcutStarted) ||
  58. Operator.shortcut(Config.keymap.rotate_envmap, ShortcutStarted) ||
  59. Operator.shortcut(Config.keymap.rotate_light, ShortcutStarted) ||
  60. (mouse.started("right") && !modif) ||
  61. (mouse.started("middle") && !modif) ||
  62. (mouse.wheelDelta != 0 && !modifKey)) {
  63. controlsDown = true;
  64. }
  65. else if (!Operator.shortcut(Config.keymap.action_rotate, ShortcutDown) &&
  66. !Operator.shortcut(Config.keymap.action_zoom, ShortcutDown) &&
  67. !Operator.shortcut(Config.keymap.action_pan, ShortcutDown) &&
  68. !Operator.shortcut(Config.keymap.rotate_envmap, ShortcutDown) &&
  69. !Operator.shortcut(Config.keymap.rotate_light, ShortcutDown) &&
  70. !(mouse.down("right") && !modif) &&
  71. !(mouse.down("middle") && !modif) &&
  72. (mouse.wheelDelta == 0 && !modifKey)) {
  73. controlsDown = false;
  74. }
  75. if (Input.occupied ||
  76. !App.uiEnabled ||
  77. App.isDragging ||
  78. App.isScrolling() ||
  79. App.isComboSelected() ||
  80. !controlsDown) {
  81. return;
  82. }
  83. var controls = Context.cameraControls;
  84. if (controls == ControlsOrbit && (Operator.shortcut(Config.keymap.action_rotate, ShortcutDown) || (mouse.down("right") && !modif))) {
  85. redraws = 2;
  86. var dist = distance();
  87. camera.transform.move(camera.lookWorld(), dist);
  88. camera.transform.rotate(Vec4.zAxis(), -mouse.movementX / 100 * Config.raw.camera_rotation_speed);
  89. camera.transform.rotate(camera.rightWorld(), -mouse.movementY / 100 * Config.raw.camera_rotation_speed);
  90. if (camera.upWorld().z < 0) {
  91. camera.transform.rotate(camera.rightWorld(), mouse.movementY / 100 * Config.raw.camera_rotation_speed);
  92. }
  93. camera.transform.move(camera.lookWorld(), -dist);
  94. }
  95. else if (controls == ControlsRotate && (Operator.shortcut(Config.keymap.action_rotate, ShortcutDown) || (mouse.down("right") && !modif))) {
  96. redraws = 2;
  97. var t = Context.mainObject().transform;
  98. var up = t.up().normalize();
  99. t.rotate(up, mouse.movementX / 100 * Config.raw.camera_rotation_speed);
  100. var right = camera.rightWorld().normalize();
  101. t.rotate(right, mouse.movementY / 100 * Config.raw.camera_rotation_speed);
  102. t.buildMatrix();
  103. if (t.up().z < 0) {
  104. t.rotate(right, -mouse.movementY / 100 * Config.raw.camera_rotation_speed);
  105. }
  106. }
  107. if (controls == ControlsRotate || controls == ControlsOrbit) {
  108. panAction(modif);
  109. if (Operator.shortcut(Config.keymap.action_zoom, ShortcutDown)) {
  110. redraws = 2;
  111. var f = getZoomDelta() / 150;
  112. f *= getCameraZoomSpeed();
  113. camera.transform.move(camera.look(), f);
  114. }
  115. if (mouse.wheelDelta != 0 && !modifKey) {
  116. redraws = 2;
  117. var f = mouse.wheelDelta * (-0.1);
  118. f *= getCameraZoomSpeed();
  119. camera.transform.move(camera.look(), f);
  120. }
  121. }
  122. else if (controls == ControlsFly && mouse.down("right")) {
  123. var moveForward = kb.down("w") || kb.down("up") || mouse.wheelDelta < 0;
  124. var moveBackward = kb.down("s") || kb.down("down") || mouse.wheelDelta > 0;
  125. var strafeLeft = kb.down("a") || kb.down("left");
  126. var strafeRight = kb.down("d") || kb.down("right");
  127. var strafeUp = kb.down("e");
  128. var strafeDown = kb.down("q");
  129. var fast = kb.down("shift") ? 2.0 : (kb.down("alt") ? 0.5 : 1.0);
  130. if (mouse.wheelDelta != 0) {
  131. fast *= Math.abs(mouse.wheelDelta) * 4.0;
  132. }
  133. if (moveForward || moveBackward || strafeRight || strafeLeft || strafeUp || strafeDown) {
  134. ease += Time.delta * 15;
  135. if (ease > 1.0) ease = 1.0;
  136. dir.set(0, 0, 0);
  137. if (moveForward) dir.addf(camera.look().x, camera.look().y, camera.look().z);
  138. if (moveBackward) dir.addf(-camera.look().x, -camera.look().y, -camera.look().z);
  139. if (strafeRight) dir.addf(camera.right().x, camera.right().y, camera.right().z);
  140. if (strafeLeft) dir.addf(-camera.right().x, -camera.right().y, -camera.right().z);
  141. if (strafeUp) dir.addf(0, 0, 1);
  142. if (strafeDown) dir.addf(0, 0, -1);
  143. }
  144. else {
  145. ease -= Time.delta * 20.0 * ease;
  146. if (ease < 0.0) ease = 0.0;
  147. }
  148. var d = Time.delta * fast * ease * 2.0 * ((moveForward || moveBackward) ? Config.raw.camera_zoom_speed : Config.raw.camera_pan_speed);
  149. if (d > 0.0) {
  150. camera.transform.move(dir, d);
  151. if (Context.cameraType == CameraOrthographic) {
  152. Viewport.updateCameraType(Context.cameraType);
  153. }
  154. }
  155. redraws = 2;
  156. camera.transform.rotate(Vec4.zAxis(), -mouse.movementX / 200 * Config.raw.camera_rotation_speed);
  157. camera.transform.rotate(camera.right(), -mouse.movementY / 200 * Config.raw.camera_rotation_speed);
  158. }
  159. if (Operator.shortcut(Config.keymap.rotate_light, ShortcutDown)) {
  160. redraws = 2;
  161. var light = iron.Scene.active.lights[0];
  162. var m = iron.math.Mat4.identity();
  163. Context.lightAngle = (Context.lightAngle + ((mouse.movementX / 100) % (2 * Math.PI) + 2 * Math.PI)) % (2 * Math.PI);
  164. m.self = kha.math.FastMatrix4.rotationZ(mouse.movementX / 100);
  165. light.transform.local.multmat(m);
  166. light.transform.decompose();
  167. }
  168. if (Operator.shortcut(Config.keymap.rotate_envmap, ShortcutDown)) {
  169. redraws = 2;
  170. Context.envmapAngle -= mouse.movementX / 100;
  171. }
  172. if (redraws > 0) {
  173. redraws--;
  174. Context.ddirty = 2;
  175. if (Context.cameraType == CameraOrthographic) {
  176. Viewport.updateCameraType(Context.cameraType);
  177. }
  178. }
  179. });
  180. }
  181. public function distance(): Float {
  182. var camera = iron.Scene.active.camera;
  183. return Vec4.distance(origins[index()], camera.transform.loc);
  184. }
  185. public function index(): Int {
  186. return Context.viewIndexLast > 0 ? 1 : 0;
  187. }
  188. function getCameraZoomSpeed(): Float {
  189. var sign = Config.raw.zoom_direction == ZoomVerticalInverted ||
  190. Config.raw.zoom_direction == ZoomHorizontalInverted ||
  191. Config.raw.zoom_direction == ZoomVerticalAndHorizontalInverted ? -1 : 1;
  192. return Config.raw.camera_zoom_speed * sign;
  193. }
  194. public function reset(viewIndex = -1) {
  195. var camera = iron.Scene.active.camera;
  196. if (viewIndex == -1) {
  197. origins = [new Vec4(0, 0, 0), new Vec4(0, 0, 0)];
  198. views = [camera.transform.local.clone(), camera.transform.local.clone()];
  199. }
  200. else {
  201. origins[viewIndex] = new Vec4(0, 0, 0);
  202. views[viewIndex] = camera.transform.local.clone();
  203. }
  204. }
  205. function panAction(modif: Bool) {
  206. var camera = iron.Scene.active.camera;
  207. var mouse = Input.getMouse();
  208. if (Operator.shortcut(Config.keymap.action_pan, ShortcutDown) || (mouse.down("middle") && !modif)) {
  209. redraws = 2;
  210. var look = camera.transform.look().normalize().mult(mouse.movementY / 150 * Config.raw.camera_pan_speed);
  211. var right = camera.transform.right().normalize().mult(-mouse.movementX / 150 * Config.raw.camera_pan_speed);
  212. camera.transform.loc.add(look);
  213. camera.transform.loc.add(right);
  214. origins[index()].add(look);
  215. origins[index()].add(right);
  216. camera.buildMatrix();
  217. }
  218. }
  219. static function getZoomDelta(): Float {
  220. var mouse = Input.getMouse();
  221. return Config.raw.zoom_direction == ZoomVertical ? -mouse.movementY :
  222. Config.raw.zoom_direction == ZoomVerticalInverted ? -mouse.movementY :
  223. Config.raw.zoom_direction == ZoomHorizontal ? mouse.movementX :
  224. Config.raw.zoom_direction == ZoomHorizontalInverted ? mouse.movementX :
  225. -(mouse.movementY - mouse.movementX);
  226. }
  227. }