Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Camera.project_ray_origin always returns the origin of the camera when in perspective projection. #41872

Closed
neauangle opened this issue Sep 8, 2020 · 4 comments

Comments

@neauangle
Copy link

neauangle commented Sep 8, 2020

Godot version:
3.2.2

OS/device including version:
Windows 10

Issue description:
No matter what Vector2 is given to Camera.project_ray_origin, it just returns the camera's origin if the camera is in perspective projection. I see in the source that it does that on purpose, and always has.

I want to cast a ray from the mouse into the world from the camera in the direction the camera is facing. Using the code from the page on RayCasting results in an inaccurate ray origin because it's the same value regardless of where the mouse is in the viewport.

For example, I add two points to an ImmediateGeometry: Vector3(0,0,0) and project_ray_origin(get_viewport().get_mouse_position()). As you can see below, the ray origin is somewhere to the right, and doesn't depend on the mouse's position at all:

Screenshot_11

If this is by design, then there's a documentation issue (it should note somewhere that it doesn't work for projection cameras), but then the question remains: how does one cast a ray from the mouse into world using a perspective camera?

Steps to reproduce:

  1. Create a scene with a camera.
  2. In the camera, project_ray_origin(get_viewport().get_mouse_position()) will not depend on the mouse position.

Minimal reproduction project:
Demo.zip

@GiantBlargg
Copy link
Contributor

Camera.project_ray_origin works correctly.

To do a raycast you need 2 points, the point to start at, and the point to end at:

project_ray_origin gives the point to start at, which for a perspective camera is always the camera's origin.

project_ray_normal gives the direction that the ray should travel in, so we can multiply the direction by the maximum distance that we want the ray to travel, and add it to the origin to get the correct end point. (If you want to be able to hit anything visible you can use Camera.get_zfar() for the maximum distance.)

You can then use intersect_ray to preform the raycast.

var mouse_pos = get_viewport().get_mouse_position()
var start = camera.project_ray_origin(mouse_pos)
var end = start + camera.project_ray_normal(mouse_pos) * camera.get_zfar()
var space_state = get_world().direct_space_state
var result = space_state.intersect_ray(start, end)

I recommend you read over the Raycast Tutorial again. It explains this, as well as what info is contained in the result of intersect_ray

@neauangle
Copy link
Author

Cheers, I figured this out soon after I posted this but couldn't figure out how to close the issue. Embarrassing. But now I'm wondering how I couldn't find the button- it's right there!

@akien-mga akien-mga added archived and removed bug labels Sep 25, 2020
@goosegarden
Copy link

"
project_ray_origin gives the point to start at, which for a perspective camera is always the camera's origin.
"
then why not directly get the camera origin ?

@fahoodey
Copy link

" project_ray_origin gives the point to start at, which for a perspective camera is always the camera's origin. " then why not directly get the camera origin ?

I know I'm "to late to the party"
but for whoever stumble upon this:

"project_ray_origin" exist because orthogonal camera origin is variable unlike perspective camera which is constant
similarly "project_ray_normal" exist because perspective camera normal is variable unlike orthogonal camera which is constant

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants