paint: merge linked meshes

This commit is contained in:
luboslenco
2026-08-14 21:48:54 +02:00
parent ff1b1e5ff1
commit 4e5971fda7
6 changed files with 367 additions and 64 deletions
+24 -4
View File
@@ -1,11 +1,30 @@
#include "../global.h"
static mesh_data_t *export_arm_named_mesh_data(mesh_object_t *p) {
// Mesh data shared by linked duplicates is named after the object holding it
if (string_equals(p->data->name, p->base->name)) {
return p->data;
}
mesh_data_t *renamed = gc_alloc(sizeof(mesh_data_t));
*renamed = *p->data;
renamed->name = string_copy(p->base->name);
return renamed;
}
static mesh_data_t *export_arm_linked_mesh_data(mesh_object_t *p, i32 source_index) {
return GC_ALLOC_INIT(mesh_data_t, {.name = util_mesh_link_name(source_index, p->base->name),
.scale_pos = p->data->scale_pos,
.scale_tex = p->data->scale_tex,
.vertex_arrays = any_array_create_from_raw((void *[]){}, 0),
.index_array = u32_array_create(0)});
}
void export_arm_run_mesh(char *path, mesh_object_t_array_t *paint_objects) {
mesh_data_t_array_t *mesh_datas = any_array_create_from_raw((void *[]){}, 0);
for (i32 i = 0; i < paint_objects->length; ++i) {
mesh_object_t *p = paint_objects->buffer[i];
any_array_push(mesh_datas, p->data);
any_array_push(mesh_datas, export_arm_named_mesh_data(p));
}
scene_t *raw = GC_ALLOC_INIT(scene_t, {.mesh_datas = mesh_datas});
@@ -186,8 +205,9 @@ void export_arm_run_project() {
mesh_data_t_array_t *md = any_array_create_from_raw((void *[]){}, 0);
for (i32 i = 0; i < g_project->_->paint_objects->length; ++i) {
mesh_object_t *p = g_project->_->paint_objects->buffer[i];
any_array_push(md, p->data);
mesh_object_t *p = g_project->_->paint_objects->buffer[i];
i32 source = util_mesh_data_owner(p->data);
any_array_push(md, source >= 0 && source < i ? export_arm_linked_mesh_data(p, source) : export_arm_named_mesh_data(p));
}
string_array_t *texture_files = export_arm_assets_to_files(g_project->_->filepath, g_project->_->assets);
@@ -305,7 +325,7 @@ void export_arm_run_project() {
for (i32 i = 0; i < g_project->mesh_parents->length; ++i) {
object_t *parent = g_project->_->paint_objects->buffer[i]->base->parent;
g_project->mesh_parents->buffer[i] = -1; // No parent
if (parent != NULL && parent != _scene_scene_parent) {
if (parent != NULL && parent != _scene_root) {
for (i32 j = 0; j < g_project->mesh_parents->length; ++j) {
if (g_project->_->paint_objects->buffer[j]->base == parent) {
g_project->mesh_parents->buffer[i] = j;
+34 -9
View File
@@ -387,25 +387,49 @@ void import_arm_run_project(char *path) {
}
}
mesh_data_t *md = mesh_data_create(g_project->mesh_datas->buffer[0]);
md->_->skin_blob = import_arm_get_mesh_skin(0);
mesh_data_t_array_t *mesh_datas = any_array_create_from_raw((void *[]){}, 0);
string_array_t *mesh_names = string_array_create(0);
for (i32 i = 0; i < g_project->mesh_datas->length; ++i) {
mesh_data_t *raw = g_project->mesh_datas->buffer[i];
i32 source_index;
char *object_name;
if (i > 0 && util_mesh_link_parse(raw->name, &source_index, &object_name)) {
any_array_push(mesh_datas, NULL);
string_array_push(mesh_names, object_name);
}
else {
mesh_data_t *md = mesh_data_create(raw);
md->_->skin_blob = import_arm_get_mesh_skin(i);
any_array_push(mesh_datas, md);
string_array_push(mesh_names, md->name);
}
}
for (i32 i = 1; i < mesh_datas->length; ++i) {
if (mesh_datas->buffer[i] != NULL) {
continue;
}
i32 source_index;
char *object_name;
util_mesh_link_parse(((mesh_data_t *)g_project->mesh_datas->buffer[i])->name, &source_index, &object_name);
bool linked = source_index >= 0 && source_index < mesh_datas->length && mesh_datas->buffer[source_index] != NULL;
mesh_datas->buffer[i] = linked ? mesh_datas->buffer[source_index] : mesh_datas->buffer[0];
}
mesh_data_t *md = mesh_datas->buffer[0];
mesh_object_set_data(g_context->paint_object, md);
g_context->paint_object->base->transform->scale = (vec4_t){1, 1, 1, 1.0};
transform_build_matrix(g_context->paint_object->base->transform);
g_context->paint_object->base->name = md->name;
g_context->paint_object->base->name = mesh_names->buffer[0];
g_project->_->paint_objects = any_array_create_from_raw(
(void *[]){
g_context->paint_object,
},
1);
for (i32 i = 1; i < g_project->mesh_datas->length; ++i) {
mesh_data_t *raw = g_project->mesh_datas->buffer[i];
mesh_data_t *md = mesh_data_create(raw);
md->_->skin_blob = import_arm_get_mesh_skin(i);
mesh_object_t *object = scene_add_mesh_object(md, g_context->paint_object->material, g_context->paint_object->base);
object->base->name = md->name;
for (i32 i = 1; i < mesh_datas->length; ++i) {
mesh_object_t *object = scene_add_mesh_object(mesh_datas->buffer[i], g_context->paint_object->material, g_context->paint_object->base);
object->base->name = mesh_names->buffer[i];
object->skip_context = "paint";
any_array_push(g_project->_->paint_objects, object);
}
@@ -663,6 +687,7 @@ void import_arm_run_project(char *path) {
object_t *parent = parent_index >= 0 ? g_project->_->paint_objects->buffer[parent_index]->base : NULL;
object_set_parent(g_project->_->paint_objects->buffer[i]->base, parent);
}
transform_build_matrix(_scene_root->transform);
}
if (g_project->mesh_physics_shapes != NULL) {