godot_heightmap_plugin icon indicating copy to clipboard operation
godot_heightmap_plugin copied to clipboard

Support terrain rotation

Open creative-brain opened this issue 4 years ago • 16 comments

Is it possible to rotate a HTerrain instance to face a particular direction? Currently it looks like its transform is locked.

creative-brain avatar Mar 12 '21 14:03 creative-brain

The gizmo is broken due to how I had to implement sculpting and painting. See https://github.com/Zylann/godot_heightmap_plugin/issues/41 You can change the transform in the inspector, however I'm not sure if rotation works.

Zylann avatar Mar 12 '21 17:03 Zylann

I can change position but not rotation in the inspector. What about procedurally generated instances? I don't mind setting it manually or even trough some hack, as far as the brush and other tools will still work... I don't need to change it on the fly, I need to set it just once.

Also viable option for me would be to define separate classes for each rotation of HTerrain. Can you point me out to where in the code should I look it?

creative-brain avatar Mar 12 '21 18:03 creative-brain

If you can't change rotation in the inspector, then it's not supported. I think several parts of the plugin don't take it well into account at the moment, considering rotated terrains was rarely needed so far.

Also viable option for me would be to define separate classes for each rotation of HTerrain

I don't think that's a good idea. If you want 90 degrees rotation along the Y axis you can rotate/transpose the heightmap in an image editor or using the Image API of Godot, but otherwise proper rotation for any angle should be implemented. You might want to change the issue title if rotation is what you want to have.

Zylann avatar Mar 12 '21 19:03 Zylann

I need both rotation and position so the issue title is correct. I guess we'll have to wait for the fix then...

creative-brain avatar Mar 12 '21 19:03 creative-brain

The title should be changed because it can be confused with #41, and only rotation is missing. I'll change it to reflect the work that has to be done.

Zylann avatar Mar 12 '21 20:03 Zylann

I can confirm that rotations work perfectly, once the terrain starts to use the proper transforms. What you need to do is in hterrain.gd:


# Gets the global transform to apply to terrain geometry,
# which is different from Spatial.global_transform gives
# (that one must only have translation)
func get_internal_transform() -> Transform:
	# Terrain can only be self-scaled and translated,
	return Transform(global_transform.basis, global_transform.origin)

https://github.com/Zylann/godot_heightmap_plugin/blob/master/addons/zylann.hterrain/hterrain.gd#L556-L561 The gismo is still broken, but you can change the rotation transform of the node, and it will rotate properly.

image

Frontrider avatar Mar 18 '21 14:03 Frontrider

return Transform(global_transform.basis, global_transform.origin)

Note that this implementation completely disregards map_scale, so it breaks that feature. The reason get_internal_transform exists is to allow to change terrain scale without affecting its children.

Also having a quick look at shaders, I think normal mapping of ground textures will be wrong when the terrain's basis is transformed (terrain_normal_world seems ok, but not ground_normal coming from textures).

Zylann avatar Mar 18 '21 16:03 Zylann

I'll look at those then.

Yeah, I missed the mapscale, yes.

Frontrider avatar Mar 18 '21 23:03 Frontrider

I see the script that bakes the normals, it does not look hard to take the transform into account but I can't find where it is called from.

Frontrider avatar Mar 21 '21 21:03 Frontrider

The script that bakes normals does not need to care about terrain rotation, it does its own thing in local space with a viewport. The problem with normals is in the shaders, when splatmapped textures are used.

Zylann avatar Mar 21 '21 21:03 Zylann

Yeah, I can understand why it's not that simple to allow rotations to the HTerrain.

However, I'm bit surprised that only few people need it. In my case, I have a procedural generation script that spawns randomized rooms and corridors between them. Some of the rooms have a HTerrain as floor, instead of normal mesh instances.

The problem is that the rooms can be spawned in 180, 90, 0 or 270 degrees, depending on the flow of the procedural generation. So whenever it needs to be rotated by an angle that is different than 0, the HTerrain doesn't follow the parent rotation.

@Zylann You said something about rotating the heightmap source image...is that possible to do dynamically, by code?

Thanks for the plugin!

Here's how my generation works: Caveery (DEBUG) 2022-03-14 20-29-51

And here's how the rotation impacts the generation: RoomH tscn - Caveery - Godot Engine 2022-03-14 20-32-19

giabeni avatar Mar 14 '22 23:03 giabeni

@Zylann You said something about rotating the heightmap source image...is that possible to do dynamically, by code?

If the rotation is 90 degrees, you could get the data, then get each map and rotate them. Although if you generate those maps, you should better do that before creating the terrain with them. You can use Image functions flip_x(), flip_y(), unfortunately I dont see rotate90. If you generate these maps procedurally a viewport with shader will be the fastest, and can do rotation pretty easily by rotating what it renders.

Zylann avatar Mar 14 '22 23:03 Zylann

Thanks, @Zylann! I'll try to do something following these suggestions.

giabeni avatar Mar 15 '22 02:03 giabeni

Just added support for rotation and centering on the master branch.

Zylann avatar Mar 26 '22 20:03 Zylann

You're talking about 3f0f7c63e207bee16ee32a0c26b9131dd071b170, right?

Zireael07 avatar Mar 27 '22 10:03 Zireael07

yes

Zylann avatar Mar 27 '22 13:03 Zylann