cloudofoz / godot-smashthemesh

Smash The Mesh (STM) is a Godot add-on that allows you to break 3D meshes into multiple pieces and apply physics to each fragment. It includes features for saving the results to disk (cache) for quick loading.
MIT License
139 stars 7 forks source link

Is this compatible with Godot Jolt physics? #2

Closed zaknafean closed 5 days ago

zaknafean commented 6 days ago

Getting this error when I try to do the explode_callback.

E 0:00:48:0153   Mob.gd:554 @ <anonymous lambda>(): Failed to apply impulse to '@RigidBody3D@1732:<RigidBody3D#924021976660>'. Doing so without a physics space is not supported by Godot Jolt. If this relates to a node, try adding the node to a scene tree first.
  <C++ Error>    Parameter "space" is null.
  <C++ Source>   src\objects\jolt_body_impl_3d.cpp:590 @ apply_impulse()
  <Stack Trace>  Mob.gd:554 @ <anonymous lambda>()
                 stm_instance.gd:329 @ chunks_iterate()
                 Mob.gd:556 @ smash()
                 Mob.gd:389 @ _damaged()
                 hurt_box.gd:21 @ do_damage()
                 hurt_box.gd:27 @ _on_collision()
                 base_weapon.gd:138 @ fire()
                 weapon_manager.gd:44 @ _physics_process()

So was wondering if there was a mistake I had made in set up or not. The code I called it from was in my enemies death method, and looked something like this:

    for stm_instance in get_tree().get_nodes_in_group('smashable'):
        if stm_instance.owner == self:
            stm_instance.smash_the_mesh()

            var explode_callback = func(rb: RigidBody3D, _from):
                rb.apply_impulse(-rb.global_position.normalized() * Vector3(1, -1, 1) * 5.0)

            stm_instance.chunks_iterate(explode_callback)

As the enemies are currently made of multiple meshes.

zaknafean commented 6 days ago

Hm may well be my implementation. When I add an await process frame this goes away.

for stm_instance in get_tree().get_nodes_in_group('smashable'):
        if stm_instance.owner == self:
            stm_instance.smash_the_mesh()

            var explode_callback = func(rb: RigidBody3D, _from):
                rb.apply_impulse(-rb.global_position.normalized() * Vector3(1, -1, 1) * 5.0)
            await get_tree().process_frame
            stm_instance.chunks_iterate(explode_callback)

So i may just be trying to apply the physics too soon. You can probably consider this closed, but a note on this may be useful in the docs, since the error one gets is worse than the actual situation.

cloudofoz commented 5 days ago

I'm glad to hear you managed to solve the issue!

You're correct that the error likely stems from trying to apply physics to a RigidBody3D before it's fully initialized in the scene tree. Awaiting a process frame resolves this because, by then, the object is properly registered in the physics space.

Another approach you could try in cases like this is using the call_deferred method.

For example: stm_instance.chunks_iterate.call_deferred(explode_callback)

This ensures that the callback is executed after the current frame completes, which should help ensure that the object is fully ready.

I'll make sure to add a note in the documentation to help others avoid this issue in the future.