| 506 | } |
| 507 | |
| 508 | Transform3D Node3D::get_global_transform_interpolated() { |
| 509 | #if 1 |
| 510 | // Pass through if physics interpolation is switched off. |
| 511 | // This is a convenience, as it allows you to easy turn off interpolation |
| 512 | // without changing any code. |
| 513 | if (SceneTree::is_fti_enabled() && is_inside_tree() && !Engine::get_singleton()->is_in_physics_frame()) { |
| 514 | // Note that with SceneTreeFTI, we may want to calculate interpolated transform for a node |
| 515 | // with physics interpolation set to OFF, if it has a parent that is ON. |
| 516 | |
| 517 | // Cheap case. |
| 518 | // We already pre-cache the visible_in_tree for VisualInstances, but NOT for Node3Ds, so we have to |
| 519 | // deal with non-VIs the slow way. |
| 520 | if (Object::cast_to<VisualInstance3D>(this) && _is_vi_visible() && data.fti_global_xform_interp_set) { |
| 521 | return data.global_transform_interpolated; |
| 522 | } |
| 523 | |
| 524 | // Find out if visible in tree. |
| 525 | // If not visible in tree, find the FIRST ancestor that is visible in tree. |
| 526 | const Node3D *visible_parent = nullptr; |
| 527 | const Node3D *s = this; |
| 528 | bool visible = true; |
| 529 | bool visible_in_tree = true; |
| 530 | |
| 531 | while (s) { |
| 532 | if (!s->data.visible) { |
| 533 | visible_in_tree = false; |
| 534 | visible = false; |
| 535 | } else { |
| 536 | if (!visible) { |
| 537 | visible_parent = s; |
| 538 | visible = true; |
| 539 | } |
| 540 | } |
| 541 | s = s->data.parent; |
| 542 | } |
| 543 | |
| 544 | // Simplest case, we can return the interpolated xform calculated by SceneTreeFTI. |
| 545 | if (visible_in_tree) { |
| 546 | return data.fti_global_xform_interp_set ? data.global_transform_interpolated : get_global_transform(); |
| 547 | } else if (visible_parent) { |
| 548 | // INVISIBLE case. Not visible, but there is a visible ancestor somewhere in the chain. |
| 549 | if (_get_scene_tree_depth() < 1) { |
| 550 | // This should not happen unless there a problem has been introduced in the scene tree depth code. |
| 551 | // Print a non-spammy error and return something reasonable. |
| 552 | ERR_PRINT_ONCE("depth is < 1."); |
| 553 | return get_global_transform(); |
| 554 | } |
| 555 | |
| 556 | // The interpolated xform is not already calculated for invisible nodes, but we can calculate this |
| 557 | // manually on demand if there is a visible parent. |
| 558 | // First create the chain (backwards), from the node up to first visible parent. |
| 559 | const Node3D **parents = (const Node3D **)alloca((sizeof(const Node3D *) * _get_scene_tree_depth())); |
| 560 | int32_t num_parents = 0; |
| 561 | |
| 562 | s = this; |
| 563 | while (s) { |
| 564 | if (s == visible_parent) { |
| 565 | // Finished. |
no test coverage detected