Comments (9)
I tested the code and was able to get a backtrace:
LocalVector<BVH_Tree<GodotCollisionObject3D,2,2,128,GodotBroadPhase3DBVH::UserPairTestFunction<GodotCollisionObject3D>,GodotBroadPhase3DBVH::UserCullTestFunction<GodotCollisionObject3D>,1,AABB,Vector3>::TLeaf,unsigned int,1,0>::operator[](unsigned int p_index) Line 177 (c:\Users\Matheus\Downloads\Godot Source\core\templates\local_vector.h:177)
PooledList<BVH_Tree<GodotCollisionObject3D,2,2,128,GodotBroadPhase3DBVH::UserPairTestFunction<GodotCollisionObject3D>,GodotBroadPhase3DBVH::UserCullTestFunction<GodotCollisionObject3D>,1,AABB,Vector3>::TLeaf,unsigned int,1,0>::operator[](unsigned int p_index) Line 90 (c:\Users\Matheus\Downloads\Godot Source\core\templates\pooled_list.h:90)
BVH_Tree<GodotCollisionObject3D,2,2,128,GodotBroadPhase3DBVH::UserPairTestFunction<GodotCollisionObject3D>,GodotBroadPhase3DBVH::UserCullTestFunction<GodotCollisionObject3D>,1,AABB,Vector3>::_node_get_leaf(BVH_Tree<GodotCollisionObject3D,2,2,128,GodotBroadPhase3DBVH::UserPairTestFunction<GodotCollisionObject3D>,GodotBroadPhase3DBVH::UserCullTestFunction<GodotCollisionObject3D>,1,AABB,Vector3>::TNode & tnode) Line 44 (c:\Users\Matheus\Downloads\Godot Source\core\math\bvh_misc.inc:44)
BVH_Tree<GodotCollisionObject3D,2,2,128,GodotBroadPhase3DBVH::UserPairTestFunction<GodotCollisionObject3D>,GodotBroadPhase3DBVH::UserCullTestFunction<GodotCollisionObject3D>,1,AABB,Vector3>::_node_add_item(unsigned int p_node_id, unsigned int p_ref_id, const BVH_ABB<AABB,Vector3> & p_aabb) Line 399 (c:\Users\Matheus\Downloads\Godot Source\core\math\bvh_tree.h:399)
BVH_Tree<GodotCollisionObject3D,2,2,128,GodotBroadPhase3DBVH::UserPairTestFunction<GodotCollisionObject3D>,GodotBroadPhase3DBVH::UserCullTestFunction<GodotCollisionObject3D>,1,AABB,Vector3>::split_leaf_complex(unsigned int p_node_id, const BVH_ABB<AABB,Vector3> & p_added_item_aabb) Line 269 (c:\Users\Matheus\Downloads\Godot Source\core\math\bvh_split.inc:269)
BVH_Tree<GodotCollisionObject3D,2,2,128,GodotBroadPhase3DBVH::UserPairTestFunction<GodotCollisionObject3D>,GodotBroadPhase3DBVH::UserCullTestFunction<GodotCollisionObject3D>,1,AABB,Vector3>::split_leaf(unsigned int p_node_id, const BVH_ABB<AABB,Vector3> & p_added_item_aabb) Line 191 (c:\Users\Matheus\Downloads\Godot Source\core\math\bvh_split.inc:191)
BVH_Tree<GodotCollisionObject3D,2,2,128,GodotBroadPhase3DBVH::UserPairTestFunction<GodotCollisionObject3D>,GodotBroadPhase3DBVH::UserCullTestFunction<GodotCollisionObject3D>,1,AABB,Vector3>::_logic_choose_item_add_node(unsigned int p_node_id, const BVH_ABB<AABB,Vector3> & p_aabb) Line 212 (c:\Users\Matheus\Downloads\Godot Source\core\math\bvh_logic.inc:212)
BVH_Tree<GodotCollisionObject3D,2,2,128,GodotBroadPhase3DBVH::UserPairTestFunction<GodotCollisionObject3D>,GodotBroadPhase3DBVH::UserCullTestFunction<GodotCollisionObject3D>,1,AABB,Vector3>::item_add(GodotCollisionObject3D * p_userdata, bool p_active, const AABB & p_aabb, int p_subindex, unsigned int p_tree_id, unsigned int p_tree_collision_mask, bool p_invisible) Line 60 (c:\Users\Matheus\Downloads\Godot Source\core\math\bvh_public.inc:60)
BVH_Manager<GodotCollisionObject3D,2,1,128,GodotBroadPhase3DBVH::UserPairTestFunction<GodotCollisionObject3D>,GodotBroadPhase3DBVH::UserCullTestFunction<GodotCollisionObject3D>,AABB,Vector3,1>::create(GodotCollisionObject3D * p_userdata, bool p_active, unsigned int p_tree_id, unsigned int p_tree_collision_mask, const AABB & p_aabb, int p_subindex) Line 118 (c:\Users\Matheus\Downloads\Godot Source\core\math\bvh.h:118)
GodotBroadPhase3DBVH::create(GodotCollisionObject3D * p_object, int p_subindex, const AABB & p_aabb, bool p_static) Line 38 (c:\Users\Matheus\Downloads\Godot Source\servers\physics_3d\godot_broad_phase_3d_bvh.cpp:38)
GodotCollisionObject3D::_update_shapes() Line 177 (c:\Users\Matheus\Downloads\Godot Source\servers\physics_3d\godot_collision_object_3d.cpp:177)
GodotCollisionObject3D::_shape_changed() Line 236 (c:\Users\Matheus\Downloads\Godot Source\servers\physics_3d\godot_collision_object_3d.cpp:236)
GodotPhysicsServer3D::_update_shapes() Line 1736 (c:\Users\Matheus\Downloads\Godot Source\servers\physics_3d\godot_physics_server_3d.cpp:1736)
GodotPhysicsServer3D::body_test_motion(RID p_body, const PhysicsServer3D::MotionParameters & p_parameters, PhysicsServer3D::MotionResult * r_result) Line 920 (c:\Users\Matheus\Downloads\Godot Source\servers\physics_3d\godot_physics_server_3d.cpp:920)
PhysicsServer3DWrapMT::body_test_motion(RID p_body, const PhysicsServer3D::MotionParameters & p_parameters, PhysicsServer3D::MotionResult * r_result) Line 263 (c:\Users\Matheus\Downloads\Godot Source\servers\physics_server_3d_wrap_mt.h:263)
PhysicsBody3D::move_and_collide(const PhysicsServer3D::MotionParameters & p_parameters, PhysicsServer3D::MotionResult & r_result, bool p_test_only, bool p_cancel_sliding) Line 109 (c:\Users\Matheus\Downloads\Godot Source\scene\3d\physics\physics_body_3d.cpp:109)
CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_floor) Line 159 (c:\Users\Matheus\Downloads\Godot Source\scene\3d\physics\character_body_3d.cpp:159)
CharacterBody3D::move_and_slide() Line 108 (c:\Users\Matheus\Downloads\Godot Source\scene\3d\physics\character_body_3d.cpp:108)
call_with_validated_variant_args_ret_helper<CharacterBody3D,bool>(CharacterBody3D * p_instance, bool(CharacterBody3D::*)() p_method, const Variant * * p_args, Variant * r_ret, IndexSequence<> __formal) Line 375 (c:\Users\Matheus\Downloads\Godot Source\core\variant\binder_common.h:375)
call_with_validated_object_instance_args_ret<CharacterBody3D,bool>(CharacterBody3D * base, bool(CharacterBody3D::*)() p_method, const Variant * * p_args, Variant * r_ret) Line 663 (c:\Users\Matheus\Downloads\Godot Source\core\variant\binder_common.h:663)
MethodBindTR<CharacterBody3D,bool>::validated_call(Object * p_object, const Variant * * p_args, Variant * r_ret) Line 537 (c:\Users\Matheus\Downloads\Godot Source\core\object\method_bind.h:537)
GDScriptFunction::call(GDScriptInstance * p_instance, const Variant * * p_args, int p_argcount, Callable::CallError & r_err, GDScriptFunction::CallState * p_state) Line 1989 (c:\Users\Matheus\Downloads\Godot Source\modules\gdscript\gdscript_vm.cpp:1989)
GDScriptInstance::callp(const StringName & p_method, const Variant * * p_args, int p_argcount, Callable::CallError & r_error) Line 1970 (c:\Users\Matheus\Downloads\Godot Source\modules\gdscript\gdscript.cpp:1970)
Node::_gdvirtual__physics_process_call<0>(double arg1) Line 351 (c:\Users\Matheus\Downloads\Godot Source\scene\main\node.h:351)
Node::_notification(int p_notification) Line 62 (c:\Users\Matheus\Downloads\Godot Source\scene\main\node.cpp:62)
Node::_notificationv(int p_notification, bool p_reversed) Line 49 (c:\Users\Matheus\Downloads\Godot Source\scene\main\node.h:49)
Node3D::_notificationv(int p_notification, bool p_reversed) Line 52 (c:\Users\Matheus\Downloads\Godot Source\scene\3d\node_3d.h:52)
CollisionObject3D::_notificationv(int p_notification, bool p_reversed) Line 38 (c:\Users\Matheus\Downloads\Godot Source\scene\3d\physics\collision_object_3d.h:38)
PhysicsBody3D::_notificationv(int p_notification, bool p_reversed) Line 41 (c:\Users\Matheus\Downloads\Godot Source\scene\3d\physics\physics_body_3d.h:41)
CharacterBody3D::_notificationv(int p_notification, bool p_reversed) Line 38 (c:\Users\Matheus\Downloads\Godot Source\scene\3d\physics\character_body_3d.h:38)
Object::notification(int p_notification, bool p_reversed) Line 902 (c:\Users\Matheus\Downloads\Godot Source\core\object\object.cpp:902)
SceneTree::_process_group(SceneTree::ProcessGroup * p_group, bool p_physics) Line 965 (c:\Users\Matheus\Downloads\Godot Source\scene\main\scene_tree.cpp:965)
SceneTree::_process(bool p_physics) Line 1050 (c:\Users\Matheus\Downloads\Godot Source\scene\main\scene_tree.cpp:1050)
SceneTree::physics_process(double p_time) Line 492 (c:\Users\Matheus\Downloads\Godot Source\scene\main\scene_tree.cpp:492)
Main::iteration() Line 3983 (c:\Users\Matheus\Downloads\Godot Source\main\main.cpp:3983)
OS_Windows::run() Line 1673 (c:\Users\Matheus\Downloads\Godot Source\platform\windows\os_windows.cpp:1673)
widechar_main(int argc, wchar_t * * argv) Line 181 (c:\Users\Matheus\Downloads\Godot Source\platform\windows\godot_windows.cpp:181)
_main() Line 206 (c:\Users\Matheus\Downloads\Godot Source\platform\windows\godot_windows.cpp:206)
main(int argc, char * * argv) Line 220 (c:\Users\Matheus\Downloads\Godot Source\platform\windows\godot_windows.cpp:220)
WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 234 (c:\Users\Matheus\Downloads\Godot Source\platform\windows\godot_windows.cpp:234)
[Inline Frame] invoke_main() Line 102 (d:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:102)
__scrt_common_main_seh() Line 288 (d:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288)
kernel32.dll!00007ffeaf277344() (Unknown Source:0)
ntdll.dll!00007ffeaf63cc91() (Unknown Source:0)
Also some pics with (maybe useful?) extra info:
from godot.
would this not just disallow generation of blocks with a negative coordinate, as this should be possible.
Ah, sorry, I misunderstood how gridmap works. It actually ranges from -1mil to +1mil
I tested the code and was able to get a backtrace
And that gives us the answer. It looks like the sheer number of collision objects is causing the crash.
Maybe this is a bug as it's not supposed to crash, but it's also going to be slow even if it wasn't...
Suggestion
Use two gridmaps. One for the visual data, that renders however far you'd like, and one for collision that only has the few chunks the player stands in is loaded.
Also, currently every block has it's own material and an identical copy of the source pixel art texture like "Snow_Blocks_PixelArt.png" and "Coal_Blocks_PixelArt.png". If they shared the same material and texture (and not have backface culling disabled) then the framerate can go up a lot.
from godot.
I did some extra investigation and what i found:
The cause of crash is a implict conversion that happens here:
godot/core/templates/pooled_list.h
Lines 88 to 90 in 71699e0
godot/core/templates/pooled_list.h
Lines 56 to 58 in 71699e0
As you can see the U value is a uint32_t in this template and for some reason tnode.get_leaf_id()
is returning a negative value (-2) here
Lines 41 to 44 in 71699e0
The uint32_t variable can't hold negative values, so the code treats the -2 as an overflow and wraps to 4294967294. tnode.get_leaf_id()
returns the value of tnode.neg_leaf_id
inverting the signal, so that means tnode.neg_leaf_id
for some reason is receiving a non-negative value and when tnode.get_leaf_id()
inverts the signal, transforms the result in a negative value
godot/core/math/bvh_structs.inc
Lines 112 to 129 in 71699e0
Considering my assumption is correct, the last question is why tnode.neg_leaf_id
is receiving a non-negative value (and is always the same value, 2)
from godot.
extends Node3D
# The size of each chunk in blocks
var chunkSize = Vector3(16, 16, 16)
var renderDistance = 20
var generatedChunks = {}
var queue = []
var tasksPerFrame = 1
var current_player_chunk = Vector3(-999, 0, -999) # Invalid initial chunk position
# The size of the world in chunks
var initialWorldSize = Vector3(8, 1, 8) # Adjust based on your needs
# Noise generator instance
var noise_generator : FastNoiseLite
# MeshLibrary containing block meshes
@export var mesh_library : MeshLibrary
# GridMap to manage the voxel terrain
@onready var grid_map : GridMap = $GridMap
func _ready():
# Load the mesh library from the provided file
mesh_library = load("res://Resources/blocks.tres")
# Initialize the noise generator
noise_generator = FastNoiseLite.new()
noise_generator.noise_type = FastNoiseLite.TYPE_SIMPLEX_SMOOTH
noise_generator.seed = randi()
noise_generator.frequency = 0.01 # Controls the frequency of the noise
# Assign the mesh library to the GridMap
grid_map.mesh_library = mesh_library
func _process(delta):
var playerPos = getPlayerPos()
var playerChunk = getPlayerChunk(playerPos)
if playerChunk != current_player_chunk:
current_player_chunk = playerChunk
generateChunkAroundPlayer(playerChunk)
processQueue()
generateChunkAroundPlayer(playerChunk)
func generateChunkAroundPlayer(playerChunk: Vector3):
for x in range(-renderDistance, renderDistance + 1):
for z in range(-renderDistance, renderDistance + 1):
var chunkPos = playerChunk + Vector3(x,0,z)
if not generatedChunks.has(chunkPos):
queue.append(chunkPos)
func processQueue():
for i in range(min(queue.size(), tasksPerFrame)):
var chunkPos = queue.pop_front()
generateChunk(chunkPos)
generatedChunks[chunkPos] = true
# Function to generate a single chunk of terrain
func generateChunk(playerChunk: Vector3):
for x in range(chunkSize.x):
for z in range(chunkSize.z):
var world_x = int(playerChunk.x * chunkSize.x + x)
var world_z = int(playerChunk.z * chunkSize.z + z)
var height = int(noise_generator.get_noise_2d(world_x * 0.1, world_z * 0.1) * 10) + 10
for y in range(chunkSize.y):
var world_y = int(y)
if world_y <= height:
if noise_generator.get_noise_3d(world_x * 0.1, world_y * 0.1, world_z * 0.1) < 0.5:
set_block(world_x, world_y, world_z, "Grass")
elif world_y < height - 3:
set_block(world_x, world_y, world_z, "Dirt")
else:
set_block(world_x, world_y, world_z, "Stone")
func getPlayerPos():
return get_node("/root/Level/Player").global_transform.origin / 2
func getPlayerChunk(playerPosition):
return Vector3(
int(floor(playerPosition.x / chunkSize.x)),
0,
int(floor(playerPosition.z / chunkSize.z))
)
# Function to set a block in the GridMap
func set_block(x: int, y: int, z: int, block_type: String):
var block_id = mesh_library.find_item_by_name(block_type)
if block_id >= 0:
grid_map.set_cell_item(Vector3i(x, y, z), block_id)
This code seems to trigger it just by itself
from godot.
Your code can't run because don't have the assets that you use and also don't have the scene tree with the correct nodes, will make debug much more easier if you upload a MRP with everything ready to test
from godot.
@matheusmdx Thanks for the reply, I've uploaded the version to github, theres pretty much nothing else there so it's pretty much an MRP. Perhaps you could give it a run? The issue happens when I up the render_distance in level.gd from 12 to like.... 21ish? \https://github.com/AlexLovelock22/VoxelOne
from godot.
I'm unable to look at the project currently, but notice that set_block isn't bounds checked and world_x and world_z could be less than zero (-1 == (uint32)4294967294)
func set_block(x: int, y: int, z: int, block_type: String):
assert(x >= 0 and y >= 0 and z >= 0, "oh no")
from godot.
@huwpascoe Thanks for the reply. Correct my if im wrong (beacuse I probably am), but would this not just disallow generation of blocks with a negative coordinate, as this should be possible. Also just realised the code snippet I sent wasnt the full one. The full one is in the repo, Scripts/level.gd. Thanks
from godot.
@matheusmdx @huwpascoe
Ah yes, thank you so much guys. I'll give it a go now :D
from godot.
Related Issues (20)
- Strange grid anchor in UV 2D.
- window node does not recognise left mouse click?
- Alignment setting in draw_string doesn't do anything HOT 1
- Using enum from another class in different scene as @export doesn't properly update it's values in editor and in used scene HOT 3
- Can't clear exported node.
- resource_importer_scene.cpp does not copy lods during _rescale_importer_mesh HOT 8
- Compute shader file gives error when exporting project
- Vulkan Mobile: LightmapGI baking makes environment light twice as dark as it should be
- Audio only plays on one viewport (3D)
- OpenGL: Baking lightmaps has broken emissive material properties
- OpenGL: `Condition "t->is_render_target" is true.` is printed every time LightmapGI is baked with Environment mode set to Scene or Custom Sky
- OpenGL: Selecting a lightmap EXR texture in the FileSystem dock prints an error about SamplerCubeArray not being supported
- [4.3.beta3]: _physics_process() does not detect Input.is_action_just_pressed
- Godot build system breaks with SCons 2.8.0 release HOT 3
- dedicated_server feature tag does not enable GODOT_SERVER preprocessor define
- Script editor autocompletion popup does not accept scroll gestures
- Project takes too long to load or remove files in the Android Editor HOT 2
- `CSGPolygon3D`'s ends in path mode are oriented incorrectly HOT 1
- match expression is not working, where the if expression is working HOT 1
- Godot C# Registers Derived Script Types Incorrectly as Supertype, and Other Cross Language Problems
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from godot.