Generate a point cloud

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

For an engineering project, I need to play with point cloud. While waiting the depth cameras, I thought I could just generate point cloud data file using Godot.

This is my simple scene:

[node name="Scene" type="Spatial"]
script = ExtResource( 1 )

[node name="CSGBox" type="CSGBox" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -5 )
use_collision = true

[node name="CSGBox2" type="CSGBox" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -4, 1, -8 )
use_collision = true

[node name="Camera" type="Camera" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0 )
fov = 86.0
near = 0.11

On the parent node, “Scene”, I have attached the follwing script:

extends Spatial

var radius = 10
var max_height = 720

var origin = null
var ray_count = 1280
var points = []
var done = false

func _ready():
	origin = self.get_node("Camera").transform.origin
	print(origin)
	
	for _i in range(0, max_height):
		points.append([])
		
	print("Point cloud generator launched.")

func _physics_process(_delta):
	if not done:
		var space_state = get_world().direct_space_state
		for height in range(0, max_height):
			for i in range(ray_count):
				var theta =  i / float(ray_count) * PI - PI
				var destination = Vector3(radius * cos(theta), height, radius * sin(theta))
				var result = space_state.intersect_ray(origin, destination)
				
				if result:
					print("hited")
					points[height].append(result.position)
			
			
		var width = len(points[0])

		var output = File.new()
		output.open("res://output.pcd", File.WRITE)
		output.store_line("VERSION .7")
		output.store_line("FIELDS x y z")
		output.store_line("SIZE double double double")
		output.store_line("TYPE F F F")
		output.store_line("COUNT 1 1 1")
		output.store_line("WIDTH %d" % width)
		output.store_line("HEIGHT %d" % max_height)
		output.store_line("VIEWPOINT 0 0 0 1 0 0 0")
		output.store_line("POINTS %d" % (width * max_height))
		output.store_line("DATA ascii")
		
		for h in points:
			for point in h:
				output.store_line("%f %f %f" % [point.x, point.z, point.y])
		
		output.close()
		
		print("Done")
		done = true

But it doesn’t work, I don’t know if it’s because my math is incorrect or if it’s because I don’t know how to do raycasting.

Do you know how can I generate a simple point cloud from a 3D environment in Godot?