camera.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. let camera_origins: vec4_box_t[];
  2. let camera_views: mat4_box_t[];
  3. let camera_redraws: i32 = 0;
  4. let camera_dir: vec4_t = vec4_create();
  5. let camera_ease: f32 = 1.0;
  6. let camera_controls_down: bool = false;
  7. function camera_init() {
  8. camera_reset();
  9. }
  10. function camera_update() {
  11. let camera: camera_object_t = scene_camera;
  12. if (mouse_view_x() < 0 || mouse_view_x() > sys_w() || mouse_view_y() < 0 || mouse_view_y() > sys_h()) {
  13. if (config_raw.wrap_mouse && camera_controls_down) {
  14. if (mouse_view_x() < 0) {
  15. mouse_x = mouse_last_x = sys_x() + sys_w();
  16. iron_mouse_set_position(math_floor(mouse_x), math_floor(mouse_y));
  17. }
  18. else if (mouse_view_x() > sys_w()) {
  19. mouse_x = mouse_last_x = sys_x();
  20. iron_mouse_set_position(math_floor(mouse_x), math_floor(mouse_y));
  21. }
  22. else if (mouse_view_y() < 0) {
  23. mouse_y = mouse_last_y = sys_y() + sys_h();
  24. iron_mouse_set_position(math_floor(mouse_x), math_floor(mouse_y));
  25. }
  26. else if (mouse_view_y() > sys_h()) {
  27. mouse_y = mouse_last_y = sys_y();
  28. iron_mouse_set_position(math_floor(mouse_x), math_floor(mouse_y));
  29. }
  30. }
  31. else {
  32. return;
  33. }
  34. }
  35. let modif_key: bool = keyboard_down("alt") || keyboard_down("shift") || keyboard_down("control");
  36. let modif: bool = modif_key || map_get(config_keymap, "action_rotate") == "middle";
  37. let default_keymap: bool = config_raw.keymap == "default.json";
  38. if (operator_shortcut(map_get(config_keymap, "action_rotate"), shortcut_type_t.STARTED) ||
  39. operator_shortcut(map_get(config_keymap, "action_zoom"), shortcut_type_t.STARTED) ||
  40. operator_shortcut(map_get(config_keymap, "action_pan"), shortcut_type_t.STARTED) ||
  41. operator_shortcut(map_get(config_keymap, "rotate_envmap"), shortcut_type_t.STARTED) || (mouse_started("right") && !modif) ||
  42. (mouse_started("middle") && !modif) || (mouse_wheel_delta != 0 && !modif_key)) {
  43. camera_controls_down = true;
  44. }
  45. else if (!operator_shortcut(map_get(config_keymap, "action_rotate"), shortcut_type_t.DOWN) &&
  46. !operator_shortcut(map_get(config_keymap, "action_zoom"), shortcut_type_t.DOWN) &&
  47. !operator_shortcut(map_get(config_keymap, "action_pan"), shortcut_type_t.DOWN) &&
  48. !operator_shortcut(map_get(config_keymap, "rotate_envmap"), shortcut_type_t.DOWN) && !(mouse_down("right") && !modif) &&
  49. !(mouse_down("middle") && !modif) && (mouse_wheel_delta == 0 && !modif_key)) {
  50. camera_controls_down = false;
  51. }
  52. if (_input_occupied || !base_ui_enabled || base_is_dragging || ui.is_scrolling || ui.combo_selected_handle != null || !camera_controls_down) {
  53. return;
  54. }
  55. let controls: camera_controls_t = context_raw.camera_controls;
  56. if (controls == camera_controls_t.ORBIT &&
  57. (operator_shortcut(map_get(config_keymap, "action_rotate"), shortcut_type_t.DOWN) || (mouse_down("right") && !modif && default_keymap))) {
  58. camera_redraws = 2;
  59. let dist: f32 = camera_distance();
  60. transform_move(camera.base.transform, camera_object_look_world(camera), dist);
  61. transform_rotate(camera.base.transform, vec4_z_axis(), -mouse_movement_x / 100 * config_raw.camera_rotation_speed);
  62. transform_rotate(camera.base.transform, camera_object_right_world(camera), -mouse_movement_y / 100 * config_raw.camera_rotation_speed);
  63. let up_world: vec4_t = camera_object_up_world(camera);
  64. if (up_world.z < 0 && !config_raw.camera_upside_down) {
  65. transform_rotate(camera.base.transform, camera_object_right_world(camera), mouse_movement_y / 100 * config_raw.camera_rotation_speed);
  66. }
  67. transform_move(camera.base.transform, camera_object_look_world(camera), -dist);
  68. }
  69. else if (controls == camera_controls_t.ROTATE &&
  70. (operator_shortcut(map_get(config_keymap, "action_rotate"), shortcut_type_t.DOWN) || (mouse_down("right") && !modif && default_keymap))) {
  71. camera_redraws = 2;
  72. let t: transform_t = context_main_object().base.transform;
  73. let up: vec4_t = transform_up(t);
  74. transform_rotate(t, up, (mouse_movement_x / 120) * config_raw.camera_rotation_speed);
  75. let right: vec4_t = camera_object_right_world(camera);
  76. transform_rotate(t, right, (mouse_movement_y / 120) * config_raw.camera_rotation_speed);
  77. transform_build_matrix(t);
  78. let tup: vec4_t = transform_up(t);
  79. if (tup.z < 0 && !config_raw.camera_upside_down) {
  80. transform_rotate(t, right, -(mouse_movement_y / 120) * config_raw.camera_rotation_speed);
  81. }
  82. }
  83. if (controls == camera_controls_t.ROTATE || controls == camera_controls_t.ORBIT) {
  84. camera_pan_action(modif, default_keymap);
  85. if (operator_shortcut(map_get(config_keymap, "action_zoom"), shortcut_type_t.DOWN)) {
  86. camera_redraws = 2;
  87. let f: f32 = camera_get_zoom_delta() / (150 * (1.0 / (camera_distance() / 2.0)));
  88. f *= camera_get_zoom_speed();
  89. transform_move(camera.base.transform, camera_object_look(camera), f);
  90. }
  91. if (mouse_wheel_delta != 0 && !modif_key) {
  92. camera_redraws = 2;
  93. let f: f32 = mouse_wheel_delta * (-0.2) * ((camera_distance() / 4.0));
  94. f *= camera_get_zoom_speed();
  95. transform_move(camera.base.transform, camera_object_look(camera), f);
  96. }
  97. }
  98. else if (controls == camera_controls_t.FLY && mouse_down("right")) {
  99. let move_forward: bool = keyboard_down("w") || keyboard_down("up") || mouse_wheel_delta < 0;
  100. let move_backward: bool = keyboard_down("s") || keyboard_down("down") || mouse_wheel_delta > 0;
  101. let strafe_left: bool = keyboard_down("a") || keyboard_down("left");
  102. let strafe_right: bool = keyboard_down("d") || keyboard_down("right");
  103. let strafe_up: bool = keyboard_down("e");
  104. let strafe_down: bool = keyboard_down("q");
  105. let fast: f32 = keyboard_down("shift") ? 2.0 : (keyboard_down("alt") ? 0.5 : 1.0);
  106. if (mouse_wheel_delta != 0) {
  107. fast *= math_abs(mouse_wheel_delta) * 4.0;
  108. }
  109. if (move_forward || move_backward || strafe_right || strafe_left || strafe_up || strafe_down) {
  110. camera_ease += sys_delta() * 15;
  111. if (camera_ease > 1.0) {
  112. camera_ease = 1.0;
  113. }
  114. camera_dir = vec4_create(0, 0, 0);
  115. let look: vec4_t = camera_object_look(camera);
  116. let right: vec4_t = camera_object_right(camera);
  117. if (move_forward) {
  118. camera_dir = vec4_fadd(camera_dir, look.x, look.y, look.z);
  119. }
  120. if (move_backward) {
  121. camera_dir = vec4_fadd(camera_dir, -look.x, -look.y, -look.z);
  122. }
  123. if (strafe_right) {
  124. camera_dir = vec4_fadd(camera_dir, right.x, right.y, right.z);
  125. }
  126. if (strafe_left) {
  127. camera_dir = vec4_fadd(camera_dir, -right.x, -right.y, -right.z);
  128. }
  129. if (strafe_up) {
  130. camera_dir = vec4_fadd(camera_dir, 0, 0, 1);
  131. }
  132. if (strafe_down) {
  133. camera_dir = vec4_fadd(camera_dir, 0, 0, -1);
  134. }
  135. }
  136. else {
  137. camera_ease -= sys_delta() * 20.0 * camera_ease;
  138. if (camera_ease < 0.0) {
  139. camera_ease = 0.0;
  140. }
  141. }
  142. let d: f32 = sys_delta() * fast * camera_ease * 2.0 * ((move_forward || move_backward) ? config_raw.camera_zoom_speed : config_raw.camera_pan_speed);
  143. if (d > 0.0) {
  144. transform_move(camera.base.transform, camera_dir, d);
  145. if (context_raw.camera_type == camera_type_t.ORTHOGRAPHIC) {
  146. viewport_update_camera_type(context_raw.camera_type);
  147. }
  148. }
  149. camera_redraws = 2;
  150. transform_rotate(camera.base.transform, vec4_z_axis(), -mouse_movement_x / 200 * config_raw.camera_rotation_speed);
  151. transform_rotate(camera.base.transform, camera_object_right(camera), -mouse_movement_y / 200 * config_raw.camera_rotation_speed);
  152. }
  153. if (operator_shortcut(map_get(config_keymap, "view_pivot_center"), shortcut_type_t.STARTED)) {
  154. camera_set_pivot_center_to_mouse();
  155. }
  156. if (operator_shortcut(map_get(config_keymap, "rotate_envmap"), shortcut_type_t.DOWN)) {
  157. camera_redraws = 2;
  158. context_raw.envmap_angle -= mouse_movement_x / 100;
  159. }
  160. if (camera_redraws > 0) {
  161. camera_redraws--;
  162. context_raw.ddirty = 2;
  163. if (context_raw.camera_type == camera_type_t.ORTHOGRAPHIC) {
  164. viewport_update_camera_type(context_raw.camera_type);
  165. }
  166. }
  167. }
  168. function camera_distance(): f32 {
  169. let camera: camera_object_t = scene_camera;
  170. return vec4_dist(camera_origins[camera_index()].v, camera.base.transform.loc);
  171. }
  172. function camera_index(): i32 {
  173. return context_raw.view_index_last > 0 ? 1 : 0;
  174. }
  175. function camera_get_zoom_speed(): f32 {
  176. let sign: i32 = config_raw.zoom_direction == zoom_direction_t.VERTICAL_INVERTED || config_raw.zoom_direction == zoom_direction_t.HORIZONTAL_INVERTED ||
  177. config_raw.zoom_direction == zoom_direction_t.VERTICAL_HORIZONTAL_INVERTED
  178. ? -1
  179. : 1;
  180. let camera: camera_object_t = scene_camera;
  181. let fov_adjust: f32 = camera.data.fov;
  182. return (config_raw.camera_zoom_speed * sign) / fov_adjust;
  183. }
  184. function camera_reset(view_index: i32 = -1) {
  185. let camera: camera_object_t = scene_camera;
  186. if (view_index == -1) {
  187. let v0: vec4_box_t = {v : vec4_create(0, 0, 0, 1)};
  188. let v1: vec4_box_t = {v : vec4_create(0, 0, 0, 1)};
  189. camera_origins = [ v0, v1 ];
  190. let m0: mat4_box_t = {v : mat4_clone(camera.base.transform.local)};
  191. let m1: mat4_box_t = {v : mat4_clone(camera.base.transform.local)};
  192. camera_views = [ m0, m1 ];
  193. }
  194. else {
  195. camera_origins[view_index].v = vec4_create(0, 0, 0);
  196. camera_views[view_index].v = mat4_clone(camera.base.transform.local);
  197. }
  198. }
  199. function camera_pan_action(modif: bool, default_keymap: bool) {
  200. let camera: camera_object_t = scene_camera;
  201. if (operator_shortcut(map_get(config_keymap, "action_pan"), shortcut_type_t.DOWN) || (mouse_down("middle") && !modif && default_keymap)) {
  202. camera_redraws = 2;
  203. let f: f32 = 150 * (1.0 / (camera_distance() / 4.0));
  204. let look: vec4_t = vec4_mult(transform_look(camera.base.transform), mouse_movement_y / f * config_raw.camera_pan_speed);
  205. let right: vec4_t = vec4_mult(transform_right(camera.base.transform), -mouse_movement_x / f * config_raw.camera_pan_speed);
  206. camera.base.transform.loc = vec4_add(camera.base.transform.loc, look);
  207. camera.base.transform.loc = vec4_add(camera.base.transform.loc, right);
  208. camera_origins[camera_index()].v = vec4_add(camera_origins[camera_index()].v, look);
  209. camera_origins[camera_index()].v = vec4_add(camera_origins[camera_index()].v, right);
  210. camera_object_build_mat(camera);
  211. }
  212. }
  213. function camera_get_zoom_delta(): f32 {
  214. return config_raw.zoom_direction == zoom_direction_t.VERTICAL ? -mouse_movement_y
  215. : config_raw.zoom_direction == zoom_direction_t.VERTICAL_INVERTED ? -mouse_movement_y
  216. : config_raw.zoom_direction == zoom_direction_t.HORIZONTAL ? mouse_movement_x
  217. : config_raw.zoom_direction == zoom_direction_t.HORIZONTAL_INVERTED ? mouse_movement_x
  218. : -(mouse_movement_y - mouse_movement_x);
  219. }
  220. function camera_set_pivot_center_to_mouse() {
  221. util_render_pick_pos_nor_tex();
  222. let is_mesh: bool = math_abs(context_raw.posx_picked) < 50 && math_abs(context_raw.posy_picked) < 50 && math_abs(context_raw.posz_picked) < 50;
  223. if (!is_mesh) {
  224. return;
  225. }
  226. let o: vec4_box_t = camera_origins[camera_index()];
  227. o.v.x = context_raw.posx_picked;
  228. o.v.y = context_raw.posy_picked;
  229. o.v.z = context_raw.posz_picked;
  230. camera_redraws = 2;
  231. let camera: camera_object_t = scene_camera;
  232. let up: vec4_t = vec4_mult(transform_up(camera.base.transform), camera_distance());
  233. camera.base.transform.loc.x = context_raw.posx_picked;
  234. camera.base.transform.loc.y = context_raw.posy_picked;
  235. camera.base.transform.loc.z = context_raw.posz_picked;
  236. camera.base.transform.loc = vec4_add(camera.base.transform.loc, up);
  237. camera_object_build_mat(camera);
  238. }