| … | … | @@ -486,44 +486,60 @@ void BlenderBridge::import_changes(Node *root) { |
| 486 | 486 | if (entry.update_type == UPDATE_VERTEX || entry.update_type == UPDATE_FULL) { |
| 487 | 487 | MeshInstance3D *mesh_inst = Object::cast_to<MeshInstance3D>(target); |
| 488 | 488 | if (mesh_inst && entry.data_size > TRANSFORM_SIZE + 4) { |
| 489 | | uint32_t vert_offset = entry.data_offset + TRANSFORM_SIZE; |
| 489 | uint32_t cursor = entry.data_offset + TRANSFORM_SIZE; |
| 490 | 490 | uint32_t vert_count; |
| 491 | | memcpy(&vert_count, base + vert_offset, 4); |
| 492 | | vert_offset += 4; |
| 491 | memcpy(&vert_count, base + cursor, 4); |
| 492 | cursor += 4; |
| 493 | 493 | |
| 494 | 494 | PackedVector3Array positions; |
| 495 | 495 | positions.resize(vert_count); |
| 496 | 496 | Vector3 *pos_w = positions.ptrw(); |
| 497 | 497 | for (uint32_t v = 0; v < vert_count; v++) { |
| 498 | 498 | float in[3]; |
| 499 | | memcpy(in, base + vert_offset, 12); |
| 500 | | vert_offset += 12; |
| 501 | | // Blender Z-up → Godot Y-up |
| 499 | memcpy(in, base + cursor, 12); |
| 500 | cursor += 12; |
| 502 | 501 | pos_w[v].x = in[0]; |
| 503 | 502 | pos_w[v].y = in[2]; |
| 504 | 503 | pos_w[v].z = -in[1]; |
| 505 | 504 | } |
| 506 | 505 | |
| 507 | | // Read normals if present |
| 506 | // Read has_normals flag |
| 508 | 507 | PackedVector3Array normals; |
| 509 | | uint32_t expected_normal_end = vert_offset + vert_count * 12; |
| 510 | | if (expected_normal_end <= entry.data_offset + entry.data_size) { |
| 508 | uint32_t has_normals = 0; |
| 509 | if (cursor + 4 <= entry.data_offset + entry.data_size) { |
| 510 | memcpy(&has_normals, base + cursor, 4); |
| 511 | cursor += 4; |
| 512 | } |
| 513 | |
| 514 | if (has_normals && cursor + vert_count * 12 <= entry.data_offset + entry.data_size) { |
| 511 | 515 | normals.resize(vert_count); |
| 512 | 516 | Vector3 *norm_w = normals.ptrw(); |
| 513 | 517 | for (uint32_t v = 0; v < vert_count; v++) { |
| 514 | 518 | float in[3]; |
| 515 | | memcpy(in, base + vert_offset, 12); |
| 516 | | vert_offset += 12; |
| 519 | memcpy(in, base + cursor, 12); |
| 520 | cursor += 12; |
| 517 | 521 | norm_w[v].x = in[0]; |
| 518 | 522 | norm_w[v].y = in[2]; |
| 519 | 523 | norm_w[v].z = -in[1]; |
| 520 | 524 | } |
| 521 | 525 | } |
| 522 | 526 | |
| 527 | // Read index buffer |
| 528 | PackedInt32Array indices; |
| 529 | uint32_t idx_count = 0; |
| 530 | if (cursor + 4 <= entry.data_offset + entry.data_size) { |
| 531 | memcpy(&idx_count, base + cursor, 4); |
| 532 | cursor += 4; |
| 533 | } |
| 534 | |
| 535 | if (idx_count > 0 && cursor + idx_count * 4 <= entry.data_offset + entry.data_size) { |
| 536 | indices.resize(idx_count); |
| 537 | memcpy(indices.ptrw(), base + cursor, idx_count * 4); |
| 538 | } |
| 539 | |
| 523 | 540 | // Rebuild mesh surface — convert to ArrayMesh if needed |
| 524 | 541 | Ref<ArrayMesh> arr_mesh = Object::cast_to<ArrayMesh>(mesh_inst->get_mesh().ptr()); |
| 525 | 542 | if (!arr_mesh.is_valid()) { |
| 526 | | // Procedural mesh (BoxMesh, etc.) — replace with ArrayMesh |
| 527 | 543 | arr_mesh.instantiate(); |
| 528 | 544 | mesh_inst->set_mesh(arr_mesh); |
| 529 | 545 | } |
| … | … | @@ -534,6 +550,9 @@ void BlenderBridge::import_changes(Node *root) { |
| 534 | 550 | if (normals.size() > 0) { |
| 535 | 551 | arrays[Mesh::ARRAY_NORMAL] = normals; |
| 536 | 552 | } |
| 553 | if (indices.size() > 0) { |
| 554 | arrays[Mesh::ARRAY_INDEX] = indices; |
| 555 | } |
| 537 | 556 | |
| 538 | 557 | arr_mesh->clear_surfaces(); |
| 539 | 558 | arr_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arrays); |