Using Res<Events<CursorMoved>>
I can get the mouse position change in screen space coordinates (zero in bottom-left corner), e.g.
#[derive(Default)]
struct State {
cursor_moved_reader: EventReader<CursorMoved>,
}
fn set_mouse_pos(mut state: ResMut<State>, cursor_moved: Res<Events<CursorMoved>>) {
for event in state.cursor_moved_reader.iter(&cursor_moved) {
println!("cursor: {:?}", event.position);
}
}
The question now is if I set SpriteComponents
' transform.translation
to the cursor position when using a camera from Camera2dComponents::default()
a sprite with position 0, 0
is rendered in the center of the screen. What's the idiomatic way of converting between the screen space mouse coords and the camera world space coords?
Normalized device space is Cartesian coordinates system. Hency, if you want to transform from normalized device space to view space, you need to transform through the inverse projection matrix and divide the x, y, and z components through the w component. Since you are using GLM, I recommend using glm::unProject for the transformation.
Clip space is a Homogeneous coordinate system. In order to transform from the clip space to normalized device space, you must do a Perspective divide. Normalized device space is Cartesian coordinates system.
If you need the world coordinates of all vertices, it's more efficient to use the transform () method: It will apply the transformation matrix to the mesh, so multiply the world matrix with all vertex coordinates. You may wonder about the change in orientation of a mesh object in viewport if you do the above.
If you have your coords in a flat numpy.array from foreach_get ("co", coords), the following dot product of the world matrix with the local coordinates will get their their global version:
The previous answer seems to be on the right track, however the transformation is not fully implemented and actually overengineered. Stumbled on the same problem and figured that's what the camera transform is for! This works for me:
fn window_to_world(
position: Vec2,
window: &Window,
camera: &Transform,
) -> Vec3 {
// Center in screen space
let norm = Vec3::new(
position.x - window.width() / 2.,
position.y - window.height() / 2.,
0.,
);
// Apply camera transform
*camera * norm
// Alternatively:
//camera.mul_vec3(norm)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With