Files
armorpaint/paint/sources/context.c
T

562 lines
19 KiB
C
Raw Normal View History

2026-03-09 13:17:15 +01:00
#include "global.h"
2026-03-06 12:56:38 +01:00
void context_init() {
2026-06-05 14:48:27 +02:00
g_context = GC_ALLOC_INIT(context_t, {0});
2026-04-05 16:41:00 +02:00
gc_root(g_context);
2026-06-05 14:48:27 +02:00
2026-06-08 11:54:42 +02:00
g_context->merged_object_is_atlas = false; // Only objects referenced by atlas are merged
g_context->ddirty = 0; // depth
g_context->pdirty = 0; // paint
g_context->rdirty = 0; // render
g_context->brush_blend_dirty = true;
g_context->split_view = false;
g_context->view_index = -1;
g_context->view_index_last = -1;
g_context->picked_color = project_make_swatch(0xffffffff);
g_context->envmap_loaded = false;
g_context->show_envmap = false;
g_context->show_envmap_blur = false;
g_context->show_envmap_spheres = false;
g_context->capturing_screenshot = false;
g_context->capture_background = false;
g_context->envmap_angle = 0.0;
g_context->light_angle = 0.0;
g_context->cull_backfaces = true;
g_context->format_type = TEXTURE_LDR_FORMAT_PNG;
g_context->format_quality = 100.0;
g_context->layers_destination = EXPORT_DESTINATION_DISK;
g_context->split_by = SPLIT_TYPE_OBJECT;
g_context->select_time = 0.0;
g_context->viewport_mode = g_config->viewport_mode;
g_context->hscale_was_changed = false;
g_context->export_mesh_format = MESH_FORMAT_OBJ;
g_context->export_mesh_index = 0;
g_context->pack_assets_on_export = true;
g_context->pack_assets_on_save = false;
g_context->paint_vec = (vec4_t){0.0, 0.0, 0.0, 1.0};
g_context->last_paint_x = -1.0;
g_context->last_paint_y = -1.0;
g_context->foreground_event = false;
g_context->painted = 0;
g_context->brush_time = 0.0;
g_context->clone_start_x = -1.0;
g_context->clone_start_y = -1.0;
g_context->clone_delta_x = 0.0;
g_context->clone_delta_y = 0.0;
g_context->show_compass = true;
g_context->last_paint_vec_x = -1.0;
g_context->last_paint_vec_y = -1.0;
g_context->prev_paint_vec_x = -1.0;
g_context->prev_paint_vec_y = -1.0;
g_context->frame = 0;
g_context->paint2d_view = false;
g_context->brush_locked = false;
g_context->camera_type = CAMERA_TYPE_PERSPECTIVE;
g_context->texture_export_path = "";
g_context->last_status_position = 0;
g_context->camera_pivot = CAMERA_PIVOT_CURSOR;
g_context->camera_controls = CAMERA_CONTROLS_ORBIT;
g_context->pen_painting_only = false; // Reject painting with finger when using pen
g_context->layer_preview_dirty = true;
g_context->layers_preview_dirty = false;
g_context->node_preview_name = "";
g_context->node_preview_socket_map = any_map_create();
g_context->node_preview_map = any_map_create();
g_context->selected_node_preview = true;
g_context->material_preview = false; // Drawing material previews
g_context->saved_camera = mat4_identity();
g_context->materialid_picked = 0;
g_context->uvx_picked = 0.0;
g_context->uvy_picked = 0.0;
g_context->picker_select_material = false;
2026-07-11 17:42:26 +02:00
g_context->picker_paint_mask = false;
g_context->picker_viewport_mask = false;
2026-06-08 11:54:42 +02:00
g_context->pick_pos_nor_tex = false;
g_context->pick_object_id = false;
g_context->posx_picked = 0.0;
g_context->posy_picked = 0.0;
g_context->posz_picked = 0.0;
g_context->norx_picked = 0.0;
g_context->nory_picked = 0.0;
g_context->norz_picked = 0.0;
g_context->draw_wireframe = false;
g_context->draw_texels = false;
g_context->colorid = 0;
g_context->colorid_picked = false;
g_context->layers_export = EXPORT_MODE_VISIBLE;
g_context->decal_preview = false;
g_context->decal_x = 0.0;
g_context->decal_y = 0.0;
g_context->write_icon_on_export = false;
g_context->particle_hit_x = 0.0;
g_context->particle_hit_y = 0.0;
g_context->particle_hit_z = 0.0;
g_context->last_particle_hit_x = 0.0;
g_context->last_particle_hit_y = 0.0;
g_context->last_particle_hit_z = 0.0;
g_context->particle_friction = 0.1;
g_context->particle_bounciness = 0.0;
g_context->particle_gravity_x = 0.0;
g_context->particle_gravity_y = 0.0;
g_context->particle_gravity_z = -9.81;
g_context->particle_lifetime = 5.0;
g_context->particle_mass = 1.0;
g_context->particle_random = 0.1;
g_context->particle_spawn_distance = 0.3;
g_context->layer_filter = 0;
g_context->gizmo_started = false;
g_context->gizmo_offset = 0.0;
g_context->gizmo_drag = 0.0;
g_context->gizmo_drag_last = 0.0;
g_context->translate_x = false;
g_context->translate_y = false;
g_context->translate_z = false;
g_context->scale_x = false;
g_context->scale_y = false;
g_context->scale_z = false;
g_context->rotate_x = false;
g_context->rotate_y = false;
g_context->rotate_z = false;
g_context->brush_nodes_radius = 1.0;
g_context->brush_nodes_opacity = 1.0;
g_context->brush_nodes_uses_random = false;
g_context->brush_mask_image_is_alpha = false;
g_context->brush_stencil_image_is_alpha = false;
g_context->brush_stencil_x = 0.02;
g_context->brush_stencil_y = 0.02;
g_context->brush_stencil_scale = 0.9;
g_context->brush_stencil_scaling = false;
g_context->brush_stencil_angle = 0.0;
g_context->brush_stencil_rotating = false;
g_context->brush_nodes_scale = 1.0;
g_context->brush_nodes_angle = 0.0;
g_context->brush_nodes_hardness = 1.0;
g_context->brush_directional = false;
g_context->brush_scale_x = 1.0;
g_context->brush_decal_mask_radius = 0.5;
g_context->brush_blending = BLEND_TYPE_MIX;
g_context->brush_opacity = 1.0;
g_context->brush_scale = 1.0;
g_context->brush_angle = 0.0;
g_context->brush_lazy_radius = 0.0;
g_context->brush_lazy_step = 0.0;
g_context->brush_lazy_x = 0.0;
g_context->brush_lazy_y = 0.0;
g_context->brush_paint = UV_TYPE_UVMAP;
g_context->brush_angle_reject_dot = 0.5;
g_context->bake_type = BAKE_TYPE_CURVATURE;
g_context->bake_axis = BAKE_AXIS_XYZ;
g_context->bake_up_axis = BAKE_UP_AXIS_Z;
g_context->bake_samples = 128;
g_context->bake_ao_strength = 1.0;
g_context->bake_ao_radius = 1.0;
g_context->bake_ao_offset = 1.0;
g_context->bake_curv_strength = 1.0;
g_context->bake_curv_radius = 1.0;
g_context->bake_curv_offset = 0.0;
g_context->bake_curv_smooth = 1;
g_context->bake_high_poly = 0;
g_context->xray = false;
g_context->sym_x = false;
g_context->sym_y = false;
g_context->sym_z = false;
g_context->fill_type = FILL_TYPE_OBJECT;
g_context->blur_type = BLUR_TYPE_BLUR;
g_context->paint2d = false;
g_context->maximized_sidebar_width = 0;
g_context->drag_dest = 0;
g_context->tool = TOOL_TYPE_BRUSH;
g_context->color_picker_previous_tool = TOOL_TYPE_BRUSH;
g_context->brush_radius = 0.5;
g_context->brush_hardness = 1.0;
2026-03-06 12:56:38 +01:00
}
bool context_use_deferred() {
2026-04-05 16:41:00 +02:00
return g_config->render_mode != RENDER_MODE_FORWARD &&
2026-04-21 10:52:27 +02:00
(g_context->viewport_mode == VIEWPORT_MODE_LIT || g_context->viewport_mode == VIEWPORT_MODE_PATH_TRACE) && g_context->tool != TOOL_TYPE_COLORID;
2026-03-06 12:56:38 +01:00
}
void context_select_material(i32 i) {
2026-06-05 20:34:10 +02:00
if (g_project->_->materials->length <= i) {
2026-03-06 12:56:38 +01:00
return;
}
2026-06-05 20:34:10 +02:00
context_set_material(g_project->_->materials->buffer[i]);
2026-03-06 12:56:38 +01:00
}
2026-03-10 11:49:57 +01:00
void context_set_material_on_next_frame(void *_) {
2026-03-09 23:02:08 +01:00
util_render_make_decal_preview();
}
2026-03-06 12:56:38 +01:00
void context_set_material(slot_material_t *m) {
2026-06-05 20:34:10 +02:00
if (array_index_of(g_project->_->materials, m) == -1) {
2026-03-06 12:56:38 +01:00
return;
}
2026-04-05 16:41:00 +02:00
g_context->material = m;
2026-03-06 12:56:38 +01:00
make_material_parse_paint_material(true);
ui_base_hwnds->buffer[TAB_AREA_SIDEBAR1]->redraws = 2;
ui_header_handle->redraws = 2;
ui_nodes_hwnd->redraws = 2;
gc_unroot(ui_nodes_group_stack);
2026-03-08 08:39:29 +01:00
ui_nodes_group_stack = any_array_create_from_raw((void *[]){}, 0);
2026-03-06 12:56:38 +01:00
gc_root(ui_nodes_group_stack);
bool decal = context_is_decal();
if (decal) {
2026-03-09 23:02:08 +01:00
sys_notify_on_next_frame(&context_set_material_on_next_frame, NULL);
2026-03-06 12:56:38 +01:00
}
}
void context_select_brush(i32 i) {
2026-06-05 20:34:10 +02:00
if (g_project->_->brushes->length <= i) {
2026-03-06 12:56:38 +01:00
return;
}
2026-06-05 20:34:10 +02:00
context_set_brush(g_project->_->brushes->buffer[i]);
2026-03-06 12:56:38 +01:00
}
void context_set_brush(slot_brush_t *b) {
2026-06-05 20:34:10 +02:00
if (array_index_of(g_project->_->brushes, b) == -1) {
2026-03-06 12:56:38 +01:00
return;
}
2026-04-05 16:41:00 +02:00
g_context->brush = b;
2026-03-06 12:56:38 +01:00
make_material_parse_brush();
2026-06-01 15:53:45 +02:00
brush_output_node_parse_inputs();
make_material_parse_paint_material(false);
2026-03-06 12:56:38 +01:00
ui_base_hwnds->buffer[TAB_AREA_SIDEBAR1]->redraws = 2;
ui_nodes_hwnd->redraws = 2;
}
void context_set_font(slot_font_t *f) {
2026-06-05 20:34:10 +02:00
if (array_index_of(g_project->_->fonts, f) == -1) {
2026-03-06 12:56:38 +01:00
return;
}
2026-04-05 16:41:00 +02:00
g_context->font = f;
2026-03-06 12:56:38 +01:00
util_render_make_text_preview();
util_render_make_decal_preview();
ui_base_hwnds->buffer[TAB_AREA_STATUS]->redraws = 2;
ui_view2d_hwnd->redraws = 2;
}
2026-04-04 21:38:20 +02:00
void context_select_font(i32 i) {
2026-06-05 20:34:10 +02:00
if (g_project->_->fonts->length <= i) {
2026-04-04 21:38:20 +02:00
return;
}
2026-06-05 20:34:10 +02:00
context_set_font(g_project->_->fonts->buffer[i]);
2026-04-04 21:38:20 +02:00
}
2026-07-05 17:24:59 +02:00
void context_set_sound(slot_sound_t *s) {
if (array_index_of(g_project->_->sounds, s) == -1) {
return;
}
g_context->sound = s;
ui_base_hwnds->buffer[TAB_AREA_STATUS]->redraws = 2;
ui_view2d_hwnd->redraws = 2;
}
void context_select_sound(i32 i) {
if (g_project->_->sounds->length <= i) {
return;
}
context_set_sound(g_project->_->sounds->buffer[i]);
}
2026-03-06 12:56:38 +01:00
void context_select_layer(i32 i) {
2026-06-05 20:34:10 +02:00
if (g_project->_->layers->length <= i) {
2026-03-06 12:56:38 +01:00
return;
}
2026-06-05 20:34:10 +02:00
context_set_layer(g_project->_->layers->buffer[i]);
2026-03-06 12:56:38 +01:00
}
void context_set_layer(slot_layer_t *l) {
2026-04-05 16:41:00 +02:00
if (l == g_context->layer) {
2026-03-06 12:56:38 +01:00
return;
}
2026-04-21 10:52:27 +02:00
g_context->layer = l;
2026-03-06 12:56:38 +01:00
ui_header_handle->redraws = 2;
2026-03-10 11:49:57 +01:00
gpu_texture_t *current = _draw_current;
bool in_use = gpu_in_use;
2026-03-06 12:56:38 +01:00
if (in_use)
draw_end();
layers_set_object_mask();
make_material_parse_mesh_material();
make_material_parse_paint_material(true);
if (in_use)
draw_begin(current, false, 0);
ui_base_hwnds->buffer[TAB_AREA_SIDEBAR0]->redraws = 2;
ui_view2d_hwnd->redraws = 2;
}
void context_select_tool(i32 i) {
2026-04-05 16:41:00 +02:00
g_context->tool = i;
2026-03-06 12:56:38 +01:00
make_material_parse_paint_material(true);
make_material_parse_mesh_material();
2026-04-21 10:52:27 +02:00
g_context->ddirty = 3;
2026-04-05 16:41:00 +02:00
viewport_mode_t _viewport_mode = g_context->viewport_mode;
2026-04-24 13:14:27 +02:00
g_context->viewport_mode = VIEWPORT_MODE_NONE;
2026-03-06 12:56:38 +01:00
context_set_viewport_mode(_viewport_mode);
context_init_tool();
ui_header_handle->redraws = 2;
ui_toolbar_handle->redraws = 2;
}
void context_init_tool() {
2026-05-12 13:58:45 +02:00
if (context_is_decal()) {
2026-04-05 16:41:00 +02:00
if (g_context->tool == TOOL_TYPE_TEXT) {
2026-03-06 12:56:38 +01:00
util_render_make_text_preview();
}
util_render_make_decal_preview();
}
2026-04-05 16:41:00 +02:00
else if (g_context->tool == TOOL_TYPE_MATERIAL) {
2026-03-06 12:56:38 +01:00
layers_update_fill_layers();
2026-03-07 21:12:59 +01:00
context_main_object()->skip_context = NULL;
2026-03-06 12:56:38 +01:00
}
}
void context_select_paint_object(mesh_object_t *o) {
ui_header_handle->redraws = 2;
2026-06-05 20:34:10 +02:00
for (i32 i = 0; i < g_project->_->paint_objects->length; ++i) {
mesh_object_t *p = g_project->_->paint_objects->buffer[i];
2026-03-06 12:56:38 +01:00
p->skip_context = "paint";
}
// #ifdef is_forge
2026-04-05 16:41:00 +02:00
// g_context->paint_object->skip_context = "";
2026-03-06 12:56:38 +01:00
// #endif
2026-04-05 16:41:00 +02:00
g_context->paint_object = o;
2026-03-06 12:56:38 +01:00
2026-04-05 16:41:00 +02:00
i32 mask = slot_layer_get_object_mask(g_context->layer);
2026-03-06 12:56:38 +01:00
if (context_layer_filter_used()) {
2026-04-05 16:41:00 +02:00
mask = g_context->layer_filter;
2026-03-06 12:56:38 +01:00
}
2026-04-05 16:41:00 +02:00
if (g_context->merged_object == NULL || mask > 0) {
g_context->paint_object->skip_context = "";
2026-03-06 12:56:38 +01:00
}
util_uv_uvmap_cached = false;
util_uv_trianglemap_cached = false;
util_uv_dilatemap_cached = false;
}
mesh_object_t *context_main_object() {
2026-06-05 20:34:10 +02:00
for (i32 i = 0; i < g_project->_->paint_objects->length; ++i) {
mesh_object_t *po = g_project->_->paint_objects->buffer[i];
2026-03-06 12:56:38 +01:00
if (po->base->children->length > 0) {
return po;
}
}
2026-06-05 20:34:10 +02:00
return g_project->_->paint_objects->buffer[0];
2026-03-06 12:56:38 +01:00
}
bool context_layer_filter_used() {
2026-06-05 20:34:10 +02:00
return g_context->layer_filter > 0 && g_context->layer_filter <= g_project->_->paint_objects->length;
2026-03-06 12:56:38 +01:00
}
bool context_object_mask_used() {
2026-06-05 20:34:10 +02:00
return slot_layer_get_object_mask(g_context->layer) > 0 && slot_layer_get_object_mask(g_context->layer) <= g_project->_->paint_objects->length;
2026-03-06 12:56:38 +01:00
}
bool context_in_3d_view() {
2026-04-05 16:41:00 +02:00
return g_context->paint_vec.x < 1 && g_context->paint_vec.x > 0 && g_context->paint_vec.y < 1 && g_context->paint_vec.y > 0;
2026-03-06 12:56:38 +01:00
}
bool context_in_paint_area() {
return context_in_3d_view() || context_in_2d_view(VIEW_2D_TYPE_LAYER);
}
bool context_in_layers() {
2026-03-07 21:12:59 +01:00
char *tab = ui_hovered_tab_name();
2026-03-15 11:37:45 +01:00
return string_equals(tab, tr("Layers"));
2026-03-06 12:56:38 +01:00
}
bool context_in_materials() {
2026-03-07 21:12:59 +01:00
char *tab = ui_hovered_tab_name();
2026-03-15 11:37:45 +01:00
return string_equals(tab, tr("Materials"));
2026-03-06 12:56:38 +01:00
}
2026-07-01 11:51:03 +02:00
bool context_in_meshes() {
char *tab = ui_hovered_tab_name();
return string_equals(tab, tr("Meshes"));
}
2026-03-06 12:56:38 +01:00
bool context_in_swatches() {
2026-03-07 21:12:59 +01:00
char *tab = ui_hovered_tab_name();
2026-03-15 11:37:45 +01:00
return string_equals(tab, tr("Swatches"));
2026-03-06 12:56:38 +01:00
}
2026-04-21 07:59:19 +02:00
bool context_in_brushes() {
char *tab = ui_hovered_tab_name();
return string_equals(tab, tr("Brushes"));
}
bool context_in_fonts() {
char *tab = ui_hovered_tab_name();
return string_equals(tab, tr("Fonts"));
}
bool context_in_textures() {
char *tab = ui_hovered_tab_name();
return string_equals(tab, tr("Textures"));
}
2026-03-06 12:56:38 +01:00
bool context_in_browser() {
2026-03-07 21:12:59 +01:00
char *tab = ui_hovered_tab_name();
2026-03-15 11:37:45 +01:00
return string_equals(tab, tr("Browser"));
2026-03-06 12:56:38 +01:00
}
2026-06-05 14:48:27 +02:00
bool context_in_2d_view(view_2d_type_t type) {
return ui_view2d_show && ui_view2d_type == type && mouse_x > ui_view2d_wx && mouse_x < ui_view2d_wx + ui_view2d_ww && mouse_y > ui_view2d_wy &&
mouse_y < ui_view2d_wy + ui_view2d_wh;
}
bool context_in_nodes() {
return ui_nodes_show && mouse_x > ui_nodes_wx && mouse_x < ui_nodes_wx + ui_nodes_ww && mouse_y > ui_nodes_wy && mouse_y < ui_nodes_wy + ui_nodes_wh;
}
2026-03-06 12:56:38 +01:00
bool context_is_decal() {
2026-04-05 16:41:00 +02:00
return g_context->tool == TOOL_TYPE_DECAL || g_context->tool == TOOL_TYPE_TEXT;
2026-03-06 12:56:38 +01:00
}
bool context_is_decal_mask() {
2026-06-08 11:31:49 +02:00
return context_is_decal() && operator_shortcut(any_map_get(g_keymap, "decal_mask"), SHORTCUT_TYPE_DOWN);
2026-03-06 12:56:38 +01:00
}
2026-07-11 22:58:31 +02:00
bool context_is_brush_camera_align() {
bool brush = g_context->tool == TOOL_TYPE_BRUSH || g_context->tool == TOOL_TYPE_ERASER;
return (context_is_decal() || brush) &&
(g_context->brush_camera_align || operator_shortcut(any_map_get(g_keymap, "brush_camera_align"), SHORTCUT_TYPE_DOWN));
2026-05-28 21:43:39 +02:00
}
2026-03-06 12:56:38 +01:00
bool context_is_decal_mask_paint() {
return context_is_decal() &&
2026-06-08 11:31:49 +02:00
operator_shortcut(string("%s+%s", any_map_get(g_keymap, "decal_mask"), any_map_get(g_keymap, "action_paint")), SHORTCUT_TYPE_DOWN);
2026-03-06 12:56:38 +01:00
}
2026-07-16 19:35:34 +02:00
bool context_is_decal_mask_paint_pass() {
return context_is_decal_mask() && (mouse_down("left") || g_context->brush_time > 0);
}
2026-03-06 12:56:38 +01:00
bool context_is_floating_toolbar() {
// Header is off -> floating toolbar
2026-04-05 16:41:00 +02:00
return g_config->layout->buffer[LAYOUT_SIZE_HEADER] == 0 || (!base_view3d_show && ui_view2d_show);
2026-03-06 12:56:38 +01:00
}
void context_set_viewport_mode(viewport_mode_t mode) {
2026-04-05 16:41:00 +02:00
if (mode == g_context->viewport_mode) {
2026-03-06 12:56:38 +01:00
return;
}
2026-07-12 16:31:07 +02:00
viewport_mode_t prev_viewport_mode = g_context->viewport_mode;
g_context->viewport_mode = mode;
2026-03-06 12:56:38 +01:00
if (context_use_deferred()) {
gc_unroot(render_path_commands);
render_path_commands = render_path_deferred_commands;
gc_root(render_path_commands);
}
else {
gc_unroot(render_path_commands);
render_path_commands = render_path_forward_commands;
gc_root(render_path_commands);
}
make_material_parse_mesh_material();
// Rotate mode is not supported for path tracing yet
2026-04-05 16:41:00 +02:00
if (g_context->viewport_mode == VIEWPORT_MODE_PATH_TRACE && g_context->camera_controls == CAMERA_CONTROLS_ROTATE) {
g_context->camera_controls = CAMERA_CONTROLS_ORBIT;
2026-03-06 12:56:38 +01:00
viewport_reset();
}
// Bake in lit mode for now
2026-04-05 16:41:00 +02:00
if (g_context->viewport_mode == VIEWPORT_MODE_PATH_TRACE && g_context->tool == TOOL_TYPE_BAKE) {
g_context->viewport_mode = VIEWPORT_MODE_LIT;
2026-03-06 12:56:38 +01:00
}
2026-07-12 16:31:07 +02:00
bool has_sculpt = false;
for (i32 i = 0; i < g_project->_->layers->length; ++i) {
if (g_project->_->layers->buffer[i]->texpaint_sculpt != NULL && slot_layer_is_visible(g_project->_->layers->buffer[i])) {
has_sculpt = true;
break;
}
}
if (has_sculpt) {
if (g_context->viewport_mode == VIEWPORT_MODE_PATH_TRACE) {
sculpt_bake_to_mesh();
}
else if (prev_viewport_mode == VIEWPORT_MODE_PATH_TRACE) {
// Restore un-sculpted mesh
util_mesh_merge(NULL);
}
}
2026-03-06 12:56:38 +01:00
}
2026-04-24 13:14:27 +02:00
void context_set_camera_controls(int i) {
g_context->camera_controls = i;
}
2026-03-06 12:56:38 +01:00
void context_load_envmap() {
2026-04-05 16:41:00 +02:00
if (!g_context->envmap_loaded) {
2026-03-06 12:56:38 +01:00
// TODO: Unable to share texture for both radiance and envmap - reload image
2026-04-05 16:41:00 +02:00
g_context->envmap_loaded = true;
2026-07-05 11:30:04 +02:00
map_delete(data_cached_textures, "World_radiance.k");
2026-03-06 12:56:38 +01:00
}
world_data_load_envmap(scene_world);
2026-04-05 16:41:00 +02:00
if (g_context->saved_envmap == NULL) {
g_context->saved_envmap = scene_world->_->envmap;
2026-03-06 12:56:38 +01:00
}
}
void context_update_envmap() {
2026-04-05 16:41:00 +02:00
if (g_context->show_envmap) {
scene_world->_->envmap = g_context->show_envmap_blur ? scene_world->_->radiance_mipmaps->buffer[0] : g_context->saved_envmap;
2026-03-06 12:56:38 +01:00
}
else {
2026-04-05 16:41:00 +02:00
scene_world->_->envmap = g_context->empty_envmap;
2026-03-06 12:56:38 +01:00
}
}
2026-03-23 23:20:02 +01:00
void context_set_viewport_shader(void *viewport_shader) {
2026-04-05 16:41:00 +02:00
g_context->viewport_shader = viewport_shader;
2026-03-06 12:56:38 +01:00
context_set_render_path();
}
2026-03-10 11:49:57 +01:00
void context_set_render_path_on_next_frame(void *_) {
2026-03-09 23:02:08 +01:00
make_material_parse_mesh_material();
}
2026-03-06 12:56:38 +01:00
void context_set_render_path() {
2026-04-05 16:41:00 +02:00
if (g_config->render_mode == RENDER_MODE_FORWARD || g_context->viewport_shader != NULL) {
2026-03-06 12:56:38 +01:00
gc_unroot(render_path_commands);
render_path_commands = render_path_forward_commands;
gc_root(render_path_commands);
}
else {
gc_unroot(render_path_commands);
render_path_commands = render_path_deferred_commands;
gc_root(render_path_commands);
}
2026-03-09 23:02:08 +01:00
sys_notify_on_next_frame(&context_set_render_path_on_next_frame, NULL);
2026-03-06 12:56:38 +01:00
}
2026-03-07 21:12:59 +01:00
bool context_enable_import_plugin(char *file) {
2026-03-06 12:56:38 +01:00
// Return plugin name suitable for importing the specified file
2026-03-07 21:12:59 +01:00
if (box_preferences_files_plugin == NULL) {
2026-03-06 12:56:38 +01:00
box_preferences_fetch_plugins();
}
2026-03-07 21:12:59 +01:00
char *ext = substring(file, string_last_index_of(file, ".") + 1, string_length(file));
2026-03-06 12:56:38 +01:00
for (i32 i = 0; i < box_preferences_files_plugin->length; ++i) {
2026-03-07 21:12:59 +01:00
char *f = box_preferences_files_plugin->buffer[i];
2026-03-06 12:56:38 +01:00
if (starts_with(f, "import_") && string_index_of(f, ext) >= 0) {
config_enable_plugin(f);
2026-03-15 11:37:45 +01:00
console_info(string("%s %s", f, tr("plugin enabled")));
2026-03-06 12:56:38 +01:00
return true;
}
}
return false;
}