Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add collision detection / raycast to MultiMeshInstance3D #10828

Open
KaijuKoder2 opened this issue Sep 26, 2024 · 1 comment
Open

Add collision detection / raycast to MultiMeshInstance3D #10828

KaijuKoder2 opened this issue Sep 26, 2024 · 1 comment

Comments

@KaijuKoder2
Copy link

KaijuKoder2 commented Sep 26, 2024

Describe the project you are working on

A game where the environment is largely made up of MultiMeshInstance3Ds. Mine is a large 3D terrain landscape made of tiles, though it could equally apply to a dungeon or a city: Anything where the scene is large and has many repeated objects: ideal for multi mesh instances.

Describe the problem or limitation you are having in your project

Want the player to be able to click on a spot in that scene and know where they clicked. Say so the player's character to walk to that spot. A common enough use case.

But while MultiMeshInstance3Ds give great performance for such 3D environments, unlike MeshInstance3Ds, you can't create a create_trimesh_collision() on a MultiMeshInstance3D, which means there's no easy way to detect raycast/collision. The workarounds are very ugly and inefficient: e.g. You recreate the entire mesh just for collision which defeats the idea of having multimeshes, or you create a collision object for each and every instance in the multimesh - but there could be thousands: See https://forum.godotengine.org/t/solved-how-set-collisionshape-on-multimeshinstance/21064

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Support collisions. Effectively do what Zylann (oh wow! That's @Zlylann! The Godot Terrain guy!) suggests in https://forum.godotengine.org/t/solved-how-set-collisionshape-on-multimeshinstance/21064 but do it within Godot so the user doesn't have to (inefficiently) create and manage a potentially huge number of collision shapes - one per instance, and again - there could be thousands of them! - to achieve the same result.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Two possible solutions.

  1. Minimal API change solution: Add create_trimesh_collision() to MultiMeshInstance3D (or possibly the underlying MultiMesh since that might be reused and the geometry identical) to create mesh from said instances (just rolling the mesh through the instance transforms and combining those). Of course, that's computationally inefficient and may consume a lot of memory - defeating the whole reason we use multi instancing to begin with, though it would reduce the burden on the Godot coder doing a similar thing in Gdscript as Zlylann describes.

  2. More elegant solution suitable for collision raycasting. Analog to Zylann's example script but do it in the Godot Engine: Take the underlying mesh, iterate through the instance transforms, evaluating the raycast against each of those. Trivial memory overhead doing it this way, and if it's used for say user clicks, those are so infrequent the processing overhead is minor. Only when they click.

If this enhancement will not be used often, can it be worked around with a few lines of script?

See Zlylann's suggestion. It can be done, but not in a few lines because you have to manage all those collision shapes, which means a lot more than just a few lines of script. (I've written similar code to handle modifying individual instances whic h requires such tracking and it's several hundred lines long). The above two solutions would provide a much cleaner, efficient, simpler way of doing it.

Is there a reason why this should be core and not an add-on in the asset library?

Requires changes to underlying Godot engine code.

@tetrapod00
Copy link

tetrapod00 commented Sep 26, 2024

It's a slightly different use case, but between this and #10669 there seems to be real demand for a new MultiMeshInstance3D-like node that has more of the features of individual instances, but with performance and usability gains over using individual nodes.

My proposed design might be something like a MultipleInstance3D, which takes a single mesh and collision shape, and has an array of transforms in its inspector. Internally it does the work of setting up the RenderingServer and PhysicsServer instances/collision shapes. You would be paying the cost (and getting the benefits) of individual instances, like collision detection and culling/LODs (see the other issue). But you would not be paying for the overhead of nodes, and you would not have to manage the boilerplate of setting things up.

I think that the existing MultiMeshInstance3D should not change too much to add extra features, if it would compromise it's primary goal of rendering many meshes all at once.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants