paint: path and curve layers
This commit is contained in:
@@ -365,19 +365,19 @@ gpu_texture_t *base_get_drag_image() {
|
||||
base_drag_tint = base_darker(ui->ops->theme->LABEL_COL, 0x00202020);
|
||||
return icons;
|
||||
}
|
||||
if (base_drag_layer != NULL && slot_layer_is_mask(base_drag_layer) && base_drag_layer->fill_layer == NULL) {
|
||||
if (base_drag_layer != NULL && slot_layer_is_mask(base_drag_layer) && base_drag_layer->fill_material == NULL) {
|
||||
tab_layers_make_mask_preview_rgba32(base_drag_layer);
|
||||
return g_context->mask_preview_rgba32;
|
||||
}
|
||||
if (base_drag_layer != NULL) {
|
||||
return base_drag_layer->fill_layer != NULL ? base_drag_layer->fill_layer->image_icon : base_drag_layer->texpaint_preview;
|
||||
return base_drag_layer->fill_material != NULL ? base_drag_layer->fill_material->image_icon : base_drag_layer->texpaint_preview;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rect_t *base_get_drag_background() {
|
||||
gpu_texture_t *icons = resource_get("icons.k");
|
||||
if (base_drag_layer != NULL && !slot_layer_is_group(base_drag_layer) && base_drag_layer->fill_layer == NULL) {
|
||||
if (base_drag_layer != NULL && !slot_layer_is_group(base_drag_layer) && base_drag_layer->fill_material == NULL) {
|
||||
return resource_tile50(icons, ICON_CHECKER);
|
||||
}
|
||||
return NULL;
|
||||
@@ -766,6 +766,7 @@ void ui_base_update_ui() {
|
||||
}
|
||||
|
||||
gizmo_update();
|
||||
util_layer_update_path();
|
||||
|
||||
// Same mapping for paint and rotate (predefined in touch keymap)
|
||||
if (context_in_3d_view()) {
|
||||
@@ -932,7 +933,7 @@ void ui_base_update_ui() {
|
||||
g_context->layer_preview_dirty = true; // Update layer preview
|
||||
|
||||
// New color id picked, update fill layer
|
||||
if (g_context->tool == TOOL_TYPE_COLORID && g_context->layer->fill_layer != NULL) {
|
||||
if (g_context->tool == TOOL_TYPE_COLORID && g_context->layer->fill_material != NULL) {
|
||||
sys_notify_on_next_frame(&ui_base_update_ui_on_next_frame, NULL);
|
||||
}
|
||||
}
|
||||
@@ -2066,7 +2067,7 @@ void base_toggle_fullscreen() {
|
||||
|
||||
bool base_is_decal_layer() {
|
||||
bool is_painting = g_context->tool != TOOL_TYPE_MATERIAL && g_context->tool != TOOL_TYPE_BAKE;
|
||||
return is_painting && g_context->layer->fill_layer != NULL && g_context->layer->uv_type == UV_TYPE_PROJECT;
|
||||
return is_painting && g_context->layer->fill_material != NULL && g_context->layer->uv_type == UV_TYPE_PROJECT;
|
||||
}
|
||||
|
||||
void base_redraw_status() {
|
||||
|
||||
@@ -64,7 +64,8 @@ void brush_output_node_parse_inputs(brush_output_node_t *self) {
|
||||
}
|
||||
|
||||
void brush_output_paint(brush_output_node_t *self) {
|
||||
bool down = mouse_down("left") || pen_down("tip");
|
||||
bool down = mouse_down("left") || pen_down("tip");
|
||||
bool started = mouse_started("left") || pen_started("tip");
|
||||
|
||||
// Set color pick
|
||||
if (down && g_context->tool == TOOL_TYPE_COLORID && project_assets->length > 0) {
|
||||
@@ -72,6 +73,16 @@ void brush_output_paint(brush_output_node_t *self) {
|
||||
ui_toolbar_handle->redraws = 1;
|
||||
}
|
||||
|
||||
// Path layer - add path points only
|
||||
if (slot_layer_is_path(g_context->layer) && !started) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Path layer - dragging existing path point
|
||||
if (slot_layer_is_path(g_context->layer) && util_layer_is_path_point_dragging()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent painting the same spot
|
||||
bool same_spot = g_context->paint_vec.x == g_context->last_paint_x && g_context->paint_vec.y == g_context->last_paint_y;
|
||||
bool lazy = g_context->tool == TOOL_TYPE_BRUSH && g_context->brush_lazy_radius > 0;
|
||||
@@ -92,6 +103,12 @@ void brush_output_paint(brush_output_node_t *self) {
|
||||
brush_output_node_parse_inputs(self);
|
||||
}
|
||||
|
||||
// Path layer - add point and repaint
|
||||
if (slot_layer_is_path(g_context->layer)) {
|
||||
util_layer_add_path_point(g_context->layer, g_context->paint_vec.x, g_context->paint_vec.y);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_context->painted <= 1) {
|
||||
g_context->pdirty = 1;
|
||||
g_context->rdirty = 2;
|
||||
@@ -135,7 +152,7 @@ void brush_output_node_run(brush_output_node_t *self, i32 from) {
|
||||
}
|
||||
|
||||
// Do not paint over fill layer
|
||||
if (g_context->layer->fill_layer != NULL && g_context->tool != TOOL_TYPE_PICKER && g_context->tool != TOOL_TYPE_MATERIAL &&
|
||||
if (g_context->layer->fill_material != NULL && g_context->tool != TOOL_TYPE_PICKER && g_context->tool != TOOL_TYPE_MATERIAL &&
|
||||
g_context->tool != TOOL_TYPE_COLORID) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ buffer_t *export_arm_rgba64_to_rgba32(buffer_t *buffer) {
|
||||
void export_arm_run_project() {
|
||||
|
||||
workflow_t _workflow = g_config->workflow;
|
||||
g_config->workflow = WORKFLOW_PBR;
|
||||
g_config->workflow = WORKFLOW_PBR;
|
||||
base_update_workflow();
|
||||
|
||||
ui_node_canvas_t_array_t *mnodes = any_array_create_from_raw((void *[]){}, 0);
|
||||
@@ -182,7 +182,7 @@ void export_arm_run_project() {
|
||||
.uv_map = l->uv_map,
|
||||
.decal_mat = l->uv_type == UV_TYPE_PROJECT ? mat4_to_f32_array(l->decal_mat) : NULL,
|
||||
.opacity_mask = l->mask_opacity,
|
||||
.fill_layer = l->fill_layer != NULL ? array_index_of(project_materials, l->fill_layer) : -1,
|
||||
.fill_material = l->fill_material != NULL ? array_index_of(project_materials, l->fill_material) : -1,
|
||||
.object_mask = l->object_mask,
|
||||
.blending = l->blending,
|
||||
.parent = l->parent != NULL ? array_index_of(project_layers, l->parent) : -1,
|
||||
@@ -199,7 +199,14 @@ void export_arm_run_project() {
|
||||
.paint_height = l->paint_height,
|
||||
.paint_height_blend = l->paint_height_blend,
|
||||
.paint_emis = l->paint_emis,
|
||||
.paint_subs = l->paint_subs});
|
||||
.paint_subs = l->paint_subs,
|
||||
.path_points = l->path_points,
|
||||
.path_points_world = l->path_points_world,
|
||||
.path_points_camera = l->path_points_camera,
|
||||
.path_points_parent = l->path_points_parent,
|
||||
.path_tool = l->path_tool,
|
||||
.path_curved = l->path_curved,
|
||||
.path_material = l->path_material != NULL ? array_index_of(project_materials, l->path_material) : -1});
|
||||
any_array_push(ld, d);
|
||||
}
|
||||
|
||||
@@ -236,8 +243,8 @@ void export_arm_run_project() {
|
||||
|
||||
f32_array_t_array_t *mesh_transforms = any_array_create_from_raw((void *[]){}, 0);
|
||||
for (i32 i = 0; i < project_paint_objects->length; ++i) {
|
||||
mesh_object_t *p = project_paint_objects->buffer[i];
|
||||
f32_array_t *ar = f32_array_create_from_raw(p->base->transform->local.m, 16);
|
||||
mesh_object_t *p = project_paint_objects->buffer[i];
|
||||
f32_array_t *ar = f32_array_create_from_raw(p->base->transform->local.m, 16);
|
||||
any_array_push(mesh_transforms, ar);
|
||||
}
|
||||
g_project->mesh_transforms = mesh_transforms;
|
||||
|
||||
@@ -38,6 +38,7 @@ slot_layer_t_array_t *slot_layer_get_filters(slot_layer_t *raw, bool include_gro
|
||||
f32 slot_layer_get_opacity(slot_layer_t *raw);
|
||||
i32 slot_layer_get_object_mask(slot_layer_t *raw);
|
||||
bool slot_layer_is_layer(slot_layer_t *raw);
|
||||
bool slot_layer_is_path(slot_layer_t *raw);
|
||||
bool slot_layer_is_group(slot_layer_t *raw);
|
||||
slot_layer_t *slot_layer_get_containing_group(slot_layer_t *raw);
|
||||
bool slot_layer_is_filter(slot_layer_t *raw);
|
||||
@@ -57,12 +58,15 @@ void layers_commands_merge_pack(gpu_pipeline_t *pipe, gpu_texture_t *i0, gpu_tex
|
||||
i32 i1blending);
|
||||
bool layers_is_fill_material();
|
||||
void layers_update_fill_layers();
|
||||
bool layers_is_path_material();
|
||||
void layers_update_path_layers();
|
||||
void layers_update_fill_layer(bool parse_paint);
|
||||
void layers_update_linked_layers();
|
||||
void layers_set_object_mask();
|
||||
slot_layer_t *layers_new_layer(bool clear, i32 position, slot_layer_t *parent);
|
||||
slot_layer_t *layers_new_mask(bool clear, slot_layer_t *parent, i32 position);
|
||||
slot_layer_t *layers_new_group();
|
||||
slot_layer_t *layers_new_path_layer(bool curved);
|
||||
void layers_create_fill_layer(uv_type_t uv_type, mat4_t decal_mat, i32 position);
|
||||
void layers_create_image_mask(asset_t *asset);
|
||||
void layers_create_color_layer(i32 base_color, f32 occlusion, f32 roughness, f32 metallic, i32 position);
|
||||
@@ -172,6 +176,11 @@ void ui_base_toggle_browser();
|
||||
void ui_base_set_icon_scale();
|
||||
void ui_base_set_viewport_col(i32 col);
|
||||
void gizmo_update();
|
||||
void util_layer_update_path();
|
||||
bool util_layer_is_path_point_dragging();
|
||||
void util_layer_add_path_point(slot_layer_t *l, f32 screen_x, f32 screen_y);
|
||||
void util_layer_repaint_path(slot_layer_t *l);
|
||||
void util_layer_clear_path_points(slot_layer_t *l);
|
||||
void make_texcoord_run(node_shader_t *kong);
|
||||
void context_init();
|
||||
void context_select_material(i32 i);
|
||||
|
||||
@@ -165,8 +165,8 @@ void gizmo_update() {
|
||||
}
|
||||
g_context->gizmo_drag_last = g_context->gizmo_drag;
|
||||
|
||||
if (g_context->material != g_context->layer->fill_layer) {
|
||||
context_set_material(g_context->layer->fill_layer);
|
||||
if (g_context->material != g_context->layer->fill_material) {
|
||||
context_set_material(g_context->layer->fill_material);
|
||||
}
|
||||
layers_update_fill_layer(g_context->gizmo_started);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
char *manifest_title = "ArmorPaint";
|
||||
char *manifest_version = "1.0 alpha";
|
||||
char *manifest_version_project = "6";
|
||||
char *manifest_version_project = "7";
|
||||
char *manifest_version_config = "1";
|
||||
char *manifest_url = "https://armorpaint.org";
|
||||
char *manifest_url_android = "https://play.google.com/store/apps/details?id=org.armorpaint";
|
||||
|
||||
@@ -264,7 +264,7 @@ void history_undo() {
|
||||
history_undo_i = history_undo_i - 1 < 0 ? g_config->undo_steps - 1 : history_undo_i - 1;
|
||||
slot_layer_t *lay = history_undo_layers->buffer[history_undo_i];
|
||||
slot_layer_swap(g_context->layer, lay);
|
||||
g_context->layer->fill_layer = project_materials->buffer[step->material];
|
||||
g_context->layer->fill_material = project_materials->buffer[step->material];
|
||||
}
|
||||
else if (step->action == HISTORY_ACTION_LAYER_OPACITY) {
|
||||
context_set_layer(project_layers->buffer[step->layer]);
|
||||
@@ -536,7 +536,7 @@ void history_redo() {
|
||||
else if (step->action == HISTORY_ACTION_TO_FILL_LAYER || step->action == HISTORY_ACTION_TO_FILL_MASK) {
|
||||
slot_layer_t *lay = history_undo_layers->buffer[history_undo_i];
|
||||
slot_layer_swap(g_context->layer, lay);
|
||||
g_context->layer->fill_layer = project_materials->buffer[step->material];
|
||||
g_context->layer->fill_material = project_materials->buffer[step->material];
|
||||
history_undo_i = (history_undo_i + 1) % g_config->undo_steps;
|
||||
}
|
||||
else if (step->action == HISTORY_ACTION_TO_PAINT_LAYER || step->action == HISTORY_ACTION_TO_PAINT_MASK) {
|
||||
|
||||
@@ -526,6 +526,12 @@ void import_arm_run_project(char *path) {
|
||||
l->paint_height_blend = ld->paint_height_blend;
|
||||
l->paint_emis = ld->paint_emis;
|
||||
l->paint_subs = ld->paint_subs;
|
||||
l->path_points = ld->path_points;
|
||||
l->path_points_world = ld->path_points_world;
|
||||
l->path_points_camera = ld->path_points_camera;
|
||||
l->path_points_parent = ld->path_points_parent;
|
||||
l->path_tool = ld->path_tool;
|
||||
l->path_curved = ld->path_curved;
|
||||
|
||||
gpu_delete_texture(_texpaint);
|
||||
if (_texpaint_nor != NULL) {
|
||||
@@ -594,13 +600,14 @@ void import_arm_run_project(char *path) {
|
||||
util_render_make_brush_preview();
|
||||
}
|
||||
|
||||
// Fill layers
|
||||
// Fill layers and path layers materials
|
||||
for (i32 i = 0; i < project->layer_datas->length; ++i) {
|
||||
layer_data_t *ld = project->layer_datas->buffer[i];
|
||||
slot_layer_t *l = project_layers->buffer[i];
|
||||
bool is_group = ld->texpaint == NULL;
|
||||
if (!is_group) {
|
||||
l->fill_layer = ld->fill_layer > -1 ? project_materials->buffer[ld->fill_layer] : NULL;
|
||||
l->fill_material = ld->fill_material > -1 ? project_materials->buffer[ld->fill_material] : NULL;
|
||||
l->path_material = ld->path_material > -1 ? project_materials->buffer[ld->path_material] : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ project_t *import_arm_from_map_to_arm(any_map_t *old) {
|
||||
ld->uv_type = armpack_map_get_i32(old, "uv_type");
|
||||
ld->decal_mat = any_map_get(old, "decal_mat");
|
||||
ld->opacity_mask = armpack_map_get_f32(old, "opacity_mask");
|
||||
ld->fill_layer = armpack_map_get_i32(old, "fill_layer");
|
||||
ld->fill_material = armpack_map_get_i32(old, "fill_material");
|
||||
ld->object_mask = armpack_map_get_i32(old, "object_mask");
|
||||
ld->blending = armpack_map_get_i32(old, "blending");
|
||||
ld->parent = armpack_map_get_i32(old, "parent");
|
||||
@@ -215,6 +215,24 @@ project_t *import_arm_from_map_to_arm(any_map_t *old) {
|
||||
return project;
|
||||
}
|
||||
|
||||
project_t *import_arm_from_version_6(any_map_t *old) {
|
||||
any_array_t *lds = any_map_get(old, "layer_datas");
|
||||
if (lds != NULL) {
|
||||
for (i32 i = 0; i < lds->length; ++i) {
|
||||
any_map_t *ld = lds->buffer[i];
|
||||
armpack_map_set_i32(ld, "fill_material", armpack_map_get_i32(ld, "fill_layer"));
|
||||
any_map_set(ld, "path_points", NULL);
|
||||
any_map_set(ld, "path_points_world", NULL);
|
||||
any_map_set(ld, "path_points_camera", NULL);
|
||||
any_map_set(ld, "path_points_parent", NULL);
|
||||
armpack_map_set_i32(ld, "path_tool", 0);
|
||||
armpack_map_set_i32(ld, "path_curved", 0);
|
||||
armpack_map_set_i32(ld, "path_material", -1);
|
||||
}
|
||||
}
|
||||
return import_arm_from_map_to_arm(old);
|
||||
}
|
||||
|
||||
project_t *import_arm_from_version_5(any_map_t *old) {
|
||||
any_array_t *mds = any_map_get(old, "mesh_datas");
|
||||
any_array_t *mts = any_array_create_from_raw((void *[]){}, 0);
|
||||
@@ -222,7 +240,7 @@ project_t *import_arm_from_version_5(any_map_t *old) {
|
||||
any_array_push(mts, mat4_to_f32_array(mat4_identity()));
|
||||
}
|
||||
any_map_set(old, "mesh_transforms", mts);
|
||||
return import_arm_from_map_to_arm(old);
|
||||
return import_arm_from_version_6(old);
|
||||
}
|
||||
|
||||
project_t *import_arm_from_version_4(any_map_t *old) {
|
||||
@@ -255,6 +273,9 @@ project_t *import_arm_from_version_2(any_map_t *old) {
|
||||
|
||||
project_t *import_arm_from_old(buffer_t *b) {
|
||||
any_map_t *old = armpack_decode_to_map(b);
|
||||
if (import_arm_is_version(b, '6')) {
|
||||
return import_arm_from_version_6(old);
|
||||
}
|
||||
if (import_arm_is_version(b, '5')) {
|
||||
return import_arm_from_version_5(old);
|
||||
}
|
||||
|
||||
@@ -193,9 +193,10 @@
|
||||
#include "ui_statusbar.c"
|
||||
#include "ui_toolbar.c"
|
||||
#include "ui_view2d.c"
|
||||
#include "uniforms_ext.c"
|
||||
#include "uniforms.c"
|
||||
#include "util_clone.c"
|
||||
#include "util_encode.c"
|
||||
#include "util_layer.c"
|
||||
#include "util_mesh.c"
|
||||
#include "util_particle.c"
|
||||
#include "util_render.c"
|
||||
|
||||
@@ -9,7 +9,7 @@ void make_brush_run(node_shader_t *kong) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool fill_layer = g_context->layer->fill_layer != NULL;
|
||||
bool fill_layer = g_context->layer->fill_material != NULL;
|
||||
bool decal = context_is_decal();
|
||||
if (decal && !fill_layer) {
|
||||
node_shader_write_frag(kong, "if (constants.decal_mask.z > 0.0) {");
|
||||
|
||||
@@ -190,7 +190,7 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
|
||||
|
||||
node_shader_write_vert(kong, "output.pos = float4(tpos, 0.0, 1.0);");
|
||||
|
||||
bool decal_layer = g_context->layer->fill_layer != NULL && g_context->layer->uv_type == UV_TYPE_PROJECT;
|
||||
bool decal_layer = g_context->layer->fill_material != NULL && g_context->layer->uv_type == UV_TYPE_PROJECT;
|
||||
if (decal_layer) {
|
||||
node_shader_add_constant(kong, "WVP: float4x4", "_decal_layer_matrix");
|
||||
}
|
||||
@@ -207,7 +207,7 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
|
||||
node_shader_write_attrib_frag(kong, "sp.y = 1.0 - sp.y;");
|
||||
node_shader_write_attrib_frag(kong, "sp.z -= 0.0001;"); // small bias
|
||||
|
||||
uv_type_t uv_type = g_context->layer->fill_layer != NULL ? g_context->layer->uv_type : g_context->brush_paint;
|
||||
uv_type_t uv_type = g_context->layer->fill_material != NULL ? g_context->layer->uv_type : g_context->brush_paint;
|
||||
if (uv_type == UV_TYPE_PROJECT) {
|
||||
kong->frag_ndcpos = true;
|
||||
}
|
||||
@@ -311,7 +311,7 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
|
||||
parser_material_parse_subsurface = g_context->material->paint_subs;
|
||||
parser_material_parse_height = g_context->material->paint_height;
|
||||
parser_material_parse_height_as_channel = true;
|
||||
uv_type_t uv_type = g_context->layer->fill_layer != NULL ? g_context->layer->uv_type : g_context->brush_paint;
|
||||
uv_type_t uv_type = g_context->layer->fill_material != NULL ? g_context->layer->uv_type : g_context->brush_paint;
|
||||
parser_material_triplanar = uv_type == UV_TYPE_TRIPLANAR && !decal;
|
||||
parser_material_sample_keep_aspect = decal;
|
||||
gc_unroot(parser_material_sample_uv_scale);
|
||||
@@ -346,7 +346,7 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
|
||||
node_shader_write_frag(kong, "var opacity: float = mat_opacity;");
|
||||
}
|
||||
|
||||
if (g_context->layer->fill_layer == NULL) {
|
||||
if (g_context->layer->fill_material == NULL) {
|
||||
node_shader_write_frag(kong, "opacity *= constants.brush_opacity;");
|
||||
}
|
||||
|
||||
@@ -512,7 +512,7 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
|
||||
node_shader_write_frag(kong,
|
||||
"output[0] = float4((basecol * t_blur + sample_undo.rgb * sample_undo.a * (1.0 - t_blur)) / max(out_a, 0.0000001), out_a);");
|
||||
}
|
||||
else if (g_context->material->paint_opac_mode == OPACITY_MODE_TRANSLUC || g_context->layer->fill_layer != NULL) {
|
||||
else if (g_context->material->paint_opac_mode == OPACITY_MODE_TRANSLUC || g_context->layer->fill_material != NULL) {
|
||||
node_shader_write_frag(kong, string("output[0] = float4(%s, %s);",
|
||||
make_material_blend_mode(kong, g_context->brush_blending, "sample_undo.rgb", "basecol", "str"), "mat_opacity"));
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ node_shader_context_t *sculpt_make_sculpt_run(material_t *data, material_context
|
||||
node_shader_write_frag(kong, "var sample_undo: float4 = sample_lod(texpaint_sculpt_undo, sampler_linear, sculpt_uv, 0.0);");
|
||||
node_shader_write_frag(kong, "var raw_undo: float4 = texpaint_sculpt_undo[uint2(uint(tex_coord.x * 2048.0), uint(tex_coord.y * 2048.0))];");
|
||||
|
||||
if (g_context->layer->fill_layer != NULL) {
|
||||
if (g_context->layer->fill_material != NULL) {
|
||||
node_shader_add_function(kong, str_octahedron_wrap);
|
||||
node_shader_write_frag(kong, "var nor_v: float = floor(raw_undo.a) / 255.0;");
|
||||
node_shader_write_frag(kong, "var nor_oct: float2 = float2(raw_undo.a - floor(raw_undo.a), nor_v) * 2.0 - 1.0;");
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
void make_texcoord_run(node_shader_t *kong) {
|
||||
|
||||
bool fill_layer = g_context->layer->fill_layer != NULL;
|
||||
bool fill_layer = g_context->layer->fill_material != NULL;
|
||||
uv_type_t uv_type = fill_layer ? g_context->layer->uv_type : g_context->brush_paint;
|
||||
bool decal = context_is_decal();
|
||||
f32 angle = g_context->brush_angle + g_context->brush_nodes_angle;
|
||||
|
||||
@@ -662,7 +662,7 @@ void render_path_paint_commands_cursor() {
|
||||
return;
|
||||
}
|
||||
|
||||
bool fill_layer = g_context->layer->fill_layer != NULL;
|
||||
bool fill_layer = g_context->layer->fill_material != NULL;
|
||||
bool group_layer = slot_layer_is_group(g_context->layer);
|
||||
if (!base_ui_enabled || base_is_dragging || fill_layer || group_layer) {
|
||||
return;
|
||||
@@ -676,7 +676,7 @@ void render_path_paint_commands_cursor() {
|
||||
}
|
||||
|
||||
bool render_path_paint_paint_enabled() {
|
||||
bool fill_layer = g_context->layer->fill_layer != NULL && g_context->tool != TOOL_TYPE_PICKER && g_context->tool != TOOL_TYPE_MATERIAL &&
|
||||
bool fill_layer = g_context->layer->fill_material != NULL && g_context->tool != TOOL_TYPE_PICKER && g_context->tool != TOOL_TYPE_MATERIAL &&
|
||||
g_context->tool != TOOL_TYPE_COLORID;
|
||||
bool group_layer = slot_layer_is_group(g_context->layer);
|
||||
|
||||
|
||||
+52
-12
@@ -280,7 +280,7 @@ void layers_apply_mask(slot_layer_t *l, slot_layer_t *m) {
|
||||
}
|
||||
|
||||
void slot_layer_apply_mask(slot_layer_t *raw) {
|
||||
if (raw->parent->fill_layer != NULL) {
|
||||
if (raw->parent->fill_material != NULL) {
|
||||
slot_layer_to_paint_layer(raw->parent);
|
||||
}
|
||||
if (slot_layer_is_group(raw->parent)) {
|
||||
@@ -346,7 +346,7 @@ slot_layer_t *slot_layer_duplicate(slot_layer_t *raw) {
|
||||
|
||||
l->visible = raw->visible;
|
||||
l->mask_opacity = raw->mask_opacity;
|
||||
l->fill_layer = raw->fill_layer;
|
||||
l->fill_material = raw->fill_material;
|
||||
l->object_mask = raw->object_mask;
|
||||
l->blending = raw->blending;
|
||||
l->uv_type = raw->uv_type;
|
||||
@@ -453,14 +453,14 @@ void slot_layer_to_fill_layer_on_next_frame(void *_) {
|
||||
|
||||
void slot_layer_to_fill_layer(slot_layer_t *raw) {
|
||||
context_set_layer(raw);
|
||||
raw->fill_layer = g_context->material;
|
||||
raw->fill_material = g_context->material;
|
||||
layers_update_fill_layer(true);
|
||||
sys_notify_on_next_frame(&slot_layer_to_fill_layer_on_next_frame, NULL);
|
||||
}
|
||||
|
||||
void slot_layer_to_paint_layer(slot_layer_t *raw) {
|
||||
context_set_layer(raw);
|
||||
raw->fill_layer = NULL;
|
||||
raw->fill_material = NULL;
|
||||
make_material_parse_paint_material(true);
|
||||
g_context->layer_preview_dirty = true;
|
||||
ui_base_hwnds->buffer[TAB_AREA_SIDEBAR0]->redraws = 2;
|
||||
@@ -607,6 +607,10 @@ bool slot_layer_is_layer(slot_layer_t *raw) {
|
||||
return raw->texpaint != NULL && raw->texpaint_nor != NULL;
|
||||
}
|
||||
|
||||
bool slot_layer_is_path(slot_layer_t *raw) {
|
||||
return raw->path_points != NULL;
|
||||
}
|
||||
|
||||
bool slot_layer_is_group(slot_layer_t *raw) {
|
||||
return raw->texpaint == NULL;
|
||||
}
|
||||
@@ -1054,7 +1058,7 @@ bool layers_is_fill_material() {
|
||||
slot_material_t *m = g_context->material;
|
||||
for (i32 i = 0; i < project_layers->length; ++i) {
|
||||
slot_layer_t *l = project_layers->buffer[i];
|
||||
if (l->fill_layer == m) {
|
||||
if (l->fill_material == m) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1105,13 +1109,13 @@ void layers_update_fill_layers() {
|
||||
bool has_fill_mask = false;
|
||||
for (i32 i = 0; i < project_layers->length; ++i) {
|
||||
slot_layer_t *l = project_layers->buffer[i];
|
||||
if (slot_layer_is_layer(l) && l->fill_layer == g_context->material) {
|
||||
if (slot_layer_is_layer(l) && l->fill_material == g_context->material) {
|
||||
has_fill_layer = true;
|
||||
}
|
||||
}
|
||||
for (i32 i = 0; i < project_layers->length; ++i) {
|
||||
slot_layer_t *l = project_layers->buffer[i];
|
||||
if (slot_layer_is_mask(l) && l->fill_layer == g_context->material) {
|
||||
if (slot_layer_is_mask(l) && l->fill_material == g_context->material) {
|
||||
has_fill_mask = true;
|
||||
}
|
||||
}
|
||||
@@ -1129,7 +1133,7 @@ void layers_update_fill_layers() {
|
||||
bool first = true;
|
||||
for (i32 i = 0; i < project_layers->length; ++i) {
|
||||
slot_layer_t *l = project_layers->buffer[i];
|
||||
if (slot_layer_is_layer(l) && l->fill_layer == g_context->material) {
|
||||
if (slot_layer_is_layer(l) && l->fill_material == g_context->material) {
|
||||
g_context->layer = l;
|
||||
if (first) {
|
||||
first = false;
|
||||
@@ -1157,7 +1161,7 @@ void layers_update_fill_layers() {
|
||||
bool first = true;
|
||||
for (i32 i = 0; i < project_layers->length; ++i) {
|
||||
slot_layer_t *l = project_layers->buffer[i];
|
||||
if (slot_layer_is_mask(l) && l->fill_layer == g_context->material) {
|
||||
if (slot_layer_is_mask(l) && l->fill_material == g_context->material) {
|
||||
g_context->layer = l;
|
||||
if (first) {
|
||||
first = false;
|
||||
@@ -1184,6 +1188,26 @@ void layers_update_fill_layers() {
|
||||
}
|
||||
}
|
||||
|
||||
bool layers_is_path_material() {
|
||||
slot_material_t *m = g_context->material;
|
||||
for (i32 i = 0; i < project_layers->length; ++i) {
|
||||
slot_layer_t *l = project_layers->buffer[i];
|
||||
if (slot_layer_is_path(l) && l->path_material == m) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void layers_update_path_layers() {
|
||||
for (i32 i = 0; i < project_layers->length; ++i) {
|
||||
slot_layer_t *l = project_layers->buffer[i];
|
||||
if (slot_layer_is_path(l) && l->path_material == g_context->material) {
|
||||
util_layer_repaint_path(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void layers_update_fill_layer(bool parse_paint) {
|
||||
gpu_texture_t *current = _draw_current;
|
||||
bool in_use = gpu_in_use;
|
||||
@@ -1366,6 +1390,22 @@ slot_layer_t *layers_new_group() {
|
||||
return l;
|
||||
}
|
||||
|
||||
slot_layer_t *layers_new_path_layer(bool curved) {
|
||||
slot_layer_t *l = layers_new_layer(true, -1, NULL);
|
||||
if (l == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
l->path_points = f32_array_create(0);
|
||||
l->path_points_world = f32_array_create(0);
|
||||
l->path_points_camera = f32_array_create(0);
|
||||
l->path_points_parent = i32_array_create(0);
|
||||
l->path_tool = -1;
|
||||
l->path_curved = curved;
|
||||
l->path_material = g_context->material;
|
||||
l->name = string(curved ? "Curve %d" : "Path %d", l->id + 1);
|
||||
return l;
|
||||
}
|
||||
|
||||
void layers_create_fill_layer_on_next_frame(void *_) {
|
||||
slot_layer_t *l = layers_new_layer(false, _layers_position, NULL);
|
||||
history_new_layer();
|
||||
@@ -1608,7 +1648,7 @@ slot_layer_t *layers_merge_group(slot_layer_t *l) {
|
||||
|
||||
children->buffer[0]->parent = NULL;
|
||||
children->buffer[0]->name = l->name;
|
||||
if (children->buffer[0]->fill_layer != NULL) {
|
||||
if (children->buffer[0]->fill_material != NULL) {
|
||||
slot_layer_to_paint_layer(children->buffer[0]);
|
||||
}
|
||||
slot_layer_delete(l);
|
||||
@@ -1883,9 +1923,9 @@ void layers_on_resized_on_next_frame(void *_) {
|
||||
slot_material_t *_material = g_context->material;
|
||||
for (i32 i = 0; i < project_layers->length; ++i) {
|
||||
slot_layer_t *l = project_layers->buffer[i];
|
||||
if (l->fill_layer != NULL) {
|
||||
if (l->fill_material != NULL) {
|
||||
g_context->layer = l;
|
||||
g_context->material = l->fill_layer;
|
||||
g_context->material = l->fill_material;
|
||||
layers_update_fill_layer(true);
|
||||
}
|
||||
}
|
||||
|
||||
+33
-23
@@ -63,8 +63,11 @@ void tab_layers_handle_layer_icon_state(slot_layer_t *l, i32 i, ui_state_t state
|
||||
if (sys_time() - g_context->select_time > 0.2) {
|
||||
g_context->select_time = sys_time();
|
||||
}
|
||||
if (l->fill_layer != NULL) {
|
||||
context_set_material(l->fill_layer);
|
||||
if (l->fill_material != NULL) {
|
||||
context_set_material(l->fill_material);
|
||||
}
|
||||
else if (l->path_material != NULL) {
|
||||
context_set_material(l->path_material);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,17 +93,17 @@ ui_state_t tab_layers_draw_layer_icon(slot_layer_t *l, i32 i, f32 uix, f32 uiy,
|
||||
gpu_texture_t *texpaint_preview = l->texpaint_preview;
|
||||
|
||||
gpu_texture_t *icon;
|
||||
if (l->fill_layer == NULL) {
|
||||
icon = texpaint_preview;
|
||||
if (l->fill_material != NULL) {
|
||||
icon = g_config->window_scale > 1 ? l->fill_material->image : l->fill_material->image_icon;
|
||||
}
|
||||
else if (g_config->window_scale > 1) {
|
||||
icon = l->fill_layer->image;
|
||||
else if (l->path_material != NULL) {
|
||||
icon = g_config->window_scale > 1 ? l->path_material->image : l->path_material->image_icon;
|
||||
}
|
||||
else {
|
||||
icon = l->fill_layer->image_icon;
|
||||
icon = texpaint_preview;
|
||||
}
|
||||
|
||||
if (l->fill_layer == NULL) {
|
||||
if (l->fill_material == NULL && l->path_material == NULL) {
|
||||
// Checker
|
||||
rect_t *r = resource_tile50(icons, ICON_CHECKER);
|
||||
f32 _x = ui->_x;
|
||||
@@ -111,14 +114,14 @@ ui_state_t tab_layers_draw_layer_icon(slot_layer_t *l, i32 i, f32 uix, f32 uiy,
|
||||
ui->_y = _y;
|
||||
ui->_w = _w;
|
||||
}
|
||||
if (l->fill_layer == NULL && slot_layer_is_mask(l)) {
|
||||
if (l->fill_material == NULL && slot_layer_is_mask(l)) {
|
||||
draw_set_pipeline(ui_view2d_pipe);
|
||||
gpu_set_int(ui_view2d_channel_loc, 1);
|
||||
}
|
||||
|
||||
ui_state_t state = ui_image(icon, 0xffffffff, icon_h);
|
||||
|
||||
if (l->fill_layer == NULL && slot_layer_is_mask(l)) {
|
||||
if (l->fill_material == NULL && slot_layer_is_mask(l)) {
|
||||
draw_set_pipeline(NULL);
|
||||
}
|
||||
|
||||
@@ -231,7 +234,7 @@ void tab_layers_draw_layer_slot_full_delete_layer(void *_) {
|
||||
}
|
||||
|
||||
void tab_layers_combo_object_layer_clear(slot_layer_t *l) {
|
||||
g_context->material = l->fill_layer;
|
||||
g_context->material = l->fill_material;
|
||||
slot_layer_clear(l, 0x00000000, NULL, 1.0, layers_default_rough, 0.0);
|
||||
layers_update_fill_layers();
|
||||
}
|
||||
@@ -259,7 +262,7 @@ ui_handle_t *tab_layers_combo_object(slot_layer_t *l, bool label) {
|
||||
if (object_handle->changed) {
|
||||
context_set_layer(l);
|
||||
make_material_parse_mesh_material();
|
||||
if (l->fill_layer != NULL) {
|
||||
if (l->fill_material != NULL) {
|
||||
sys_notify_on_next_frame(&tab_layers_combo_object_layer_clear, l);
|
||||
}
|
||||
else {
|
||||
@@ -574,7 +577,7 @@ void tab_layers_draw_layer_context_menu_merge_down(void *_) {
|
||||
context_set_layer(l);
|
||||
history_merge_layers();
|
||||
layers_merge_down();
|
||||
if (g_context->layer->fill_layer != NULL)
|
||||
if (g_context->layer->fill_material != NULL)
|
||||
slot_layer_to_paint_layer(g_context->layer);
|
||||
}
|
||||
|
||||
@@ -611,6 +614,7 @@ void tab_layers_draw_layer_context_menu_clear(void *_) {
|
||||
if (!slot_layer_is_group(l)) {
|
||||
history_clear_layer();
|
||||
slot_layer_clear(l, 0x00000000, NULL, 1.0, layers_default_rough, 0.0);
|
||||
util_layer_clear_path_points(l);
|
||||
}
|
||||
else {
|
||||
for (i32 i = 0; i < slot_layer_get_children(l)->length; ++i) {
|
||||
@@ -663,15 +667,15 @@ void tab_layers_draw_layer_context_menu_draw() {
|
||||
char *to_fill_string = slot_layer_is_layer(l) ? tr("To Fill Layer") : tr("To Fill Mask");
|
||||
char *to_paint_string = slot_layer_is_layer(l) ? tr("To Paint Layer") : tr("To Paint Mask");
|
||||
|
||||
if (l->fill_layer == NULL && ui_menu_button(to_fill_string, "", ICON_SPHERE)) {
|
||||
if (l->fill_material == NULL && ui_menu_button(to_fill_string, "", ICON_SPHERE)) {
|
||||
sys_notify_on_next_frame(&tab_layers_draw_layer_context_menu_to_fill_layer, NULL);
|
||||
}
|
||||
if (l->fill_layer != NULL && ui_menu_button(to_paint_string, "", ICON_PAINT)) {
|
||||
if (l->fill_material != NULL && ui_menu_button(to_paint_string, "", ICON_PAINT)) {
|
||||
sys_notify_on_next_frame(&tab_layers_draw_layer_context_menu_to_paint_layer, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (slot_layer_is_layer(l) && l->fill_layer != NULL && l->texpaint_sculpt != NULL && ui_menu_button(tr("Apply"), "", ICON_CHECK)) {
|
||||
if (slot_layer_is_layer(l) && l->fill_material != NULL && l->texpaint_sculpt != NULL && ui_menu_button(tr("Apply"), "", ICON_CHECK)) {
|
||||
sys_notify_on_next_frame(&tab_layers_draw_layer_context_menu_apply_sculpt, NULL);
|
||||
}
|
||||
|
||||
@@ -681,11 +685,11 @@ void tab_layers_draw_layer_context_menu_draw() {
|
||||
}
|
||||
ui->enabled = true;
|
||||
|
||||
if (l->fill_layer == NULL && ui_menu_button(tr("Clear"), "", ICON_ERASE)) {
|
||||
if (l->fill_material == NULL && ui_menu_button(tr("Clear"), "", ICON_ERASE)) {
|
||||
context_set_layer(l);
|
||||
sys_notify_on_next_frame(&tab_layers_draw_layer_context_menu_clear, NULL);
|
||||
}
|
||||
if (slot_layer_is_mask(l) && l->fill_layer == NULL && ui_menu_button(tr("Invert"), "", ICON_INVERT)) {
|
||||
if (slot_layer_is_mask(l) && l->fill_material == NULL && ui_menu_button(tr("Invert"), "", ICON_INVERT)) {
|
||||
sys_notify_on_next_frame(&tab_layers_draw_layer_context_menu_invert, NULL);
|
||||
}
|
||||
if (slot_layer_is_mask(l) && ui_menu_button(tr("Apply"), "", ICON_CHECK)) {
|
||||
@@ -798,13 +802,13 @@ void tab_layers_draw_layer_context_menu_draw() {
|
||||
ui_menu_keep_open = true;
|
||||
}
|
||||
}
|
||||
if (l->fill_layer != NULL) {
|
||||
if (l->fill_material != NULL) {
|
||||
ui_menu_align();
|
||||
ui_handle_t *scale_handle = ui_nest(ui_handle(__ID__), l->id);
|
||||
scale_handle->f = l->scale;
|
||||
l->scale = ui_slider(scale_handle, tr("UV Scale"), 0.0, 5.0, true, 100.0, true, UI_ALIGN_RIGHT, true);
|
||||
if (scale_handle->changed) {
|
||||
context_set_material(l->fill_layer);
|
||||
context_set_material(l->fill_material);
|
||||
context_set_layer(l);
|
||||
sys_notify_on_next_frame(&tab_layers_draw_layer_context_menu_update_fill_layers, NULL);
|
||||
ui_menu_keep_open = true;
|
||||
@@ -815,7 +819,7 @@ void tab_layers_draw_layer_context_menu_draw() {
|
||||
angle_handle->f = l->angle;
|
||||
l->angle = ui_slider(angle_handle, tr("Angle"), 0.0, 360, true, 1, true, UI_ALIGN_RIGHT, true);
|
||||
if (angle_handle->changed) {
|
||||
context_set_material(l->fill_layer);
|
||||
context_set_material(l->fill_material);
|
||||
context_set_layer(l);
|
||||
make_material_parse_paint_material(true);
|
||||
sys_notify_on_next_frame(&tab_layers_draw_layer_context_menu_update_fill_layers, NULL);
|
||||
@@ -834,7 +838,7 @@ void tab_layers_draw_layer_context_menu_draw() {
|
||||
3);
|
||||
l->uv_type = ui_inline_radio(uv_type_handle, uv_type_items, UI_ALIGN_LEFT);
|
||||
if (uv_type_handle->changed) {
|
||||
context_set_material(l->fill_layer);
|
||||
context_set_material(l->fill_material);
|
||||
context_set_layer(l);
|
||||
make_material_parse_paint_material(true);
|
||||
sys_notify_on_next_frame(&tab_layers_draw_layer_context_menu_update_fill_layers, NULL);
|
||||
@@ -1029,7 +1033,13 @@ void tab_layers_button_new_menu() {
|
||||
if (ui_menu_button(tr("Decal"), "", ICON_DECAL)) {
|
||||
layers_create_fill_layer(UV_TYPE_PROJECT, mat4_nan(), -1);
|
||||
}
|
||||
if (ui_menu_button(tr("Path"), "", ICON_RULER)) {
|
||||
if (ui_menu_button(tr("Path"), "", ICON_PATH)) {
|
||||
layers_new_path_layer(false);
|
||||
history_new_layer();
|
||||
}
|
||||
if (ui_menu_button(tr("Curve"), "", ICON_CURVE)) {
|
||||
layers_new_path_layer(true);
|
||||
history_new_layer();
|
||||
}
|
||||
if (ui_menu_button(tr("Black Mask"), "", ICON_MASK)) {
|
||||
if (slot_layer_is_mask(l) || slot_layer_is_filter(l)) {
|
||||
|
||||
@@ -60,8 +60,8 @@ void tab_materials_delete_material(slot_material_t *m) {
|
||||
i32 i = array_index_of(project_materials, m);
|
||||
for (i32 i = 0; i < project_layers->length; ++i) {
|
||||
slot_layer_t *l = project_layers->buffer[i];
|
||||
if (l->fill_layer == m) {
|
||||
l->fill_layer = NULL;
|
||||
if (l->fill_material == m) {
|
||||
l->fill_material = NULL;
|
||||
}
|
||||
}
|
||||
history_delete_material();
|
||||
|
||||
+16
-2
@@ -24,7 +24,7 @@ typedef struct slot_layer {
|
||||
struct gpu_texture *texpaint_pack;
|
||||
struct gpu_texture *texpaint_preview; // Layer preview
|
||||
f32 mask_opacity; // Opacity mask
|
||||
struct slot_material *fill_layer;
|
||||
struct slot_material *fill_material;
|
||||
bool show_panel;
|
||||
blend_type_t blending;
|
||||
i32 object_mask;
|
||||
@@ -45,6 +45,13 @@ typedef struct slot_layer {
|
||||
bool paint_subs;
|
||||
mat4_t decal_mat; // Decal layer
|
||||
struct gpu_texture *texpaint_sculpt;
|
||||
f32_array_t *path_points; // uv-space [x, y, ..]
|
||||
f32_array_t *path_points_world; // world-space [x, y, z, ..]
|
||||
f32_array_t *path_points_camera; // [loc.xyzw, rot.xyzw, aspect, ..] at time of point placement
|
||||
i32_array_t *path_points_parent;
|
||||
i32 path_tool;
|
||||
bool path_curved;
|
||||
struct slot_material *path_material;
|
||||
} slot_layer_t;
|
||||
|
||||
typedef struct slot_font {
|
||||
@@ -572,7 +579,7 @@ typedef struct layer_data {
|
||||
i32 uv_type;
|
||||
struct f32_array *decal_mat;
|
||||
f32 opacity_mask;
|
||||
i32 fill_layer;
|
||||
i32 fill_material;
|
||||
i32 object_mask;
|
||||
i32 blending;
|
||||
i32 parent;
|
||||
@@ -591,6 +598,13 @@ typedef struct layer_data {
|
||||
bool paint_emis;
|
||||
bool paint_subs;
|
||||
i32 uv_map;
|
||||
f32_array_t *path_points;
|
||||
f32_array_t *path_points_world;
|
||||
f32_array_t *path_points_camera;
|
||||
i32_array_t *path_points_parent;
|
||||
i32 path_tool;
|
||||
bool path_curved;
|
||||
i32 path_material;
|
||||
} layer_data_t;
|
||||
|
||||
typedef struct shader_out {
|
||||
|
||||
@@ -787,7 +787,16 @@ void ui_nodes_recompile() {
|
||||
if (ui_nodes_is_tab_selected()) {
|
||||
g_context->material = ui_nodes_tabs->buffer[ui_nodes_tab_index()];
|
||||
}
|
||||
layers_is_fill_material() ? layers_update_fill_layers() : util_render_make_material_preview();
|
||||
if (layers_is_fill_material()) {
|
||||
layers_update_fill_layers();
|
||||
}
|
||||
else if (layers_is_path_material()) {
|
||||
layers_update_path_layers();
|
||||
}
|
||||
else {
|
||||
util_render_make_material_preview();
|
||||
}
|
||||
|
||||
g_context->material = _material;
|
||||
|
||||
if (ui_view2d_show && ui_view2d_type == VIEW_2D_TYPE_NODE) {
|
||||
@@ -805,9 +814,15 @@ void ui_nodes_recompile() {
|
||||
else if (ui_nodes_recompile_mat_final) {
|
||||
make_material_parse_paint_material(true);
|
||||
|
||||
if (ui_nodes_canvas_type == CANVAS_TYPE_MATERIAL && layers_is_fill_material()) {
|
||||
layers_update_fill_layers();
|
||||
util_render_make_material_preview();
|
||||
if (ui_nodes_canvas_type == CANVAS_TYPE_MATERIAL) {
|
||||
if (layers_is_fill_material()) {
|
||||
layers_update_fill_layers();
|
||||
util_render_make_material_preview();
|
||||
}
|
||||
if (layers_is_path_material()) {
|
||||
layers_update_path_layers();
|
||||
util_render_make_material_preview();
|
||||
}
|
||||
}
|
||||
|
||||
bool decal = context_is_decal();
|
||||
|
||||
@@ -79,7 +79,7 @@ f32 uniforms_ext_f32_link(object_t *object, material_data_t *mat, char *link) {
|
||||
// i32 atlas_stride = atlas_w / (float)item_w;
|
||||
// return atlas_stride;
|
||||
// }
|
||||
bool fill = g_context->layer->fill_layer != NULL;
|
||||
bool fill = g_context->layer->fill_material != NULL;
|
||||
f32 val = (fill ? g_context->layer->scale : g_context->brush_scale) * g_context->brush_nodes_scale;
|
||||
return val;
|
||||
}
|
||||
@@ -153,7 +153,7 @@ vec2_t uniforms_ext_vec2_link(object_t *object, material_data_t *mat, char *link
|
||||
}
|
||||
else if (string_equals(link, "_brush_angle")) {
|
||||
f32 brush_angle = g_context->brush_angle + g_context->brush_nodes_angle;
|
||||
f32 angle = g_context->layer->fill_layer != NULL ? g_context->layer->angle : brush_angle;
|
||||
f32 angle = g_context->layer->fill_material != NULL ? g_context->layer->angle : brush_angle;
|
||||
angle *= (math_pi() / 180.0);
|
||||
if (g_config->pressure_angle && pen_down("tip")) {
|
||||
angle *= pen_pressure * g_config->pressure_sensitivity;
|
||||
@@ -275,7 +275,7 @@ buffer_t *util_encode_project(project_t *raw) {
|
||||
if (raw->layer_datas != NULL) {
|
||||
armpack_encode_array(raw->layer_datas->length);
|
||||
for (i32 i = 0; i < raw->layer_datas->length; ++i) {
|
||||
armpack_encode_map(28);
|
||||
armpack_encode_map(35);
|
||||
armpack_encode_string("name");
|
||||
armpack_encode_string(raw->layer_datas->buffer[i]->name);
|
||||
armpack_encode_string("res");
|
||||
@@ -294,8 +294,8 @@ buffer_t *util_encode_project(project_t *raw) {
|
||||
armpack_encode_array_f32(raw->layer_datas->buffer[i]->decal_mat);
|
||||
armpack_encode_string("opacity_mask");
|
||||
armpack_encode_f32(raw->layer_datas->buffer[i]->opacity_mask);
|
||||
armpack_encode_string("fill_layer");
|
||||
armpack_encode_i32(raw->layer_datas->buffer[i]->fill_layer);
|
||||
armpack_encode_string("fill_material");
|
||||
armpack_encode_i32(raw->layer_datas->buffer[i]->fill_material);
|
||||
armpack_encode_string("object_mask");
|
||||
armpack_encode_i32(raw->layer_datas->buffer[i]->object_mask);
|
||||
armpack_encode_string("blending");
|
||||
@@ -332,6 +332,20 @@ buffer_t *util_encode_project(project_t *raw) {
|
||||
armpack_encode_bool(raw->layer_datas->buffer[i]->paint_subs);
|
||||
armpack_encode_string("uv_map");
|
||||
armpack_encode_i32(raw->layer_datas->buffer[i]->uv_map);
|
||||
armpack_encode_string("path_points");
|
||||
armpack_encode_array_f32(raw->layer_datas->buffer[i]->path_points);
|
||||
armpack_encode_string("path_points_world");
|
||||
armpack_encode_array_f32(raw->layer_datas->buffer[i]->path_points_world);
|
||||
armpack_encode_string("path_points_camera");
|
||||
armpack_encode_array_f32(raw->layer_datas->buffer[i]->path_points_camera);
|
||||
armpack_encode_string("path_points_parent");
|
||||
armpack_encode_array_i32(raw->layer_datas->buffer[i]->path_points_parent);
|
||||
armpack_encode_string("path_tool");
|
||||
armpack_encode_i32(raw->layer_datas->buffer[i]->path_tool);
|
||||
armpack_encode_string("path_curved");
|
||||
armpack_encode_bool(raw->layer_datas->buffer[i]->path_curved);
|
||||
armpack_encode_string("path_material");
|
||||
armpack_encode_i32(raw->layer_datas->buffer[i]->path_material);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -0,0 +1,415 @@
|
||||
|
||||
#include "global.h"
|
||||
|
||||
static slot_layer_t *path_layer_current = NULL;
|
||||
static object_t **path_point_spheres = NULL;
|
||||
static i32 path_point_sphere_count = 0;
|
||||
static i32 path_point_dragging = -1;
|
||||
static i32 path_layer_last_active = -1;
|
||||
|
||||
bool util_layer_is_path_point_dragging() {
|
||||
return path_point_dragging >= 0;
|
||||
}
|
||||
|
||||
static void path_layer_destroy_spheres() {
|
||||
for (i32 i = 0; i < path_point_sphere_count; i++) {
|
||||
mesh_object_remove((mesh_object_t *)path_point_spheres[i]->ext);
|
||||
}
|
||||
gc_free(path_point_spheres);
|
||||
path_point_spheres = NULL;
|
||||
path_point_sphere_count = 0;
|
||||
}
|
||||
|
||||
static void path_layer_push_camera(f32_array_t *ar) {
|
||||
vec4_t loc = scene_camera->base->transform->loc;
|
||||
quat_t rot = scene_camera->base->transform->rot;
|
||||
f32_array_push(ar, loc.x);
|
||||
f32_array_push(ar, loc.y);
|
||||
f32_array_push(ar, loc.z);
|
||||
f32_array_push(ar, loc.w);
|
||||
f32_array_push(ar, rot.x);
|
||||
f32_array_push(ar, rot.y);
|
||||
f32_array_push(ar, rot.z);
|
||||
f32_array_push(ar, rot.w);
|
||||
f32_array_push(ar, sys_w() / (f32)sys_h());
|
||||
}
|
||||
|
||||
static void path_set_camera(f32_array_t *points_camera, i32 num_camera, i32 ci) {
|
||||
if (ci < num_camera) {
|
||||
scene_camera->base->transform->loc = (vec4_t){points_camera->buffer[ci * 9 + 0], points_camera->buffer[ci * 9 + 1], points_camera->buffer[ci * 9 + 2],
|
||||
points_camera->buffer[ci * 9 + 3]};
|
||||
scene_camera->base->transform->rot = (quat_t){points_camera->buffer[ci * 9 + 4], points_camera->buffer[ci * 9 + 5], points_camera->buffer[ci * 9 + 6],
|
||||
points_camera->buffer[ci * 9 + 7]};
|
||||
camera_object_build_proj(scene_camera, points_camera->buffer[ci * 9 + 8]);
|
||||
camera_object_build_mat(scene_camera);
|
||||
render_path_base_draw_gbuffer();
|
||||
}
|
||||
}
|
||||
|
||||
static void path_paint(f32 px, f32 py, bool is_decal, f32 *prev_px, f32 *prev_py) {
|
||||
if (is_decal) {
|
||||
g_context->decal_x = px;
|
||||
g_context->decal_y = py;
|
||||
}
|
||||
g_context->paint_vec.x = px;
|
||||
g_context->paint_vec.y = py;
|
||||
g_context->last_paint_vec_x = *prev_px;
|
||||
g_context->last_paint_vec_y = *prev_py;
|
||||
g_context->pdirty = 1;
|
||||
render_path_paint_commands_paint(false);
|
||||
*prev_px = px;
|
||||
*prev_py = py;
|
||||
}
|
||||
|
||||
static void layers_repaint_path_layer(slot_layer_t *l) {
|
||||
if (l->path_material == NULL) {
|
||||
return;
|
||||
}
|
||||
f32_array_t *points_world = l->path_points_world;
|
||||
if (points_world == NULL || points_world->length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
slot_layer_t *_layer = g_context->layer;
|
||||
slot_material_t *_material = g_context->material;
|
||||
tool_type_t _tool = g_context->tool;
|
||||
f32 _last_x = g_context->last_paint_vec_x;
|
||||
f32 _last_y = g_context->last_paint_vec_y;
|
||||
vec4_t _paint_vec = g_context->paint_vec;
|
||||
g_context->layer = l;
|
||||
g_context->material = l->path_material;
|
||||
g_context->tool = l->path_tool;
|
||||
|
||||
bool _depth_reject = g_config->brush_depth_reject;
|
||||
bool _angle_reject = g_config->brush_angle_reject;
|
||||
g_config->brush_depth_reject = false;
|
||||
g_config->brush_angle_reject = false;
|
||||
|
||||
make_material_parse_paint_material(false);
|
||||
layers_set_object_mask();
|
||||
|
||||
slot_layer_clear(l, 0x00000000, NULL, 1.0, layers_default_rough, 0.0);
|
||||
|
||||
vec4_t _camera_loc = scene_camera->base->transform->loc;
|
||||
quat_t _camera_rot = scene_camera->base->transform->rot;
|
||||
|
||||
f32_array_t *points = l->path_points;
|
||||
f32_array_t *points_camera = l->path_points_camera;
|
||||
i32_array_t *points_parent = l->path_points_parent;
|
||||
i32 num_world = points_world->length / 3;
|
||||
i32 num_camera = points_camera->length / 9;
|
||||
i32 num_parent = points_parent->length;
|
||||
bool is_decal = context_is_decal();
|
||||
|
||||
if (l->path_curved && num_world >= 1) {
|
||||
f32 prev_px = 0.5f;
|
||||
f32 prev_py = 0.5f;
|
||||
|
||||
// Paint the first anchor
|
||||
f32 pt0x = points->length >= 2 ? points->buffer[0] : 0.5f;
|
||||
f32 pt0y = points->length >= 2 ? points->buffer[1] : 0.5f;
|
||||
path_set_camera(points_camera, num_camera, 0);
|
||||
prev_px = pt0x;
|
||||
prev_py = pt0y;
|
||||
path_paint(pt0x, pt0y, is_decal, &prev_px, &prev_py);
|
||||
|
||||
// Paint curve - anchor[k], control[k+1], anchor[k+2]
|
||||
for (i32 k = 0; k + 2 < num_world; k += 2) {
|
||||
f32 ax0 = k * 2 + 1 < (i32)points->length ? points->buffer[k * 2] : 0.5f;
|
||||
f32 ay0 = k * 2 + 1 < (i32)points->length ? points->buffer[k * 2 + 1] : 0.5f;
|
||||
f32 cx = (k + 1) * 2 + 1 < (i32)points->length ? points->buffer[(k + 1) * 2] : 0.5f;
|
||||
f32 cy = (k + 1) * 2 + 1 < (i32)points->length ? points->buffer[(k + 1) * 2 + 1] : 0.5f;
|
||||
f32 ax1 = (k + 2) * 2 + 1 < (i32)points->length ? points->buffer[(k + 2) * 2] : 0.5f;
|
||||
f32 ay1 = (k + 2) * 2 + 1 < (i32)points->length ? points->buffer[(k + 2) * 2 + 1] : 0.5f;
|
||||
|
||||
// 16 intermediate points + final anchor
|
||||
bool have_k2 = k + 2 < num_camera;
|
||||
for (i32 s = 1; s <= 17; s++) {
|
||||
f32 t = s / 17.0f;
|
||||
f32 t1 = 1.0f - t;
|
||||
f32 bx = t1 * t1 * t1 * ax0 + 3.0f * t * t1 * cx + t * t * t * ax1;
|
||||
f32 by = t1 * t1 * t1 * ay0 + 3.0f * t * t1 * cy + t * t * t * ay1;
|
||||
// f32 bx = t1 * t1 * ax0 + 2.0f * t * t1 * cx + t * t * ax1;
|
||||
// f32 by = t1 * t1 * ay0 + 2.0f * t * t1 * cy + t * t * ay1;
|
||||
if (s == 17 && have_k2) {
|
||||
path_set_camera(points_camera, num_camera, k + 2);
|
||||
}
|
||||
path_paint(bx, by, is_decal, &prev_px, &prev_py);
|
||||
}
|
||||
}
|
||||
|
||||
render_path_paint_dilate(true, true);
|
||||
}
|
||||
else {
|
||||
for (i32 i = 0; i < num_world; i++) {
|
||||
path_set_camera(points_camera, num_camera, i);
|
||||
|
||||
f32 cur_px = points->buffer[i * 2];
|
||||
f32 cur_py = points->buffer[i * 2 + 1];
|
||||
|
||||
// Project parent world point for stroke connection
|
||||
f32 prev_px = cur_px;
|
||||
f32 prev_py = cur_py;
|
||||
if (!is_decal) {
|
||||
i32 parent = points_parent->buffer[i];
|
||||
if (parent >= 0) {
|
||||
f32 pwx = points_world->buffer[parent * 3];
|
||||
f32 pwy = points_world->buffer[parent * 3 + 1];
|
||||
f32 pwz = points_world->buffer[parent * 3 + 2];
|
||||
vec4_t clip = vec4_apply_mat4((vec4_t){pwx, pwy, pwz, 1.0f}, scene_camera->vp);
|
||||
if (clip.w > 0.0f) {
|
||||
prev_px = (clip.x / clip.w + 1.0f) * 0.5f;
|
||||
prev_py = (-clip.y / clip.w + 1.0f) * 0.5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
path_paint(cur_px, cur_py, is_decal, &prev_px, &prev_py);
|
||||
}
|
||||
|
||||
render_path_paint_dilate(true, true);
|
||||
}
|
||||
|
||||
g_config->brush_depth_reject = _depth_reject;
|
||||
g_config->brush_angle_reject = _angle_reject;
|
||||
g_context->tool = _tool;
|
||||
|
||||
scene_camera->base->transform->loc = _camera_loc;
|
||||
scene_camera->base->transform->rot = _camera_rot;
|
||||
camera_object_build_proj(scene_camera, -1.0);
|
||||
camera_object_build_mat(scene_camera);
|
||||
render_path_base_draw_gbuffer();
|
||||
|
||||
g_context->pdirty = 0;
|
||||
g_context->rdirty = 2;
|
||||
g_context->layer = _layer;
|
||||
g_context->material = _material;
|
||||
make_material_parse_paint_material(false);
|
||||
g_context->last_paint_vec_x = _last_x;
|
||||
g_context->last_paint_vec_y = _last_y;
|
||||
g_context->paint_vec = _paint_vec;
|
||||
}
|
||||
|
||||
void util_layer_clear_path_points(slot_layer_t *l) {
|
||||
if (l->path_points == NULL) {
|
||||
return;
|
||||
}
|
||||
l->path_points->length = 0;
|
||||
l->path_points_world->length = 0;
|
||||
l->path_points_camera->length = 0;
|
||||
l->path_points_parent->length = 0;
|
||||
l->path_tool = -1;
|
||||
path_layer_last_active = -1;
|
||||
}
|
||||
|
||||
void util_layer_add_path_point(slot_layer_t *l, f32 screen_x, f32 screen_y) {
|
||||
if (l->path_tool == -1) {
|
||||
l->path_tool = g_context->tool;
|
||||
}
|
||||
if ((i32)g_context->tool != l->path_tool) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i32 j = 0; j < path_point_sphere_count; j++) {
|
||||
path_point_spheres[j]->visible = false;
|
||||
}
|
||||
|
||||
// Re-render gbuffer without spheres so gbufferD is clean
|
||||
render_path_base_draw_gbuffer();
|
||||
|
||||
f32_array_t *points = l->path_points;
|
||||
f32_array_t *points_world = l->path_points_world;
|
||||
f32_array_t *points_camera = l->path_points_camera;
|
||||
i32_array_t *points_parent = l->path_points_parent;
|
||||
|
||||
f32_array_push(points, screen_x);
|
||||
f32_array_push(points, screen_y);
|
||||
f32 saved_pvx = g_context->paint_vec.x;
|
||||
f32 saved_pvy = g_context->paint_vec.y;
|
||||
g_context->paint_vec.x = screen_x;
|
||||
g_context->paint_vec.y = screen_y;
|
||||
util_render_pick_pos_nor_tex();
|
||||
g_context->paint_vec.x = saved_pvx;
|
||||
g_context->paint_vec.y = saved_pvy;
|
||||
f32_array_push(points_world, g_context->posx_picked);
|
||||
f32_array_push(points_world, g_context->posy_picked);
|
||||
f32_array_push(points_world, g_context->posz_picked);
|
||||
path_layer_push_camera(points_camera);
|
||||
i32_array_push(points_parent, path_layer_last_active);
|
||||
|
||||
// New point becomes the parent for the next stroke
|
||||
i32 new_index = points->length / 2 - 1;
|
||||
path_layer_last_active = new_index;
|
||||
|
||||
layers_repaint_path_layer(l);
|
||||
|
||||
for (i32 j = 0; j < path_point_sphere_count; j++) {
|
||||
path_point_spheres[j]->visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
void util_layer_repaint_path(slot_layer_t *l) {
|
||||
for (i32 j = 0; j < path_point_sphere_count; j++) {
|
||||
path_point_spheres[j]->visible = false;
|
||||
}
|
||||
layers_repaint_path_layer(l);
|
||||
for (i32 j = 0; j < path_point_sphere_count; j++) {
|
||||
path_point_spheres[j]->visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
void util_layer_update_path() {
|
||||
if (g_config->workspace == WORKSPACE_PLAYER || g_context->paint2d) {
|
||||
return;
|
||||
}
|
||||
|
||||
slot_layer_t *l = g_context->layer;
|
||||
bool is_path = slot_layer_is_path(l);
|
||||
|
||||
// Clear spheres when switching away from path layer
|
||||
if (path_layer_current != l) {
|
||||
path_layer_destroy_spheres();
|
||||
path_point_dragging = -1;
|
||||
path_layer_current = is_path ? l : NULL;
|
||||
path_layer_last_active = -1;
|
||||
if (is_path) {
|
||||
// Resume from the last point when switching to a path layer
|
||||
i32 n = l->path_points->length / 2;
|
||||
path_layer_last_active = n > 0 ? n - 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_path) {
|
||||
return;
|
||||
}
|
||||
|
||||
f32_array_t *points = l->path_points;
|
||||
f32_array_t *points_world = l->path_points_world;
|
||||
i32 num_points = points->length / 2;
|
||||
i32 num_world = points_world->length / 3;
|
||||
i32 vis_points = num_points;
|
||||
|
||||
// Sync sphere count with number of visible path points
|
||||
if (vis_points < path_point_sphere_count) {
|
||||
while (path_point_sphere_count > vis_points) {
|
||||
path_point_sphere_count--;
|
||||
mesh_object_remove((mesh_object_t *)path_point_spheres[path_point_sphere_count]->ext);
|
||||
path_point_spheres[path_point_sphere_count] = NULL;
|
||||
}
|
||||
}
|
||||
else if (vis_points > path_point_sphere_count) {
|
||||
path_point_spheres = (object_t **)gc_realloc(path_point_spheres, vis_points * sizeof(object_t *));
|
||||
gc_root(path_point_spheres);
|
||||
for (i32 i = path_point_sphere_count; i < vis_points; i++) {
|
||||
object_t *o = scene_spawn_object(".Sphere", NULL, true);
|
||||
o->visible = true;
|
||||
path_point_spheres[i] = o;
|
||||
}
|
||||
path_point_sphere_count = vis_points;
|
||||
}
|
||||
|
||||
// Update sphere transforms
|
||||
for (i32 i = 0; i < vis_points; i++) {
|
||||
if (path_point_spheres[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
f32 wx = points_world->buffer[i * 3];
|
||||
f32 wy = points_world->buffer[i * 3 + 1];
|
||||
f32 wz = points_world->buffer[i * 3 + 2];
|
||||
f32 dist = vec4_dist(scene_camera->base->transform->loc, (vec4_t){wx, wy, wz, 1.0});
|
||||
f32 fov = scene_camera->data->fov;
|
||||
f32 scale = dist / 8.0f * fov * 0.1f * (i == path_layer_last_active ? 1.5f : 1.0f);
|
||||
|
||||
path_point_spheres[i]->transform->loc = (vec4_t){wx, wy, wz, 1.0};
|
||||
path_point_spheres[i]->transform->scale = (vec4_t){scale, scale, scale, 1.0};
|
||||
transform_build_matrix(path_point_spheres[i]->transform);
|
||||
}
|
||||
|
||||
// Release drag - the dragged point becomes the parent for the next new point
|
||||
if (mouse_released("left") && path_point_dragging >= 0) {
|
||||
for (i32 j = 0; j < path_point_sphere_count; j++) {
|
||||
path_point_spheres[j]->visible = true;
|
||||
}
|
||||
path_layer_last_active = path_point_dragging;
|
||||
path_point_dragging = -1;
|
||||
g_context->layer_preview_dirty = true;
|
||||
g_context->layers_preview_dirty = true;
|
||||
}
|
||||
|
||||
// Drag point
|
||||
if (mouse_down("left") && !mouse_started("left") && path_point_dragging >= 0) {
|
||||
f32 new_x = g_context->paint_vec.x;
|
||||
f32 new_y = g_context->paint_vec.y;
|
||||
f32 old_x = points->buffer[path_point_dragging * 2];
|
||||
f32 old_y = points->buffer[path_point_dragging * 2 + 1];
|
||||
|
||||
if (math_abs(new_x - old_x) > 0.0005f || math_abs(new_y - old_y) > 0.0005f) {
|
||||
points->buffer[path_point_dragging * 2] = new_x;
|
||||
points->buffer[path_point_dragging * 2 + 1] = new_y;
|
||||
|
||||
// Pick world position at new screen location
|
||||
f32 saved_pvx = g_context->paint_vec.x;
|
||||
f32 saved_pvy = g_context->paint_vec.y;
|
||||
g_context->paint_vec.x = new_x;
|
||||
g_context->paint_vec.y = new_y;
|
||||
util_render_pick_pos_nor_tex();
|
||||
g_context->paint_vec.x = saved_pvx;
|
||||
g_context->paint_vec.y = saved_pvy;
|
||||
|
||||
if (math_abs(g_context->posx_picked) < 50.0f) {
|
||||
points_world->buffer[path_point_dragging * 3] = g_context->posx_picked;
|
||||
points_world->buffer[path_point_dragging * 3 + 1] = g_context->posy_picked;
|
||||
points_world->buffer[path_point_dragging * 3 + 2] = g_context->posz_picked;
|
||||
f32_array_t *points_camera = l->path_points_camera;
|
||||
if (points_camera->length >= (path_point_dragging + 1) * 9) {
|
||||
vec4_t loc = scene_camera->base->transform->loc;
|
||||
quat_t rot = scene_camera->base->transform->rot;
|
||||
points_camera->buffer[path_point_dragging * 9 + 0] = loc.x;
|
||||
points_camera->buffer[path_point_dragging * 9 + 1] = loc.y;
|
||||
points_camera->buffer[path_point_dragging * 9 + 2] = loc.z;
|
||||
points_camera->buffer[path_point_dragging * 9 + 3] = loc.w;
|
||||
points_camera->buffer[path_point_dragging * 9 + 4] = rot.x;
|
||||
points_camera->buffer[path_point_dragging * 9 + 5] = rot.y;
|
||||
points_camera->buffer[path_point_dragging * 9 + 6] = rot.z;
|
||||
points_camera->buffer[path_point_dragging * 9 + 7] = rot.w;
|
||||
points_camera->buffer[path_point_dragging * 9 + 8] = sys_w() / (f32)sys_h();
|
||||
}
|
||||
}
|
||||
|
||||
util_layer_repaint_path(l);
|
||||
for (i32 j = 0; j < path_point_sphere_count; j++) {
|
||||
path_point_spheres[j]->visible = false;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if mouse ray hits any point sphere
|
||||
if (mouse_started("left") && !ui->is_hovered && !base_is_dragging && vis_points > 0) {
|
||||
f32 min_dist = 1e10f;
|
||||
i32 closest = -1;
|
||||
|
||||
for (i32 i = 0; i < vis_points; i++) {
|
||||
f32 wx = points_world->buffer[i * 3];
|
||||
f32 wy = points_world->buffer[i * 3 + 1];
|
||||
f32 wz = points_world->buffer[i * 3 + 2];
|
||||
f32 dist = vec4_dist(scene_camera->base->transform->loc, (vec4_t){wx, wy, wz, 1.0});
|
||||
f32 fov = scene_camera->data->fov;
|
||||
f32 hit_radius = dist / 8.0f * fov * 0.25f;
|
||||
ray_t *ray = raycast_get_ray(mouse_view_x(), mouse_view_y(), scene_camera);
|
||||
if (ray_intersects_sphere(ray, (vec4_t){wx, wy, wz, 1.0}, hit_radius) && dist < min_dist) {
|
||||
min_dist = dist;
|
||||
closest = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (closest >= 0) {
|
||||
path_point_dragging = closest;
|
||||
for (i32 j = 0; j < path_point_sphere_count; j++) {
|
||||
if (path_point_spheres[j] != NULL) {
|
||||
path_point_spheres[j]->visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -264,8 +264,8 @@ void util_render_make_brush_preview() {
|
||||
g_context->layer = g_context->layer->parent;
|
||||
}
|
||||
|
||||
slot_material_t *_fill_layer = g_context->layer->fill_layer;
|
||||
g_context->layer->fill_layer = NULL;
|
||||
slot_material_t *_fill_material = g_context->layer->fill_material;
|
||||
g_context->layer->fill_material = NULL;
|
||||
|
||||
render_path_paint_use_live_layer(true);
|
||||
make_material_parse_paint_material(false);
|
||||
@@ -375,10 +375,10 @@ void util_render_make_brush_preview() {
|
||||
g_context->prev_paint_vec_y = -1;
|
||||
g_context->pdirty = _pdirty;
|
||||
render_path_paint_use_live_layer(false);
|
||||
g_context->layer->fill_layer = _fill_layer;
|
||||
g_context->layer = _layer;
|
||||
g_context->material = _material;
|
||||
g_context->tool = _tool;
|
||||
g_context->layer->fill_material = _fill_material;
|
||||
g_context->layer = _layer;
|
||||
g_context->material = _material;
|
||||
g_context->tool = _tool;
|
||||
sys_notify_on_next_frame(&util_render_make_brush_preview_parse_paint_material, NULL);
|
||||
|
||||
// Restore paint mesh
|
||||
|
||||
Reference in New Issue
Block a user