From b417c7c557149e2715f1f02ff668734166fa4dde Mon Sep 17 00:00:00 2001 From: Spencer Killen Date: Fri, 29 Sep 2023 19:11:24 -0600 Subject: [PATCH] Enable nested VoxelModifiers --- modifiers/godot/voxel_modifier_gd.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/modifiers/godot/voxel_modifier_gd.cpp b/modifiers/godot/voxel_modifier_gd.cpp index adb7ff843..eae2f2ea1 100644 --- a/modifiers/godot/voxel_modifier_gd.cpp +++ b/modifiers/godot/voxel_modifier_gd.cpp @@ -7,7 +7,7 @@ namespace zylann::voxel::gd { VoxelModifier::VoxelModifier() { - set_notify_local_transform(true); + set_notify_transform(true); } zylann::voxel::VoxelModifier *VoxelModifier::create(zylann::voxel::VoxelModifierStack &modifiers, uint32_t id) { @@ -78,6 +78,17 @@ void VoxelModifier::_notification(int p_what) { ZN_ASSERT_RETURN(parent != nullptr); ZN_ASSERT_RETURN(_volume == nullptr); VoxelLodTerrain *volume = Object::cast_to(parent); + // Using get_parent_node_3d when terrain is immediate parent + // would be a breaking change as it returns null if node is toplevel + if (volume == nullptr) { + Node3D *grandparent = get_parent_node_3d(); + volume = Object::cast_to(grandparent); + while (grandparent != nullptr && volume == nullptr) { + grandparent = grandparent->get_parent_node_3d(); + volume = Object::cast_to(grandparent); + } + } + _volume = volume; if (_volume != nullptr) { @@ -92,7 +103,8 @@ void VoxelModifier::_notification(int p_what) { sdf_modifier->set_operation(to_op(_operation)); sdf_modifier->set_smoothness(_smoothness); } - + // This transform is wrong, but will be updated with NOTIFICATION_TRANSFORM_CHANGED + // After node enters the tree modifier->set_transform(get_transform()); _modifier_id = id; // TODO Optimize: on loading of a scene, this could be very bad for performance because there could be, @@ -116,7 +128,7 @@ void VoxelModifier::_notification(int p_what) { } } break; - case Node3D::NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { + case Node3D::NOTIFICATION_TRANSFORM_CHANGED: { if (_volume != nullptr && is_inside_tree()) { VoxelData &voxel_data = _volume->get_storage(); VoxelModifierStack &modifiers = voxel_data.get_modifiers(); @@ -124,7 +136,8 @@ void VoxelModifier::_notification(int p_what) { ZN_ASSERT_RETURN(modifier != nullptr); const AABB prev_aabb = modifier->get_aabb(); - modifier->set_transform(get_transform()); + Transform3D terrain_local = _volume->get_global_transform().affine_inverse() * get_global_transform(); + modifier->set_transform(terrain_local); const AABB aabb = modifier->get_aabb(); post_edit_modifier(*_volume, prev_aabb); post_edit_modifier(*_volume, aabb);