Open bialpio opened 5 months ago
Thanks for the detailed report.
v0.9.1-beta
Is this reproducible in a nightly build from main
in your project?
Is the issue reproducible in the demo? No
I'm curious why this is only in your project. It doesn't happen for you in the demo? And it doesn't happen for me. This needs further exploration as to what conditions you've created in your project to trigger these errors.
When closing the scene preview of a scene that contains only a Camera and Terrain3D node, the Godot console shows:
What is a scene preview
and how are you creating it?
Does this scene contain any scripts attached to those nodes? Are the Camera3D and Terrain3D attached to a parent Node3D or what structure? What other nodes are in the scene?
In this scene preview, does it quit automatically via your script or manually?
With this and looking at Godot's
servers/physics_3d/godot_collision_object_3d.h:124
, it looks likeTerrain3D::_destroy_collision()
should check the body shape count before calling intobody_get_shape(_static_body, 0)
here.
There is already a check in this section to make sure the staticbody that contains the shape is valid. What's more concerning is why you don't have a collision shape. If you have collision enabled, the shape should exist to be destroyed. If you don't, the staticbody will be null and it won't try to destroy it.
ERROR: Attempt to register extension class 'Terrain3D', which appears to be already registered. at: (core/extension/gdextension.cpp:386) ERROR: Attempt to register extension class 'Terrain3DMaterial', which appears to be already registered. at: (core/extension/gdextension.cpp:386) ERROR: Attempt to register extension class 'Terrain3DStorage', which appears to be already registered. at: (core/extension/gdextension.cpp:386) ERROR: Attempt to register extension class 'Terrain3DTexture', which appears to be already registered. at: (core/extension/gdextension.cpp:386) ERROR: Attempt to register extension class 'Terrain3DTextureList', which appears to be already register. at: (core/extension/gdextension.cpp:386) ERROR: Attempt to register extension class 'Terrain3DEditor', which appears to be already registered. at: (core/extension/gdextension.cpp:386)
I don't get this on the demo or in my project. Do you have two copies of Terrain3D under addons in different folders? Whatever is causing this might be the problem. I presume that you don't get this in the demo project?
Terrain3D::_build_collision: Building collision with physics server Terrain3D::_update_collision: Collision creation time: 0 ms Terrain3D::_notification: NOTIFICATION_READY Terrain3D::_initialize: Checking material, storage, texture_list, signal, and mesh initialization Terrain3D::__process: camera is null, getting the current one Terrain3D::_grab_camera: Connecting to the in-game viewport camera Terrain3D::_notification: NOTIFICATION_EXIT_TREE Terrain3D::_clear: Clearing the terrain Terrain3D::_destroy_collision: Freeing physics body ERROR: FATAL: Index p_index = 0 is out of bounds (shapes.size() = 0). at: get_shape (servers/physics_3d/godot_collision_object_3d.h:124)
How much time is elapsing between build collision / READY and EXIT_TREE? Are they instant, within the same frame caused by a script quitting? Or are there multiple frames rendered at least in between?
Replying with some easier-to-get answers to your questions. :)
What is a
scene preview
and how are you creating it?
It may be my wrong use of terminology, I'm just using F6 to preview the current scene.
Does this scene contain any scripts attached to those nodes? Are the Camera3D and Terrain3D attached to a parent Node3D or what structure? What other nodes are in the scene?
The scene contains:
I have attached the smallest project that reproduces the issue. TerrainRepro.zip
In this scene preview, does it quit automatically via your script or manually?
I'm closing the preview by clicking the X button of the window.
I don't get this on the demo or in my project. Do you have two copies of Terrain3D under addons in different folders? Whatever is causing this might be the problem. I presume that you don't get this in the demo project?
You're right, it was my bad - I was making copies of the addons folder (in order to rapidly switch between the Terrain3D that I downloaded from github and the one I built myself) thinking that it's a specially named folder from Godot's perspective. The repro project that I attached should not have this problem.
How much time is elapsing between build collision / READY and EXIT_TREE? Are they instant, within the same frame caused by a script quitting? Or are there multiple frames rendered at least in between?
I assume there's multiple frames in between. When the scene is loaded, the log reaches the Terrain3D::_grab_camera: Connecting to the in-game viewport camera
line. The subsequent line (NOTIFICATION_EXIT_TREE) only shows up when I close the preview window.
I think I may know what the problem is. Terrain3D::_update_collision()
will not reach line 446 if there are no regions on the Terrain3D, therefore, when destroying collisions, there are no available shapes added to the _static_body
. I'm not sure if this is the right diagnosis though - in _update_collisions()
, we add one shape per region, but in _destroy_collisions()
, we're only freeing the shape that is at index 0 - shouldn't that code enumerate over all shapes added to the _static_body
?
I have tried with my own custom build yet again. The changes I've made:
LOG(DEBUG, "Adding shape to _static_body, region index ", i);
.LOG(INFO, "Freeing physics body, shape count ", PhysicsServer3D::get_singleton()->body_get_shape_count(_static_body));
that I have added previously at line 475.The log excerpt is:
Terrain3D::_build: Creating mesh instances
Terrain3D::_build_collision: Building collision with physics server
Terrain3D::_update_collision: Collision creation time: 0 ms
Terrain3D::_notification: NOTIFICATION_READY
Terrain3D::_initialize: Checking material, storage, texture_list, signal, and mesh initialization
Terrain3D::__process: camera is null, getting the current one
Terrain3D::_grab_camera: Connecting to the in-game viewport camera
Terrain3D::_notification: NOTIFICATION_EXIT_TREE
Terrain3D::_clear: Clearing the terrain
Terrain3D::_destroy_collision: Freeing physics body, shape count 0
ERROR: FATAL: Index p_index = 0 is out of bounds (shapes.size() = 0).
at: get_shape (servers/physics_3d/godot_collision_object_3d.h:124)
Notably, my newly added log is not present, presumably because there are no regions on the Terrain3D.
I see. If there are no regions, the static body is still created but no shapes are made, so it should not assume there is a region to destroy. We'll need to make sure #278 fixes this.
Terrain3D version
v0.9.1-beta
System information
Godot v4.2.1.stable - Windows 10.0.22631 - Vulkan (Forward+) - dedicated AMD Radeon RX 7900 XT (Advanced Micro Devices, Inc.; 31.0.24019.1006) - AMD Ryzen 9 7900 12-Core Processor (24 Threads)
Is the issue reproducable in the demo?
No
Issue description
When closing the scene preview of a scene that contains only a Camera and Terrain3D node, the Godot console shows:
I have manually compiled the Terrain3D and was able to grab the stack trace in WinDbg:
With this and looking at Godot's
servers/physics_3d/godot_collision_object_3d.h:124
, it looks likeTerrain3D::_destroy_collision()
should check the body shape count before calling intobody_get_shape(_static_body, 0)
here.To confirm, I have added extra information at terrain_3d.cpp:475:
LOG(INFO, "Freeing physics body, shape count ", PhysicsServer3D::get_singleton()->body_get_shape_count(_static_body));
With that change, I see the logs contain the following:
Terrain3D::_destroy_collision: Freeing physics body, shape count 0
I have attached the log without my custom changes. I can try to grab more information if required.
Logs