brush_output_node_ext.ts 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. type brush_output_node_t = {
  2. base?: logic_node_t;
  3. raw?: ui_node_t;
  4. };
  5. function brush_output_node_create_ext(n: brush_output_node_t) {
  6. context_raw.brush_output_node_inst = n;
  7. }
  8. function brush_output_node_parse_inputs(self: brush_output_node_t) {
  9. let last_mask: gpu_texture_t = context_raw.brush_mask_image;
  10. let last_stencil: gpu_texture_t = context_raw.brush_stencil_image;
  11. let input0: logic_node_value_t = logic_node_input_get(self.base.inputs[0]);
  12. let input1: logic_node_value_t = logic_node_input_get(self.base.inputs[1]);
  13. let input2: logic_node_value_t = logic_node_input_get(self.base.inputs[2]);
  14. let input3: logic_node_value_t = logic_node_input_get(self.base.inputs[3]);
  15. let input4: logic_node_value_t = logic_node_input_get(self.base.inputs[4]);
  16. let input5: logic_node_value_t = logic_node_input_get(self.base.inputs[5]);
  17. let input6: logic_node_value_t = logic_node_input_get(self.base.inputs[6]);
  18. context_raw.paint_vec = input0._vec4;
  19. context_raw.brush_nodes_radius = input1._f32;
  20. context_raw.brush_nodes_scale = input2._f32;
  21. context_raw.brush_nodes_angle = input3._f32;
  22. let opac: logic_node_value_t = input4; // Float or texture name
  23. if (opac == null) {
  24. opac = { _f32: 1.0 };
  25. }
  26. if (opac._str != null) { // string
  27. context_raw.brush_mask_image_is_alpha = ends_with(opac._str, ".a");
  28. opac._str = substring(opac._str, 0, string_last_index_of(opac._str, "."));
  29. context_raw.brush_nodes_opacity = 1.0;
  30. let index: i32 = array_index_of(project_asset_names, opac._str);
  31. let asset: asset_t = project_assets[index];
  32. context_raw.brush_mask_image = project_get_image(asset);
  33. }
  34. else {
  35. context_raw.brush_nodes_opacity = opac._f32;
  36. context_raw.brush_mask_image = null;
  37. }
  38. context_raw.brush_nodes_hardness = input5._f32;
  39. let stencil: logic_node_value_t = input6; // Float or texture name
  40. if (stencil == null) {
  41. stencil = { _f32: 1.0 };
  42. }
  43. if (stencil._str != null) { // string
  44. context_raw.brush_stencil_image_is_alpha = ends_with(stencil._str, ".a");
  45. stencil._str = substring(stencil._str, 0, string_last_index_of(stencil._str, "."));
  46. let index: i32 = array_index_of(project_asset_names, stencil._str);
  47. let asset: asset_t = project_assets[index];
  48. context_raw.brush_stencil_image = project_get_image(asset);
  49. }
  50. else {
  51. context_raw.brush_stencil_image = null;
  52. }
  53. if (last_mask != context_raw.brush_mask_image ||
  54. last_stencil != context_raw.brush_stencil_image) {
  55. make_material_parse_paint_material();
  56. }
  57. context_raw.brush_directional = self.raw.buttons[0].default_value[0] > 0.0;
  58. }
  59. function brush_output_node_run(self: brush_output_node_t, from: i32) {
  60. let left: f32 = 0.0;
  61. let right: f32 = 1.0;
  62. let top: f32 = 0.0;
  63. let bottom: f32 = 1.0;
  64. if (context_raw.paint2d) {
  65. left = 1.0;
  66. right = (context_raw.split_view ? 2.0 : 1.0) + ui_view2d_ww / base_w();
  67. }
  68. // Do not paint over floating toolbar
  69. if (context_is_floating_toolbar()) {
  70. let w: i32 = ui_toolbar_x() + ui_toolbar_w();
  71. left += w / sys_w();
  72. top += w / sys_h();
  73. }
  74. // First time init
  75. if (context_raw.last_paint_x < 0 || context_raw.last_paint_y < 0) {
  76. context_raw.last_paint_vec_x = context_raw.paint_vec.x;
  77. context_raw.last_paint_vec_y = context_raw.paint_vec.y;
  78. }
  79. // Paint bounds
  80. if (context_raw.paint_vec.x < left ||
  81. context_raw.paint_vec.x > right ||
  82. context_raw.paint_vec.y < top ||
  83. context_raw.paint_vec.y > bottom) {
  84. return;
  85. }
  86. // Do not paint over fill layer
  87. let fill_layer: bool = context_raw.layer.fill_layer != null &&
  88. context_raw.tool != workspace_tool_t.PICKER &&
  89. context_raw.tool != workspace_tool_t.MATERIAL &&
  90. context_raw.tool != workspace_tool_t.COLORID;
  91. if (fill_layer) {
  92. return;
  93. }
  94. // Do not paint over groups
  95. if (slot_layer_is_group(context_raw.layer)) {
  96. return;
  97. }
  98. if (!slot_layer_is_visible(context_raw.layer) && !context_raw.paint2d) {
  99. return;
  100. }
  101. if (ui_base_ui.is_hovered ||
  102. base_is_dragging ||
  103. base_is_resizing ||
  104. base_is_scrolling() ||
  105. base_is_combo_selected()) {
  106. return;
  107. }
  108. brush_output_paint(self);
  109. }
  110. function brush_output_paint(self: brush_output_node_t) {
  111. let down: bool = mouse_down() || pen_down();
  112. // Set color pick
  113. if (down && context_raw.tool == workspace_tool_t.COLORID && project_assets.length > 0) {
  114. context_raw.colorid_picked = true;
  115. ui_toolbar_handle.redraws = 1;
  116. }
  117. // Prevent painting the same spot
  118. let same_spot: bool = context_raw.paint_vec.x == context_raw.last_paint_x && context_raw.paint_vec.y == context_raw.last_paint_y;
  119. let lazy: bool = context_raw.tool == workspace_tool_t.BRUSH && context_raw.brush_lazy_radius > 0;
  120. if (down && (same_spot || lazy)) {
  121. context_raw.painted++;
  122. }
  123. else {
  124. context_raw.painted = 0;
  125. }
  126. context_raw.last_paint_x = context_raw.paint_vec.x;
  127. context_raw.last_paint_y = context_raw.paint_vec.y;
  128. if (context_raw.tool == workspace_tool_t.PARTICLE) {
  129. context_raw.painted = 0; // Always paint particles
  130. }
  131. if (context_raw.painted == 0) {
  132. brush_output_node_parse_inputs(self);
  133. }
  134. if (context_raw.painted <= 1) {
  135. context_raw.pdirty = 1;
  136. context_raw.rdirty = 2;
  137. }
  138. }
  139. // let brush_output_node_def: node_t = {
  140. // id: 0,
  141. // name: _tr("Brush Output"),
  142. // type: "brush_output_node",
  143. // x: 0,
  144. // y: 0,
  145. // color: 0xff4982a0,
  146. // inputs: [
  147. // {
  148. // id: 0,
  149. // node_id: 0,
  150. // name: _tr("Position"),
  151. // type: "VECTOR",
  152. // color: 0xff63c763,
  153. // default_value: f32_array_create_xyz(0.0, 0.0, 0.0),
  154. // min: 0.0,
  155. // max: 1.0,
  156. // precision: 100,
  157. // display: 0
  158. // },
  159. // {
  160. // id: 0,
  161. // node_id: 0,
  162. // name: _tr("Radius"),
  163. // type: "VALUE",
  164. // color: 0xffa1a1a1,
  165. // default_value: f32_array_create_x(1.0),
  166. // min: 0.0,
  167. // max: 1.0,
  168. // precision: 100,
  169. // display: 0
  170. // },
  171. // {
  172. // id: 0,
  173. // node_id: 0,
  174. // name: _tr("Scale"),
  175. // type: "VALUE",
  176. // color: 0xffa1a1a1,
  177. // default_value: f32_array_create_x(1.0),
  178. // min: 0.0,
  179. // max: 1.0,
  180. // precision: 100,
  181. // display: 0
  182. // },
  183. // {
  184. // id: 0,
  185. // node_id: 0,
  186. // name: _tr("Angle"),
  187. // type: "VALUE",
  188. // color: 0xffa1a1a1,
  189. // default_value: f32_array_create_x(0.0),
  190. // min: 0.0,
  191. // max: 1.0,
  192. // precision: 100,
  193. // display: 0
  194. // },
  195. // {
  196. // id: 0,
  197. // node_id: 0,
  198. // name: _tr("Opacity"),
  199. // type: "VALUE",
  200. // color: 0xffa1a1a1,
  201. // default_value: f32_array_create_x(1.0),
  202. // min: 0.0,
  203. // max: 1.0,
  204. // precision: 100,
  205. // display: 0
  206. // },
  207. // {
  208. // id: 0,
  209. // node_id: 0,
  210. // name: _tr("Hardness"),
  211. // type: "VALUE",
  212. // color: 0xffa1a1a1,
  213. // default_value: f32_array_create_x(1.0),
  214. // min: 0.0,
  215. // max: 1.0,
  216. // precision: 100,
  217. // display: 0
  218. // },
  219. // {
  220. // id: 0,
  221. // node_id: 0,
  222. // name: _tr("Stencil"),
  223. // type: "VALUE",
  224. // color: 0xffa1a1a1,
  225. // default_value: f32_array_create_x(1.0),
  226. // min: 0.0,
  227. // max: 1.0,
  228. // precision: 100,
  229. // display: 0
  230. // }
  231. // ],
  232. // outputs: [],
  233. // buttons: [
  234. // {
  235. // name: _tr("Directional"),
  236. // type: "BOOL",
  237. // output: 0,
  238. // default_value: f32_array_create_x(0),
  239. // data: null,
  240. // min: 0.0,
  241. // max: 1.0,
  242. // precision: 100,
  243. // height: 0
  244. // }
  245. // ],
  246. // width: 0
  247. // };