MultiMesh: how to use Populate Surface tool in gdscript

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By DaddyMonster

Hi. I want to use the very convenient Populate Surface tool found in the editor with MultiMeshInstance. However, the mesh I want to apply to the surface of is procedurally generated so I can’t just pick the target surface from the node tree.

I’ve checked the docs and I can’t see how to run this tool in gdscript. Is it only available in the editor? If so, how do I reference it?

Thanks in advance

couldn’t you create an empty node with the generation script attached to it? Then you could reference that node in the tool.

Millard | 2020-09-22 19:18

Yeah, I guess I could work around it. I’m just really surprised that there’s something in Godot you can’t control in the code.

DaddyMonster | 2020-09-22 21:08

:bust_in_silhouette: Reply From: Zylann

I didnt know this tool before. From what I understand, it generates instances based on an existing mesh surface?

Assuming that:

  • You want to do this only in editor? (won’t be available in game).
  • Your procedurally generated mesh comes from a tool script

In this situation, you can’t see your node in the tree because by default the owner of nodes created from tool scripts is not the edited scene root, which makes the editor hide them.

Possible solutions:

  • Make your node appear by setting the owner of your generated MeshInstance using yournode.set_owner(get_tree().edited_scene_root). This, however, will make the node behave as if you had created it yourself. It will then be saved by Godot with the mesh it holds (which might bloat your scene file). It also means your tool script will have to check if it has generated the mesh already, because when you reload the scene it will be there already.

  • You can cheat: even though your node won’t be listed in the popup, it doesn’t mean it can’t be accessed. If you give a name to the MeshInstance generated by your script, perhaps you can input its real path manually in the text field.

  • You could make your tool script save a mesh which you can then use in your scene like a regular imported mesh, rather than having it generate directly in the scene

  • If you want to automate the Populate tool as part of your procedural generation script, or if you do this only in game, you may have to recode this tool if it’s not exposed. It might be relatively simple though, once you know how to deal with indexed triangles (that’s what ArrayMeshes are most of the time). You can see how it’s made in the source code: https://github.com/godotengine/godot/blob/9a463cb1d62a174aa34f608c0281963cdad255e9/editor/plugins/multimesh_editor_plugin.cpp#L44

Alternatively, you could open a proposal on Github to expose an API for this functionality.

That’s very good info, thanks.

Sorry if I wasn’t clear, I do want it to appear in my game. It’s simply that, because it’s procedural and the mesh doesn’t exist until the game is launched I was unable to use the editor as I obviously cannot select a target surface that doesn’t exist yet. And also, for optimisation reasons I wanted the option of placing stuff in runtime.

I was really surprised when I checked the docs and found there were no methods I could call to simply run the tool from script.

In the end I just did it the old fashioned way and looped through it setting it to the surface but it was a shame not to have an api for this tool, which is super convenient. Maybe the approach that’s most in the spirit of OpenSource is what you suggested last, I should have a crack at coding it myself if my shaky C++ is up to it. :slight_smile:

Thanks again!

DaddyMonster | 2020-09-24 13:03

Using from game explains a lot. You will have to go the manual part then.
When the populate tool was added, whoever did it had a demand to have that in the editor I guess, so if you want something similar for in-game you would need to ask for it as well.

Zylann | 2020-09-24 13:11