How is the path3d visualized in the editor

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

Hello dear community!

I’ve been told many times that the godot editor was implemented purely in godot. I have recently begun working with VR a bit and tried to implement my own teleportation with a technique i found that is called tall ray casting. I have been able to sucessfully implement the feature however i am missing a proper visualization for where I am teleporting.

Having tried multiple different approaches that all looked quite performance-heavy, i started wondering how the 2D visualization of a Path3D in the editor actually works as it looks promissingly performance-light. Can someone explain to me how i could render a simple line like this in 3D?

Edit: I should probably note that i would require a bezier line, not just a simple “raycast”.

:bust_in_silhouette: Reply From: Zylann

You could try using the ImmediateGeometry node, which allows you to draw lines from script in real time: https://docs.godotengine.org/en/stable/classes/class_immediategeometry.html

Does it support bezier behaviour somehow? Looking into the docs I have not found anything like that. I really wonder how the godot editor implements the visualization.

Toothgapsy | 2020-03-03 10:40

It just draws lines, really.
Bezier is not something you will find in the drawing methods themselves, it’s rather the data you are using to draw such lines.

The Path3D node can look curvy because it uses a Curve3D resource, which can provide bezier positions by interpolating its points.
So if you want to draw bezier curves, you need to use a Curve3D resource, add points to it, define its control points, and use interpolate_baked(), or tessellate() to obtain points along the curve: Curve3D — Godot Engine (stable) documentation in English

Now to draw it, all you need is to draw a line between each of the points you obtained.
Here is how Godot does it: https://github.com/godotengine/godot/blob/80582ffa662bb4dea223003856320ede37365603/editor/plugins/path_editor_plugin.cpp#L228
It uses a Gizmo API which generates a mesh behind the scenes, but you can also do it with ImmediateGeometry, SurfaceTool or ArrayMesh.add_surface_from_arrays.

Zylann | 2020-03-03 18:46

Just figured that out myself yesterday. Thank you, functioning just as needed :slight_smile:

Toothgapsy | 2020-03-04 14:41

:bust_in_silhouette: Reply From: mplorentz

I’ve been trying to do a similar thing. Here’s the ImmediateGeometry code I came up with. The hardest part was setting a color. I’m running this code in _process() because my path changes each frame.

var drawn_line: ImmediateGeometry
var path: Path = your_path

var curve = path.curve
	
if drawn_line == null:
	drawn_line = ImmediateGeometry.new()
	get_tree().root.add_child(drawn_line)
	var m = SpatialMaterial.new()
	m.flags_use_point_size = true
	m.params_point_size = 5
	m.vertex_color_use_as_albedo = true
	m.albedo_color = Color(0, 0, 1)
	drawn_line.set_material_override(m)
	curve.bake_interval = 0.0001
	

var curve_length = curve.get_point_count()

drawn_line.clear()
drawn_line.begin(Mesh.PRIMITIVE_POINTS)


for index in range(0, curve_length):
	drawn_line.add_vertex(curve.get_point_position(index))
	
drawn_line.end()