diff --git a/armorlab/sources/base_ext.ts b/armorlab/sources/base_ext.ts index 9966a1a2..6034a726 100644 --- a/armorlab/sources/base_ext.ts +++ b/armorlab/sources/base_ext.ts @@ -4,9 +4,7 @@ function base_ext_init() { } function base_ext_render() { - if (context_raw.frame == 2) { - app_notify_on_next_frame(function () { app_notify_on_next_frame(function () { tab_meshes_set_default_mesh(".Sphere"); @@ -14,86 +12,3 @@ function base_ext_render() { }); } } - -function base_ext_flatten(height_to_normal: bool = false, layers: slot_layer_t[] = null): slot_layer_t { - let texpaint: image_t = brush_output_node_inst.texpaint; - let texpaint_nor: image_t = brush_output_node_inst.texpaint_nor; - let texpaint_pack: image_t = brush_output_node_inst.texpaint_pack; - - let nodes: ui_nodes_t = ui_nodes_get_nodes(); - let canvas: ui_node_canvas_t = ui_nodes_get_canvas(true); - if (nodes.nodes_selected_id.length > 0) { - let node: ui_node_t = ui_get_node(canvas.nodes, nodes.nodes_selected_id[0]); - let brush_node: logic_node_ext_t = parser_logic_get_logic_node(node); - if (brush_node != null && logic_node_get_cached_image(brush_node.base) != null) { - texpaint = logic_node_get_cached_image(brush_node.base); - let texpaint_nor_rt: render_target_t = map_get(render_path_render_targets, "texpaint_nor_empty"); - let texpaint_pack_rt: render_target_t = map_get(render_path_render_targets, "texpaint_pack_empty"); - texpaint_nor = texpaint_nor_rt._image; - texpaint_pack = texpaint_pack_rt._image; - } - } - - let l: slot_layer_t = { texpaint: texpaint, texpaint_nor: texpaint_nor, texpaint_pack: texpaint_pack }; - return l; -} - -function base_ext_on_layers_resized() { - image_unload(brush_output_node_inst.texpaint); - let texpaint_rt: render_target_t = map_get(render_path_render_targets, "texpaint"); - brush_output_node_inst.texpaint = texpaint_rt._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y()); - - image_unload(brush_output_node_inst.texpaint_nor); - let texpaint_nor_rt: render_target_t = map_get(render_path_render_targets, "texpaint_nor"); - brush_output_node_inst.texpaint_nor = texpaint_nor_rt._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y()); - - image_unload(brush_output_node_inst.texpaint_pack); - let texpaint_pack_rt: render_target_t = map_get(render_path_render_targets, "texpaint_pack"); - brush_output_node_inst.texpaint_pack = texpaint_pack_rt._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y()); - - if (inpaint_node_image != null) { - image_unload(inpaint_node_image); - inpaint_node_image = null; - image_unload(inpaint_node_mask); - inpaint_node_mask = null; - inpaint_node_init(); - } - - if (photo_to_pbr_node_images != null) { - for (let i: i32 = 0; i < photo_to_pbr_node_images.length; ++i) { - let image: image_t = photo_to_pbr_node_images[i]; - image_unload(image); - } - photo_to_pbr_node_images = null; - photo_to_pbr_node_init(); - } - - if (tiling_node_image != null) { - image_unload(tiling_node_image); - tiling_node_image = null; - tiling_node_init(); - } - - let texpaint_blend0_rt: render_target_t = map_get(render_path_render_targets, "texpaint_blend0"); - image_unload(texpaint_blend0_rt._image); - texpaint_blend0_rt._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8); - - let texpaint_blend1_rt: render_target_t = map_get(render_path_render_targets, "texpaint_blend1"); - image_unload(texpaint_blend1_rt._image); - texpaint_blend1_rt._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8); - - if (map_get(render_path_render_targets, "texpaint_node") != null) { - map_delete(render_path_render_targets, "texpaint_node"); - } - if (map_get(render_path_render_targets, "texpaint_node_target") != null) { - map_delete(render_path_render_targets, "texpaint_node_target"); - } - - app_notify_on_next_frame(function () { - base_init_layers(); - }); - - ///if (arm_direct3d12 || arm_vulkan || arm_metal) - render_path_raytrace_ready = false; - ///end -} diff --git a/armorlab/sources/context_ext.ts b/armorlab/sources/context_ext.ts new file mode 100644 index 00000000..5d778e41 --- /dev/null +++ b/armorlab/sources/context_ext.ts @@ -0,0 +1,23 @@ + +function context_ext_init(c: context_t) { + c.tool = workspace_tool_t.ERASER; + c.color_picker_previous_tool = workspace_tool_t.ERASER; + c.brush_radius = 0.25; + c.brush_radius_handle.value = 0.25; + c.brush_hardness = 0.8; + + c.coords = vec4_create(); + c.start_x = 0.0; + c.start_y = 0.0; + + c.lock_begin = false; + c.lock_x = false; + c.lock_y = false; + c.lock_start_x = 0.0; + c.lock_start_y = 0.0; + c.registered = false; +} + +function context_ext_select_paint_object(o: mesh_object_t) { + context_raw.paint_object = o; +} diff --git a/armorlab/sources/layers_ext.ts b/armorlab/sources/layers_ext.ts new file mode 100644 index 00000000..863b0675 --- /dev/null +++ b/armorlab/sources/layers_ext.ts @@ -0,0 +1,83 @@ + +function layers_ext_flatten(height_to_normal: bool = false, layers: slot_layer_t[] = null): slot_layer_t { + let texpaint: image_t = brush_output_node_inst.texpaint; + let texpaint_nor: image_t = brush_output_node_inst.texpaint_nor; + let texpaint_pack: image_t = brush_output_node_inst.texpaint_pack; + + let nodes: ui_nodes_t = ui_nodes_get_nodes(); + let canvas: ui_node_canvas_t = ui_nodes_get_canvas(true); + if (nodes.nodes_selected_id.length > 0) { + let node: ui_node_t = ui_get_node(canvas.nodes, nodes.nodes_selected_id[0]); + let brush_node: logic_node_ext_t = parser_logic_get_logic_node(node); + if (brush_node != null && logic_node_get_cached_image(brush_node.base) != null) { + texpaint = logic_node_get_cached_image(brush_node.base); + let texpaint_nor_rt: render_target_t = map_get(render_path_render_targets, "texpaint_nor_empty"); + let texpaint_pack_rt: render_target_t = map_get(render_path_render_targets, "texpaint_pack_empty"); + texpaint_nor = texpaint_nor_rt._image; + texpaint_pack = texpaint_pack_rt._image; + } + } + + let l: slot_layer_t = { texpaint: texpaint, texpaint_nor: texpaint_nor, texpaint_pack: texpaint_pack }; + return l; +} + +function layers_ext_on_resized() { + image_unload(brush_output_node_inst.texpaint); + let texpaint_rt: render_target_t = map_get(render_path_render_targets, "texpaint"); + brush_output_node_inst.texpaint = texpaint_rt._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y()); + + image_unload(brush_output_node_inst.texpaint_nor); + let texpaint_nor_rt: render_target_t = map_get(render_path_render_targets, "texpaint_nor"); + brush_output_node_inst.texpaint_nor = texpaint_nor_rt._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y()); + + image_unload(brush_output_node_inst.texpaint_pack); + let texpaint_pack_rt: render_target_t = map_get(render_path_render_targets, "texpaint_pack"); + brush_output_node_inst.texpaint_pack = texpaint_pack_rt._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y()); + + if (inpaint_node_image != null) { + image_unload(inpaint_node_image); + inpaint_node_image = null; + image_unload(inpaint_node_mask); + inpaint_node_mask = null; + inpaint_node_init(); + } + + if (photo_to_pbr_node_images != null) { + for (let i: i32 = 0; i < photo_to_pbr_node_images.length; ++i) { + let image: image_t = photo_to_pbr_node_images[i]; + image_unload(image); + } + photo_to_pbr_node_images = null; + photo_to_pbr_node_init(); + } + + if (tiling_node_image != null) { + image_unload(tiling_node_image); + tiling_node_image = null; + tiling_node_init(); + } + + let texpaint_blend0_rt: render_target_t = map_get(render_path_render_targets, "texpaint_blend0"); + image_unload(texpaint_blend0_rt._image); + texpaint_blend0_rt._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8); + + let texpaint_blend1_rt: render_target_t = map_get(render_path_render_targets, "texpaint_blend1"); + image_unload(texpaint_blend1_rt._image); + texpaint_blend1_rt._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8); + + if (map_get(render_path_render_targets, "texpaint_node") != null) { + map_delete(render_path_render_targets, "texpaint_node"); + } + if (map_get(render_path_render_targets, "texpaint_node_target") != null) { + map_delete(render_path_render_targets, "texpaint_node_target"); + } + + app_notify_on_next_frame(function () { + layers_init(); + }); + + ///if (arm_direct3d12 || arm_vulkan || arm_metal) + render_path_raytrace_ready = false; + ///end +} diff --git a/armorlab/sources/nodes/brush_output_node.ts b/armorlab/sources/nodes/brush_output_node.ts index 33c4cc7a..de5c2c98 100644 --- a/armorlab/sources/nodes/brush_output_node.ts +++ b/armorlab/sources/nodes/brush_output_node.ts @@ -65,9 +65,126 @@ function brush_output_node_create(raw: ui_node_t, args: f32_array_t): brush_outp } brush_output_node_inst = n; + + context_raw.run_brush = brush_output_node_run; + context_raw.parse_brush_inputs = brush_output_node_parse_inputs; + return n; } function brush_output_node_get_as_image(self: brush_output_node_t, from: i32): image_t { return logic_node_input_get_as_image(self.base.inputs[from]); } + +function brush_output_node_run(from: i32) { + let left: f32 = 0.0; + let right: f32 = 1.0; + + // First time init + if (context_raw.last_paint_x < 0 || context_raw.last_paint_y < 0) { + context_raw.last_paint_vec_x = context_raw.paint_vec.x; + context_raw.last_paint_vec_y = context_raw.paint_vec.y; + } + + let nodes: ui_nodes_t = ui_nodes_get_nodes(); + let canvas: ui_node_canvas_t = ui_nodes_get_canvas(true); + let inpaint: bool = nodes.nodes_selected_id.length > 0 && ui_get_node(canvas.nodes, nodes.nodes_selected_id[0]).type == "inpaint_node"; + + // Paint bounds + if (inpaint && + context_raw.paint_vec.x > left && + context_raw.paint_vec.x < right && + context_raw.paint_vec.y > 0 && + context_raw.paint_vec.y < 1 && + !base_is_dragging && + !base_is_resizing && + !base_is_scrolling() && + !base_is_combo_selected()) { + + let down: bool = mouse_down() || pen_down(); + + // Prevent painting the same spot + let same_spot: bool = context_raw.paint_vec.x == context_raw.last_paint_x && context_raw.paint_vec.y == context_raw.last_paint_y; + if (down && same_spot) { + context_raw.painted++; + } + else { + context_raw.painted = 0; + } + context_raw.last_paint_x = context_raw.paint_vec.x; + context_raw.last_paint_y = context_raw.paint_vec.y; + + if (context_raw.painted == 0) { + brush_output_node_parse_inputs(); + } + + if (context_raw.painted <= 1) { + context_raw.pdirty = 1; + context_raw.rdirty = 2; + } + } +} + +function brush_output_node_parse_inputs() { + if (!context_raw.registered) { + context_raw.registered = true; + app_notify_on_update(brush_output_node_update); + } + + context_raw.paint_vec = context_raw.coords; +} + +function brush_output_node_update() { + let paint_x: f32 = mouse_view_x() / app_w(); + let paint_y: f32 = mouse_view_y() / app_h(); + if (mouse_started()) { + context_raw.start_x = mouse_view_x() / app_w(); + context_raw.start_y = mouse_view_y() / app_h(); + } + + if (pen_down()) { + paint_x = pen_view_x() / app_w(); + paint_y = pen_view_y() / app_h(); + } + if (pen_started()) { + context_raw.start_x = pen_view_x() / app_w(); + context_raw.start_y = pen_view_y() / app_h(); + } + + if (operator_shortcut(map_get(config_keymap, "brush_ruler") + "+" + map_get(config_keymap, "action_paint"), shortcut_type_t.DOWN)) { + if (context_raw.lock_x) { + paint_x = context_raw.start_x; + } + if (context_raw.lock_y) { + paint_y = context_raw.start_y; + } + } + + context_raw.coords.x = paint_x; + context_raw.coords.y = paint_y; + + if (context_raw.lock_begin) { + let dx: i32 = math_abs(context_raw.lock_start_x - mouse_view_x()); + let dy: i32 = math_abs(context_raw.lock_start_y - mouse_view_y()); + if (dx > 1 || dy > 1) { + context_raw.lock_begin = false; + if (dx > dy) { + context_raw.lock_y = true; + } + else { + context_raw.lock_x = true; + } + } + } + + if (keyboard_started(map_get(config_keymap, "brush_ruler"))) { + context_raw.lock_start_x = mouse_view_x(); + context_raw.lock_start_y = mouse_view_y(); + context_raw.lock_begin = true; + } + else if (keyboard_released(map_get(config_keymap, "brush_ruler"))) { + context_raw.lock_x = context_raw.lock_y = context_raw.lock_begin = false; + } + + brush_output_node_parse_inputs(); +} diff --git a/armorlab/sources/ui_nodes_ext.ts b/armorlab/sources/ui_nodes_ext.ts index 3c802f0f..91ad765f 100644 --- a/armorlab/sources/ui_nodes_ext.ts +++ b/armorlab/sources/ui_nodes_ext.ts @@ -120,7 +120,7 @@ function ui_nodes_ext_draw_buttons(ew: f32, start_y: f32) { ///end if (base_res_handle.changed) { - base_on_layers_resized(); + layers_on_resized(); } ui._x += ew + 3; ui._y = 2 + start_y; diff --git a/armorpaint/sources/base_ext.ts b/armorpaint/sources/base_ext.ts index beb0591c..1aaecd97 100644 --- a/armorpaint/sources/base_ext.ts +++ b/armorpaint/sources/base_ext.ts @@ -3,7 +3,6 @@ function base_ext_init() { } function base_ext_render() { - if (context_raw.frame == 2) { util_render_make_material_preview(); ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; @@ -28,188 +27,3 @@ function base_ext_render() { ///end } } - -function base_ext_flatten(height_to_normal: bool = false, layers: slot_layer_t[] = null): slot_layer_t { - if (layers == null) { - layers = project_layers; - } - base_make_temp_img(); - base_make_export_img(); - - let empty_rt: render_target_t = map_get(render_path_render_targets, "empty_white"); - let empty: image_t = empty_rt._image; - - // Clear export layer - g4_begin(base_expa); - g4_clear(color_from_floats(0.0, 0.0, 0.0, 0.0)); - g4_end(); - g4_begin(base_expb); - g4_clear(color_from_floats(0.5, 0.5, 1.0, 0.0)); - g4_end(); - g4_begin(base_expc); - g4_clear(color_from_floats(1.0, 0.0, 0.0, 0.0)); - g4_end(); - - // Flatten layers - for (let i: i32 = 0; i < layers.length; ++i) { - let l1: slot_layer_t = layers[i]; - if (!slot_layer_is_visible(l1)) { - continue; - } - if (!slot_layer_is_layer(l1)) { - continue; - } - - let mask: image_t = empty; - let l1masks: slot_layer_t[] = slot_layer_get_masks(l1); - if (l1masks != null) { - if (l1masks.length > 1) { - base_make_temp_mask_img(); - g2_begin(pipes_temp_mask_image); - g2_clear(0x00000000); - g2_end(); - let l1: slot_layer_t = { texpaint: pipes_temp_mask_image }; - for (let i: i32 = 0; i < l1masks.length; ++i) { - base_merge_layer(l1, l1masks[i]); - } - mask = pipes_temp_mask_image; - } - else { - mask = l1masks[0].texpaint; - } - } - - if (l1.paint_base) { - g2_begin(base_temp_image); // Copy to temp - g2_set_pipeline(pipes_copy); - g2_draw_image(base_expa, 0, 0); - g2_set_pipeline(null); - g2_end(); - - g4_begin(base_expa); - g4_set_pipeline(pipes_merge); - g4_set_tex(pipes_tex0, l1.texpaint); - g4_set_tex(pipes_tex1, empty); - g4_set_tex(pipes_texmask, mask); - g4_set_tex(pipes_texa, base_temp_image); - g4_set_float(pipes_opac, slot_layer_get_opacity(l1)); - g4_set_int(pipes_blending, layers.length > 1 ? l1.blending : 0); - g4_set_vertex_buffer(const_data_screen_aligned_vb); - g4_set_index_buffer(const_data_screen_aligned_ib); - g4_draw(); - g4_end(); - } - - if (l1.paint_nor) { - g2_begin(base_temp_image); - g2_set_pipeline(pipes_copy); - g2_draw_image(base_expb, 0, 0); - g2_set_pipeline(null); - g2_end(); - - g4_begin(base_expb); - g4_set_pipeline(pipes_merge); - g4_set_tex(pipes_tex0, l1.texpaint); - g4_set_tex(pipes_tex1, l1.texpaint_nor); - g4_set_tex(pipes_texmask, mask); - g4_set_tex(pipes_texa, base_temp_image); - g4_set_float(pipes_opac, slot_layer_get_opacity(l1)); - g4_set_int(pipes_blending, l1.paint_nor_blend ? -2 : -1); - g4_set_vertex_buffer(const_data_screen_aligned_vb); - g4_set_index_buffer(const_data_screen_aligned_ib); - g4_draw(); - g4_end(); - } - - if (l1.paint_occ || l1.paint_rough || l1.paint_met || l1.paint_height) { - g2_begin(base_temp_image); - g2_set_pipeline(pipes_copy); - g2_draw_image(base_expc, 0, 0); - g2_set_pipeline(null); - g2_end(); - - if (l1.paint_occ && l1.paint_rough && l1.paint_met && l1.paint_height) { - base_commands_merge_pack(pipes_merge, base_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask, l1.paint_height_blend ? -3 : -1); - } - else { - if (l1.paint_occ) { - base_commands_merge_pack(pipes_merge_r, base_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); - } - if (l1.paint_rough) { - base_commands_merge_pack(pipes_merge_g, base_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); - } - if (l1.paint_met) { - base_commands_merge_pack(pipes_merge_b, base_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); - } - } - } - } - - ///if arm_metal - // Flush command list - g2_begin(base_expa); - g2_end(); - g2_begin(base_expb); - g2_end(); - g2_begin(base_expc); - g2_end(); - ///end - - let l0: slot_layer_t = { - texpaint: base_expa, - texpaint_nor: base_expb, - texpaint_pack: base_expc - }; - - // Merge height map into normal map - if (height_to_normal && make_material_height_used) { - - g2_begin(base_temp_image); - g2_set_pipeline(pipes_copy); - g2_draw_image(l0.texpaint_nor, 0, 0); - g2_set_pipeline(null); - g2_end(); - - g4_begin(l0.texpaint_nor); - g4_set_pipeline(pipes_merge); - g4_set_tex(pipes_tex0, base_temp_image); - g4_set_tex(pipes_tex1, l0.texpaint_pack); - g4_set_tex(pipes_texmask, empty); - g4_set_tex(pipes_texa, empty); - g4_set_float(pipes_opac, 1.0); - g4_set_int(pipes_blending, -4); - g4_set_vertex_buffer(const_data_screen_aligned_vb); - g4_set_index_buffer(const_data_screen_aligned_ib); - g4_draw(); - g4_end(); - } - - return l0; -} - -function base_ext_on_layers_resized() { - app_notify_on_init(function () { - base_resize_layers(); - let _layer: slot_layer_t = context_raw.layer; - let _material: slot_material_t = context_raw.material; - for (let i: i32 = 0; i < project_layers.length; ++i) { - let l: slot_layer_t = project_layers[i]; - if (l.fill_layer != null) { - context_raw.layer = l; - context_raw.material = l.fill_layer; - base_update_fill_layer(); - } - } - context_raw.layer = _layer; - context_raw.material = _material; - make_material_parse_paint_material(); - }); - util_uv_uvmap = null; - util_uv_uvmap_cached = false; - util_uv_trianglemap = null; - util_uv_trianglemap_cached = false; - util_uv_dilatemap_cached = false; - ///if (arm_direct3d12 || arm_vulkan || arm_metal) - render_path_raytrace_ready = false; - ///end -} diff --git a/armorpaint/sources/context_ext.ts b/armorpaint/sources/context_ext.ts new file mode 100644 index 00000000..a509397a --- /dev/null +++ b/armorpaint/sources/context_ext.ts @@ -0,0 +1,32 @@ + +function context_ext_init(c: context_t) { + c.tool = workspace_tool_t.BRUSH; + c.color_picker_previous_tool = workspace_tool_t.BRUSH; + c.brush_radius = 0.5; + c.brush_radius_handle.value = 0.5; + c.brush_hardness = 0.8; + ///if is_sculpt + c.brush_hardness = 0.05; + ///end +} + +function context_ext_select_paint_object(o: mesh_object_t) { + ui_header_handle.redraws = 2; + for (let i: i32 = 0; i < project_paint_objects.length; ++i) { + let p: mesh_object_t = project_paint_objects[i]; + p.skip_context = "paint"; + } + context_raw.paint_object = o; + + let mask: i32 = slot_layer_get_object_mask(context_raw.layer); + if (context_layer_filter_used()) { + mask = context_raw.layer_filter; + } + + if (context_raw.merged_object == null || mask > 0) { + context_raw.paint_object.skip_context = ""; + } + util_uv_uvmap_cached = false; + util_uv_trianglemap_cached = false; + util_uv_dilatemap_cached = false; +} diff --git a/armorpaint/sources/layers_ext.ts b/armorpaint/sources/layers_ext.ts new file mode 100644 index 00000000..ad01b767 --- /dev/null +++ b/armorpaint/sources/layers_ext.ts @@ -0,0 +1,185 @@ + +function layers_ext_flatten(height_to_normal: bool = false, layers: slot_layer_t[] = null): slot_layer_t { + if (layers == null) { + layers = project_layers; + } + layers_make_temp_img(); + layers_make_export_img(); + + let empty_rt: render_target_t = map_get(render_path_render_targets, "empty_white"); + let empty: image_t = empty_rt._image; + + // Clear export layer + g4_begin(layers_expa); + g4_clear(color_from_floats(0.0, 0.0, 0.0, 0.0)); + g4_end(); + g4_begin(layers_expb); + g4_clear(color_from_floats(0.5, 0.5, 1.0, 0.0)); + g4_end(); + g4_begin(layers_expc); + g4_clear(color_from_floats(1.0, 0.0, 0.0, 0.0)); + g4_end(); + + // Flatten layers + for (let i: i32 = 0; i < layers.length; ++i) { + let l1: slot_layer_t = layers[i]; + if (!slot_layer_is_visible(l1)) { + continue; + } + if (!slot_layer_is_layer(l1)) { + continue; + } + + let mask: image_t = empty; + let l1masks: slot_layer_t[] = slot_layer_get_masks(l1); + if (l1masks != null) { + if (l1masks.length > 1) { + layers_make_temp_mask_img(); + g2_begin(pipes_temp_mask_image); + g2_clear(0x00000000); + g2_end(); + let l1: slot_layer_t = { texpaint: pipes_temp_mask_image }; + for (let i: i32 = 0; i < l1masks.length; ++i) { + layers_merge_layer(l1, l1masks[i]); + } + mask = pipes_temp_mask_image; + } + else { + mask = l1masks[0].texpaint; + } + } + + if (l1.paint_base) { + g2_begin(layers_temp_image); // Copy to temp + g2_set_pipeline(pipes_copy); + g2_draw_image(layers_expa, 0, 0); + g2_set_pipeline(null); + g2_end(); + + g4_begin(layers_expa); + g4_set_pipeline(pipes_merge); + g4_set_tex(pipes_tex0, l1.texpaint); + g4_set_tex(pipes_tex1, empty); + g4_set_tex(pipes_texmask, mask); + g4_set_tex(pipes_texa, layers_temp_image); + g4_set_float(pipes_opac, slot_layer_get_opacity(l1)); + g4_set_int(pipes_blending, layers.length > 1 ? l1.blending : 0); + g4_set_vertex_buffer(const_data_screen_aligned_vb); + g4_set_index_buffer(const_data_screen_aligned_ib); + g4_draw(); + g4_end(); + } + + if (l1.paint_nor) { + g2_begin(layers_temp_image); + g2_set_pipeline(pipes_copy); + g2_draw_image(layers_expb, 0, 0); + g2_set_pipeline(null); + g2_end(); + + g4_begin(layers_expb); + g4_set_pipeline(pipes_merge); + g4_set_tex(pipes_tex0, l1.texpaint); + g4_set_tex(pipes_tex1, l1.texpaint_nor); + g4_set_tex(pipes_texmask, mask); + g4_set_tex(pipes_texa, layers_temp_image); + g4_set_float(pipes_opac, slot_layer_get_opacity(l1)); + g4_set_int(pipes_blending, l1.paint_nor_blend ? -2 : -1); + g4_set_vertex_buffer(const_data_screen_aligned_vb); + g4_set_index_buffer(const_data_screen_aligned_ib); + g4_draw(); + g4_end(); + } + + if (l1.paint_occ || l1.paint_rough || l1.paint_met || l1.paint_height) { + g2_begin(layers_temp_image); + g2_set_pipeline(pipes_copy); + g2_draw_image(layers_expc, 0, 0); + g2_set_pipeline(null); + g2_end(); + + if (l1.paint_occ && l1.paint_rough && l1.paint_met && l1.paint_height) { + layers_commands_merge_pack(pipes_merge, layers_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask, l1.paint_height_blend ? -3 : -1); + } + else { + if (l1.paint_occ) { + layers_commands_merge_pack(pipes_merge_r, layers_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); + } + if (l1.paint_rough) { + layers_commands_merge_pack(pipes_merge_g, layers_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); + } + if (l1.paint_met) { + layers_commands_merge_pack(pipes_merge_b, layers_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); + } + } + } + } + + ///if arm_metal + // Flush command list + g2_begin(layers_expa); + g2_end(); + g2_begin(layers_expb); + g2_end(); + g2_begin(layers_expc); + g2_end(); + ///end + + let l0: slot_layer_t = { + texpaint: layers_expa, + texpaint_nor: layers_expb, + texpaint_pack: layers_expc + }; + + // Merge height map into normal map + if (height_to_normal && make_material_height_used) { + + g2_begin(layers_temp_image); + g2_set_pipeline(pipes_copy); + g2_draw_image(l0.texpaint_nor, 0, 0); + g2_set_pipeline(null); + g2_end(); + + g4_begin(l0.texpaint_nor); + g4_set_pipeline(pipes_merge); + g4_set_tex(pipes_tex0, layers_temp_image); + g4_set_tex(pipes_tex1, l0.texpaint_pack); + g4_set_tex(pipes_texmask, empty); + g4_set_tex(pipes_texa, empty); + g4_set_float(pipes_opac, 1.0); + g4_set_int(pipes_blending, -4); + g4_set_vertex_buffer(const_data_screen_aligned_vb); + g4_set_index_buffer(const_data_screen_aligned_ib); + g4_draw(); + g4_end(); + } + + return l0; +} + +function layers_ext_on_resized() { + app_notify_on_init(function () { + layers_resize(); + let _layer: slot_layer_t = context_raw.layer; + let _material: slot_material_t = context_raw.material; + for (let i: i32 = 0; i < project_layers.length; ++i) { + let l: slot_layer_t = project_layers[i]; + if (l.fill_layer != null) { + context_raw.layer = l; + context_raw.material = l.fill_layer; + layers_update_fill_layer(); + } + } + context_raw.layer = _layer; + context_raw.material = _material; + make_material_parse_paint_material(); + }); + util_uv_uvmap = null; + util_uv_uvmap_cached = false; + util_uv_trianglemap = null; + util_uv_trianglemap_cached = false; + util_uv_dilatemap_cached = false; + ///if (arm_direct3d12 || arm_vulkan || arm_metal) + render_path_raytrace_ready = false; + ///end +} diff --git a/armorpaint/sources/render_path_paint.ts b/armorpaint/sources/render_path_paint.ts index 289ca4e9..0d5823a3 100644 --- a/armorpaint/sources/render_path_paint.ts +++ b/armorpaint/sources/render_path_paint.ts @@ -886,7 +886,7 @@ function render_path_paint_unbind_layers() { function render_path_paint_dilate(base: bool, nor_pack: bool) { if (config_raw.dilate_radius > 0 && !context_raw.paint2d) { util_uv_cache_dilate_map(); - base_make_temp_img(); + layers_make_temp_img(); let tid: i32 = context_raw.layer.id; if (base) { let texpaint: string = "texpaint"; diff --git a/armorsculpt/sources/import_mesh.ts b/armorsculpt/sources/import_mesh.ts index 33bc94a1..d8b38df9 100644 --- a/armorsculpt/sources/import_mesh.ts +++ b/armorsculpt/sources/import_mesh.ts @@ -115,8 +115,8 @@ function _import_mesh_make_mesh(mesh: raw_mesh_t) { let l: slot_layer_t = array_pop(project_layers); slot_layer_unload(l); } - base_new_layer(false); - app_notify_on_init(base_init_layers); + layers_new_layer(false); + app_notify_on_init(layers_init); history_reset(); } diff --git a/armorsculpt/sources/tab_layers.ts b/armorsculpt/sources/tab_layers.ts index c8385f10..0ea6ce68 100644 --- a/armorsculpt/sources/tab_layers.ts +++ b/armorsculpt/sources/tab_layers.ts @@ -76,7 +76,7 @@ function tab_layers_button_new(text: string) { ui_menu_draw(function (ui: ui_t) { let l: slot_layer_t = context_raw.layer; if (ui_menu_button(ui, tr("Paint Layer"))) { - base_new_layer(); + layers_new_layer(); history_new_layer(); } }); diff --git a/base/sources/base.ts b/base/sources/base.ts index 3d311289..911b6205 100644 --- a/base/sources/base.ts +++ b/base/sources/base.ts @@ -32,30 +32,8 @@ let base_last_window_width: i32 = 0; let base_last_window_height: i32 = 0; let base_drag_material: slot_material_t = null; let base_drag_layer: slot_layer_t = null; - -let base_temp_image: image_t = null; -let base_expa: image_t = null; -let base_expb: image_t = null; -let base_expc: image_t = null; - let base_default_fov: f32 = 0.69; -let base_default_base: f32 = 0.5; -let base_default_rough: f32 = 0.4; -let base_max_layers: i32 = -///if (arm_android || arm_ios) - 18; -///else - 255; -///end - let _base_material_count: i32; -let _base_uv_type: uv_type_t; -let _base_decal_mat: mat4_t; -let _base_position: i32; -let _base_base_color: i32; -let _base_occlusion: f32; -let _base_roughness: f32; -let _base_metallic: f32; function base_init() { base_last_window_width = sys_width(); @@ -394,7 +372,7 @@ function base_update() { } // Create mask else if (context_in_layers() || context_in_2d_view()) { - base_create_image_mask(base_drag_asset); + layers_create_image_mask(base_drag_asset); } base_drag_asset = null; } @@ -412,12 +390,12 @@ function base_update() { else if (context_in_viewport()) { let color: i32 = base_drag_swatch.base; color = color_set_ab(color, base_drag_swatch.opacity * 255); - base_create_color_layer(color, base_drag_swatch.occlusion, base_drag_swatch.roughness, base_drag_swatch.metallic); + layers_create_color_layer(color, base_drag_swatch.occlusion, base_drag_swatch.roughness, base_drag_swatch.metallic); } else if (context_in_layers() && tab_layers_can_drop_new_layer(context_raw.drag_dest)) { let color: i32 = base_drag_swatch.base; color = color_set_ab(color, base_drag_swatch.opacity * 255); - base_create_color_layer(color, base_drag_swatch.occlusion, base_drag_swatch.roughness, base_drag_swatch.metallic, context_raw.drag_dest); + layers_create_color_layer(color, base_drag_swatch.occlusion, base_drag_swatch.roughness, base_drag_swatch.metallic, context_raw.drag_dest); } base_drag_swatch = null; @@ -493,12 +471,12 @@ function base_material_dropped() { if (context_in_viewport()) { let uv_type: uv_type_t = keyboard_down("control") ? uv_type_t.PROJECT : uv_type_t.UVMAP; let decal_mat: mat4_t = uv_type == uv_type_t.PROJECT ? util_render_get_decal_mat() : mat4_nan(); - base_create_fill_layer(uv_type, decal_mat); + layers_create_fill_layer(uv_type, decal_mat); } if (context_in_layers() && tab_layers_can_drop_new_layer(context_raw.drag_dest)) { let uv_type: uv_type_t = keyboard_down("control") ? uv_type_t.PROJECT : uv_type_t.UVMAP; let decal_mat: mat4_t = uv_type == uv_type_t.PROJECT ? util_render_get_decal_mat() : mat4_nan(); - base_create_fill_layer(uv_type, decal_mat, context_raw.drag_dest); + layers_create_fill_layer(uv_type, decal_mat, context_raw.drag_dest); } else if (context_in_nodes()) { ui_nodes_accept_material_drag(array_index_of(project_materials, base_drag_material)); @@ -852,797 +830,3 @@ function base_init_config() { raw.dilate_radius = 2; raw.gpu_inference = true; } - -function base_init_layers() { - ///if (is_paint || is_sculpt) - slot_layer_clear(project_layers[0], color_from_floats(base_default_base, base_default_base, base_default_base, 1.0)); - ///end - - ///if is_lab - let texpaint: render_target_t = map_get(render_path_render_targets, "texpaint"); - let texpaint_nor: render_target_t = map_get(render_path_render_targets, "texpaint_nor"); - let texpaint_pack: render_target_t = map_get(render_path_render_targets, "texpaint_pack"); - g2_begin(texpaint._image); - g2_draw_scaled_image(resource_get("placeholder.k"), 0, 0, config_get_texture_res_x(), config_get_texture_res_y()); // Base - g2_end(); - g4_begin(texpaint_nor._image); - g4_clear(color_from_floats(0.5, 0.5, 1.0, 0.0)); // Nor - g4_end(); - g4_begin(texpaint_pack._image); - g4_clear(color_from_floats(1.0, 0.4, 0.0, 0.0)); // Occ, rough, met - g4_end(); - let texpaint_nor_empty: render_target_t = map_get(render_path_render_targets, "texpaint_nor_empty"); - let texpaint_pack_empty: render_target_t = map_get(render_path_render_targets, "texpaint_pack_empty"); - g4_begin(texpaint_nor_empty._image); - g4_clear(color_from_floats(0.5, 0.5, 1.0, 0.0)); // Nor - g4_end(); - g4_begin(texpaint_pack_empty._image); - g4_clear(color_from_floats(1.0, 0.4, 0.0, 0.0)); // Occ, rough, met - g4_end(); - ///end -} - -function base_resize_layers() { - let conf: config_t = config_raw; - if (base_res_handle.position >= math_floor(texture_res_t.RES16384)) { // Save memory for >=16k - conf.undo_steps = 1; - if (context_raw.undo_handle != null) { - context_raw.undo_handle.value = conf.undo_steps; - } - while (history_undo_layers.length > conf.undo_steps) { - let l: slot_layer_t = array_pop(history_undo_layers); - app_notify_on_next_frame(function (l: slot_layer_t) { - slot_layer_unload(l); - }, l); - } - } - for (let i: i32 = 0; i < project_layers.length; ++i) { - let l: slot_layer_t = project_layers[i]; - slot_layer_resize_and_set_bits(l); - } - for (let i: i32 = 0; i < history_undo_layers.length; ++i) { - let l: slot_layer_t = history_undo_layers[i]; - slot_layer_resize_and_set_bits(l); - } - - let rts: map_t = render_path_render_targets; - - let blend0: render_target_t = map_get(rts, "texpaint_blend0"); - let _texpaint_blend0: image_t = blend0._image; - app_notify_on_next_frame(function (_texpaint_blend0: image_t) { - image_unload(_texpaint_blend0); - }, _texpaint_blend0); - blend0.width = config_get_texture_res_x(); - blend0.height = config_get_texture_res_y(); - blend0._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8); - - let blend1: render_target_t = map_get(rts, "texpaint_blend1"); - let _texpaint_blend1: image_t = blend1._image; - app_notify_on_next_frame(function (_texpaint_blend1: image_t) { - image_unload(_texpaint_blend1); - }, _texpaint_blend1); - blend1.width = config_get_texture_res_x(); - blend1.height = config_get_texture_res_y(); - blend1._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8); - - context_raw.brush_blend_dirty = true; - - let blur: render_target_t = map_get(rts, "texpaint_blur"); - if (blur != null) { - let _texpaint_blur: image_t = blur._image; - app_notify_on_next_frame(function (_texpaint_blur: image_t) { - image_unload(_texpaint_blur); - }, _texpaint_blur); - let size_x: f32 = math_floor(config_get_texture_res_x() * 0.95); - let size_y: f32 = math_floor(config_get_texture_res_y() * 0.95); - blur.width = size_x; - blur.height = size_y; - blur._image = image_create_render_target(size_x, size_y); - } - if (render_path_paint_live_layer != null) { - slot_layer_resize_and_set_bits(render_path_paint_live_layer); - } - ///if (arm_direct3d12 || arm_vulkan || arm_metal) - render_path_raytrace_ready = false; // Rebuild baketex - ///end - context_raw.ddirty = 2; -} - -function base_set_layer_bits() { - for (let i: i32 = 0; i < project_layers.length; ++i) { - let l: slot_layer_t = project_layers[i]; - slot_layer_resize_and_set_bits(l); - } - for (let i: i32 = 0; i < history_undo_layers.length; ++i) { - let l: slot_layer_t = history_undo_layers[i]; - slot_layer_resize_and_set_bits(l); - } -} - -function base_make_temp_img() { - ///if (is_paint || is_sculpt) - let l: slot_layer_t = project_layers[0]; - ///end - ///if is_lab - let l: brush_output_node_t = brush_output_node_inst; - ///end - - if (base_temp_image != null && (base_temp_image.width != l.texpaint.width || base_temp_image.height != l.texpaint.height || base_temp_image.format != l.texpaint.format)) { - let _temptex0: render_target_t = map_get(render_path_render_targets, "temptex0"); - app_notify_on_next_frame(function (_temptex0: render_target_t) { - render_target_unload(_temptex0); - }, _temptex0); - map_delete(render_path_render_targets, "temptex0"); - base_temp_image = null; - } - if (base_temp_image == null) { - let format: string = base_bits_handle.position == texture_bits_t.BITS8 ? "RGBA32" : - base_bits_handle.position == texture_bits_t.BITS16 ? "RGBA64" : - "RGBA128"; - ///if is_lab - format = "RGBA32"; - ///end - - let t: render_target_t = render_target_create(); - t.name = "temptex0"; - t.width = l.texpaint.width; - t.height = l.texpaint.height; - t.format = format; - let rt: render_target_t = render_path_create_render_target(t); - base_temp_image = rt._image; - } -} - -function base_make_temp_mask_img() { - if (pipes_temp_mask_image != null && (pipes_temp_mask_image.width != config_get_texture_res_x() || pipes_temp_mask_image.height != config_get_texture_res_y())) { - let _temp_mask_image: image_t = pipes_temp_mask_image; - app_notify_on_next_frame(function (_temp_mask_image: image_t) { - image_unload(_temp_mask_image); - }, _temp_mask_image); - pipes_temp_mask_image = null; - } - if (pipes_temp_mask_image == null) { - pipes_temp_mask_image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8); - } -} - -function base_make_export_img() { - ///if (is_paint || is_sculpt) - let l: slot_layer_t = project_layers[0]; - ///end - ///if is_lab - let l: brush_output_node_t = brush_output_node_inst; - ///end - - if (base_expa != null && (base_expa.width != l.texpaint.width || base_expa.height != l.texpaint.height || base_expa.format != l.texpaint.format)) { - let _expa: image_t = base_expa; - let _expb: image_t = base_expb; - let _expc: image_t = base_expc; - app_notify_on_next_frame(function (_expa: image_t) { - image_unload(_expa); - }, _expa); - app_notify_on_next_frame(function (_expb: image_t) { - image_unload(_expb); - }, _expb); - app_notify_on_next_frame(function (_expc: image_t) { - image_unload(_expc); - }, _expc); - base_expa = null; - base_expb = null; - base_expc = null; - map_delete(render_path_render_targets, "expa"); - map_delete(render_path_render_targets, "expb"); - map_delete(render_path_render_targets, "expc"); - } - if (base_expa == null) { - let format: string = base_bits_handle.position == texture_bits_t.BITS8 ? "RGBA32" : - base_bits_handle.position == texture_bits_t.BITS16 ? "RGBA64" : - "RGBA128"; - - ///if is_lab - format = "RGBA32"; - ///end - - { - let t: render_target_t = render_target_create(); - t.name = "expa"; - t.width = l.texpaint.width; - t.height = l.texpaint.height; - t.format = format; - let rt: render_target_t = render_path_create_render_target(t); - base_expa = rt._image; - } - - { - let t: render_target_t = render_target_create(); - t.name = "expb"; - t.width = l.texpaint.width; - t.height = l.texpaint.height; - t.format = format; - let rt: render_target_t = render_path_create_render_target(t); - base_expb = rt._image; - } - - { - let t: render_target_t = render_target_create(); - t.name = "expc"; - t.width = l.texpaint.width; - t.height = l.texpaint.height; - t.format = format; - let rt: render_target_t = render_path_create_render_target(t); - base_expc = rt._image; - } - } -} - -function base_apply_mask(l: slot_layer_t, m: slot_layer_t) { - if (!slot_layer_is_layer(l) || !slot_layer_is_mask(m)) { - return; - } - - base_make_temp_img(); - - // Copy layer to temp - g2_begin(base_temp_image); - g2_set_pipeline(pipes_copy); - g2_draw_image(l.texpaint, 0, 0); - g2_set_pipeline(null); - g2_end(); - - // Apply mask - g4_begin(l.texpaint); - g4_set_pipeline(pipes_apply_mask); - g4_set_tex(pipes_tex0_mask, base_temp_image); - g4_set_tex(pipes_texa_mask, m.texpaint); - g4_set_vertex_buffer(const_data_screen_aligned_vb); - g4_set_index_buffer(const_data_screen_aligned_ib); - g4_draw(); - g4_end(); -} - -function base_commands_merge_pack(pipe: pipeline_t, i0: image_t, i1: image_t, i1pack: image_t, i1mask_opacity: f32, i1texmask: image_t, i1blending: i32 = -1) { - g4_begin(i0); - g4_set_pipeline(pipe); - g4_set_tex(pipes_tex0, i1); - g4_set_tex(pipes_tex1, i1pack); - g4_set_tex(pipes_texmask, i1texmask); - g4_set_tex(pipes_texa, base_temp_image); - g4_set_float(pipes_opac, i1mask_opacity); - g4_set_int(pipes_blending, i1blending); - g4_set_vertex_buffer(const_data_screen_aligned_vb); - g4_set_index_buffer(const_data_screen_aligned_ib); - g4_draw(); - g4_end(); -} - -function base_is_fill_material(): bool { - if (context_raw.tool == workspace_tool_t.MATERIAL) { - return true; - } - - let m: slot_material_t = context_raw.material; - for (let i: i32 = 0; i < project_layers.length; ++i) { - let l: slot_layer_t = project_layers[i]; - if (l.fill_layer == m) { - return true; - } - } - return false; -} - -function base_update_fill_layers() { - let _layer: slot_layer_t = context_raw.layer; - let _tool: workspace_tool_t = context_raw.tool; - let _fill_type: i32 = context_raw.fill_type_handle.position; - let current: image_t = null; - - if (context_raw.tool == workspace_tool_t.MATERIAL) { - if (render_path_paint_live_layer == null) { - render_path_paint_live_layer = slot_layer_create("_live"); - } - - current = _g2_current; - if (current != null) g2_end(); - - context_raw.tool = workspace_tool_t.FILL; - context_raw.fill_type_handle.position = fill_type_t.OBJECT; - make_material_parse_paint_material(false); - context_raw.pdirty = 1; - render_path_paint_use_live_layer(true); - render_path_paint_commands_paint(false); - render_path_paint_dilate(true, true); - render_path_paint_use_live_layer(false); - context_raw.tool = _tool; - context_raw.fill_type_handle.position = _fill_type; - context_raw.pdirty = 0; - context_raw.rdirty = 2; - - if (current != null) g2_begin(current); - return; - } - - let has_fill_layer: bool = false; - let has_fill_mask: bool = false; - for (let i: i32 = 0; i < project_layers.length; ++i) { - let l: slot_layer_t = project_layers[i]; - if (slot_layer_is_layer(l) && l.fill_layer == context_raw.material) { - has_fill_layer = true; - } - } - for (let i: i32 = 0; i < project_layers.length; ++i) { - let l: slot_layer_t = project_layers[i]; - if (slot_layer_is_mask(l) && l.fill_layer == context_raw.material) { - has_fill_mask = true; - } - } - - if (has_fill_layer || has_fill_mask) { - current = _g2_current; - if (current != null) { - g2_end(); - } - context_raw.pdirty = 1; - context_raw.tool = workspace_tool_t.FILL; - context_raw.fill_type_handle.position = fill_type_t.OBJECT; - - if (has_fill_layer) { - let first: bool = true; - for (let i: i32 = 0; i < project_layers.length; ++i) { - let l: slot_layer_t = project_layers[i]; - if (slot_layer_is_layer(l) && l.fill_layer == context_raw.material) { - context_raw.layer = l; - if (first) { - first = false; - make_material_parse_paint_material(false); - } - base_set_object_mask(); - slot_layer_clear(l); - render_path_paint_commands_paint(false); - render_path_paint_dilate(true, true); - } - } - } - if (has_fill_mask) { - let first: bool = true; - for (let i: i32 = 0; i < project_layers.length; ++i) { - let l: slot_layer_t = project_layers[i]; - if (slot_layer_is_mask(l) && l.fill_layer == context_raw.material) { - context_raw.layer = l; - if (first) { - first = false; - make_material_parse_paint_material(false); - } - base_set_object_mask(); - slot_layer_clear(l); - render_path_paint_commands_paint(false); - render_path_paint_dilate(true, true); - } - } - } - - context_raw.pdirty = 0; - context_raw.ddirty = 2; - context_raw.rdirty = 2; - context_raw.layers_preview_dirty = true; // Repaint all layer previews as multiple layers might have changed. - if (current != null) g2_begin(current); - context_raw.layer = _layer; - base_set_object_mask(); - context_raw.tool = _tool; - context_raw.fill_type_handle.position = _fill_type; - make_material_parse_paint_material(false); - } -} - -function base_update_fill_layer(parse_paint: bool = true) { - let current: image_t = _g2_current; - let g2_in_use: bool = _g2_in_use; - if (g2_in_use) g2_end(); - - let _tool: workspace_tool_t = context_raw.tool; - let _fill_type: i32 = context_raw.fill_type_handle.position; - context_raw.tool = workspace_tool_t.FILL; - context_raw.fill_type_handle.position = fill_type_t.OBJECT; - context_raw.pdirty = 1; - - slot_layer_clear(context_raw.layer); - - if (parse_paint) { - make_material_parse_paint_material(false); - } - render_path_paint_commands_paint(false); - render_path_paint_dilate(true, true); - - context_raw.rdirty = 2; - context_raw.tool = _tool; - context_raw.fill_type_handle.position = _fill_type; - if (g2_in_use) g2_begin(current); -} - -function base_set_object_mask() { - ///if is_sculpt - return; - ///end - - let ar: string[] = [tr("None")]; - for (let i: i32 = 0; i < project_paint_objects.length; ++i) { - let p: mesh_object_t = project_paint_objects[i]; - array_push(ar, p.base.name); - } - - let mask: i32 = context_object_mask_used() ? slot_layer_get_object_mask(context_raw.layer) : 0; - if (context_layer_filter_used()) { - mask = context_raw.layer_filter; - } - if (mask > 0) { - if (context_raw.merged_object != null) { - context_raw.merged_object.base.visible = false; - } - let o: mesh_object_t = project_paint_objects[0]; - for (let i: i32 = 0; i < project_paint_objects.length; ++i) { - let p: mesh_object_t = project_paint_objects[i]; - let mask_name: string = ar[mask]; - if (p.base.name == mask_name) { - o = p; - break; - } - } - context_select_paint_object(o); - } - else { - let is_atlas: bool = slot_layer_get_object_mask(context_raw.layer) > 0 && slot_layer_get_object_mask(context_raw.layer) <= project_paint_objects.length; - if (context_raw.merged_object == null || is_atlas || context_raw.merged_object_is_atlas) { - let visibles: mesh_object_t[] = is_atlas ? project_get_atlas_objects(slot_layer_get_object_mask(context_raw.layer)) : null; - util_mesh_merge(visibles); - } - context_select_paint_object(context_main_object()); - context_raw.paint_object.skip_context = "paint"; - context_raw.merged_object.base.visible = true; - } - util_uv_dilatemap_cached = false; -} - -function base_new_layer(clear: bool = true, position: i32 = -1): slot_layer_t { - if (project_layers.length > base_max_layers) { - return null; - } - - let l: slot_layer_t = slot_layer_create(); - l.object_mask = context_raw.layer_filter; - - if (position == -1) { - if (slot_layer_is_mask(context_raw.layer)) context_set_layer(context_raw.layer.parent); - array_insert(project_layers, array_index_of(project_layers, context_raw.layer) + 1, l); - } - else { - array_insert(project_layers, position, l); - } - - context_set_layer(l); - let li: i32 = array_index_of(project_layers, context_raw.layer); - if (li > 0) { - let below: slot_layer_t = project_layers[li - 1]; - if (slot_layer_is_layer(below)) { - context_raw.layer.parent = below.parent; - } - } - if (clear) { - app_notify_on_init(function (l: slot_layer_t) { - slot_layer_clear(l); - }, l); - } - context_raw.layer_preview_dirty = true; - return l; -} - -function base_new_mask(clear: bool = true, parent: slot_layer_t, position: i32 = -1): slot_layer_t { - if (project_layers.length > base_max_layers) { - return null; - } - let l: slot_layer_t = slot_layer_create("", layer_slot_type_t.MASK, parent); - if (position == -1) { - position = array_index_of(project_layers, parent); - } - array_insert(project_layers, position, l); - context_set_layer(l); - if (clear) { - app_notify_on_init(function (l: slot_layer_t) { - slot_layer_clear(l); - }, l); - } - context_raw.layer_preview_dirty = true; - return l; -} - -function base_new_group(): slot_layer_t { - if (project_layers.length > base_max_layers) { - return null; - } - let l: slot_layer_t = slot_layer_create("", layer_slot_type_t.GROUP); - array_push(project_layers, l); - context_set_layer(l); - return l; -} - -function base_create_fill_layer(uv_type: uv_type_t = uv_type_t.UVMAP, decal_mat: mat4_t = mat4nan, position: i32 = -1) { - _base_uv_type = uv_type; - _base_decal_mat = decal_mat; - _base_position = position; - app_notify_on_init(function () { - let l: slot_layer_t = base_new_layer(false, _base_position); - history_new_layer(); - l.uv_type = _base_uv_type; - if (!mat4_isnan(_base_decal_mat)) { - l.decal_mat = _base_decal_mat; - } - l.object_mask = context_raw.layer_filter; - history_to_fill_layer(); - slot_layer_to_fill_layer(l); - }); -} - -function base_create_image_mask(asset: asset_t) { - let l: slot_layer_t = context_raw.layer; - if (slot_layer_is_mask(l) || slot_layer_is_group(l)) { - return; - } - - history_new_layer(); - let m: slot_layer_t = base_new_mask(false, l); - slot_layer_clear(m, 0x00000000, project_get_image(asset)); - context_raw.layer_preview_dirty = true; -} - -function base_create_color_layer(base_color: i32, occlusion: f32 = 1.0, roughness: f32 = base_default_rough, metallic: f32 = 0.0, position: i32 = -1) { - _base_base_color = base_color; - _base_occlusion = occlusion; - _base_roughness = roughness; - _base_metallic = metallic; - _base_position = position; - - app_notify_on_init(function () { - let l: slot_layer_t = base_new_layer(false, _base_position); - history_new_layer(); - l.uv_type = uv_type_t.UVMAP; - l.object_mask = context_raw.layer_filter; - slot_layer_clear(l, _base_base_color, null, _base_occlusion, _base_roughness, _base_metallic); - }); -} - -function base_duplicate_layer(l: slot_layer_t) { - if (!slot_layer_is_group(l)) { - let new_layer: slot_layer_t = slot_layer_duplicate(l); - context_set_layer(new_layer); - let masks: slot_layer_t[] = slot_layer_get_masks(l, false); - if (masks != null) { - for (let i: i32 = 0; i < masks.length; ++i) { - let m: slot_layer_t = masks[i]; - m = slot_layer_duplicate(m); - m.parent = new_layer; - array_remove(project_layers, m); - array_insert(project_layers, array_index_of(project_layers, new_layer), m); - } - } - context_set_layer(new_layer); - } - else { - let new_group: slot_layer_t = base_new_group(); - array_remove(project_layers, new_group); - array_insert(project_layers, array_index_of(project_layers, l) + 1, new_group); - // group.show_panel = true; - for (let i: i32 = 0; i < slot_layer_get_children(l).length; ++i) { - let c: slot_layer_t = slot_layer_get_children(l)[i]; - let masks: slot_layer_t[] = slot_layer_get_masks(c, false); - let new_layer: slot_layer_t = slot_layer_duplicate(c); - new_layer.parent = new_group; - array_remove(project_layers, new_layer); - array_insert(project_layers, array_index_of(project_layers, new_group), new_layer); - if (masks != null) { - for (let i: i32 = 0; i < masks.length; ++i) { - let m: slot_layer_t = masks[i]; - let new_mask: slot_layer_t = slot_layer_duplicate(m); - new_mask.parent = new_layer; - array_remove(project_layers, new_mask); - array_insert(project_layers, array_index_of(project_layers, new_layer), new_mask); - } - } - } - let group_masks: slot_layer_t[] = slot_layer_get_masks(l); - if (group_masks != null) { - for (let i: i32 = 0; i < group_masks.length; ++i) { - let m: slot_layer_t = group_masks[i]; - let new_mask: slot_layer_t = slot_layer_duplicate(m); - new_mask.parent = new_group; - array_remove(project_layers, new_mask); - array_insert(project_layers, array_index_of(project_layers, new_group), new_mask); - } - } - context_set_layer(new_group); - } -} - -function base_apply_masks(l: slot_layer_t) { - let masks: slot_layer_t[] = slot_layer_get_masks(l); - - if (masks != null) { - for (let i: i32 = 0; i < masks.length - 1; ++i) { - base_merge_layer(masks[i + 1], masks[i]); - slot_layer_delete(masks[i]); - } - slot_layer_apply_mask(masks[masks.length - 1]); - context_raw.layer_preview_dirty = true; - } -} - -function base_merge_down() { - let l1: slot_layer_t = context_raw.layer; - - if (slot_layer_is_group(l1)) { - l1 = base_merge_group(l1); - } - else if (slot_layer_has_masks(l1)) { // It is a layer - base_apply_masks(l1); - context_set_layer(l1); - } - - let l0: slot_layer_t = project_layers[array_index_of(project_layers, l1) - 1]; - - if (slot_layer_is_group(l0)) { - l0 = base_merge_group(l0); - } - else if (slot_layer_has_masks(l0)) { // It is a layer - base_apply_masks(l0); - context_set_layer(l0); - } - - base_merge_layer(l0, l1); - slot_layer_delete(l1); - context_set_layer(l0); - context_raw.layer_preview_dirty = true; -} - -function base_merge_group(l: slot_layer_t): slot_layer_t { - if (!slot_layer_is_group(l)) { - return null; - } - - let children: slot_layer_t[] = slot_layer_get_children(l); - - if (children.length == 1 && slot_layer_has_masks(children[0], false)) { - base_apply_masks(children[0]); - } - - for (let i: i32 = 0; i < children.length - 1; ++i) { - context_set_layer(children[children.length - 1 - i]); - history_merge_layers(); - base_merge_down(); - } - - // Now apply the group masks - let masks: slot_layer_t[] = slot_layer_get_masks(l); - if (masks != null) { - for (let i: i32 = 0; i < masks.length - 1; ++i) { - base_merge_layer(masks[i + 1], masks[i]); - slot_layer_delete(masks[i]); - } - base_apply_mask(children[0], masks[masks.length - 1]); - } - - children[0].parent = null; - children[0].name = l.name; - if (children[0].fill_layer != null) { - slot_layer_to_paint_layer(children[0]); - } - slot_layer_delete(l); - return children[0]; -} - -function base_merge_layer(l0 : slot_layer_t, l1: slot_layer_t, use_mask: bool = false) { - if (!l1.visible || slot_layer_is_group(l1)) { - return; - } - - base_make_temp_img(); - - g2_begin(base_temp_image); // Copy to temp - g2_set_pipeline(pipes_copy); - g2_draw_image(l0.texpaint, 0, 0); - g2_set_pipeline(null); - g2_end(); - - let empty_rt: render_target_t = map_get(render_path_render_targets, "empty_white"); - let empty: image_t = empty_rt._image; - let mask: image_t = empty; - let l1masks: slot_layer_t[] = use_mask ? slot_layer_get_masks(l1) : null; - if (l1masks != null) { - // for (let i: i32 = 1; i < l1masks.length - 1; ++i) { - // mergeLayer(l1masks[i + 1], l1masks[i]); - // } - mask = l1masks[0].texpaint; - } - - if (slot_layer_is_mask(l1)) { - g4_begin(l0.texpaint); - g4_set_pipeline(pipes_merge_mask); - g4_set_tex(pipes_tex0_merge_mask, l1.texpaint); - g4_set_tex(pipes_texa_merge_mask, base_temp_image); - g4_set_float(pipes_opac_merge_mask, slot_layer_get_opacity(l1)); - g4_set_int(pipes_blending_merge_mask, l1.blending); - g4_set_vertex_buffer(const_data_screen_aligned_vb); - g4_set_index_buffer(const_data_screen_aligned_ib); - g4_draw(); - g4_end(); - } - - if (slot_layer_is_layer(l1)) { - if (l1.paint_base) { - g4_begin(l0.texpaint); - g4_set_pipeline(pipes_merge); - g4_set_tex(pipes_tex0, l1.texpaint); - g4_set_tex(pipes_tex1, empty); - g4_set_tex(pipes_texmask, mask); - g4_set_tex(pipes_texa, base_temp_image); - g4_set_float(pipes_opac, slot_layer_get_opacity(l1)); - g4_set_int(pipes_blending, l1.blending); - g4_set_vertex_buffer(const_data_screen_aligned_vb); - g4_set_index_buffer(const_data_screen_aligned_ib); - g4_draw(); - g4_end(); - } - - if (l0.texpaint_nor != null) { - g2_begin(base_temp_image); - g2_set_pipeline(pipes_copy); - g2_draw_image(l0.texpaint_nor, 0, 0); - g2_set_pipeline(null); - g2_end(); - - if (l1.paint_nor) { - g4_begin(l0.texpaint_nor); - g4_set_pipeline(pipes_merge); - g4_set_tex(pipes_tex0, l1.texpaint); - g4_set_tex(pipes_tex1, l1.texpaint_nor); - g4_set_tex(pipes_texmask, mask); - g4_set_tex(pipes_texa, base_temp_image); - g4_set_float(pipes_opac, slot_layer_get_opacity(l1)); - g4_set_int(pipes_blending, l1.paint_nor_blend ? -2 : -1); - g4_set_vertex_buffer(const_data_screen_aligned_vb); - g4_set_index_buffer(const_data_screen_aligned_ib); - g4_draw(); - g4_end(); - } - } - - if (l0.texpaint_pack != null) { - g2_begin(base_temp_image); - g2_set_pipeline(pipes_copy); - g2_draw_image(l0.texpaint_pack, 0, 0); - g2_set_pipeline(null); - g2_end(); - - if (l1.paint_occ || l1.paint_rough || l1.paint_met || l1.paint_height) { - if (l1.paint_occ && l1.paint_rough && l1.paint_met && l1.paint_height) { - base_commands_merge_pack(pipes_merge, l0.texpaint_pack, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask, l1.paint_height_blend ? -3 : -1); - } - else { - if (l1.paint_occ) { - base_commands_merge_pack(pipes_merge_r, l0.texpaint_pack, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); - } - if (l1.paint_rough) { - base_commands_merge_pack(pipes_merge_g, l0.texpaint_pack, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); - } - if (l1.paint_met) { - base_commands_merge_pack(pipes_merge_b, l0.texpaint_pack, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); - } - } - } - } - } -} - -function base_flatten(height_to_normal: bool = false, layers: slot_layer_t[] = null): slot_layer_t { - return base_ext_flatten(height_to_normal, layers); -} - -function base_on_layers_resized() { - base_ext_on_layers_resized(); -} diff --git a/base/sources/box_export.ts b/base/sources/box_export.ts index 253f6dc5..0fe724c6 100644 --- a/base/sources/box_export.ts +++ b/base/sources/box_export.ts @@ -90,7 +90,7 @@ function box_export_tab_export_textures(ui: ui_t, title: string, bake_material: ui_combo(base_res_handle, base_res_combo, tr("Resolution"), true); if (base_res_handle.changed) { - base_on_layers_resized(); + layers_on_resized(); } ///if (is_lab || arm_android || arm_ios) @@ -101,7 +101,7 @@ function box_export_tab_export_textures(ui: ui_t, title: string, bake_material: ui_combo(base_bits_handle, base_bits_combo, tr("Color"), true); if (base_bits_handle.changed) { - app_notify_on_init(base_set_layer_bits); + app_notify_on_init(layers_set_bits); } ui_row2(); diff --git a/base/sources/box_preferences.ts b/base/sources/box_preferences.ts index 0aae0f7c..b5067ce1 100644 --- a/base/sources/box_preferences.ts +++ b/base/sources/box_preferences.ts @@ -562,12 +562,11 @@ function box_preferences_show() { let row: f32[] = [0.5]; ui_row(row); if (ui_button(tr("Help"))) { - ///if (is_paint || is_sculpt) - file_load_url("https://github.com/armory3d/armorpaint_docs///pen"); - ///end - ///if is_lab - file_load_url("https://github.com/armory3d/armorlab_docs///pen"); - ///end + let url: string = "https://github.com/armory3d/"; + let name: string = to_lower_case(manifest_title); + url += name; + url += "_docs#pen"; + file_load_url(url); } } diff --git a/base/sources/config.ts b/base/sources/config.ts index 08e89f63..746a8794 100644 --- a/base/sources/config.ts +++ b/base/sources/config.ts @@ -170,11 +170,6 @@ function config_init() { keymap_load(); } -type version_t = { - sha: string; - date: string; -}; - function config_get_sha(): string { let blob: buffer_t = data_get_blob("version.json"); if (blob == null) { @@ -357,6 +352,11 @@ function config_disable_plugin(f: string) { plugin_stop(f); } +type version_t = { + sha: string; + date: string; +}; + type config_t = { // The locale should be specified in ISO 639-1 format: // https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes diff --git a/base/sources/context.ts b/base/sources/context.ts index c3204fd8..278bbd14 100644 --- a/base/sources/context.ts +++ b/base/sources/context.ts @@ -349,8 +349,6 @@ function context_create(): context_t { c.camera_controls = camera_controls_t.ORBIT; c.pen_painting_only = false; // Reject painting with finger when using pen - ///if (is_paint || is_sculpt) - c.tool = workspace_tool_t.BRUSH; c.layer_preview_dirty = true; c.layers_preview_dirty = false; c.node_preview_dirty = false; @@ -358,7 +356,6 @@ function context_create(): context_t { c.colorid_picked = false; c.material_preview = false; // Drawing material previews c.saved_camera = mat4_identity(); - c.color_picker_previous_tool = workspace_tool_t.BRUSH; c.materialid_picked = 0; c.uvx_picked = 0.0; c.uvy_picked = 0.0; @@ -419,9 +416,8 @@ function context_create(): context_t { c.brush_nodes_angle = 0.0; c.brush_nodes_hardness = 1.0; c.brush_directional = false; - c.brush_radius = 0.5; + c.brush_radius_handle = ui_handle_create(); - c.brush_radius_handle.value = 0.5; c.brush_scale_x = 1.0; c.brush_decal_mask_radius = 0.5; c.brush_decal_mask_radius_handle = ui_handle_create(); @@ -436,12 +432,6 @@ function context_create(): context_t { c.brush_angle = 0.0; c.brush_angle_handle = ui_handle_create(); c.brush_angle_handle.value = 0.0; - ///if is_paint - c.brush_hardness = 0.8; - ///end - ///if is_sculpt - c.brush_hardness = 0.05; - ///end c.brush_lazy_radius = 0.0; c.brush_lazy_step = 0.0; c.brush_lazy_x = 0.0; @@ -469,31 +459,13 @@ function context_create(): context_t { c.last_htab0_pos = 0; c.maximized_sidebar_width = 0; c.drag_dest = 0; - ///end - - ///if is_lab - c.tool = workspace_tool_t.ERASER; - c.color_picker_previous_tool = workspace_tool_t.ERASER; - c.brush_radius = 0.25; - c.brush_radius_handle = ui_handle_create(); - c.brush_radius_handle.value = 0.25; - c.brush_scale = 1.0; - c.coords = vec4_create(); - c.start_x = 0.0; - c.start_y = 0.0; - c.lock_begin = false; - c.lock_x = false; - c.lock_y = false; - c.lock_start_x = 0.0; - c.lock_start_y = 0.0; - c.registered = false; - ///end return c; } function context_init() { context_raw = context_create(); + context_ext_init(context_raw); } function context_use_deferred(): bool { @@ -577,7 +549,7 @@ function context_set_layer(l: slot_layer_t) { let g2_in_use: bool = _g2_in_use; if (g2_in_use) g2_end(); - base_set_object_mask(); + layers_set_object_mask(); make_material_parse_mesh_material(); make_material_parse_paint_material(); @@ -623,7 +595,7 @@ function context_init_tool() { ///end } else if (context_raw.tool == workspace_tool_t.MATERIAL) { - base_update_fill_layers(); + layers_update_fill_layers(); context_main_object().skip_context = null; } @@ -634,30 +606,7 @@ function context_init_tool() { } function context_select_paint_object(o: mesh_object_t) { - ///if (is_paint || is_sculpt) - ui_header_handle.redraws = 2; - for (let i: i32 = 0; i < project_paint_objects.length; ++i) { - let p: mesh_object_t = project_paint_objects[i]; - p.skip_context = "paint"; - } - context_raw.paint_object = o; - - let mask: i32 = slot_layer_get_object_mask(context_raw.layer); - if (context_layer_filter_used()) { - mask = context_raw.layer_filter; - } - - if (context_raw.merged_object == null || mask > 0) { - context_raw.paint_object.skip_context = ""; - } - util_uv_uvmap_cached = false; - util_uv_trianglemap_cached = false; - util_uv_dilatemap_cached = false; - ///end - - ///if is_lab - context_raw.paint_object = o; - ///end + context_ext_select_paint_object(o); } function context_main_object(): mesh_object_t { @@ -852,116 +801,3 @@ function context_enable_import_plugin(file: string): bool { function context_set_swatch(s: swatch_color_t) { context_raw.swatch = s; } - -function context_run_brush(from: i32) { - let left: f32 = 0.0; - let right: f32 = 1.0; - - // First time init - if (context_raw.last_paint_x < 0 || context_raw.last_paint_y < 0) { - context_raw.last_paint_vec_x = context_raw.paint_vec.x; - context_raw.last_paint_vec_y = context_raw.paint_vec.y; - } - - let nodes: ui_nodes_t = ui_nodes_get_nodes(); - let canvas: ui_node_canvas_t = ui_nodes_get_canvas(true); - let inpaint: bool = nodes.nodes_selected_id.length > 0 && ui_get_node(canvas.nodes, nodes.nodes_selected_id[0]).type == "inpaint_node"; - - // Paint bounds - if (inpaint && - context_raw.paint_vec.x > left && - context_raw.paint_vec.x < right && - context_raw.paint_vec.y > 0 && - context_raw.paint_vec.y < 1 && - !base_is_dragging && - !base_is_resizing && - !base_is_scrolling() && - !base_is_combo_selected()) { - - let down: bool = mouse_down() || pen_down(); - - // Prevent painting the same spot - let same_spot: bool = context_raw.paint_vec.x == context_raw.last_paint_x && context_raw.paint_vec.y == context_raw.last_paint_y; - if (down && same_spot) { - context_raw.painted++; - } - else { - context_raw.painted = 0; - } - context_raw.last_paint_x = context_raw.paint_vec.x; - context_raw.last_paint_y = context_raw.paint_vec.y; - - if (context_raw.painted == 0) { - context_parse_brush_inputs(); - } - - if (context_raw.painted <= 1) { - context_raw.pdirty = 1; - context_raw.rdirty = 2; - } - } -} - -function context_parse_brush_inputs() { - if (!context_raw.registered) { - context_raw.registered = true; - app_notify_on_update(context_update); - } - - context_raw.paint_vec = context_raw.coords; -} - -function context_update() { - let paint_x: f32 = mouse_view_x() / app_w(); - let paint_y: f32 = mouse_view_y() / app_h(); - if (mouse_started()) { - context_raw.start_x = mouse_view_x() / app_w(); - context_raw.start_y = mouse_view_y() / app_h(); - } - - if (pen_down()) { - paint_x = pen_view_x() / app_w(); - paint_y = pen_view_y() / app_h(); - } - if (pen_started()) { - context_raw.start_x = pen_view_x() / app_w(); - context_raw.start_y = pen_view_y() / app_h(); - } - - if (operator_shortcut(map_get(config_keymap, "brush_ruler") + "+" + map_get(config_keymap, "action_paint"), shortcut_type_t.DOWN)) { - if (context_raw.lock_x) { - paint_x = context_raw.start_x; - } - if (context_raw.lock_y) { - paint_y = context_raw.start_y; - } - } - - context_raw.coords.x = paint_x; - context_raw.coords.y = paint_y; - - if (context_raw.lock_begin) { - let dx: i32 = math_abs(context_raw.lock_start_x - mouse_view_x()); - let dy: i32 = math_abs(context_raw.lock_start_y - mouse_view_y()); - if (dx > 1 || dy > 1) { - context_raw.lock_begin = false; - if (dx > dy) { - context_raw.lock_y = true; - } - else { - context_raw.lock_x = true; - } - } - } - - if (keyboard_started(map_get(config_keymap, "brush_ruler"))) { - context_raw.lock_start_x = mouse_view_x(); - context_raw.lock_start_y = mouse_view_y(); - context_raw.lock_begin = true; - } - else if (keyboard_released(map_get(config_keymap, "brush_ruler"))) { - context_raw.lock_x = context_raw.lock_y = context_raw.lock_begin = false; - } - - context_parse_brush_inputs(); -} diff --git a/base/sources/export_arm.ts b/base/sources/export_arm.ts index ade506bd..8c0aa774 100644 --- a/base/sources/export_arm.ts +++ b/base/sources/export_arm.ts @@ -172,11 +172,13 @@ function export_arm_run_project() { g2_draw_scaled_image(tex, -(256 * r - 256) / 2, 0, 256 * r, 256); ///end g2_end(); + ///if arm_metal // Flush command list g2_begin(mesh_icon); g2_end(); ///end + let mesh_icon_pixels: buffer_t = image_get_pixels(mesh_icon); let u8a: u8_array_t = mesh_icon_pixels; for (let i: i32 = 0; i < 256 * 256 * 4; ++i) { @@ -185,9 +187,11 @@ function export_arm_run_project() { ///if (arm_metal || arm_vulkan) export_arm_bgra_swap(mesh_icon_pixels); ///end + app_notify_on_next_frame(function (mesh_icon: image_t) { image_unload(mesh_icon); }); + // raw.mesh_icons = // ///if (arm_metal || arm_vulkan) // [encode(bgraSwap(mesh_icon_pixels)]; @@ -213,6 +217,7 @@ function export_arm_run_project() { ///else let recent_path: string = project_filepath; ///end + ///if arm_windows recent_path = string_replace_all(recent_path, "\\", "/"); ///end @@ -244,22 +249,6 @@ function export_arm_export_node(n: ui_node_t, assets: asset_t[] = null) { } } } - // Pack colors - // if (n.color > 0) { - // n.color -= 4294967296; - // } - // for (let i: i32 = 0; i < n.inputs.length; ++i) { - // let inp: ui_node_socket_t = n.inputs[i]; - // if (inp.color > 0) { - // inp.color -= 4294967296; - // } - // } - // for (let i: i32 = 0; i < n.outputs.length; ++i) { - // let out: ui_node_socket_t = n.outputs[i]; - // if (out.color > 0) { - // out.color -= 4294967296; - // } - // } } function export_arm_run_material(path: string) { diff --git a/base/sources/export_texture.ts b/base/sources/export_texture.ts index 5cc68e7b..3f95a951 100644 --- a/base/sources/export_texture.ts +++ b/base/sources/export_texture.ts @@ -175,8 +175,8 @@ function export_texture_run_layers(path: string, layers: slot_layer_t[], object_ ext = object_name + ext; } - base_make_temp_img(); - base_make_export_img(); + layers_make_temp_img(); + layers_make_export_img(); let rt: render_target_t = map_get(render_path_render_targets, "empty_white"); let empty: image_t = rt._image; @@ -190,13 +190,13 @@ function export_texture_run_layers(path: string, layers: slot_layer_t[], object_ } // Clear export layer - g4_begin(base_expa); + g4_begin(layers_expa); g4_clear(color_from_floats(0.0, 0.0, 0.0, 0.0)); g4_end(); - g4_begin(base_expb); + g4_begin(layers_expb); g4_clear(color_from_floats(0.5, 0.5, 1.0, 0.0)); g4_end(); - g4_begin(base_expc); + g4_begin(layers_expc); g4_clear(color_from_floats(1.0, 0.0, 0.0, 0.0)); g4_end(); @@ -224,7 +224,7 @@ function export_texture_run_layers(path: string, layers: slot_layer_t[], object_ let l1masks: slot_layer_t[] = slot_layer_get_masks(l1); if (l1masks != null && !bake_material) { if (l1masks.length > 1) { - base_make_temp_mask_img(); + layers_make_temp_mask_img(); g2_begin(pipes_temp_mask_image); g2_clear(0x00000000); g2_end(); @@ -232,7 +232,7 @@ function export_texture_run_layers(path: string, layers: slot_layer_t[], object_ texpaint: pipes_temp_mask_image }; for (let i: i32 = 0; i < l1masks.length; ++i) { - base_merge_layer(l1, l1masks[i]); + layers_merge_layer(l1, l1masks[i]); } mask = pipes_temp_mask_image; } @@ -242,18 +242,18 @@ function export_texture_run_layers(path: string, layers: slot_layer_t[], object_ } if (l1.paint_base) { - g2_begin(base_temp_image); // Copy to temp + g2_begin(layers_temp_image); // Copy to temp g2_set_pipeline(pipes_copy); - g2_draw_image(base_expa, 0, 0); + g2_draw_image(layers_expa, 0, 0); g2_set_pipeline(null); g2_end(); - g4_begin(base_expa); + g4_begin(layers_expa); g4_set_pipeline(pipes_merge); g4_set_tex(pipes_tex0, l1.texpaint); g4_set_tex(pipes_tex1, empty); g4_set_tex(pipes_texmask, mask); - g4_set_tex(pipes_texa, base_temp_image); + g4_set_tex(pipes_texa, layers_temp_image); g4_set_float(pipes_opac, slot_layer_get_opacity(l1)); g4_set_int(pipes_blending, layers.length > 1 ? l1.blending : 0); g4_set_vertex_buffer(const_data_screen_aligned_vb); @@ -263,18 +263,18 @@ function export_texture_run_layers(path: string, layers: slot_layer_t[], object_ } if (l1.paint_nor) { - g2_begin(base_temp_image); + g2_begin(layers_temp_image); g2_set_pipeline(pipes_copy); - g2_draw_image(base_expb, 0, 0); + g2_draw_image(layers_expb, 0, 0); g2_set_pipeline(null); g2_end(); - g4_begin(base_expb); + g4_begin(layers_expb); g4_set_pipeline(pipes_merge); g4_set_tex(pipes_tex0, l1.texpaint); g4_set_tex(pipes_tex1, l1.texpaint_nor); g4_set_tex(pipes_texmask, mask); - g4_set_tex(pipes_texa, base_temp_image); + g4_set_tex(pipes_texa, layers_temp_image); g4_set_float(pipes_opac, slot_layer_get_opacity(l1)); g4_set_int(pipes_blending, l1.paint_nor_blend ? -2 : -1); g4_set_vertex_buffer(const_data_screen_aligned_vb); @@ -284,37 +284,37 @@ function export_texture_run_layers(path: string, layers: slot_layer_t[], object_ } if (l1.paint_occ || l1.paint_rough || l1.paint_met || l1.paint_height) { - g2_begin(base_temp_image); + g2_begin(layers_temp_image); g2_set_pipeline(pipes_copy); - g2_draw_image(base_expc, 0, 0); + g2_draw_image(layers_expc, 0, 0); g2_set_pipeline(null); g2_end(); if (l1.paint_occ && l1.paint_rough && l1.paint_met && l1.paint_height) { - base_commands_merge_pack(pipes_merge, base_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask, l1.paint_height_blend ? -3 : -1); + layers_commands_merge_pack(pipes_merge, layers_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask, l1.paint_height_blend ? -3 : -1); } else { - if (l1.paint_occ) base_commands_merge_pack(pipes_merge_r, base_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); - if (l1.paint_rough) base_commands_merge_pack(pipes_merge_g, base_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); - if (l1.paint_met) base_commands_merge_pack(pipes_merge_b, base_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); + if (l1.paint_occ) layers_commands_merge_pack(pipes_merge_r, layers_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); + if (l1.paint_rough) layers_commands_merge_pack(pipes_merge_g, layers_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); + if (l1.paint_met) layers_commands_merge_pack(pipes_merge_b, layers_expc, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); } } } ///if arm_metal // Flush command list - g2_begin(base_expa); + g2_begin(layers_expa); g2_end(); - g2_begin(base_expb); + g2_begin(layers_expb); g2_end(); - g2_begin(base_expc); + g2_begin(layers_expc); g2_end(); ///end ///end - let texpaint: image_t = base_expa; - let texpaint_nor: image_t = base_expb; - let texpaint_pack: image_t = base_expc; + let texpaint: image_t = layers_expa; + let texpaint_nor: image_t = layers_expb; + let texpaint_pack: image_t = layers_expc; ///if is_lab texpaint = brush_output_node_inst.texpaint; diff --git a/base/sources/gizmo.ts b/base/sources/gizmo.ts index dc51822c..fd3fd27d 100644 --- a/base/sources/gizmo.ts +++ b/base/sources/gizmo.ts @@ -155,7 +155,7 @@ function gizmo_update() { if (context_raw.material != context_raw.layer.fill_layer) { context_set_material(context_raw.layer.fill_layer); } - base_update_fill_layer(context_raw.gizmo_started); + layers_update_fill_layer(context_raw.gizmo_started); } } diff --git a/base/sources/history.ts b/base/sources/history.ts index 15248671..0827c27e 100644 --- a/base/sources/history.ts +++ b/base/sources/history.ts @@ -136,7 +136,7 @@ function history_undo() { // Now restore the applied mask history_undo_i = history_undo_i - 1 < 0 ? config_raw.undo_steps - 1 : history_undo_i - 1; let mask: slot_layer_t = history_undo_layers[history_undo_i]; - base_new_mask(false, current_layer, mask_pos); + layers_new_mask(false, current_layer, mask_pos); slot_layer_swap(context_raw.layer, mask); context_raw.layers_preview_dirty = true; context_set_layer(context_raw.layer); @@ -152,7 +152,7 @@ function history_undo() { let lay: slot_layer_t = history_undo_layers[history_undo_i]; context_set_layer(project_layers[step.layer]); slot_layer_swap(context_raw.layer, lay); - base_new_mask(false, context_raw.layer); + layers_new_mask(false, context_raw.layer); slot_layer_swap(context_raw.layer, lay); context_raw.layer_preview_dirty = true; } @@ -266,7 +266,7 @@ function history_redo() { } else if (step.name == tr("New Group")) { let l: slot_layer_t = project_layers[step.layer - 1]; - let group: slot_layer_t = base_new_group(); + let group: slot_layer_t = layers_new_group(); array_remove(project_layers, group); array_insert(project_layers, step.layer, group); l.parent = group; @@ -302,7 +302,7 @@ function history_redo() { else if (step.name == tr("Duplicate Layer")) { context_raw.layer = project_layers[step.layer]; app_notify_on_next_frame(function () { - base_duplicate_layer(context_raw.layer); + layers_duplicate_layer(context_raw.layer); }); } else if (step.name == tr("Order Layers")) { @@ -313,7 +313,7 @@ function history_redo() { else if (step.name == tr("Merge Layers")) { context_raw.layer = project_layers[step.layer + 1]; app_notify_on_init(history_redo_merge_layers); - app_notify_on_init(base_merge_down); + app_notify_on_init(layers_merge_down); } else if (step.name == tr("Apply Mask")) { context_raw.layer = project_layers[step.layer]; @@ -344,7 +344,7 @@ function history_redo() { let lay: slot_layer_t = history_undo_layers[history_undo_i]; context_set_layer(project_layers[step.layer]); slot_layer_swap(context_raw.layer, lay); - base_new_mask(false, lay); + layers_new_mask(false, lay); slot_layer_swap(context_raw.layer, lay); context_raw.layer_preview_dirty = true; history_undo_i = (history_undo_i + 1) % config_raw.undo_steps; @@ -425,7 +425,6 @@ function history_redo() { } function history_reset() { - ///if (is_paint || is_sculpt) history_steps = [ { name: tr("New", null), @@ -437,15 +436,6 @@ function history_reset() { brush: 0 } ]; - ///end - ///if is_lab - history_steps = [ - { - name: tr("New", null) - } - ]; - ///end - history_undos = 0; history_redos = 0; history_undo_i = 0; @@ -454,9 +444,7 @@ function history_reset() { function history_edit_nodes(canvas: ui_node_canvas_t, canvas_type: i32, canvas_group: i32 = -1) { let step: step_t = history_push(tr("Edit Nodes")); step.canvas_group = canvas_group; - ///if (is_paint || is_sculpt) step.canvas_type = canvas_type; - ///end step.canvas = util_clone_canvas(canvas); } @@ -640,17 +628,16 @@ function history_push(name: string): step_t { layer_object: context_raw.layer.object_mask, layer_blending: context_raw.layer.blending }; - - array_push(history_steps, step); ///end ///if is_lab let step: step_t = { name: name }; - array_push(history_steps, step); ///end + array_push(history_steps, step); + while (history_steps.length > config_raw.undo_steps + 1) { array_shift(history_steps); } @@ -684,7 +671,6 @@ function history_swap_active() { } function history_copy_to_undo(from_id: i32, to_id: i32, is_mask: bool) { - ///if is_sculpt is_mask = true; ///end @@ -707,29 +693,25 @@ function history_copy_to_undo(from_id: i32, to_id: i32, is_mask: bool) { } function history_get_canvas(step: step_t): ui_node_canvas_t { - ///if (is_paint || is_sculpt) + ///if is_lab + return null; + ///end + if (step.canvas_group == -1) { return project_materials[step.material].canvas; } else { return project_material_groups[step.canvas_group].canvas; } - ///end - - ///if is_lab - return null; - ///end } function history_set_canvas(step: step_t, canvas: ui_node_canvas_t) { - ///if (is_paint || is_sculpt) if (step.canvas_group == -1) { project_materials[step.material].canvas = canvas; } else { project_material_groups[step.canvas_group].canvas = canvas; } - ///end } function history_swap_canvas(step: step_t) { diff --git a/base/sources/import_arm.ts b/base/sources/import_arm.ts index 0f8cf9a0..8f405a13 100644 --- a/base/sources/import_arm.ts +++ b/base/sources/import_arm.ts @@ -421,7 +421,7 @@ function import_arm_run_mesh(raw: project_format_t) { util_mesh_merge(); viewport_scale_to_bounds(); } - app_notify_on_init(base_init_layers); + app_notify_on_init(layers_init); history_reset(); } diff --git a/base/sources/import_mesh.ts b/base/sources/import_mesh.ts index 4fcb411a..b3f736bd 100644 --- a/base/sources/import_mesh.ts +++ b/base/sources/import_mesh.ts @@ -160,8 +160,8 @@ function _import_mesh_make_mesh(mesh: raw_mesh_t) { let l: slot_layer_t = array_pop(project_layers); slot_layer_unload(l); } - base_new_layer(false); - app_notify_on_init(base_init_layers); + layers_new_layer(false); + app_notify_on_init(layers_init); history_reset(); } ///end diff --git a/base/sources/layers.ts b/base/sources/layers.ts new file mode 100644 index 00000000..2ab07f94 --- /dev/null +++ b/base/sources/layers.ts @@ -0,0 +1,815 @@ + +let layers_temp_image: image_t = null; +let layers_expa: image_t = null; +let layers_expb: image_t = null; +let layers_expc: image_t = null; +let layers_default_base: f32 = 0.5; +let layers_default_rough: f32 = 0.4; +let layers_max_layers: i32 = +///if (arm_android || arm_ios) + 18; +///else + 255; +///end + +let _layers_uv_type: uv_type_t; +let _layers_decal_mat: mat4_t; +let _layers_position: i32; +let _layers_base_color: i32; +let _layers_occlusion: f32; +let _layers_roughness: f32; +let _layers_metallic: f32; + +function layers_init() { + ///if (is_paint || is_sculpt) + slot_layer_clear(project_layers[0], color_from_floats(layers_default_base, layers_default_base, layers_default_base, 1.0)); + ///end + + ///if is_lab + let texpaint: render_target_t = map_get(render_path_render_targets, "texpaint"); + let texpaint_nor: render_target_t = map_get(render_path_render_targets, "texpaint_nor"); + let texpaint_pack: render_target_t = map_get(render_path_render_targets, "texpaint_pack"); + g2_begin(texpaint._image); + g2_draw_scaled_image(resource_get("placeholder.k"), 0, 0, config_get_texture_res_x(), config_get_texture_res_y()); // Base + g2_end(); + g4_begin(texpaint_nor._image); + g4_clear(color_from_floats(0.5, 0.5, 1.0, 0.0)); // Nor + g4_end(); + g4_begin(texpaint_pack._image); + g4_clear(color_from_floats(1.0, 0.4, 0.0, 0.0)); // Occ, rough, met + g4_end(); + let texpaint_nor_empty: render_target_t = map_get(render_path_render_targets, "texpaint_nor_empty"); + let texpaint_pack_empty: render_target_t = map_get(render_path_render_targets, "texpaint_pack_empty"); + g4_begin(texpaint_nor_empty._image); + g4_clear(color_from_floats(0.5, 0.5, 1.0, 0.0)); // Nor + g4_end(); + g4_begin(texpaint_pack_empty._image); + g4_clear(color_from_floats(1.0, 0.4, 0.0, 0.0)); // Occ, rough, met + g4_end(); + ///end +} + +function layers_resize() { + let conf: config_t = config_raw; + if (base_res_handle.position >= math_floor(texture_res_t.RES16384)) { // Save memory for >=16k + conf.undo_steps = 1; + if (context_raw.undo_handle != null) { + context_raw.undo_handle.value = conf.undo_steps; + } + while (history_undo_layers.length > conf.undo_steps) { + let l: slot_layer_t = array_pop(history_undo_layers); + app_notify_on_next_frame(function (l: slot_layer_t) { + slot_layer_unload(l); + }, l); + } + } + for (let i: i32 = 0; i < project_layers.length; ++i) { + let l: slot_layer_t = project_layers[i]; + slot_layer_resize_and_set_bits(l); + } + for (let i: i32 = 0; i < history_undo_layers.length; ++i) { + let l: slot_layer_t = history_undo_layers[i]; + slot_layer_resize_and_set_bits(l); + } + + let rts: map_t = render_path_render_targets; + + let blend0: render_target_t = map_get(rts, "texpaint_blend0"); + let _texpaint_blend0: image_t = blend0._image; + app_notify_on_next_frame(function (_texpaint_blend0: image_t) { + image_unload(_texpaint_blend0); + }, _texpaint_blend0); + blend0.width = config_get_texture_res_x(); + blend0.height = config_get_texture_res_y(); + blend0._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8); + + let blend1: render_target_t = map_get(rts, "texpaint_blend1"); + let _texpaint_blend1: image_t = blend1._image; + app_notify_on_next_frame(function (_texpaint_blend1: image_t) { + image_unload(_texpaint_blend1); + }, _texpaint_blend1); + blend1.width = config_get_texture_res_x(); + blend1.height = config_get_texture_res_y(); + blend1._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8); + + context_raw.brush_blend_dirty = true; + + let blur: render_target_t = map_get(rts, "texpaint_blur"); + if (blur != null) { + let _texpaint_blur: image_t = blur._image; + app_notify_on_next_frame(function (_texpaint_blur: image_t) { + image_unload(_texpaint_blur); + }, _texpaint_blur); + let size_x: f32 = math_floor(config_get_texture_res_x() * 0.95); + let size_y: f32 = math_floor(config_get_texture_res_y() * 0.95); + blur.width = size_x; + blur.height = size_y; + blur._image = image_create_render_target(size_x, size_y); + } + if (render_path_paint_live_layer != null) { + slot_layer_resize_and_set_bits(render_path_paint_live_layer); + } + ///if (arm_direct3d12 || arm_vulkan || arm_metal) + render_path_raytrace_ready = false; // Rebuild baketex + ///end + context_raw.ddirty = 2; +} + +function layers_set_bits() { + for (let i: i32 = 0; i < project_layers.length; ++i) { + let l: slot_layer_t = project_layers[i]; + slot_layer_resize_and_set_bits(l); + } + for (let i: i32 = 0; i < history_undo_layers.length; ++i) { + let l: slot_layer_t = history_undo_layers[i]; + slot_layer_resize_and_set_bits(l); + } +} + +function layers_make_temp_img() { + ///if (is_paint || is_sculpt) + let l: slot_layer_t = project_layers[0]; + ///end + ///if is_lab + let l: brush_output_node_t = brush_output_node_inst; + ///end + + if (layers_temp_image != null && (layers_temp_image.width != l.texpaint.width || layers_temp_image.height != l.texpaint.height || layers_temp_image.format != l.texpaint.format)) { + let _temptex0: render_target_t = map_get(render_path_render_targets, "temptex0"); + app_notify_on_next_frame(function (_temptex0: render_target_t) { + render_target_unload(_temptex0); + }, _temptex0); + map_delete(render_path_render_targets, "temptex0"); + layers_temp_image = null; + } + if (layers_temp_image == null) { + let format: string = base_bits_handle.position == texture_bits_t.BITS8 ? "RGBA32" : + base_bits_handle.position == texture_bits_t.BITS16 ? "RGBA64" : + "RGBA128"; + ///if is_lab + format = "RGBA32"; + ///end + + let t: render_target_t = render_target_create(); + t.name = "temptex0"; + t.width = l.texpaint.width; + t.height = l.texpaint.height; + t.format = format; + let rt: render_target_t = render_path_create_render_target(t); + layers_temp_image = rt._image; + } +} + +function layers_make_temp_mask_img() { + if (pipes_temp_mask_image != null && (pipes_temp_mask_image.width != config_get_texture_res_x() || pipes_temp_mask_image.height != config_get_texture_res_y())) { + let _temp_mask_image: image_t = pipes_temp_mask_image; + app_notify_on_next_frame(function (_temp_mask_image: image_t) { + image_unload(_temp_mask_image); + }, _temp_mask_image); + pipes_temp_mask_image = null; + } + if (pipes_temp_mask_image == null) { + pipes_temp_mask_image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8); + } +} + +function layers_make_export_img() { + ///if (is_paint || is_sculpt) + let l: slot_layer_t = project_layers[0]; + ///end + ///if is_lab + let l: brush_output_node_t = brush_output_node_inst; + ///end + + if (layers_expa != null && (layers_expa.width != l.texpaint.width || layers_expa.height != l.texpaint.height || layers_expa.format != l.texpaint.format)) { + let _expa: image_t = layers_expa; + let _expb: image_t = layers_expb; + let _expc: image_t = layers_expc; + app_notify_on_next_frame(function (_expa: image_t) { + image_unload(_expa); + }, _expa); + app_notify_on_next_frame(function (_expb: image_t) { + image_unload(_expb); + }, _expb); + app_notify_on_next_frame(function (_expc: image_t) { + image_unload(_expc); + }, _expc); + layers_expa = null; + layers_expb = null; + layers_expc = null; + map_delete(render_path_render_targets, "expa"); + map_delete(render_path_render_targets, "expb"); + map_delete(render_path_render_targets, "expc"); + } + if (layers_expa == null) { + let format: string = base_bits_handle.position == texture_bits_t.BITS8 ? "RGBA32" : + base_bits_handle.position == texture_bits_t.BITS16 ? "RGBA64" : + "RGBA128"; + + ///if is_lab + format = "RGBA32"; + ///end + + { + let t: render_target_t = render_target_create(); + t.name = "expa"; + t.width = l.texpaint.width; + t.height = l.texpaint.height; + t.format = format; + let rt: render_target_t = render_path_create_render_target(t); + layers_expa = rt._image; + } + + { + let t: render_target_t = render_target_create(); + t.name = "expb"; + t.width = l.texpaint.width; + t.height = l.texpaint.height; + t.format = format; + let rt: render_target_t = render_path_create_render_target(t); + layers_expb = rt._image; + } + + { + let t: render_target_t = render_target_create(); + t.name = "expc"; + t.width = l.texpaint.width; + t.height = l.texpaint.height; + t.format = format; + let rt: render_target_t = render_path_create_render_target(t); + layers_expc = rt._image; + } + } +} + +function layers_apply_mask(l: slot_layer_t, m: slot_layer_t) { + if (!slot_layer_is_layer(l) || !slot_layer_is_mask(m)) { + return; + } + + layers_make_temp_img(); + + // Copy layer to temp + g2_begin(layers_temp_image); + g2_set_pipeline(pipes_copy); + g2_draw_image(l.texpaint, 0, 0); + g2_set_pipeline(null); + g2_end(); + + // Apply mask + g4_begin(l.texpaint); + g4_set_pipeline(pipes_apply_mask); + g4_set_tex(pipes_tex0_mask, layers_temp_image); + g4_set_tex(pipes_texa_mask, m.texpaint); + g4_set_vertex_buffer(const_data_screen_aligned_vb); + g4_set_index_buffer(const_data_screen_aligned_ib); + g4_draw(); + g4_end(); +} + +function layers_commands_merge_pack(pipe: pipeline_t, i0: image_t, i1: image_t, i1pack: image_t, i1mask_opacity: f32, i1texmask: image_t, i1blending: i32 = -1) { + g4_begin(i0); + g4_set_pipeline(pipe); + g4_set_tex(pipes_tex0, i1); + g4_set_tex(pipes_tex1, i1pack); + g4_set_tex(pipes_texmask, i1texmask); + g4_set_tex(pipes_texa, layers_temp_image); + g4_set_float(pipes_opac, i1mask_opacity); + g4_set_int(pipes_blending, i1blending); + g4_set_vertex_buffer(const_data_screen_aligned_vb); + g4_set_index_buffer(const_data_screen_aligned_ib); + g4_draw(); + g4_end(); +} + +function layers_is_fill_material(): bool { + if (context_raw.tool == workspace_tool_t.MATERIAL) { + return true; + } + + let m: slot_material_t = context_raw.material; + for (let i: i32 = 0; i < project_layers.length; ++i) { + let l: slot_layer_t = project_layers[i]; + if (l.fill_layer == m) { + return true; + } + } + return false; +} + +function layers_update_fill_layers() { + let _layer: slot_layer_t = context_raw.layer; + let _tool: workspace_tool_t = context_raw.tool; + let _fill_type: i32 = context_raw.fill_type_handle.position; + let current: image_t = null; + + if (context_raw.tool == workspace_tool_t.MATERIAL) { + if (render_path_paint_live_layer == null) { + render_path_paint_live_layer = slot_layer_create("_live"); + } + + current = _g2_current; + if (current != null) g2_end(); + + context_raw.tool = workspace_tool_t.FILL; + context_raw.fill_type_handle.position = fill_type_t.OBJECT; + make_material_parse_paint_material(false); + context_raw.pdirty = 1; + render_path_paint_use_live_layer(true); + render_path_paint_commands_paint(false); + render_path_paint_dilate(true, true); + render_path_paint_use_live_layer(false); + context_raw.tool = _tool; + context_raw.fill_type_handle.position = _fill_type; + context_raw.pdirty = 0; + context_raw.rdirty = 2; + + if (current != null) g2_begin(current); + return; + } + + let has_fill_layer: bool = false; + let has_fill_mask: bool = false; + for (let i: i32 = 0; i < project_layers.length; ++i) { + let l: slot_layer_t = project_layers[i]; + if (slot_layer_is_layer(l) && l.fill_layer == context_raw.material) { + has_fill_layer = true; + } + } + for (let i: i32 = 0; i < project_layers.length; ++i) { + let l: slot_layer_t = project_layers[i]; + if (slot_layer_is_mask(l) && l.fill_layer == context_raw.material) { + has_fill_mask = true; + } + } + + if (has_fill_layer || has_fill_mask) { + current = _g2_current; + if (current != null) { + g2_end(); + } + context_raw.pdirty = 1; + context_raw.tool = workspace_tool_t.FILL; + context_raw.fill_type_handle.position = fill_type_t.OBJECT; + + if (has_fill_layer) { + let first: bool = true; + for (let i: i32 = 0; i < project_layers.length; ++i) { + let l: slot_layer_t = project_layers[i]; + if (slot_layer_is_layer(l) && l.fill_layer == context_raw.material) { + context_raw.layer = l; + if (first) { + first = false; + make_material_parse_paint_material(false); + } + layers_set_object_mask(); + slot_layer_clear(l); + render_path_paint_commands_paint(false); + render_path_paint_dilate(true, true); + } + } + } + if (has_fill_mask) { + let first: bool = true; + for (let i: i32 = 0; i < project_layers.length; ++i) { + let l: slot_layer_t = project_layers[i]; + if (slot_layer_is_mask(l) && l.fill_layer == context_raw.material) { + context_raw.layer = l; + if (first) { + first = false; + make_material_parse_paint_material(false); + } + layers_set_object_mask(); + slot_layer_clear(l); + render_path_paint_commands_paint(false); + render_path_paint_dilate(true, true); + } + } + } + + context_raw.pdirty = 0; + context_raw.ddirty = 2; + context_raw.rdirty = 2; + context_raw.layers_preview_dirty = true; // Repaint all layer previews as multiple layers might have changed. + if (current != null) g2_begin(current); + context_raw.layer = _layer; + layers_set_object_mask(); + context_raw.tool = _tool; + context_raw.fill_type_handle.position = _fill_type; + make_material_parse_paint_material(false); + } +} + +function layers_update_fill_layer(parse_paint: bool = true) { + let current: image_t = _g2_current; + let g2_in_use: bool = _g2_in_use; + if (g2_in_use) g2_end(); + + let _tool: workspace_tool_t = context_raw.tool; + let _fill_type: i32 = context_raw.fill_type_handle.position; + context_raw.tool = workspace_tool_t.FILL; + context_raw.fill_type_handle.position = fill_type_t.OBJECT; + context_raw.pdirty = 1; + + slot_layer_clear(context_raw.layer); + + if (parse_paint) { + make_material_parse_paint_material(false); + } + render_path_paint_commands_paint(false); + render_path_paint_dilate(true, true); + + context_raw.rdirty = 2; + context_raw.tool = _tool; + context_raw.fill_type_handle.position = _fill_type; + if (g2_in_use) g2_begin(current); +} + +function layers_set_object_mask() { + ///if is_sculpt + return; + ///end + + let ar: string[] = [tr("None")]; + for (let i: i32 = 0; i < project_paint_objects.length; ++i) { + let p: mesh_object_t = project_paint_objects[i]; + array_push(ar, p.base.name); + } + + let mask: i32 = context_object_mask_used() ? slot_layer_get_object_mask(context_raw.layer) : 0; + if (context_layer_filter_used()) { + mask = context_raw.layer_filter; + } + if (mask > 0) { + if (context_raw.merged_object != null) { + context_raw.merged_object.base.visible = false; + } + let o: mesh_object_t = project_paint_objects[0]; + for (let i: i32 = 0; i < project_paint_objects.length; ++i) { + let p: mesh_object_t = project_paint_objects[i]; + let mask_name: string = ar[mask]; + if (p.base.name == mask_name) { + o = p; + break; + } + } + context_select_paint_object(o); + } + else { + let is_atlas: bool = slot_layer_get_object_mask(context_raw.layer) > 0 && slot_layer_get_object_mask(context_raw.layer) <= project_paint_objects.length; + if (context_raw.merged_object == null || is_atlas || context_raw.merged_object_is_atlas) { + let visibles: mesh_object_t[] = is_atlas ? project_get_atlas_objects(slot_layer_get_object_mask(context_raw.layer)) : null; + util_mesh_merge(visibles); + } + context_select_paint_object(context_main_object()); + context_raw.paint_object.skip_context = "paint"; + context_raw.merged_object.base.visible = true; + } + util_uv_dilatemap_cached = false; +} + +function layers_new_layer(clear: bool = true, position: i32 = -1): slot_layer_t { + if (project_layers.length > layers_max_layers) { + return null; + } + + let l: slot_layer_t = slot_layer_create(); + l.object_mask = context_raw.layer_filter; + + if (position == -1) { + if (slot_layer_is_mask(context_raw.layer)) context_set_layer(context_raw.layer.parent); + array_insert(project_layers, array_index_of(project_layers, context_raw.layer) + 1, l); + } + else { + array_insert(project_layers, position, l); + } + + context_set_layer(l); + let li: i32 = array_index_of(project_layers, context_raw.layer); + if (li > 0) { + let below: slot_layer_t = project_layers[li - 1]; + if (slot_layer_is_layer(below)) { + context_raw.layer.parent = below.parent; + } + } + if (clear) { + app_notify_on_init(function (l: slot_layer_t) { + slot_layer_clear(l); + }, l); + } + context_raw.layer_preview_dirty = true; + return l; +} + +function layers_new_mask(clear: bool = true, parent: slot_layer_t, position: i32 = -1): slot_layer_t { + if (project_layers.length > layers_max_layers) { + return null; + } + let l: slot_layer_t = slot_layer_create("", layer_slot_type_t.MASK, parent); + if (position == -1) { + position = array_index_of(project_layers, parent); + } + array_insert(project_layers, position, l); + context_set_layer(l); + if (clear) { + app_notify_on_init(function (l: slot_layer_t) { + slot_layer_clear(l); + }, l); + } + context_raw.layer_preview_dirty = true; + return l; +} + +function layers_new_group(): slot_layer_t { + if (project_layers.length > layers_max_layers) { + return null; + } + let l: slot_layer_t = slot_layer_create("", layer_slot_type_t.GROUP); + array_push(project_layers, l); + context_set_layer(l); + return l; +} + +function layers_create_fill_layer(uv_type: uv_type_t = uv_type_t.UVMAP, decal_mat: mat4_t = mat4nan, position: i32 = -1) { + _layers_uv_type = uv_type; + _layers_decal_mat = decal_mat; + _layers_position = position; + app_notify_on_init(function () { + let l: slot_layer_t = layers_new_layer(false, _layers_position); + history_new_layer(); + l.uv_type = _layers_uv_type; + if (!mat4_isnan(_layers_decal_mat)) { + l.decal_mat = _layers_decal_mat; + } + l.object_mask = context_raw.layer_filter; + history_to_fill_layer(); + slot_layer_to_fill_layer(l); + }); +} + +function layers_create_image_mask(asset: asset_t) { + let l: slot_layer_t = context_raw.layer; + if (slot_layer_is_mask(l) || slot_layer_is_group(l)) { + return; + } + + history_new_layer(); + let m: slot_layer_t = layers_new_mask(false, l); + slot_layer_clear(m, 0x00000000, project_get_image(asset)); + context_raw.layer_preview_dirty = true; +} + +function layers_create_color_layer(base_color: i32, occlusion: f32 = 1.0, roughness: f32 = layers_default_rough, metallic: f32 = 0.0, position: i32 = -1) { + _layers_base_color = base_color; + _layers_occlusion = occlusion; + _layers_roughness = roughness; + _layers_metallic = metallic; + _layers_position = position; + + app_notify_on_init(function () { + let l: slot_layer_t = layers_new_layer(false, _layers_position); + history_new_layer(); + l.uv_type = uv_type_t.UVMAP; + l.object_mask = context_raw.layer_filter; + slot_layer_clear(l, _layers_base_color, null, _layers_occlusion, _layers_roughness, _layers_metallic); + }); +} + +function layers_duplicate_layer(l: slot_layer_t) { + if (!slot_layer_is_group(l)) { + let new_layer: slot_layer_t = slot_layer_duplicate(l); + context_set_layer(new_layer); + let masks: slot_layer_t[] = slot_layer_get_masks(l, false); + if (masks != null) { + for (let i: i32 = 0; i < masks.length; ++i) { + let m: slot_layer_t = masks[i]; + m = slot_layer_duplicate(m); + m.parent = new_layer; + array_remove(project_layers, m); + array_insert(project_layers, array_index_of(project_layers, new_layer), m); + } + } + context_set_layer(new_layer); + } + else { + let new_group: slot_layer_t = layers_new_group(); + array_remove(project_layers, new_group); + array_insert(project_layers, array_index_of(project_layers, l) + 1, new_group); + // group.show_panel = true; + for (let i: i32 = 0; i < slot_layer_get_children(l).length; ++i) { + let c: slot_layer_t = slot_layer_get_children(l)[i]; + let masks: slot_layer_t[] = slot_layer_get_masks(c, false); + let new_layer: slot_layer_t = slot_layer_duplicate(c); + new_layer.parent = new_group; + array_remove(project_layers, new_layer); + array_insert(project_layers, array_index_of(project_layers, new_group), new_layer); + if (masks != null) { + for (let i: i32 = 0; i < masks.length; ++i) { + let m: slot_layer_t = masks[i]; + let new_mask: slot_layer_t = slot_layer_duplicate(m); + new_mask.parent = new_layer; + array_remove(project_layers, new_mask); + array_insert(project_layers, array_index_of(project_layers, new_layer), new_mask); + } + } + } + let group_masks: slot_layer_t[] = slot_layer_get_masks(l); + if (group_masks != null) { + for (let i: i32 = 0; i < group_masks.length; ++i) { + let m: slot_layer_t = group_masks[i]; + let new_mask: slot_layer_t = slot_layer_duplicate(m); + new_mask.parent = new_group; + array_remove(project_layers, new_mask); + array_insert(project_layers, array_index_of(project_layers, new_group), new_mask); + } + } + context_set_layer(new_group); + } +} + +function layers_apply_masks(l: slot_layer_t) { + let masks: slot_layer_t[] = slot_layer_get_masks(l); + + if (masks != null) { + for (let i: i32 = 0; i < masks.length - 1; ++i) { + layers_merge_layer(masks[i + 1], masks[i]); + slot_layer_delete(masks[i]); + } + slot_layer_apply_mask(masks[masks.length - 1]); + context_raw.layer_preview_dirty = true; + } +} + +function layers_merge_down() { + let l1: slot_layer_t = context_raw.layer; + + if (slot_layer_is_group(l1)) { + l1 = layers_merge_group(l1); + } + else if (slot_layer_has_masks(l1)) { // It is a layer + layers_apply_masks(l1); + context_set_layer(l1); + } + + let l0: slot_layer_t = project_layers[array_index_of(project_layers, l1) - 1]; + + if (slot_layer_is_group(l0)) { + l0 = layers_merge_group(l0); + } + else if (slot_layer_has_masks(l0)) { // It is a layer + layers_apply_masks(l0); + context_set_layer(l0); + } + + layers_merge_layer(l0, l1); + slot_layer_delete(l1); + context_set_layer(l0); + context_raw.layer_preview_dirty = true; +} + +function layers_merge_group(l: slot_layer_t): slot_layer_t { + if (!slot_layer_is_group(l)) { + return null; + } + + let children: slot_layer_t[] = slot_layer_get_children(l); + + if (children.length == 1 && slot_layer_has_masks(children[0], false)) { + layers_apply_masks(children[0]); + } + + for (let i: i32 = 0; i < children.length - 1; ++i) { + context_set_layer(children[children.length - 1 - i]); + history_merge_layers(); + layers_merge_down(); + } + + // Now apply the group masks + let masks: slot_layer_t[] = slot_layer_get_masks(l); + if (masks != null) { + for (let i: i32 = 0; i < masks.length - 1; ++i) { + layers_merge_layer(masks[i + 1], masks[i]); + slot_layer_delete(masks[i]); + } + layers_apply_mask(children[0], masks[masks.length - 1]); + } + + children[0].parent = null; + children[0].name = l.name; + if (children[0].fill_layer != null) { + slot_layer_to_paint_layer(children[0]); + } + slot_layer_delete(l); + return children[0]; +} + +function layers_merge_layer(l0 : slot_layer_t, l1: slot_layer_t, use_mask: bool = false) { + if (!l1.visible || slot_layer_is_group(l1)) { + return; + } + + layers_make_temp_img(); + + g2_begin(layers_temp_image); // Copy to temp + g2_set_pipeline(pipes_copy); + g2_draw_image(l0.texpaint, 0, 0); + g2_set_pipeline(null); + g2_end(); + + let empty_rt: render_target_t = map_get(render_path_render_targets, "empty_white"); + let empty: image_t = empty_rt._image; + let mask: image_t = empty; + let l1masks: slot_layer_t[] = use_mask ? slot_layer_get_masks(l1) : null; + if (l1masks != null) { + // for (let i: i32 = 1; i < l1masks.length - 1; ++i) { + // mergeLayer(l1masks[i + 1], l1masks[i]); + // } + mask = l1masks[0].texpaint; + } + + if (slot_layer_is_mask(l1)) { + g4_begin(l0.texpaint); + g4_set_pipeline(pipes_merge_mask); + g4_set_tex(pipes_tex0_merge_mask, l1.texpaint); + g4_set_tex(pipes_texa_merge_mask, layers_temp_image); + g4_set_float(pipes_opac_merge_mask, slot_layer_get_opacity(l1)); + g4_set_int(pipes_blending_merge_mask, l1.blending); + g4_set_vertex_buffer(const_data_screen_aligned_vb); + g4_set_index_buffer(const_data_screen_aligned_ib); + g4_draw(); + g4_end(); + } + + if (slot_layer_is_layer(l1)) { + if (l1.paint_base) { + g4_begin(l0.texpaint); + g4_set_pipeline(pipes_merge); + g4_set_tex(pipes_tex0, l1.texpaint); + g4_set_tex(pipes_tex1, empty); + g4_set_tex(pipes_texmask, mask); + g4_set_tex(pipes_texa, layers_temp_image); + g4_set_float(pipes_opac, slot_layer_get_opacity(l1)); + g4_set_int(pipes_blending, l1.blending); + g4_set_vertex_buffer(const_data_screen_aligned_vb); + g4_set_index_buffer(const_data_screen_aligned_ib); + g4_draw(); + g4_end(); + } + + if (l0.texpaint_nor != null) { + g2_begin(layers_temp_image); + g2_set_pipeline(pipes_copy); + g2_draw_image(l0.texpaint_nor, 0, 0); + g2_set_pipeline(null); + g2_end(); + + if (l1.paint_nor) { + g4_begin(l0.texpaint_nor); + g4_set_pipeline(pipes_merge); + g4_set_tex(pipes_tex0, l1.texpaint); + g4_set_tex(pipes_tex1, l1.texpaint_nor); + g4_set_tex(pipes_texmask, mask); + g4_set_tex(pipes_texa, layers_temp_image); + g4_set_float(pipes_opac, slot_layer_get_opacity(l1)); + g4_set_int(pipes_blending, l1.paint_nor_blend ? -2 : -1); + g4_set_vertex_buffer(const_data_screen_aligned_vb); + g4_set_index_buffer(const_data_screen_aligned_ib); + g4_draw(); + g4_end(); + } + } + + if (l0.texpaint_pack != null) { + g2_begin(layers_temp_image); + g2_set_pipeline(pipes_copy); + g2_draw_image(l0.texpaint_pack, 0, 0); + g2_set_pipeline(null); + g2_end(); + + if (l1.paint_occ || l1.paint_rough || l1.paint_met || l1.paint_height) { + if (l1.paint_occ && l1.paint_rough && l1.paint_met && l1.paint_height) { + layers_commands_merge_pack(pipes_merge, l0.texpaint_pack, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask, l1.paint_height_blend ? -3 : -1); + } + else { + if (l1.paint_occ) { + layers_commands_merge_pack(pipes_merge_r, l0.texpaint_pack, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); + } + if (l1.paint_rough) { + layers_commands_merge_pack(pipes_merge_g, l0.texpaint_pack, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); + } + if (l1.paint_met) { + layers_commands_merge_pack(pipes_merge_b, l0.texpaint_pack, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask); + } + } + } + } + } +} + +function layers_flatten(height_to_normal: bool = false, layers: slot_layer_t[] = null): slot_layer_t { + return layers_ext_flatten(height_to_normal, layers); +} + +function layers_on_resized() { + layers_ext_on_resized(); +} diff --git a/base/sources/project.ts b/base/sources/project.ts index d7384ab2..bf1b06c9 100644 --- a/base/sources/project.ts +++ b/base/sources/project.ts @@ -153,7 +153,6 @@ function project_new(reset_layers: bool = true) { ///end project_filepath = ""; - ///if (is_paint || is_sculpt) if (context_raw.merged_object != null) { mesh_object_remove(context_raw.merged_object); data_delete_mesh(context_raw.merged_object.data._.handle); @@ -162,7 +161,6 @@ function project_new(reset_layers: bool = true) { context_raw.layer_preview_dirty = true; context_raw.layer_filter = 0; project_mesh_assets = []; - ///end viewport_reset(); context_raw.paint_object = context_main_object(); @@ -309,11 +307,11 @@ function project_new(reset_layers: bool = true) { array_push(project_layers, layer); context_set_layer(layer); if (aspect_ratio_changed) { - app_notify_on_init(base_resize_layers); + app_notify_on_init(layers_resize); } ///end - app_notify_on_init(base_init_layers); + app_notify_on_init(layers_init); } if (g2_in_use) g2_begin(current); diff --git a/base/sources/render_path_raytrace.ts b/base/sources/render_path_raytrace.ts index 8a41de95..b8c79b50 100644 --- a/base/sources/render_path_raytrace.ts +++ b/base/sources/render_path_raytrace.ts @@ -52,12 +52,12 @@ function render_path_raytrace_commands(use_live_layer: bool) { let bnoise_scramble: image_t = map_get(scene_embedded, "bnoise_scramble.k"); let bnoise_rank: image_t = map_get(scene_embedded, "bnoise_rank.k"); - let l: slot_layer_t = base_flatten(true); + let l: slot_layer_t = layers_flatten(true); iron_raytrace_set_textures(l.texpaint, l.texpaint_nor, l.texpaint_pack, saved_envmap.texture_, bnoise_sobol.texture_, bnoise_scramble.texture_, bnoise_rank.texture_); } ///if is_lab - let l: slot_layer_t = base_flatten(true); + let l: slot_layer_t = layers_flatten(true); if (l.texpaint != render_path_raytrace_last_texpaint) { render_path_raytrace_last_texpaint = l.texpaint; @@ -70,7 +70,7 @@ function render_path_raytrace_commands(use_live_layer: bool) { ///end if (context_raw.pdirty > 0 || render_path_raytrace_dirty > 0) { - base_flatten(true); + layers_flatten(true); } let cam: camera_object_t = scene_camera; diff --git a/base/sources/slot_layer.ts b/base/sources/slot_layer.ts index c31d25d7..28a902e2 100644 --- a/base/sources/slot_layer.ts +++ b/base/sources/slot_layer.ts @@ -243,7 +243,7 @@ function slot_layer_swap(raw: slot_layer_t, other: slot_layer_t) { } } -function slot_layer_clear(raw: slot_layer_t, base_color: i32 = 0x00000000, base_image: image_t = null, occlusion: f32 = 1.0, roughness: f32 = base_default_rough, metallic: f32 = 0.0) { +function slot_layer_clear(raw: slot_layer_t, base_color: i32 = 0x00000000, base_image: image_t = null, occlusion: f32 = 1.0, roughness: f32 = layers_default_rough, metallic: f32 = 0.0) { g4_begin(raw.texpaint); g4_clear(base_color); // Base g4_end(); @@ -290,11 +290,11 @@ function slot_layer_apply_mask(raw: slot_layer_t) { if (slot_layer_is_group(raw.parent)) { for (let i: i32 = 0; i < slot_layer_get_children(raw.parent).length; ++i) { let c: slot_layer_t = slot_layer_get_children(raw.parent)[i]; - base_apply_mask(c, raw); + layers_apply_mask(c, raw); } } else { - base_apply_mask(raw.parent, raw); + layers_apply_mask(raw.parent, raw); } slot_layer_delete(raw); } @@ -464,7 +464,7 @@ function slot_layer_resize_and_set_bits(raw: slot_layer_t) { function slot_layer_to_fill_layer(raw: slot_layer_t) { context_set_layer(raw); raw.fill_layer = context_raw.material; - base_update_fill_layer(); + layers_update_fill_layer(); app_notify_on_next_frame(function () { make_material_parse_paint_material(); context_raw.layer_preview_dirty = true; diff --git a/base/sources/tab_browser.ts b/base/sources/tab_browser.ts index 9fc4a291..a2139951 100644 --- a/base/sources/tab_browser.ts +++ b/base/sources/tab_browser.ts @@ -148,7 +148,7 @@ function tab_browser_draw(htab: ui_handle_t) { } } if (asset_index != -1) { - base_create_image_mask(project_assets[asset_index]); + layers_create_image_mask(project_assets[asset_index]); } }); }); diff --git a/base/sources/tab_layers.ts b/base/sources/tab_layers.ts index 0c5cab94..55d9d2f9 100644 --- a/base/sources/tab_layers.ts +++ b/base/sources/tab_layers.ts @@ -89,14 +89,14 @@ function tab_layers_button_new(text: string) { ui_menu_draw(function (ui: ui_t) { let l: slot_layer_t = context_raw.layer; if (ui_menu_button(ui, tr("Paint Layer"))) { - base_new_layer(); + layers_new_layer(); history_new_layer(); } if (ui_menu_button(ui, tr("Fill Layer"))) { - base_create_fill_layer(uv_type_t.UVMAP); + layers_create_fill_layer(uv_type_t.UVMAP); } if (ui_menu_button(ui, tr("Decal Layer"))) { - base_create_fill_layer(uv_type_t.PROJECT); + layers_create_fill_layer(uv_type_t.PROJECT); } if (ui_menu_button(ui, tr("Black Mask"))) { if (slot_layer_is_mask(l)) { @@ -104,13 +104,13 @@ function tab_layers_button_new(text: string) { } // let l: slot_layer_t = raw.layer; - let m: slot_layer_t = base_new_mask(false, l); + let m: slot_layer_t = layers_new_mask(false, l); app_notify_on_next_frame(function (m: slot_layer_t) { slot_layer_clear(m, 0x00000000); }, m); context_raw.layer_preview_dirty = true; history_new_black_mask(); - base_update_fill_layers(); + layers_update_fill_layers(); } if (ui_menu_button(ui, tr("White Mask"))) { if (slot_layer_is_mask(l)) { @@ -118,13 +118,13 @@ function tab_layers_button_new(text: string) { } // let l: slot_layer_t = raw.layer; - let m: slot_layer_t = base_new_mask(false, l); + let m: slot_layer_t = layers_new_mask(false, l); app_notify_on_next_frame(function (m: slot_layer_t) { slot_layer_clear(m, 0xffffffff); }, m); context_raw.layer_preview_dirty = true; history_new_white_mask(); - base_update_fill_layers(); + layers_update_fill_layers(); } if (ui_menu_button(ui, tr("Fill Mask"))) { if (slot_layer_is_mask(l)) { @@ -132,13 +132,13 @@ function tab_layers_button_new(text: string) { } // let l: slot_layer_t = raw.layer; - let m: slot_layer_t = base_new_mask(false, l); + let m: slot_layer_t = layers_new_mask(false, l); app_notify_on_init(function (m: slot_layer_t) { slot_layer_to_fill_layer(m); }, m); context_raw.layer_preview_dirty = true; history_new_fill_mask(); - base_update_fill_layers(); + layers_update_fill_layers(); } ui.enabled = !slot_layer_is_group(context_raw.layer) && !slot_layer_is_in_group(context_raw.layer); if (ui_menu_button(ui, tr("Group"))) { @@ -151,7 +151,7 @@ function tab_layers_button_new(text: string) { } let pointers: map_t = tab_layers_init_layer_map(); - let group: slot_layer_t = base_new_group(); + let group: slot_layer_t = layers_new_group(); context_set_layer(l); array_remove(project_layers, group); array_insert(project_layers, array_index_of(project_layers, l) + 1, group); @@ -203,7 +203,7 @@ function tab_layers_combo_filter() { } util_mesh_merge(visibles); } - base_set_object_mask(); + layers_set_object_mask(); util_uv_uvmap_cached = false; context_raw.ddirty = 2; ///if (arm_direct3d12 || arm_vulkan || arm_metal) @@ -511,11 +511,11 @@ function tab_layers_combo_object(ui: ui_t, l: slot_layer_t, label: bool = false) app_notify_on_init(function (l: slot_layer_t) { context_raw.material = l.fill_layer; slot_layer_clear(l); - base_update_fill_layers(); + layers_update_fill_layers(); }, l); } else { - base_set_object_mask(); + layers_set_object_mask(); } } return object_handle; @@ -840,7 +840,7 @@ function tab_layers_draw_layer_context_menu(l: slot_layer_t, mini: bool) { if (slot_layer_is_group(l) && ui_menu_button(ui, tr("Merge Group"))) { app_notify_on_init(function () { let l: slot_layer_t = tab_layers_l; - base_merge_group(l); + layers_merge_group(l); }); } ui.enabled = tab_layers_can_merge_down(l); @@ -849,7 +849,7 @@ function tab_layers_draw_layer_context_menu(l: slot_layer_t, mini: bool) { let l: slot_layer_t = tab_layers_l; context_set_layer(l); history_merge_layers(); - base_merge_down(); + layers_merge_down(); if (context_raw.layer.fill_layer != null) slot_layer_to_paint_layer(context_raw.layer); }); } @@ -859,7 +859,7 @@ function tab_layers_draw_layer_context_menu(l: slot_layer_t, mini: bool) { let l: slot_layer_t = tab_layers_l; context_set_layer(l); history_duplicate_layer(); - base_duplicate_layer(l); + layers_duplicate_layer(l); }); } @@ -891,7 +891,7 @@ function tab_layers_draw_layer_context_menu(l: slot_layer_t, mini: bool) { ui_menu_keep_open = true; } if (res_handle_changed_last && !base_res_handle.changed) { - base_on_layers_resized(); + layers_on_resized(); } ui._y = _y; ui_draw_string(tr("Res"), -1, 0, ui_align_t.RIGHT, true); @@ -906,7 +906,7 @@ function tab_layers_draw_layer_context_menu(l: slot_layer_t, mini: bool) { ui_inline_radio(base_bits_handle, bits_items, ui_align_t.LEFT); ///end if (base_bits_handle.changed) { - app_notify_on_init(base_set_layer_bits); + app_notify_on_init(layers_set_bits); ui_menu_keep_open = true; } } @@ -920,7 +920,7 @@ function tab_layers_draw_layer_context_menu(l: slot_layer_t, mini: bool) { context_set_material(l.fill_layer); context_set_layer(l); app_notify_on_init(function () { - base_update_fill_layers(); + layers_update_fill_layers(); }); ui_menu_keep_open = true; } @@ -934,7 +934,7 @@ function tab_layers_draw_layer_context_menu(l: slot_layer_t, mini: bool) { context_set_layer(l); make_material_parse_paint_material(); app_notify_on_init(function () { - base_update_fill_layers(); + layers_update_fill_layers(); }); ui_menu_keep_open = true; } @@ -949,7 +949,7 @@ function tab_layers_draw_layer_context_menu(l: slot_layer_t, mini: bool) { context_set_layer(l); make_material_parse_paint_material(); app_notify_on_init(function () { - base_update_fill_layers(); + layers_update_fill_layers(); }); ui_menu_keep_open = true; } @@ -1069,7 +1069,7 @@ function tab_layers_delete_layer(l: slot_layer_t) { if (slot_layer_is_mask(l)) { context_raw.layer = l.parent; - base_update_fill_layers(); + layers_update_fill_layers(); } // Remove empty group diff --git a/base/sources/tab_materials.ts b/base/sources/tab_materials.ts index 7f10d8e7..41a3b6f6 100644 --- a/base/sources/tab_materials.ts +++ b/base/sources/tab_materials.ts @@ -132,7 +132,7 @@ function tab_materials_draw_slots(mini: bool) { context_select_material(i); ///if is_paint if (context_raw.tool == workspace_tool_t.MATERIAL) { - app_notify_on_init(base_update_fill_layers); + app_notify_on_init(layers_update_fill_layers); } ///end } @@ -159,7 +159,7 @@ function tab_materials_draw_slots(mini: bool) { if (ui_menu_button(ui, tr("To Fill Layer"))) { context_select_material(i); - base_create_fill_layer(); + layers_create_fill_layer(); } if (ui_menu_button(ui, tr("Export"))) { diff --git a/base/sources/tab_swatches.ts b/base/sources/tab_swatches.ts index 74e37c75..61164d14 100644 --- a/base/sources/tab_swatches.ts +++ b/base/sources/tab_swatches.ts @@ -209,7 +209,7 @@ function tab_swatches_draw(htab: ui_handle_t) { else if (ui_menu_button(ui, tr("Create Color Layer"))) { let color: i32 = project_raw.swatches[i].base; color = color_set_ab(color, project_raw.swatches[i].opacity * 255); - base_create_color_layer(color, project_raw.swatches[i].occlusion, project_raw.swatches[i].roughness, project_raw.swatches[i].metallic); + layers_create_color_layer(color, project_raw.swatches[i].occlusion, project_raw.swatches[i].roughness, project_raw.swatches[i].metallic); } ///end }); diff --git a/base/sources/tab_textures.ts b/base/sources/tab_textures.ts index a9da2cbf..70617916 100644 --- a/base/sources/tab_textures.ts +++ b/base/sources/tab_textures.ts @@ -166,7 +166,7 @@ function tab_textures_draw(htab: ui_handle_t) { ///if (is_paint || is_sculpt) if (ui_menu_button(ui, tr("To Mask"))) { app_notify_on_next_frame(function () { - base_create_image_mask(_tab_textures_draw_asset); + layers_create_image_mask(_tab_textures_draw_asset); }); } ///end diff --git a/base/sources/ui_base.ts b/base/sources/ui_base.ts index b9a9be64..fe2a792d 100644 --- a/base/sources/ui_base.ts +++ b/base/sources/ui_base.ts @@ -178,7 +178,7 @@ function ui_base_init() { project_canvas = armpack_decode(project_default_canvas); project_canvas.name = "Brush 1"; - context_parse_brush_inputs(); + brush_output_node_parse_inputs(); parser_logic_parse(project_canvas); ///end @@ -261,7 +261,7 @@ function ui_base_init() { project_paint_objects = [context_raw.paint_object]; if (project_filepath == "") { - app_notify_on_init(base_init_layers); + app_notify_on_init(layers_init); } context_raw.project_objects = []; @@ -1128,17 +1128,9 @@ function ui_base_update_ui() { context_raw.brush_time += time_delta(); - ///if (is_paint || is_sculpt) if (context_raw.run_brush != null) { context_raw.run_brush(context_raw.brush_output_node_inst, 0); } - ///end - ///if is_lab - if (context_run_brush != null) { - // context_run_brush(context_raw.brush_output_node_inst, 0); - context_run_brush(0); - } - ///end } } } @@ -1156,7 +1148,7 @@ function ui_base_update_ui() { // New color id picked, update fill layer if (context_raw.tool == workspace_tool_t.COLORID && context_raw.layer.fill_layer != null) { app_notify_on_next_frame(function () { - base_update_fill_layer(); + layers_update_fill_layer(); make_material_parse_paint_material(false); }); } diff --git a/base/sources/ui_header.ts b/base/sources/ui_header.ts index 859d1281..148e57e5 100644 --- a/base/sources/ui_header.ts +++ b/base/sources/ui_header.ts @@ -88,7 +88,7 @@ function ui_header_draw_tool_properties(ui: ui_t) { if (slot_layer_is_mask(context_raw.layer)) { context_set_layer(context_raw.layer.parent); } - let m: slot_layer_t = base_new_mask(false, context_raw.layer); + let m: slot_layer_t = layers_new_mask(false, context_raw.layer); app_notify_on_next_frame(function (m: slot_layer_t) { g4_begin(m.texpaint); g4_set_pipeline(pipes_colorid_to_mask); @@ -103,7 +103,7 @@ function ui_header_draw_tool_properties(ui: ui_t) { ui_toolbar_handle.redraws = 1; ui_header_handle.redraws = 1; context_raw.layer_preview_dirty = true; - base_update_fill_layers(); + layers_update_fill_layers(); }, m); history_new_white_mask(); } diff --git a/base/sources/ui_menu.ts b/base/sources/ui_menu.ts index 6410984c..589ddc77 100644 --- a/base/sources/ui_menu.ts +++ b/base/sources/ui_menu.ts @@ -44,7 +44,7 @@ function ui_menu_render() { } else { if (ui_menu_category == menu_category_t.FILE) { - if (ui_menu_button(ui, tr("New .."), map_get(config_keymap, "file_new"))) { + if (ui_menu_button(ui, tr("New Project..."), map_get(config_keymap, "file_new"))) { project_new_box(); } if (ui_menu_button(ui, tr("Open..."), map_get(config_keymap, "file_open"))) { diff --git a/base/sources/ui_nodes.ts b/base/sources/ui_nodes.ts index 4fb94bfb..a899cbc2 100644 --- a/base/sources/ui_nodes.ts +++ b/base/sources/ui_nodes.ts @@ -753,7 +753,7 @@ function ui_nodes_render() { ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2; } else { - base_is_fill_material() ? base_update_fill_layers() : util_render_make_material_preview(); + layers_is_fill_material() ? layers_update_fill_layers() : util_render_make_material_preview(); if (ui_view2d_show && ui_view2d_type == view_2d_type_t.NODE) { ui_view2d_hwnd.redraws = 2; } @@ -775,8 +775,8 @@ function ui_nodes_render() { ///if (is_paint || is_sculpt) make_material_parse_paint_material(); - if (ui_nodes_canvas_type == canvas_type_t.MATERIAL && base_is_fill_material()) { - base_update_fill_layers(); + if (ui_nodes_canvas_type == canvas_type_t.MATERIAL && layers_is_fill_material()) { + layers_update_fill_layers(); util_render_make_material_preview(); } diff --git a/base/sources/ui_view2d.ts b/base/sources/ui_view2d.ts index 58bca624..ebf0986a 100644 --- a/base/sources/ui_view2d.ts +++ b/base/sources/ui_view2d.ts @@ -173,14 +173,14 @@ function ui_view2d_render() { let current: image_t = _g2_current; let g2_in_use: bool = _g2_in_use; if (g2_in_use) g2_end(); - layer = base_flatten(); + layer = layers_flatten(); if (g2_in_use) g2_begin(current); } else if (slot_layer_is_group(layer)) { let current: image_t = _g2_current; let g2_in_use: bool = _g2_in_use; if (g2_in_use) g2_end(); - layer = base_flatten(false, slot_layer_get_children(layer)); + layer = layers_flatten(false, slot_layer_get_children(layer)); if (g2_in_use) g2_begin(current); }