Zylann / godot_heightmap_plugin

HeightMap terrain for Godot implemented in GDScript
Other
1.74k stars 159 forks source link

mesh export is not same collide with the hterrain #451

Closed yythlj closed 3 months ago

yythlj commented 4 months ago

I use export mesh lod 16 for server program check the collide. run the full hterrain node on the client

and I use move_and_collide for move

but it occur different result, if far away from center. more diff between the two program.

Zylann commented 4 months ago

I'm confused about what you did exactly. Why do you need to export a mesh for collision? Why can't you use the terrain itself, which generatres a heightmap collider already, which would perfectly match?

Anyways, if you're trying to use the mesh generated by the "generate mesh" tool, keep in mind that mesh was originally meant to be used for creating navigation. It's also not using exactly the same triangle topology as the collider, which might be noticeable if you scaled your terrain so much that triangles become huge or if you use very small bodies (see https://github.com/Zylann/godot_heightmap_plugin/issues/439). Finally, using lod 16 will give you a mesh that is extremely different from the full-resolution terrain, because it's being decimated 16 times, so obviously you will not get a perfect match compared to the normal terrain collider.

yythlj commented 4 months ago

In order to improve the running efficiency of the server, the server does not need to render details, it only needs collisions. Therefore, I want to obtain the heightmap from it and use it as collisions for the server.

When using StaticBody with CollideShape, setting the mapdata of HeightMapShape3D to 2049 x 2049 or 2048 x 2048 is incorrect. image

image func BuildMap()-> void: var heightmap_image: Image = ResourceLoader.load("res://world/maps/data/nature_map/normal.png").get_image()

heightmap_image.convert(Image.FORMAT_RF)

#var heightmap_image: Image = ResourceLoader.load("res://world/maps/data/nature_map/height.res")
#this is same, work incorrectly

var height_min: float = 0
var height_max: float = 400

heightmap_shape.get_shape().update_map_data_from_image(heightmap_image, height_min, height_max)

image

yythlj commented 4 months ago

in server program ,I need a best performce for collide, without other code use cpu. and run on a headless mode

yythlj commented 4 months ago

if I use mesh, only lod1 collide same with the client, but the verticles and triangles is too much

yythlj commented 4 months ago

and I dont use other on server, because the play room may close and server program will never exit.so I want keep it simple.

yythlj commented 4 months ago

can you provide a headless option for these case?only use the collide with the hterrain, no detail, no color. and there is no camera

Zylann commented 4 months ago

In order to improve the running efficiency of the server, the server does not need to render details, it only needs collisions.

can you provide a headless option for these case?only use the collide with the hterrain, no detail, no color. and there is no camera

You can already do all that, just not with a single checkbox I guess (or almost). It's already possible to use Godot in headless mode, where the renderer will just do nothing. You can also remove detail layers eventually, or even turn off terrain processing in Node settings since all it does is generally some chunk management which is probably not needed either. With that, what will mostly remain is the collider, which is created when the terrain is loaded.

When using StaticBody with CollideShape, setting the mapdata of HeightMapShape3D to 2049 x 2049 or 2048 x 2048 is incorrect.

Not sure what you did there, I assume you tried to load the .res containing heights into a HeighMap shape? If you want to do the heightmap collider manually, that would be another way of going about it, since that .res is just an Image resource with 32-bit float format (it should already be in the RF format). No idea what you mean by "incorrect". But if you do that you need to account for scaling, transforming and centering yourself, because HeightMapShape does automatic centering that the plugin has to adjust for. The plugin sets the transform like this: https://github.com/Zylann/godot_heightmap_plugin/blob/9b0d219bfd558e3318be81b3d58d4ed0e632b6f0/addons/zylann.hterrain/hterrain_collider.gd#L109-L114 And calculates terrain_transform like this: https://github.com/Zylann/godot_heightmap_plugin/blob/9b0d219bfd558e3318be81b3d58d4ed0e632b6f0/addons/zylann.hterrain/hterrain.gd#L681-L687 Min and max heights are also calculated from the actual min and max heights of the heightmap, not hardcoded values.

yythlj commented 4 months ago

I update the comment with picture

---Original--- From: @.> Date: Sat, Jun 22, 2024 09:01 AM To: @.>; Cc: @.**@.>; Subject: Re: [Zylann/godot_heightmap_plugin] mesh export is not same collidewith the hterrain (Issue #451)

In order to improve the running efficiency of the server, the server does not need to render details, it only needs collisions.

can you provide a headless option for these case?only use the collide with the hterrain, no detail, no color. and there is no camera

You can already do all that, just not with a single checkbox I guess. It's already possible to use Godot in headless mode, where the renderer will just do nothing. You can also remove detail layers eventually, or even turn off terrain processing in Node settings since all it does is generally some chunk management which is probably not needed either. With that, what will mostly remain is the collider, which is created when the terrain is loaded.

When using StaticBody with CollideShape, setting the mapdata of HeightMapShape3D to 2049 x 2049 or 2048 x 2048 is incorrect.

Not sure what you did there, I assume you tried to load the .res containing heights into a HeighMap shape? That would be another way of going about it, since that .res is just an Image resource with 32-bit float format (it should already be in the RF format). No idea what you mean by "incorrect". If you do that you need to account for scaling, transforming and centering yourself, because HeightMapShape does automatic centering that the plugin has to adjust for. The plugin sets the transform like this: https://github.com/Zylann/godot_heightmap_plugin/blob/9b0d219bfd558e3318be81b3d58d4ed0e632b6f0/addons/zylann.hterrain/hterrain_collider.gd#L109 And calculates terrain_transform like this: https://github.com/Zylann/godot_heightmap_plugin/blob/9b0d219bfd558e3318be81b3d58d4ed0e632b6f0/addons/zylann.hterrain/hterrain.gd#L681

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

Zylann commented 4 months ago

var heightmap_image: Image = ResourceLoader.load("res://world/maps/data/nature_map/normal.png").get_image()

Also that code is wrong, normal.png is a normalmap, not a heightmap. You need to load height.res.

yythlj commented 4 months ago

that way I try also not true

---Original--- From: @.> Date: Sat, Jun 22, 2024 09:13 AM To: @.>; Cc: @.**@.>; Subject: Re: [Zylann/godot_heightmap_plugin] mesh export is not same collidewith the hterrain (Issue #451)

var heightmap_image: Image = ResourceLoader.load("res://world/maps/data/nature_map/normal.png").get_image()

Also that code is wrong, normal.png is a normalmap, not a heightmap. You need to load height.res.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

Zylann commented 4 months ago

Well for sure there are more steps which you probably got wrong but I can tell you this should work if you do the same as the plugin does.

But did you read https://github.com/Zylann/godot_heightmap_plugin/issues/451#issuecomment-2183633638? You can already configure the plugin to turn off most of its CPU usage, and GPU usage can be removed completely by running Godot in headless mode.

yythlj commented 4 months ago

You're right, the server side also uses hterrain and setting process to false can run. However, the FPS is not very stable, and the memory usage is relatively high, so I want to make a compromise. For both segments, use the LOD 8 mesh, which is sufficient for my game, and the server can use the exported mesh + csgmesh to achieve this. On the client side, to retain the texture, hterrain is needed. Is there a way to set the hterrain in the game to use a certain LOD as the minimum LOD to display fixedly?

thanks for your help

---Original--- From: @.> Date: Sat, Jun 22, 2024 09:17 AM To: @.>; Cc: @.**@.>; Subject: Re: [Zylann/godot_heightmap_plugin] mesh export is not same collidewith the hterrain (Issue #451)

Well for sure there are more steps which you probably got wrong but I can tell you this should work if you do the same as the plugin does.

But did you read #451 (comment)? You can already configure the plugin to turn off most of its CPU usage, and GPU usage can be removed by running Godot in headless mode.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

Zylann commented 4 months ago

If you're having these problems it looks like you simply have bad hardware for the task... 2049x2049 isn't that big to run on nowadays computers, or you'd have to use an even lower resolution. And with CPU features turned off, it's super weird that you still somehow get framerate issues, because at this point the terrain does nothing during the main loop.

is there a way to set the hterrain in the game to use a certain LOD as the minimum LOD to display fixedly?

No. Also I don't see any relation between that and what you described earlier... that's going to increase resource usage, because if you're raising the minimum LOD, lower LODs won't ever display, so more chunks will have to render, which means more polygons. If you meant the opposite, i.e never render the highest LOD for example, then you also can't do that. Instead you should just use a terrain with smaller resolution and scale it up.