Skip to content

Conversation

@kushalkolar
Copy link
Contributor

Simple example of how to map event locations from screen space to world space, includes viewports. As someone who isn't really a graphics person it took me a while to figure out 😄

click_example-2023-04-19_02.57.02.mp4

@kushalkolar kushalkolar requested a review from Korijn as a code owner April 19, 2023 06:58
@almarklein
Copy link
Member

Nice example to have! Note that this will change / get easier with #492.

@kushalkolar
Copy link
Contributor Author

I think this should be good to go, or I can wait until #492 and update it then.

@almarklein
Copy link
Member

Would you mind waiting at least for #482?

@kushalkolar
Copy link
Contributor Author

Yes of course (I haven't been following that PR, it is massive 😄 )

@Korijn
Copy link
Collaborator

Korijn commented May 2, 2023

Yes of course (I haven't been following that PR, it is massive 😄 )

It's been merged now, so if you can refactor your example to be compatible, we can have another look and merge it.

@kushalkolar
Copy link
Contributor Author

kushalkolar commented May 22, 2023

Digging through pylinalg and can't quite figure out the equivalent for how it worked before with pygfx.linalg:

pos_world = (
    camera.position.clone().project(camera).add(pos_ndc).unproject(camera)
)

This is not quite right:

# this is the click position in canvas space
pos = (ev.x, ev.y)
print(f"position click: {pos}")

for viewport, scene, camera in zip(viewports, scenes, cameras):
    if not viewport.is_inside(*pos):
        continue

    # get position relative to viewport
    pos_rel = (
        pos[0] - viewport.rect[0],
        pos[1] - viewport.rect[1],
    )

    vs = viewport.logical_size

    # convert position to NDC
    x = pos_rel[0] / vs[0] * 2 - 1
    y = -(pos_rel[1] / vs[1] * 2 - 1)
    pos_ndc = (x, y)

    vec = vec_unproject(
        pos_ndc, camera.camera_matrix
    )

    x = vec[0] + x
    y = vec[1] + y

    pos_world = vec_transform((x, y, 0), camera.view_matrix)
clicks-2023-05-22_02.21.07.mp4

@almarklein
Copy link
Member

You'd have to use the camera.camera_matrix in both cases. I think it'd be something like (untested):

abs_pos_ndc = vec_transform(camera.world.position, camera.camera_matrix) + pos_ndc
pos_world = vec_unproject(abs_pos_ndc, camera.camera_matrix)

@kushalkolar
Copy link
Contributor Author

That almost does it, thanks! Ready for a look again. I think a click exampe for perspective projections can be separate since that's a bit more involved.

@Korijn Korijn merged commit c3e6f85 into pygfx:main May 24, 2023
@Korijn
Copy link
Collaborator

Korijn commented May 24, 2023

Thanks again!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants