Screen Offset by two Vector3s

Hi there,

Apologies if this is long-winded, I’m still fairly new to this and I’m very stuck.

I’m currently using camera.targetScreenOffset to offset a camera in relation to two points the user has selected in the scene space.

I’ve managed to get the offset working correctly when the user has the camera position towards the x/y plane. However, when the model rotates the offset no longer works as the z-axis comes into play.

The problem I’m stuck with is the camera.targetScreenOffset only needs an x and y value. How do I calculate the screen offset when the z-axis also plays a part in the distance to offset by?

Here’s a playground which I hope shows the problem: https://playground.babylonjs.com/#EBPQH9#35

Your PG does not use targetScreenOffset(?)

targetScreenOffset is used to move the camera in the 2D screen, you can’t have a z coordinate: it’s an offset in the X and Y screen coordinate space.

Oops, looks like I added the wrong PG @Evgeni_Popov. I’ve updated the PG, I’m stuck with the panning issue. Trying to create a custom panning function that offsets the model on a pixel by pixel basis. So the pointer sticks to the model or world space when they pan. The default panning is not accurate enough. Maybe I have the wrong approach. Thanks for any help you can give :slight_smile:

https://playground.babylonjs.com/#EBPQH9#35

Your code is working great, I only have to bind it to the right mouse button, it seems the middle button is adding some weird effect…

Thanks, @Evgeni_Popov, yeap the scroll pointer behaviour is the problem I’m trying to solve. I appreciate you having a look. The right-click panning is good but doesn’t provide a pixel to pixel panning offset I’m trying to solve. I’ve got the panning working when the camera is directly on the x/y plane. But when you rotate the model it goes crazy. Not sure the best approach to take

Ah yes, did not see that…

I don’t know why it’s doing that, maybe someone will know more.

1 Like

I think this is what you want? https://playground.babylonjs.com/#EBPQH9#36

Thank you for your reply @bghgary, that’s very close to what I’m trying to get to! I appreciate your response. I used your approach the first time around using a hard-coded scale factor but it still has an unwanted offset as you pan.

Somehow I need to find the correct scale factor to maintain a pixel for pixel pan no matter where in the space the user clicks or has zoomed. Ideally, the pointer needs to stick like glue in the space. So everything pans to the exact measurement the pointer moves. I’m not sure how to get the panning to that granularity.

Appreciate any further help or guidance you might be able to give :slight_smile:

Fixed the problem! For anyone in future looking for the same fix, you need to take the canvas width and height into consideration. Then use the camera ortho left/right and top/bottom values with the canvas values to get the screen ortho scale factor.

Here’s a playground: https://playground.babylonjs.com/#EBPQH9#43

Big thanks to @bghgary and @Evgeni_Popov for both of your help/direction.

2 Likes

Awesome! If you feel inclined, I think it would be great if we can add a mode to the camera’s panning to use this behavior in a PR. :slight_smile:

Hi @jcoop, @bghgary and all !
thank you all for the great PG you’ve come up with.

Would you know a way to project a distance vector (in world space) to the corresponding targetScreenOffset ?

Let’s say I have some meshes in my scene.
And I want to switch my arcRotate camera’s target from one mesh to another when clicking on it but without having that targeted mesh centered on my screen (which is the default behaviour of that camera right ?). I want the scene to look exactly the same, just the center of rotation of my camera to be different.

You can try it here : https://playground.babylonjs.com/#V181I2#34

I thought I would compute the distance between two successive camera targets and convert that into an offset for my camera’s targetScreenOffset property. But I can’t find the right way to do that. Would you ?
Or do you know of a better way to achieve what I’m looking for ?

Thank you for your help !