Create heightmap from external data

Godot Version

4.4.1

Question

Hi Folks,

I’m trying to create a HeightMapShape3D from external data. I’m very new to Godot, so please be gentle with me :wink:

I have a scene that includes a .glb file (named Track here) and I’d like to create a heightmap that matches the ground of the model. I already have height data for this. My scene looks like this:


I’ve created the TrackHeightMap element as a StaticBody3D and then attached the following script to it:

extends StaticBody3D

var heightmap_shape = HeightMapShape3D.new()

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	var file = FileAccess.open("track.json", FileAccess.READ)
	var json = JSON.new()
	var content = file.get_as_text()
	var error = json.parse(content)
	var heightfield_data
	if error == OK:
		var data_received = json.data
		heightfield_data = data_received["heightfield"]
	else:
		print("JSON Parse Error: ", json.get_error_message(), " in ", content, " at line ", json.get_error_line())
	var height_map_array = PackedFloat32Array()	
	height_map_array.resize(len(heightfield_data))
	for i in height_map_array.size():
		height_map_array[i] = heightfield_data[i]
	heightmap_shape.map_depth = sqrt(len(heightfield_data))
	heightmap_shape.map_width = sqrt(len(heightfield_data))
	heightmap_shape.map_data = height_map_array

I can see that my heightmap_shape variable looks to have the data I would expect, but I don’t think I have the heightmap I’m expecting (when I load something into a scene that contains this scene it appears to just fall through the ground).

What am I doing wrong? Do I need to assign the heightmap to the StaticBody3D (TrackHeightMap) somehow? Is this the right approach for programmatically creating a heightmap? How would I assign a color to the heightmap so I can see it in some kind of debug mode?

Many thanks, Tom

I think I’m making some progress. I’ve moved the script to the root node of the scene and am then adding this at the end:

$TrackHeightMap/CollisionShape3D.shape = heightmap_shape

The heightmap isn’t quite as expected, but there is at least one, so I suspect it’s not correctly aligned, will look into that.