gizmo.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. ///if (is_paint || is_sculpt)
  2. let gizmo_v: vec4_t = vec4_create();
  3. let gizmo_v0: vec4_t = vec4_create();
  4. let gizmo_q: quat_t = quat_create();
  5. let gizmo_q0: quat_t = quat_create();
  6. function gizmo_update() {
  7. let is_object: bool = context_raw.tool == workspace_tool_t.GIZMO;
  8. let is_decal: bool = base_is_decal_layer();
  9. let gizmo: object_t = context_raw.gizmo;
  10. let hide: bool = operator_shortcut(map_get(config_keymap, "stencil_hide"), shortcut_type_t.DOWN);
  11. gizmo.visible = (is_object || is_decal) && !hide;
  12. if (!gizmo.visible) {
  13. return;
  14. }
  15. let paint_object: object_t = context_raw.paint_object.base;
  16. ///if is_forge
  17. if (context_raw.selected_object != null) {
  18. paint_object = context_raw.selected_object;
  19. }
  20. ///end
  21. if (is_object) {
  22. vec4_set_from(gizmo.transform.loc, paint_object.transform.loc);
  23. }
  24. else if (is_decal) {
  25. vec4_set(gizmo.transform.loc, context_raw.layer.decal_mat.m[12], context_raw.layer.decal_mat.m[13], context_raw.layer.decal_mat.m[14]);
  26. }
  27. let cam: camera_object_t = scene_camera;
  28. let fov: f32 = cam.data.fov;
  29. let dist: f32 = vec4_dist(cam.base.transform.loc, gizmo.transform.loc) / 8 * fov;
  30. vec4_set(gizmo.transform.scale, dist, dist, dist);
  31. vec4_set(context_raw.gizmo_translate_x.transform.scale, dist, dist, dist);
  32. vec4_set(context_raw.gizmo_translate_y.transform.scale, dist, dist, dist);
  33. vec4_set(context_raw.gizmo_translate_z.transform.scale, dist, dist, dist);
  34. vec4_set(context_raw.gizmo_scale_x.transform.scale, dist, dist, dist);
  35. vec4_set(context_raw.gizmo_scale_y.transform.scale, dist, dist, dist);
  36. vec4_set(context_raw.gizmo_scale_z.transform.scale, dist, dist, dist);
  37. vec4_set(context_raw.gizmo_rotate_x.transform.scale, dist, dist, dist);
  38. vec4_set(context_raw.gizmo_rotate_y.transform.scale, dist, dist, dist);
  39. vec4_set(context_raw.gizmo_rotate_z.transform.scale, dist, dist, dist);
  40. transform_build_matrix(gizmo.transform);
  41. // Scene control
  42. if (is_object) {
  43. if (context_raw.translate_x || context_raw.translate_y || context_raw.translate_z || context_raw.scale_x || context_raw.scale_y || context_raw.scale_z || context_raw.rotate_x || context_raw.rotate_y || context_raw.rotate_z) {
  44. if (context_raw.translate_x) {
  45. paint_object.transform.loc.x = context_raw.gizmo_drag;
  46. }
  47. else if (context_raw.translate_y) {
  48. paint_object.transform.loc.y = context_raw.gizmo_drag;
  49. }
  50. else if (context_raw.translate_z) {
  51. paint_object.transform.loc.z = context_raw.gizmo_drag;
  52. }
  53. else if (context_raw.scale_x) {
  54. paint_object.transform.scale.x += context_raw.gizmo_drag - context_raw.gizmo_drag_last;
  55. }
  56. else if (context_raw.scale_y) {
  57. paint_object.transform.scale.y += context_raw.gizmo_drag - context_raw.gizmo_drag_last;
  58. }
  59. else if (context_raw.scale_z) {
  60. paint_object.transform.scale.z += context_raw.gizmo_drag - context_raw.gizmo_drag_last;
  61. }
  62. else if (context_raw.rotate_x) {
  63. quat_from_axis_angle(gizmo_q0, vec4_x_axis(), context_raw.gizmo_drag - context_raw.gizmo_drag_last);
  64. quat_mult(paint_object.transform.rot, gizmo_q0);
  65. }
  66. else if (context_raw.rotate_y) {
  67. quat_from_axis_angle(gizmo_q0, vec4_y_axis(), context_raw.gizmo_drag - context_raw.gizmo_drag_last);
  68. quat_mult(paint_object.transform.rot, gizmo_q0);
  69. }
  70. else if (context_raw.rotate_z) {
  71. quat_from_axis_angle(gizmo_q0, vec4_z_axis(), context_raw.gizmo_drag - context_raw.gizmo_drag_last);
  72. quat_mult(paint_object.transform.rot, gizmo_q0);
  73. }
  74. context_raw.gizmo_drag_last = context_raw.gizmo_drag;
  75. transform_build_matrix(paint_object.transform);
  76. ///if arm_physics
  77. let pb: physics_body_t = map_get(physics_body_object_map, paint_object);
  78. if (pb != null) {
  79. physics_body_sync_transform(pb);
  80. }
  81. ///end
  82. }
  83. }
  84. // Decal layer control
  85. else if (is_decal) {
  86. if (context_raw.translate_x || context_raw.translate_y || context_raw.translate_z || context_raw.scale_x || context_raw.scale_y || context_raw.scale_z || context_raw.rotate_x || context_raw.rotate_y || context_raw.rotate_z) {
  87. if (context_raw.translate_x) {
  88. context_raw.layer.decal_mat.m[12] = context_raw.gizmo_drag;
  89. }
  90. else if (context_raw.translate_y) {
  91. context_raw.layer.decal_mat.m[13] = context_raw.gizmo_drag;
  92. }
  93. else if (context_raw.translate_z) {
  94. context_raw.layer.decal_mat.m[14] = context_raw.gizmo_drag;
  95. }
  96. else if (context_raw.scale_x) {
  97. mat4_decompose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0);
  98. gizmo_v0.x += context_raw.gizmo_drag - context_raw.gizmo_drag_last;
  99. mat4_compose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0);
  100. }
  101. else if (context_raw.scale_y) {
  102. mat4_decompose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0);
  103. gizmo_v0.y += context_raw.gizmo_drag - context_raw.gizmo_drag_last;
  104. mat4_compose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0);
  105. }
  106. else if (context_raw.scale_z) {
  107. mat4_decompose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0);
  108. gizmo_v0.z += context_raw.gizmo_drag - context_raw.gizmo_drag_last;
  109. mat4_compose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0);
  110. }
  111. else if (context_raw.rotate_x) {
  112. mat4_decompose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0);
  113. quat_from_axis_angle(gizmo_q0, vec4_x_axis(), -context_raw.gizmo_drag + context_raw.gizmo_drag_last);
  114. quat_mult_quats(gizmo_q, gizmo_q0, gizmo_q);
  115. mat4_compose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0);
  116. }
  117. else if (context_raw.rotate_y) {
  118. mat4_decompose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0);
  119. quat_from_axis_angle(gizmo_q0, vec4_y_axis(), -context_raw.gizmo_drag + context_raw.gizmo_drag_last);
  120. quat_mult_quats(gizmo_q, gizmo_q0, gizmo_q);
  121. mat4_compose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0);
  122. }
  123. else if (context_raw.rotate_z) {
  124. mat4_decompose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0);
  125. quat_from_axis_angle(gizmo_q0, vec4_z_axis(), context_raw.gizmo_drag - context_raw.gizmo_drag_last);
  126. quat_mult_quats(gizmo_q, gizmo_q0, gizmo_q);
  127. mat4_compose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0);
  128. }
  129. context_raw.gizmo_drag_last = context_raw.gizmo_drag;
  130. if (context_raw.material != context_raw.layer.fill_layer) {
  131. context_set_material(context_raw.layer.fill_layer);
  132. }
  133. base_update_fill_layer(context_raw.gizmo_started);
  134. }
  135. }
  136. context_raw.gizmo_started = false;
  137. if (mouse_started("left") && paint_object.name != "Scene") {
  138. // Translate, scale
  139. let trs: transform_t[] = [
  140. context_raw.gizmo_translate_x.transform,
  141. context_raw.gizmo_translate_y.transform,
  142. context_raw.gizmo_translate_z.transform,
  143. context_raw.gizmo_scale_x.transform,
  144. context_raw.gizmo_scale_y.transform,
  145. context_raw.gizmo_scale_z.transform
  146. ];
  147. let hit: transform_t = raycast_closest_box_intersect(trs, mouse_view_x(), mouse_view_y(), scene_camera);
  148. if (hit != null) {
  149. if (hit.object == context_raw.gizmo_translate_x) {
  150. context_raw.translate_x = true;
  151. }
  152. else if (hit.object == context_raw.gizmo_translate_y) {
  153. context_raw.translate_y = true;
  154. }
  155. else if (hit.object == context_raw.gizmo_translate_z) {
  156. context_raw.translate_z = true;
  157. }
  158. else if (hit.object == context_raw.gizmo_scale_x) {
  159. context_raw.scale_x = true;
  160. }
  161. else if (hit.object == context_raw.gizmo_scale_y) {
  162. context_raw.scale_y = true;
  163. }
  164. else if (hit.object == context_raw.gizmo_scale_z) {
  165. context_raw.scale_z = true;
  166. }
  167. if (context_raw.translate_x || context_raw.translate_y || context_raw.translate_z || context_raw.scale_x || context_raw.scale_y || context_raw.scale_z) {
  168. context_raw.gizmo_offset = 0.0;
  169. context_raw.gizmo_started = true;
  170. }
  171. }
  172. else {
  173. // Rotate
  174. let trs: transform_t[] = [
  175. context_raw.gizmo_rotate_x.transform,
  176. context_raw.gizmo_rotate_y.transform,
  177. context_raw.gizmo_rotate_z.transform
  178. ];
  179. let hit: transform_t = raycast_closest_box_intersect(trs, mouse_view_x(), mouse_view_y(), scene_camera);
  180. if (hit != null) {
  181. if (hit.object == context_raw.gizmo_rotate_x) {
  182. context_raw.rotate_x = true;
  183. }
  184. else if (hit.object == context_raw.gizmo_rotate_y) {
  185. context_raw.rotate_y = true;
  186. }
  187. else if (hit.object == context_raw.gizmo_rotate_z) {
  188. context_raw.rotate_z = true;
  189. }
  190. if (context_raw.rotate_x || context_raw.rotate_y || context_raw.rotate_z) {
  191. context_raw.gizmo_offset = 0.0;
  192. context_raw.gizmo_started = true;
  193. }
  194. }
  195. }
  196. }
  197. else if (mouse_released("left")) {
  198. context_raw.translate_x = context_raw.translate_y = context_raw.translate_z = false;
  199. context_raw.scale_x = context_raw.scale_y = context_raw.scale_z = false;
  200. context_raw.rotate_x = context_raw.rotate_y = context_raw.rotate_z = false;
  201. }
  202. if (context_raw.translate_x || context_raw.translate_y || context_raw.translate_z || context_raw.scale_x || context_raw.scale_y || context_raw.scale_z || context_raw.rotate_x || context_raw.rotate_y || context_raw.rotate_z) {
  203. context_raw.rdirty = 2;
  204. if (is_object) {
  205. let t: transform_t = paint_object.transform;
  206. vec4_set(gizmo_v, transform_world_x(t), transform_world_y(t), transform_world_z(t));
  207. }
  208. else if (is_decal) {
  209. vec4_set(gizmo_v, context_raw.layer.decal_mat.m[12], context_raw.layer.decal_mat.m[13], context_raw.layer.decal_mat.m[14]);
  210. }
  211. if (context_raw.translate_x || context_raw.scale_x) {
  212. let hit: vec4_t = raycast_plane_intersect(vec4_y_axis(), gizmo_v, mouse_view_x(), mouse_view_y(), scene_camera);
  213. if (hit != null) {
  214. if (context_raw.gizmo_started) {
  215. context_raw.gizmo_offset = hit.x - gizmo_v.x;
  216. }
  217. context_raw.gizmo_drag = hit.x - context_raw.gizmo_offset;
  218. }
  219. }
  220. else if (context_raw.translate_y || context_raw.scale_y) {
  221. let hit: vec4_t = raycast_plane_intersect(vec4_x_axis(), gizmo_v, mouse_view_x(), mouse_view_y(), scene_camera);
  222. if (hit != null) {
  223. if (context_raw.gizmo_started) {
  224. context_raw.gizmo_offset = hit.y - gizmo_v.y;
  225. }
  226. context_raw.gizmo_drag = hit.y - context_raw.gizmo_offset;
  227. }
  228. }
  229. else if (context_raw.translate_z || context_raw.scale_z) {
  230. let hit: vec4_t = raycast_plane_intersect(vec4_x_axis(), gizmo_v, mouse_view_x(), mouse_view_y(), scene_camera);
  231. if (hit != null) {
  232. if (context_raw.gizmo_started) {
  233. context_raw.gizmo_offset = hit.z - gizmo_v.z;
  234. }
  235. context_raw.gizmo_drag = hit.z - context_raw.gizmo_offset;
  236. }
  237. }
  238. else if (context_raw.rotate_x) {
  239. let hit: vec4_t = raycast_plane_intersect(vec4_x_axis(), gizmo_v, mouse_view_x(), mouse_view_y(), scene_camera);
  240. if (hit != null) {
  241. if (context_raw.gizmo_started) {
  242. mat4_decompose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0);
  243. context_raw.gizmo_offset = math_atan2(hit.y - gizmo_v.y, hit.z - gizmo_v.z);
  244. }
  245. context_raw.gizmo_drag = math_atan2(hit.y - gizmo_v.y, hit.z - gizmo_v.z) - context_raw.gizmo_offset;
  246. }
  247. }
  248. else if (context_raw.rotate_y) {
  249. let hit: vec4_t = raycast_plane_intersect(vec4_y_axis(), gizmo_v, mouse_view_x(), mouse_view_y(), scene_camera);
  250. if (hit != null) {
  251. if (context_raw.gizmo_started) {
  252. mat4_decompose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0);
  253. context_raw.gizmo_offset = math_atan2(hit.z - gizmo_v.z, hit.x - gizmo_v.x);
  254. }
  255. context_raw.gizmo_drag = math_atan2(hit.z - gizmo_v.z, hit.x - gizmo_v.x) - context_raw.gizmo_offset;
  256. }
  257. }
  258. else if (context_raw.rotate_z) {
  259. let hit: vec4_t = raycast_plane_intersect(vec4_z_axis(), gizmo_v, mouse_view_x(), mouse_view_y(), scene_camera);
  260. if (hit != null) {
  261. if (context_raw.gizmo_started) {
  262. mat4_decompose(context_raw.layer.decal_mat, gizmo_v, gizmo_q, gizmo_v0);
  263. context_raw.gizmo_offset = math_atan2(hit.y - gizmo_v.y, hit.x - gizmo_v.x);
  264. }
  265. context_raw.gizmo_drag = math_atan2(hit.y - gizmo_v.y, hit.x - gizmo_v.x) - context_raw.gizmo_offset;
  266. }
  267. }
  268. if (context_raw.gizmo_started) {
  269. context_raw.gizmo_drag_last = context_raw.gizmo_drag;
  270. }
  271. ///if is_forge
  272. util_mesh_remove_merged();
  273. render_path_raytrace_ready = false;
  274. ///end
  275. }
  276. _input_occupied = (context_raw.translate_x || context_raw.translate_y || context_raw.translate_z || context_raw.scale_x || context_raw.scale_y || context_raw.scale_z || context_raw.rotate_x || context_raw.rotate_y || context_raw.rotate_z) && mouse_view_x() < base_w();
  277. }
  278. ///end