godot-docs icon indicating copy to clipboard operation
godot-docs copied to clipboard

ImmediateGeometry base class is missing in Godot 4

Open lokimckay opened this issue 2 years ago • 4 comments

Your Godot version: Godot v4.0.alpha9.official [fc18891db]

Issue description:
The ImmediateGeometry base class is not present in Godot 4, but the latest documentation still references it.

image

image

There has been some discussion from users on discord about what should be used instead, but I'm unclear on how to workaround this issue. It would be great if the documentation could be updated to provide an example

image

URL to the documentation page: Webpage: https://docs.godotengine.org/en/latest/tutorials/3d/procedural_geometry/immediategeometry.html Code: https://github.com/godotengine/godot-docs/blame/master/tutorials/3d/procedural_geometry/immediategeometry.rst

lokimckay avatar Jul 02 '22 13:07 lokimckay

See https://docs.godotengine.org/en/latest/classes/class_immediatemesh.html#class-immediatemesh

fire avatar Jul 02 '22 13:07 fire

There is an in production example here.

https://github.com/V-Sekai/godot-vrm/blob/master/addons/vrm/vrm_secondary.gd#L101-L197

editor_screenshot_2022-07-02T070233

The line gizmos are ImmediateMesh. Note that this example is NOT a triangle mesh. It can be a triangle mesh.

fire avatar Jul 02 '22 14:07 fire

ImmediateGeometry node was replaced by the ImmediateMesh resource.

The manual page in question needs to be rewritten from scratch for 4.0.

Calinou avatar Jul 02 '22 16:07 Calinou

For googlers, here is a cut-down version of @fire's example that I am using to draw lines and spheres from an auto-loaded script (in-game only, not an editor tool)

# debug.gd (autoloaded)
extends MeshInstance3D

var mat: StandardMaterial3D = StandardMaterial3D.new()

func draw_line(begin_pos: Vector3, end_pos: Vector3, color: Color = Color.RED) -> void:
	mesh.surface_begin(Mesh.PRIMITIVE_LINES)
	mesh.surface_set_color(color)
	mesh.surface_add_vertex(begin_pos)
	mesh.surface_add_vertex(end_pos)
	mesh.surface_end()

func draw_sphere(center: Vector3, radius: float = 1.0, color: Color = Color.RED) -> void:
	var step: int = 15
	var sppi: float = 2 * PI / step
	var axes = [
		[Vector3.UP, Vector3.RIGHT],
		[Vector3.RIGHT, Vector3.FORWARD],
		[Vector3.FORWARD, Vector3.UP]
	]
	mesh.surface_begin(Mesh.PRIMITIVE_LINE_STRIP)
	mesh.surface_set_color(color)
	for axis in axes:
		for i in range(step + 1):
			mesh.surface_add_vertex(center + (axis[0] * radius)
				.rotated(axis[1], sppi * (i % step)))
	mesh.surface_end()

func _ready():
	mesh = ImmediateMesh.new()
	mat.no_depth_test = true
	mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
	mat.vertex_color_use_as_albedo = true
	mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
	set_material_override(mat)

func _process(_delta):
	mesh.clear_surfaces()

# otherscript.gd
func _process(_delta):
	Debug.draw_line(Vector3(0,0,0), Vector3(0,100,0))
	Debug.draw_sphere(Vector3(0,0,0))

lokimckay avatar Jul 02 '22 16:07 lokimckay

For googlers, here is a cut-down version of @fire's example that I am using to draw lines and spheres from an auto-loaded script (in-game only, not an editor tool)

Cheers mate, here's the C# equiv, written for Godot 4.11 (vaguely matches the 4.2 'latest' docs).

using Godot;

// Thanks to lokimckay: https://github.com/godotengine/godot-docs/issues/5901#issuecomment-1172923676
// C# conversion by Sickle, github.com/JonathanDotCel/

public partial class DrawTools : MeshInstance3D
{

    [Export( PropertyHint.None, "Components" )]
    private Material iMat;
    [Export( PropertyHint.None, "Components" )]
    private ImmediateMesh iMesh;

    public void DrawLine( Vector3 start, Vector3 end, Color? color = null )
    {

        iMesh.SurfaceBegin( Mesh.PrimitiveType.Lines );
        iMesh.SurfaceSetColor( color ?? new Color( 0, 0, 0, 1 ) );
        iMesh.SurfaceAddVertex( start );
        iMesh.SurfaceAddVertex( end );
        iMesh.SurfaceEnd();

    }

    public void DrawSphere( Vector3 center, float radius, Color? color = null )
    {

        float numSteps = 16;
        float stepSize = (Mathf.Tau) / numSteps;

        // move here from the center
        Vector3[] primaryAxis = { Vector3.Up, Vector3.Right, Vector3.Forward };
        // then rotate around this axis
        Vector3[] rotationAxis = { Vector3.Right, Vector3.Forward, Vector3.Up };

        iMesh.SurfaceBegin( Mesh.PrimitiveType.LineStrip );
        iMesh.SurfaceSetColor( color ?? new Color( 0, 0, 0, 1 ) );

        for ( int axis = 0; axis < primaryAxis.Length; axis++ )
        {
            // ad an extra step to close the gap on the final disc of each rotation
            for ( float i = 0; i <= numSteps; i++ )
            {
                Vector3 vert = (primaryAxis[ axis ] * radius);
                vert = vert.Rotated( rotationAxis[ axis ], stepSize * i );
                vert += center;
                iMesh.SurfaceAddVertex( vert );
            }
            // throw in an extra center vert to tidy up the lines between axes
            iMesh.SurfaceAddVertex( center );

        }
        iMesh.SurfaceEnd();

    }

    public override void _Ready()
    {

        iMesh = new ImmediateMesh();
        iMat = new StandardMaterial3D();

        iMat.Set( "no_depth_test", false );
        iMat.Set( "shading_mode", (int)BaseMaterial3D.ShadingModeEnum.Unshaded );
        iMat.Set( "vertex_color_use_as_albedo", true );
        iMat.Set( "transparency", (int)BaseMaterial3D.TransparencyEnum.Alpha );

        iMesh.SurfaceSetMaterial( 0, iMat );

        this.Mesh = iMesh;
        this.MaterialOverride = iMat;

    }

    public override void _Process( double delta )
    {
        iMesh.ClearSurfaces();
        Example();
    }

    public void Example()
    {
        DrawLine( Vector3.Zero, Vector3.One * 20, new Color( "blue" ) );
        DrawSphere( Vector3.Zero, 20, new Color( "red" ) );
    }

}

JonathanDotCel avatar Oct 01 '23 14:10 JonathanDotCel

Can someone submit a documentation pr using my sample?

fire avatar Oct 02 '23 03:10 fire