[GDExtension] Any methods to raycast in an Editor Scene Viewport?

Godot Version

4.2.1

Question

I’m making my level editor in Godot, and I want to raycast the object through the mouse position, after a lot of struggle, I got the below code:

    EditorInterface *interface = EditorInterface::get_singleton();
    SubViewport *viewport = interface->get_editor_viewport_3d(0);
    Camera3D *camera = viewport->get_camera_3d();
    Vector2 mousePos = viewport->get_mouse_position();
    Rect2 viewportRect = viewport->get_visible_rect();
    if (viewportRect.has_point(mousePos)) {
        // mousePos is inside the viewport
        Vector3 from = camera->project_ray_origin(mousePos);
        Vector3 direction = camera->project_ray_normal(mousePos);
        auto world = viewport->get_world_3d();
        auto spaceState = world->get_direct_space_state();
        Ref<PhysicsRayQueryParameters3D> raycastArgs;
        raycastArgs.instantiate();
        raycastArgs->set_from(from);
        raycastArgs->set_to(from + direction * 4000);
        auto dict = spaceState->intersect_ray(raycastArgs);
        if (dict.has("collider")) {
            Node3D *collider = Object::cast_to<Node3D>(dict["collider"]);
            if (collider) {
                result.hitNode = collider;
                result.hitPosition = dict["position"];
                result.hitNormal = dict["normal"];
            }
        } 
        if (result.hitNode == nullptr) {
            // We have our refer depth as raycast's target.
            real_t referY = _config.is_null() ? 0.0 : _config->referDepth();
            real_t t = (referY - from.y) / direction.y;
            Vector3 hit = from + direction * t;
            hit.y = referY;
            result.hitPosition = hit;
            result.hitNormal = maths_3d::yAxis();
        }
        return true;
    }
    return false;

But the world3d of viewport is null so it leads to crash.
By the way, I even don’t know how to get the selected scene’s index.
Any methods to implement it?

I don’t know about cpp etc., but there are some methods which are not intended for use in the Editor. Have a look here:

Thanks. I found my bug through your code.
I should use get_world_3d of a node3d rather than viewport. And my code works after that.
I almost intended to implement my own BVH partitioning, thanks for your help.
By the way, how do you get your selected scene’s viewport? I’d like to render some gizmos on it but I don’t know how to get current scene when there are a lot of tabs.

1 Like

Cool.

Don’t know offhand. If I find out will post.

I tested a lot and find get_editor_viewport_3d(0) always return the activated scene view, but if you try to split your view into several parts, the index becomes confused though.

I’ve rendered gizmos in a plugin recently, but there was no mention of a viewport.
I used EditorPlugin and it’s add_node_3d_gizmo_plugin method.

I was going to say, I think the selected scene will be the only viewport anyway. That method should give you the sub-sections.

Maybe you are trying to use the wrong tool for the job. Have a look into the EditorPlugin rabbithole.

It seems Node3DGizmoPlugin only works on nodes of speicified type, but I don’t want these constraints.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.