paint: call order fixes

This commit is contained in:
luboslenco
2026-07-12 00:42:45 +02:00
parent 6052e5d6a2
commit 59679abbc8
5 changed files with 70 additions and 32 deletions
+1
View File
@@ -219,6 +219,7 @@ void ui_base_set_viewport_col(i32 col);
void render_gizmo_update();
void util_layer_update_preview();
void util_layer_update_path();
void util_layer_check_path_grab();
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);
+3
View File
@@ -160,6 +160,7 @@ void render_path_base_commands(void (*draw_commands)(void)) {
}
if (base_ui_enabled) {
util_layer_check_path_grab();
util_brush_update();
}
@@ -173,6 +174,8 @@ void render_path_base_commands(void (*draw_commands)(void)) {
if (g_context->viewport_mode == VIEWPORT_MODE_PATH_TRACE) {
bool use_live_layer = g_context->tool == TOOL_TYPE_MATERIAL;
render_path_raytrace_draw(use_live_layer);
g_context->last_paint_vec_x = g_context->paint_vec.x;
g_context->last_paint_vec_y = g_context->paint_vec.y;
g_context->foreground_event = false;
render_path_base_end();
return;
+18 -1
View File
@@ -48,8 +48,25 @@ void render_path_raytrace_commands(bool use_live_layer) {
}
////
if (g_context->pdirty > 0 || g_context->rtdirty > 0) {
bool is_live = g_config->brush_live && render_path_paint_live_layer_drawn > 0 && render_path_paint_live_layer != NULL;
if (g_context->pdirty > 0 || g_context->rtdirty > 0 || is_live) {
slot_layer_t *layer = g_context->layer;
gpu_texture_t *_texpaint = layer->texpaint;
gpu_texture_t *_texpaint_nor = layer->texpaint_nor;
gpu_texture_t *_texpaint_pack = layer->texpaint_pack;
if (is_live) {
layer->texpaint = render_path_paint_live_layer->texpaint;
if (slot_layer_is_layer(layer)) {
layer->texpaint_nor = render_path_paint_live_layer->texpaint_nor;
layer->texpaint_pack = render_path_paint_live_layer->texpaint_pack;
}
}
layers_flatten(true, NULL);
if (is_live) {
layer->texpaint = _texpaint;
layer->texpaint_nor = _texpaint_nor;
layer->texpaint_pack = _texpaint_pack;
}
g_context->rtdirty = 0;
}
+4 -1
View File
@@ -395,7 +395,8 @@ void layers_update_fill_layers() {
g_context->pdirty = 0;
g_context->ddirty = 2;
g_context->rdirty = 2;
g_context->layers_preview_dirty = true; // Repaint all layer previews as multiple layers might have changed.
g_context->rtdirty = 1;
g_context->layers_preview_dirty = true;
if (in_use)
draw_begin(current, false, 0);
g_context->layer = _layer;
@@ -1208,11 +1209,13 @@ void layers_on_resized_on_next_frame(void *_) {
if (l->fill_material != NULL) {
g_context->layer = l;
g_context->material = l->fill_material;
layers_set_object_mask();
layers_update_fill_layer(true);
}
}
g_context->layer = _layer;
g_context->material = _material;
layers_set_object_mask();
make_material_parse_paint_material(true);
}
+44 -30
View File
@@ -467,6 +467,50 @@ static void path_point_move(slot_layer_t *l, i32 idx, f32 new_x, f32 new_y) {
}
}
void util_layer_check_path_grab() {
// Check if mouse ray hits any point sphere
if (g_config->workspace == WORKSPACE_PLAYER || g_context->paint2d) {
return;
}
slot_layer_t *l = g_context->layer;
if (!slot_layer_is_path(l)) {
return;
}
i32 vis_points = l->path_points->length / 2;
if (!mouse_started("left") || g_ui->is_hovered || base_is_dragging || vis_points == 0) {
return;
}
f32_array_t *points_world = l->path_points_world;
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;
}
}
}
}
void util_layer_update_path() {
if (g_config->workspace == WORKSPACE_PLAYER || g_context->paint2d) {
return;
@@ -495,7 +539,6 @@ void util_layer_update_path() {
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
@@ -572,33 +615,4 @@ void util_layer_update_path() {
}
return;
}
// Check if mouse ray hits any point sphere
if (mouse_started("left") && !g_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;
}
}
}
}
}