group_node.ts 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. let _nodes_material_nodes: ui_nodes_t;
  2. let _nodes_material_node: ui_node_t;
  3. let _nodes_material_sockets: ui_node_socket_t[];
  4. function group_node_init() {
  5. array_push(nodes_material_group, group_node_def);
  6. map_set(parser_material_node_vectors, "GROUP", group_node_vector);
  7. map_set(parser_material_node_values, "GROUP", group_node_value);
  8. map_set(ui_nodes_custom_buttons, "nodes_material_new_group_button", nodes_material_new_group_button);
  9. map_set(ui_nodes_custom_buttons, "nodes_material_group_input_button", nodes_material_group_input_button);
  10. map_set(ui_nodes_custom_buttons, "nodes_material_group_output_button", nodes_material_group_output_button);
  11. }
  12. function group_node_vector(node: ui_node_t, socket: ui_node_socket_t): string {
  13. return parser_material_parse_group(node, socket);
  14. }
  15. function group_node_value(node: ui_node_t, socket: ui_node_socket_t): string {
  16. return parser_material_parse_group(node, socket);
  17. }
  18. function nodes_material_new_group_button(node_id: i32) {
  19. let node: ui_node_t = ui_get_node(ui_nodes_get_canvas(true).nodes, node_id);
  20. if (node.name == "New Group") {
  21. for (let i: i32 = 1; i < 999; ++i) {
  22. node.name = tr("Group") + " " + i;
  23. let found: bool = false;
  24. for (let i: i32 = 0; i < project_material_groups.length; ++i) {
  25. let g: node_group_t = project_material_groups[i];
  26. let cname: string = g.canvas.name;
  27. if (cname == node.name) {
  28. found = true;
  29. break;
  30. }
  31. }
  32. if (!found) {
  33. break;
  34. }
  35. }
  36. let canvas: ui_node_canvas_t = {
  37. name : node.name,
  38. nodes : [
  39. {
  40. id : 0,
  41. name : _tr("Group Input"),
  42. type : "GROUP_INPUT",
  43. x : 50,
  44. y : 200,
  45. color : 0xff448c6d,
  46. inputs : [],
  47. outputs : [],
  48. buttons : [ {name : "nodes_material_group_input_button", type : "CUSTOM", height : 1} ],
  49. width : 0,
  50. flags : 0
  51. },
  52. {
  53. id : 1,
  54. name : _tr("Group Output"),
  55. type : "GROUP_OUTPUT",
  56. x : 450,
  57. y : 200,
  58. color : 0xff448c6d,
  59. inputs : [],
  60. outputs : [],
  61. buttons : [ {name : "nodes_material_group_output_button", type : "CUSTOM", height : 1} ],
  62. width : 0,
  63. flags : 0
  64. }
  65. ],
  66. links : []
  67. };
  68. let ng: node_group_t = {canvas : canvas, nodes : ui_nodes_create()};
  69. array_push(project_material_groups, ng);
  70. }
  71. let group: node_group_t = null;
  72. for (let i: i32 = 0; i < project_material_groups.length; ++i) {
  73. let g: node_group_t = project_material_groups[i];
  74. let cname: string = g.canvas.name;
  75. if (cname == node.name) {
  76. group = g;
  77. break;
  78. }
  79. }
  80. if (ui_button(tr("Nodes"))) {
  81. array_push(ui_nodes_group_stack, group);
  82. }
  83. }
  84. function nodes_material_group_input_button(node_id: i32) {
  85. let nodes: ui_nodes_t = ui_nodes_get_nodes();
  86. let node: ui_node_t = ui_get_node(ui_nodes_get_canvas(true).nodes, node_id);
  87. nodes_material_add_socket_button(nodes, node, node.outputs);
  88. }
  89. function nodes_material_group_output_button(node_id: i32) {
  90. let nodes: ui_nodes_t = ui_nodes_get_nodes();
  91. let node: ui_node_t = ui_get_node(ui_nodes_get_canvas(true).nodes, node_id);
  92. nodes_material_add_socket_button(nodes, node, node.inputs);
  93. }
  94. function nodes_material_add_socket_button(nodes: ui_nodes_t, node: ui_node_t, sockets: ui_node_socket_t[]) {
  95. if (ui_button(tr("Add"))) {
  96. _nodes_material_nodes = nodes;
  97. _nodes_material_node = node;
  98. _nodes_material_sockets = sockets;
  99. ui_menu_draw(function() {
  100. let nodes: ui_nodes_t = _nodes_material_nodes;
  101. let node: ui_node_t = _nodes_material_node;
  102. let sockets: ui_node_socket_t[] = _nodes_material_sockets;
  103. let group_stack: node_group_t[] = ui_nodes_group_stack;
  104. let c: ui_node_canvas_t = group_stack[group_stack.length - 1].canvas;
  105. if (ui_menu_button(tr("RGBA"))) {
  106. array_push(sockets, nodes_material_create_socket(nodes, node, null, "RGBA", c));
  107. nodes_material_sync_sockets(node);
  108. }
  109. if (ui_menu_button(tr("Vector"))) {
  110. array_push(sockets, nodes_material_create_socket(nodes, node, null, "VECTOR", c));
  111. nodes_material_sync_sockets(node);
  112. }
  113. if (ui_menu_button(tr("Value"))) {
  114. array_push(sockets, nodes_material_create_socket(nodes, node, null, "VALUE", c));
  115. nodes_material_sync_sockets(node);
  116. }
  117. });
  118. }
  119. }
  120. function nodes_material_sync_sockets(node: ui_node_t) {
  121. let group_stack: node_group_t[] = ui_nodes_group_stack;
  122. let c: ui_node_canvas_t = group_stack[group_stack.length - 1].canvas;
  123. for (let i: i32 = 0; i < project_materials.length; ++i) {
  124. let m: slot_material_t = project_materials[i];
  125. nodes_material_sync_group_sockets(m.canvas, c.name, node);
  126. }
  127. for (let i: i32 = 0; i < project_material_groups.length; ++i) {
  128. let g: node_group_t = project_material_groups[i];
  129. nodes_material_sync_group_sockets(g.canvas, c.name, node);
  130. }
  131. }
  132. function nodes_material_sync_group_sockets(canvas: ui_node_canvas_t, group_name: string, node: ui_node_t) {
  133. for (let i: i32 = 0; i < canvas.nodes.length; ++i) {
  134. let n: ui_node_t = canvas.nodes[i];
  135. if (n.type == "GROUP" && n.name == group_name) {
  136. let is_inputs: bool = node.name == "Group Input";
  137. let old_sockets: ui_node_socket_t[] = is_inputs ? n.inputs : n.outputs;
  138. let sockets: ui_node_socket_t[] = util_clone_canvas_sockets(is_inputs ? node.outputs : node.inputs);
  139. if (is_inputs) {
  140. n.inputs = sockets;
  141. }
  142. else {
  143. n.outputs = sockets;
  144. }
  145. for (let i: i32 = 0; i < sockets.length; ++i) {
  146. let s: ui_node_socket_t = sockets[i];
  147. s.node_id = n.id;
  148. }
  149. let num_sockets: i32 = sockets.length < old_sockets.length ? sockets.length : old_sockets.length;
  150. for (let i: i32 = 0; i < num_sockets; ++i) {
  151. if (sockets[i].type == old_sockets[i].type) {
  152. sockets[i].default_value = old_sockets[i].default_value;
  153. }
  154. }
  155. }
  156. }
  157. }
  158. function nodes_material_get_socket_color(type: string): i32 {
  159. return type == "RGBA" ? 0xffc7c729 : type == "VECTOR" ? 0xff6363c7 : 0xffa1a1a1;
  160. }
  161. function nodes_material_get_socket_default_value(type: string): f32_array_t {
  162. return type == "RGBA" ? f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0) : type == "VECTOR" ? f32_array_create_xyz(0.0, 0.0, 0.0) : f32_array_create_x(0.0);
  163. }
  164. function nodes_material_get_socket_name(type: string): string {
  165. return type == "RGBA" ? _tr("Color") : type == "VECTOR" ? _tr("Vector") : _tr("Value");
  166. }
  167. function nodes_material_create_socket(nodes: ui_nodes_t, node: ui_node_t, name: string, type: string, canvas: ui_node_canvas_t, min: f32 = 0.0, max: f32 = 1.0,
  168. default_value: any = null): ui_node_socket_t {
  169. let soc: ui_node_socket_t = {
  170. id : ui_get_socket_id(canvas.nodes),
  171. node_id : node.id,
  172. name : name == null ? nodes_material_get_socket_name(type) : name,
  173. type : type,
  174. color : nodes_material_get_socket_color(type),
  175. default_value : default_value == null ? nodes_material_get_socket_default_value(type) : default_value,
  176. min : min,
  177. max : max,
  178. precision : 100
  179. };
  180. return soc;
  181. }
  182. let group_node_def: ui_node_t = {
  183. id : 0,
  184. name : _tr("New Group"),
  185. type : "GROUP",
  186. x : 0,
  187. y : 0,
  188. color : 0xffb34f5a,
  189. inputs : [],
  190. outputs : [],
  191. buttons : [ {
  192. name : "nodes_material_new_group_button",
  193. type : "CUSTOM",
  194. output : -1,
  195. default_value : f32_array_create_x(0),
  196. data : null,
  197. min : 0.0,
  198. max : 1.0,
  199. precision : 100,
  200. height : 1
  201. } ],
  202. width : 0,
  203. flags : 0
  204. };