screentoworld and worldtoscreen messages

pseudostereo's icon

I had assumed that the messages 'screentoworld' and 'worldtoscreen' to jit.world (and jit.gl.render) would translate between xy pixel coordinates and the xyz position in world space that corresponds to those coordinates. To do this correctly, the conversion would obviously have to take into account the current camera position, scale and rotation, since these change the relationship between the world and the screen. Unfortunately, this isn't what seems to be happening.

The 'screentoworld' and 'worldtoscreen' messages work as long as settings for jit.world (or jit.gl.render) (and jit.gl.camera) are left at the defaults for position, rotation, scale (as well as camera position, rotation and lens angle). As soon as any of these parameters are changed, the relationship between screen and world coordinates breaks down. What you actually seem to get is simply a conversion between 2D screen coordinates and the (also 2D) xy plane (which is parallel to the screen).

Example attached. First drag the square around on the screen; it matches the mouse position. Then change any of the world or camera parameters and see what happens. The square stays glued to the xz (blue) plane.

Am I missing something? Is there some other way to determine the correlation between screen and world coordinates?

Max Patch
Copy patch and select New From Clipboard in Max.

Greg Finger's icon

since the xyz axes are glued to their absolute positions, you're gonna have to do some conversions based on how you've changed the jit.world's position/rotation/scale.

for example if you rotated the world on the Y-axis by 90 degrees (spun the world to the right by 90 degrees and now see the green plane), the y-axis will still be the y-axis, but visually the x-axis will actually be the z-axis. So you'll want your mouse's Y position to still be mapped to the world's/object's Y position, but your mouse's X position needs to be mapped to the Z position. So this is pretty easy to mend, just unpack the 3 digit-float screentoworld list that comes out of jit.world, and patch it back into a 3 float pack, but route the first outlet (x) of the unpack into the third inlet (z) of the pack and the third outlet (z) into the first inlet (x). the second outlet (y) still goes into the second inlet (y). This should give you an idea of what's going on.

However, this example doesn't solve anything except for when you jit.world is exactly rotated those 90 degrees on the Y-axis. You can guess it gets pretty tricky when you got non-right-angle rotations or any changes to the position or scale.

I'd honestly find another way to control the cube's position. Companies do make a special mouse for 3D modeling software. Perhaps you can use that and the [hi] object to get data from it to control the cube's position.

I'm going to subscribe to this thread because maybe someone has an interesting solution. cheers.

Rob Ramirez's icon

this is another result of the internal structure of jit.world.

simply give a @drawto arg to jit.world, and add the jit.gl.camera to that context:

Max Patch
Copy patch and select New From Clipboard in Max.

pseudostereo's icon

Brilliant! Thanks Rob. I've been trying to sort this out for some time, specifically to determine whether something is currently visible onscreen (that is, inside the camera frustum). And this works beautifully for that purpose, at least for finding out whether the center of the object is within the screen boundaries - I'm not sure how to take into account the bounding box of the object, so if anyone has any hints on that I'd appreciate it.

Here's an example patch.

Max Patch
Copy patch and select New From Clipboard in Max.

pseudostereo's icon

OK, I worked out the bounding box thing - might not be the most efficient, but it's accurate (as long as the object scale is the same in all dimensions). I'm testing against the 8 corners and the center - so as long as at least one of them is onscreen, the object registers as onscreen (of course if the object is large enough or close enough, it could fill the screen even though all the corners & center are offscreen, in which case the test fails).

Max Patch
Copy patch and select New From Clipboard in Max.

Greg Finger's icon

What's the purpose of the [jit.anim.node @tripod 1]? It throws off the [jit.anim.drive] and how you'd expect to navigate the world with the keyboard/mouse. Just piqued my interest my bit as something i don't understand.

also i there anyway to incorporate the idlemouse position into the jit.anim.drive/navigation? seems it'd be more fluid in terms of changing the view's rotation instead of having to click+hold+drag the mouse everytime.

Rob Ramirez's icon

depends on how you expect to navigate, hence the option. it keeps the object's Y axis aligned with the world Y axis, as if the camera was mounted on a tripod rolling around on a dolly. if disabled the movement is more like a flight simulator.

you probably also want to set @move_mode to local on the jit.anim.node. this mimics the behavior of an anim.drive connected directly to a jit.gl.camera.

idle mouse can be enabled by editing the anim.drive ui dictionary. double-click on the anim.drive and change "mouse_down_*" to "mouse_*" see the anim.drive reference for more info.

Greg Finger's icon

cool, editing the drive dictionary worked perfectly (and it was right there in the reference, whoops).

Another question, so when you hit the bounds of the window/viewer, it no longer registers any mouse interaction, because the anim_turn is based on mouse position (& velocity?). So I guess using "pupdate" to reset the mouse position to the center when it hits the window bounds would fix that, except that anim.drive registers that automatic mouse movement and will make the camera tweak out for a little. So i figured send a "automatic 0" to the anim.drive before the pupudate message, and then "automatic 1" afterwards should do the trick, but there's some timing issues, so I had to [pipe] the "automatic 1" message by a bit. I suppose instead of sending the automatic message, i could also quickly change the dictionary entry to make mouse movements "turn 0 0 0", and then reset it back to the default turn values after the pupdate message.

Anyways wondering if you had a better solution. (this guy seems to have it figured out using mousestate (and without anim.drive?), but it'll take me a little bit to breakdown to see what's going on: https://cycling74.com/tools/seldess-glnavigator/ )

TobyAM's icon

Hey Rob, how would you get the correct screentoworld coordinates if you were using a jit.gl.handle on the jit.gl.render to rotate the world?

Rob Ramirez's icon

it may be that this is buggy. my recommendation is to not use jit.gl.handle on a jit.gl.render at all, instead use a jit.gl.node to contain the objects you want to transform.