From 420551ee3c2fe594dc06312829a9735ed0cc9115 Mon Sep 17 00:00:00 2001 From: luboslenco Date: Mon, 3 Aug 2026 15:04:18 +0200 Subject: [PATCH] paint: merge minic_api --- paint/sources/functions.h | 4 ++ paint/sources/minic_api.c | 25 ++++++++---- paint/sources/minic_impl.c | 79 ++++++++++++++++++++++++++++++++++---- 3 files changed, 93 insertions(+), 15 deletions(-) diff --git a/paint/sources/functions.h b/paint/sources/functions.h index b2cc3702..99c925f1 100644 --- a/paint/sources/functions.h +++ b/paint/sources/functions.h @@ -428,6 +428,7 @@ void script_paint_end(void); void script_fill_layer(void); slot_material_t *script_material_create(char *name); void script_material_set(slot_material_t *m); +void script_object_set_material(object_t *o, slot_material_t *m); void script_material_delete(slot_material_t *m); ui_node_t *script_material_create_node(char *type); ui_node_t *script_material_create_node_at(char *type, f32 x, f32 y); @@ -451,6 +452,7 @@ context_t *script_get_context(); config_t *script_get_config(); project_t *script_get_project(); object_t *script_get_object(char *s); +object_t *script_shape_add(char *name); void script_draw_particles(gpu_texture_t *texture, float x, float y, float w, float h, int atlas_x, int atlas_frames); void ui_files_show2(char *filters, bool is_save, bool open_multiple, void *files_done); char *project_filepath_get(); @@ -729,7 +731,9 @@ void ui_box_hide(); void tab_meshes_draw(ui_handle_t *htab); void tab_meshes_reset_preview_map(); void tab_meshes_accept_mesh_drop(mesh_object_t *mesh); +mesh_object_t *tab_meshes_append_shape(char *mesh_name); void tab_meshes_set_override(mesh_object_t *o, i32 mat_index); +void tab_meshes_set_override_data(mesh_object_t *o, i32 mat_index, material_data_t *data); i32 tab_meshes_get_override(mesh_object_t *o); void tab_meshes_on_material_deleted(i32 deleted_index); void tab_meshes_on_material_reordered(i32 old_index, i32 new_index); diff --git a/paint/sources/minic_api.c b/paint/sources/minic_api.c index e75addd5..c6184c1a 100644 --- a/paint/sources/minic_api.c +++ b/paint/sources/minic_api.c @@ -178,14 +178,23 @@ static void minic_set_mat3(minic_val_t *o, mat3_t m) { minic_box(o, m.m, 9); } static void minic_set_mat4(minic_val_t *o, mat4_t m) { minic_box(o, m.m, 16); } // clang-format on +// A call may pass too few arguments or the wrong kind +static void *minic_arg_ptr(minic_val_t *a, int c, int i) { + return (i < c && a[i].type == MINIC_T_PTR) ? a[i].p : NULL; +} + +static float minic_arg_float(minic_val_t *a, int c, int i) { + return i < c ? (float)minic_val_to_d(a[i]) : 0.0f; +} + // Argument accessors for the wrapper table -#define V2(i) minic_get_vec2(_a[i].p) -#define V4(i) minic_get_vec4(_a[i].p) -#define QT(i) minic_get_quat(_a[i].p) -#define M3(i) minic_get_mat3(_a[i].p) -#define M4(i) minic_get_mat4(_a[i].p) -#define AF(i) (_a[i].f) -#define AP(i) (_a[i].p) +#define V2(i) minic_get_vec2(minic_arg_ptr(_a, _c, i)) +#define V4(i) minic_get_vec4(minic_arg_ptr(_a, _c, i)) +#define QT(i) minic_get_quat(minic_arg_ptr(_a, _c, i)) +#define M3(i) minic_get_mat3(minic_arg_ptr(_a, _c, i)) +#define M4(i) minic_get_mat4(minic_arg_ptr(_a, _c, i)) +#define AF(i) minic_arg_float(_a, _c, i) +#define AP(i) minic_arg_ptr(_a, _c, i) // One X(return-kind, name, call) line per math function; expanded twice: // once to define the mn_* wrappers, once to register them @@ -1221,6 +1230,7 @@ void minic_register_builtins() { R(script_get_config, "p()"); R(script_get_project, "p()"); R(script_get_object, "p(p s)"); + R(script_shape_add, "p(p name)"); R(script_set_stage, "v(p name)"); R(script_show_envmap, "v(i b)"); R(script_fade_to_stage, "v(p stage)"); @@ -1234,6 +1244,7 @@ void minic_register_builtins() { R(script_fill_layer, "v()"); R(script_material_create, "p(p name)"); R(script_material_set, "v(p m)"); + R(script_object_set_material, "v(p object,p material)"); R(script_material_delete, "v(p m)"); R(script_material_create_node, "p(p type)"); R(script_material_create_node_at, "p(p type,f x,f y)"); diff --git a/paint/sources/minic_impl.c b/paint/sources/minic_impl.c index d53d68ae..236ec178 100644 --- a/paint/sources/minic_impl.c +++ b/paint/sources/minic_impl.c @@ -308,7 +308,7 @@ static ui_node_canvas_t *script_material_canvas(void) { return g_context->material->canvas; } -static void script_material_gpu_begin(gpu_texture_t **out_current, bool *out_in_use) { +static void script_gpu_begin(gpu_texture_t **out_current, bool *out_in_use) { *out_current = _draw_current; *out_in_use = gpu_in_use; if (*out_in_use) { @@ -316,7 +316,7 @@ static void script_material_gpu_begin(gpu_texture_t **out_current, bool *out_in_ } } -static void script_material_gpu_end(gpu_texture_t *current, bool in_use) { +static void script_gpu_end(gpu_texture_t *current, bool in_use) { if (in_use) { draw_begin(current, false, 0); } @@ -335,10 +335,10 @@ slot_material_t *script_material_create(char *name) { gpu_texture_t *current; bool in_use; - script_material_gpu_begin(¤t, &in_use); + script_gpu_begin(¤t, &in_use); context_set_material(m); util_render_make_material_preview(); - script_material_gpu_end(current, in_use); + script_gpu_end(current, in_use); history_new_material(); if (ui_base_hwnds != NULL && ui_base_hwnds->length > 1) { @@ -353,16 +353,47 @@ void script_material_set(slot_material_t *m) { } gpu_texture_t *current; bool in_use; - script_material_gpu_begin(¤t, &in_use); + script_gpu_begin(¤t, &in_use); context_set_material(m); util_render_make_material_preview(); - script_material_gpu_end(current, in_use); + script_gpu_end(current, in_use); +} + +static slot_material_t *script_object_material_slot = NULL; +static material_data_t *script_object_material_data = NULL; + +static void script_object_material_reset(void) { + gc_unroot(script_object_material_data); + script_object_material_slot = NULL; + script_object_material_data = NULL; +} + +void script_object_set_material(object_t *o, slot_material_t *m) { + if (o == NULL || g_project == NULL || g_project->_ == NULL || g_project->_->materials == NULL) { + return; + } + if (!string_equals(o->ext_type, "mesh_object_t")) { + return; + } + i32 index = m != NULL ? array_index_of(g_project->_->materials, m) : -1; + if (index >= 0 && m != script_object_material_slot) { + script_object_material_reset(); + script_object_material_slot = m; + script_object_material_data = make_mesh_preview_viewport(m); + gc_root(script_object_material_data); + } + tab_meshes_set_override_data(o->ext, index, index >= 0 ? script_object_material_data : NULL); + g_project->mesh_materials = i32_array_create(0); + g_context->ddirty = 2; } void script_material_delete(slot_material_t *m) { if (m == NULL || g_project == NULL || g_project->_ == NULL || g_project->_->materials == NULL) { return; } + if (m == script_object_material_slot) { + script_object_material_reset(); + } if (g_project->_->materials->length <= 1) { return; } @@ -529,10 +560,11 @@ void script_material_update(void) { if (g_context == NULL || g_context->material == NULL) { return; } + script_object_material_reset(); gpu_texture_t *current; bool in_use; - script_material_gpu_begin(¤t, &in_use); + script_gpu_begin(¤t, &in_use); make_material_parse_paint_material(true); util_render_make_material_preview(); @@ -541,7 +573,7 @@ void script_material_update(void) { } base_update_workflow_nodes(); - script_material_gpu_end(current, in_use); + script_gpu_end(current, in_use); if (ui_nodes_hwnd != NULL) { ui_nodes_hwnd->redraws = 2; @@ -556,6 +588,37 @@ void script_material_update(void) { g_context->rtdirty = 1; } +string_array_t *script_shape_list(void) { + project_fetch_default_meshes(); + return project_default_mesh_list; +} + +object_t *script_shape_add(char *name) { + if (name == NULL || string_array_index_of(script_shape_list(), name) < 0) { + return NULL; + } + if (g_project == NULL || g_project->_ == NULL || g_project->_->paint_objects == NULL || g_project->_->paint_objects->length == 0) { + return NULL; + } + + gpu_texture_t *current; + bool in_use; + script_gpu_begin(¤t, &in_use); + mesh_object_t *mo = tab_meshes_append_shape(name); + script_gpu_end(current, in_use); + + if (mo == NULL) { + return NULL; + } + + tab_meshes_reset_preview_map(); + g_context->ddirty = 2; + if (ui_base_hwnds != NULL && ui_base_hwnds->length > TAB_AREA_SIDEBAR0) { + ui_base_hwnds->buffer[TAB_AREA_SIDEBAR0]->redraws = 2; + } + return mo->base; +} + extern string_array_t *_path_texture_formats; extern string_array_t *_path_mesh_formats; extern string_array_t *_path_text_formats;