Files
armorpaint/paint/sources/sim.c
T

108 lines
2.4 KiB
C
Raw Normal View History

2026-03-09 13:17:15 +01:00
#include "global.h"
2026-08-23 14:19:14 +02:00
bool sim_initialized = false;
2026-04-05 16:09:00 +02:00
2026-03-06 12:56:38 +01:00
void sim_init() {
if (sim_initialized) {
return;
}
2026-08-12 16:06:03 +02:00
physics_world_create();
2026-03-06 12:56:38 +01:00
sim_initialized = true;
}
void sim_update() {
render_path_raytrace_ready = false;
if (sim_running) {
2026-08-12 13:04:02 +02:00
trait_update();
2026-08-12 16:06:03 +02:00
physics_world_update();
2026-03-06 12:56:38 +01:00
iron_delay_idle_sleep();
}
}
void sim_play() {
sim_running = true;
}
void sim_stop() {
sim_running = false;
2026-08-12 13:04:02 +02:00
trait_stop();
2026-03-06 12:56:38 +01:00
}
2026-08-12 16:06:03 +02:00
void sim_add_body(object_t *o, physics_shape_t shape, f32 mass) {
2026-07-18 15:45:49 +02:00
sim_init();
2026-08-12 16:06:03 +02:00
physics_body_create(o, shape, mass);
2026-07-01 19:21:53 +02:00
}
2026-08-22 21:57:57 +02:00
static void sim_shift_object_masks(i32 from) {
if (g_project->_->layers != NULL) {
for (i32 i = 0; i < g_project->_->layers->length; ++i) {
slot_layer_t *l = g_project->_->layers->buffer[i];
if (l->object_mask >= from) {
++l->object_mask;
}
}
}
if (g_context->layer_filter >= from) {
++g_context->layer_filter;
}
}
2026-08-11 14:52:06 +02:00
mesh_object_t *sim_duplicate_object(mesh_object_t *so) {
2026-07-01 11:53:20 +02:00
// Mesh
if (so == NULL) {
2026-08-11 14:52:06 +02:00
return NULL;
2026-04-18 14:14:54 +02:00
}
2026-07-01 19:21:53 +02:00
2026-08-14 21:48:54 +02:00
mesh_data_t *data = so->data;
2026-07-01 19:21:53 +02:00
mesh_object_t *dup = scene_add_mesh_object(data, so->material, so->base->parent);
2026-03-06 12:56:38 +01:00
transform_set_matrix(dup->base->transform, so->base->transform->local);
2026-08-22 21:57:57 +02:00
// Insert below the original
i32 index = array_index_of(g_project->_->paint_objects, so);
i32 at = index < 0 ? g_project->_->paint_objects->length : index + 1;
array_insert((any_array_t *)g_project->_->paint_objects, at, dup);
sim_shift_object_masks(at + 1);
2026-07-01 11:53:20 +02:00
// Ensure unique name
2026-08-24 21:19:48 +02:00
dup->base->name = string_copy(_import_mesh_unique_name(so->base->name));
2026-08-11 16:54:37 +02:00
tab_stages_add_object(dup->base->name);
2026-03-06 12:56:38 +01:00
2026-08-03 20:53:47 +02:00
// Material override
i32 mat_index = tab_meshes_get_override(so);
if (mat_index >= 0) {
tab_meshes_set_override_data(dup, mat_index, so->material);
g_project->mesh_materials = i32_array_create(0);
}
2026-03-06 12:56:38 +01:00
// Physics
2026-08-12 16:06:03 +02:00
physics_body_t *pb = so->base->_->body;
2026-03-07 21:12:59 +01:00
if (pb != NULL) {
2026-08-12 16:06:03 +02:00
physics_body_create(dup->base, pb->shape, pb->mass);
2026-03-06 12:56:38 +01:00
}
2026-08-11 14:52:06 +02:00
2026-08-22 21:57:57 +02:00
tab_meshes_sort_hierarchy();
tab_timeline_sync();
2026-08-11 14:52:06 +02:00
return dup;
}
void sim_duplicate() {
2026-08-24 21:19:48 +02:00
mesh_object_t *dup = sim_duplicate_object(g_context->paint_object);
if (dup != NULL) {
g_context->paint_object = dup;
ui_header_handle->redraws = 2;
ui_base_hwnds->buffer[TAB_AREA_SIDEBAR0]->redraws = 2;
}
2026-08-14 21:48:54 +02:00
util_mesh_merge(NULL);
g_context->ddirty = 2;
2026-03-06 12:56:38 +01:00
}
void sim_delete() {
2026-08-21 22:35:41 +02:00
if (g_project->_->paint_objects->length < 2) {
return;
}
tab_meshes_draw_context_menu_delete(g_context->paint_object);
2026-03-06 12:56:38 +01:00
}