Gridmap with static bodies is slow to load

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

Hello,
I have an issue related to this topic:
https://forum.godotengine.org/27821/how-to-improve-gridmap-performance-octant-size?show=27952#c27952

In short, if I use a 3D GridMap with a meshlibrary composed of Meshes ONLY, the loading of the map is superquick (i´m talking about hundreds of thousands of mesh - if not millions- in a few seconds).
If I go with a meshlibrary composed of StaticBodies (i need them to detect the click of the mouse on the object placed on the gridmap), a simple 10 thousands bodies map will takes several minutes to load, a 50k bodies map will take up to 15-20 minutes.

Point is I was expecting a slow down of the performance, but one would expect adding physics objects would impact mainly on the frame rate, but that´s totally untrue: the framerate remain basically untouched.

I would like to know where this slow loading time came from, why does a static body take more time to appear on the scene than a simple mesh, even before any physic is involved?

Andrea

Maybe PhysicsBodys need to be preprocessed in someway first when added to the physics world. Especially ones with concave collision shapes, as they’ll need to be decomposed into simpler convex geometry.

SIsilicon | 2018-05-09 15:45

That’s not my case though, I’m using only cubes and boxes, so no pre-construction of simpler bodies

Andrea | 2018-05-10 05:16

While I was playing around with the 3D platformer demo, it only takes a second or two for it to load the level on runtime(not the editor). But when I enable the collision shape debug, it takes considerably longer. Do you have that enabled?

SIsilicon | 2018-05-10 17:13

Do you mean the visible collision shape debugger? if it is, no it is not enabled (and I honestly cant tell much difference in loading speed if i enable it or not).

By the way, do you mean this demo?
3D Platformer Demo - Godot Asset Library
If yes, the amount of StaticBodies in this scene is not so big (i guess around two thousands) so the problem is limited here.

I prepared a test scene for you to try if you want, it´s a simple gridmap where the cells are filled using this simple script:

extends Spatial

var map_size=200

func _ready():
	for i in range(0,map_size):
		for j in range(0,map_size):
			$GridMap.set_cell_item(i,0,j,0)

Could you please verify that changing the theme of the gridmap (between “bodies” and “meshes”) does indeed affect loading time?
Here the “project”: https://drive.google.com/open?id=1OPg71wKa0_fKNaWGeStAZEas7tZO1xdr

Andrea | 2018-05-11 11:36

Ok I’ll check it out.

SIsilicon | 2018-05-11 17:15

Ok after playing around with the project you sent me, I realized something. Minecraft has the same problem. And I should know. What relevant about it? Well in the said project I noticed that all the grid elements were set in all at once. And notice how every time you generate a Minecraft world, it also takes a while, albeit more optimized over the years. But it doesn’t stop there. I am very accustomed with redstone and pistons. If you don’t know what a piston is, it’s a block that can push up to twelve blocks in front of it. I tried to make a piston tape. It works as expected. It push a bunch of blocks in a circle(square :/). But a soon I made a bunch of them in rows, oh the performance hit! Took me a while to get to the switch. So what does this have to do with your problem. What I’m saying is that your problem is that your placing of blocks all at once. In my piston tape armada all the blocks in it have to be removed and placed back in their new position. All at once in a single frame! So what I am saying is that your problem is universal and pretty much unavoidable unless everyone had an nvidia 1080 GPU. Godot’s gridmap could use a little bit more optimization.

SIsilicon | 2018-05-13 19:06

I understood that, what I dont understand is why Godot is able to load the same amount of meshes in seconds, while the amount of pre-loading of the static bodies is considerably greater.

But anyway, up to now it doesnt seem there is any particular reason or any parameter I can switch to make it go faster, so I have to work around it in the code.

Thanks again Sisilicon!

Andrea | 2018-05-14 09:03

It’s S I silicon.
The first two letters are capital.
Lol.

SIsilicon | 2018-05-17 21:05

i just saw an email saying you replied my post and gave me hopes that you found a solution, just to came here and read this XD

Andrea | 2018-05-21 01:15

So you didn’t actually read it? When I get my email from this website it shows me what comments I get too.

SIsilicon | 2018-05-21 03:29

nah, i click the link, then read

Andrea | 2018-05-21 06:54

I just had a similar problem instancing nodes with static bodies. Not sure if it applies to your case, but in mine, changing the position of the node before adding it as a child solved the problem.

var child = Child.instance()
child.set_position(Vector2(x, y))
parent.add_child(child)

I guess Godot recalculates collisions on each child added and, by default, they would stack on 0, 0, causing the lag.

cgx | 2019-06-15 09:28

This works, thank you!

 # Create many collision shapes
var collisionNode = StaticBody.new()
collisionNode.set_translation(Vector3(i * 10, 1, 1))
self.add_child(collisionNode)

JeremiahLR | 2019-11-05 02:22

:bust_in_silhouette: Reply From: Scotti8

Just came across this question as I was having the same issue and wanted to add to it.

I initially fixed the issue in a different way: I set the collision layer and mask and the for the static body to different layers so each tile wouldnt interact.

This worked, and it may be worth doing this also. But cgx’s answer is very efficient.

If only I had those answers 2 years ago :slight_smile:

Andrea | 2021-08-25 21:38