#Zoom orthographic 3d camera

1 messages · Page 1 of 1 (latest)

karmic sky
#

I'm trying to create a system which will allow me to zoom in an out on a orthographic camera (taken from the orthographic bevy example). However, the following query produces 0 results: mut query: Query<(&mut Transform, &mut OrthographicProjection)>. What's the proper way to query for this camera so that I can update the projection scale and camera position? Thanks!

elfin egret
#
fn modify_camera(mut query: Query<(&mut Transform, &mut OrthographicProjection)>) {
    let Some(camera) = query.iter_mut().next() else { return };
    dbg!(camera);
}

I tried this and it works for me, I'm just using the default Camera2dBundle as well, here's the output:

karmic sky
#

It seems like this is the problem. When I switch to Camera2dBundle, the query starts returning results, but then the 3d orthographic rendering breaks.

#

So something seems to be broken with this query when using Camera3dBundle but not with Camera2dBundle

elfin egret
#

camera3dbundle uses perspective projection by default

#
fn setup_camera(mut commands: Commands) {
    commands.spawn(Camera3dBundle {
        projection: Projection::Orthographic(OrthographicProjection::default()),
        ..default()
    });
}

fn modify_camera(mut query: Query<(&mut Transform, &mut Projection)>) {
    let Some(camera) = query.iter_mut().next() else { return };
    dbg!(camera);
}

doing this worked for me, since Projection is the component on Camera3dBundle which wraps OrthoGraphicProjection (or PerspectiveProjection, if you're using that)

#

in vscode, with the bundle you can use go to definition (ctrl+left click) which shows that the bundle has a Projection component

karmic sky
#

Ah, I'll try using Projection in the query! Just waiting for the build now... been getting these spurious errors where LINK.EXE complains about "unresolved external symbol"s and cargo clean has been the only thing to resolve it when it occurs every now and then

karmic sky
#

hm, how do you access the ortographicprojection scale when you have the Projection enum:

#
    Perspective(PerspectiveProjection),
    Orthographic(OrthographicProjection),
}```
?
#

a stalled diff adding zooming to the orthographic example 🙂

#

the pull is also trying to use OrthographicProjection. not sure if the Projection enum is meant to be used in a query...

elfin egret
#
fn setup_camera(mut commands: Commands) {
    commands.spawn(Camera3dBundle {
        projection: Projection::Orthographic(OrthographicProjection::default()),
        ..default()
    });
}

fn modify_camera(mut query: Query<(&mut Transform, &mut Projection)>) {
    let Some(mut camera) = query.iter_mut().next() else { return };
    camera.0.scale.x += 0.1;
    dbg!(camera.0.scale.x);
}

the enum has two values, each value is a 1-element tuple, so you access the projection like this

#

I think 1 element tuple is the right way to describe it technically, it's when you have a type that's SomeType(ExistingType)

karmic sky
#

projection.0 doesn't seem to work in this context. im such a noob with rust, but at least i can see that the scale is in there:

#
[src\main.rs:37] projection = Mut(
    Orthographic(
        OrthographicProjection {
            left: -0.8888889,
            right: 0.8888889,
            bottom: -0.5,
            top: 0.5,
            near: 0.0,
            far: 1000.0,
            window_origin: Center,
            scaling_mode: FixedVertical(
                1.0,
            ),
            scale: 4.0,
        },
    ),
)
elfin egret
#

oh wait my code is accessing the transform, not the projection, I'm not any better with rust either

karmic sky
#

yeah you forgot it's a tuple but i got what you were going for

elfin egret
#
fn modify_camera(mut query: Query<&Projection>) {
    let Some(camera) = query.iter_mut().next() else { return };
    let Projection::Orthographic(orthographic) = camera else { return };
    dbg!(orthographic);
}

I can access the orthographic projection like this, but if I change it to &mut Projection I get an error that I don't know what to do with

grizzled meteor
#

You need to dereference camera since bevy is giving you a Mut<Projection>

#

Try = *camera

grizzled meteor
karmic sky
#

Yeah, I think I understand what you mean, but given a Projection, I've only been able to replace the whole thing, rather than just changing the scale, like so:

            *projection = Projection::Orthographic(OrthographicProjection {
                scale: 14.0,
                scaling_mode: ScalingMode::FixedVertical(1.0),
                ..default()
            });    
#

But it'd be much better to be able to just change the scale, though I can't figure out how to drill down into that Mut<Projection>

#

reading about newtype

#

Ok this also works

#
            match *projection {
                Projection::Orthographic(ref mut ortho) => {
                    ortho.scale += dist;
                },
                _ => (),
            }
#

This also works. Don't know if it can be made any cleaner still

#
if let Projection::Orthographic(ref mut ortho) = *projection {
                ortho.scale += dist;
            }
#

So this does what I was hoping for:

fn player_camera_control(
    kb: Res<Input<KeyCode>>, 
    time: Res<Time>,
    mut cameras: Query<(&mut Transform, &mut Projection)>,    
) {
    if let Some((mut transform, mut projection)) = cameras.iter_mut().next() {
        if let Projection::Orthographic(ref mut ortho) = *projection {
            let dist = 1. * time.delta().as_secs_f32();
            let mut log_scale = ortho.scale.ln();

            if kb.pressed(KeyCode::PageUp) {
                log_scale += dist;
            }
            if kb.pressed(KeyCode::PageDown) {
                log_scale -= dist;
            }

            ortho.scale = log_scale.exp();
        }
    }
}
grizzled meteor
#

Also, another thing to keep in mind is that mutable dereferencing like this triggers change detection (which should be fine here since you’re always mutating). So just be mindful of that if you rely on change detection for that component anywhere

karmic sky
#

The ref mut? I see. Well, ideally this would query for the OrtographicProjection directly, but that query didn't produce any results.