Colliding with ray breaks for some reason

Good day.

I am prototyping on JMonkeyEngine 3 (version 3.2.2-stable), studying it in parallel, and bumped with an issue. Here is a link to the source code.

I have a simple terrain. Initially is was attached to rootNode with default position and rotation. Camera is looking on terrain from the “top”:

camera.setLocation(new Vector3f(0f, 200f, 0f));
camera.lookAt(new Vector3f(0f, 0f, 0f), new Vector3f(0f, 0f, 1f));

Also, I have an analog listener which is literally copy-pasted from here. So I click on the terrain and detect a collision of ray with it.

Everything worked flawlessly, until I decided to turn the whole scene so that z axis direction would be towards the camera instead of y axis. I changed camera location:

camera.setLocation(new Vector3f(0f, 0f, 200f));
camera.lookAt(new Vector3f(0f, 0f, 0f), new Vector3f(0f, 0f, 1f));

…and rotated the terrain:

terrain.rotate(FastMath.HALF_PI, 0, 0);

Visually, the scene looks the same. However, ray doesn’t collide with terrain anymore. I checked the ray’s origin and direction - theoretically it should hit the terrain, yet it doesn’t.

What am I missing?

Can you post the code that does the collision check?

You could also use Lemur, this GUI library has some super useful utilities, like mouse and cursorlisteners you can attach to spatials.

It could be a limitation in the terrain quad stuff. I think it implements its own collision stuff and maybe it isn’t properly inverse transforming the ray.

@remy_vd all the code I referenced in the first comment. Collision check happens here.

Vector3f click3d = camera.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 1f).clone();
            System.out.println(click3d);
            
            Vector3f dir = camera.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).subtractLocal(click3d).normalizeLocal();

z is back to front, swap the 1f and the 0f .

@thetoucher Tried:

        Vector3f click3d = camera.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).clone();
        System.out.println(click3d);
        
        Vector3f dir = camera.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 1f).subtractLocal(click3d).normalizeLocal();
        System.out.println(dir);

Unfortunately, it didn’t help.

sorry, worth a shot.

@pspeed is always right by the way =).

there is some issue, anyway in JME y axis should be up/down with right hand rule.

so its suggested to use y as up, not z.

default terrain height is also only height axis based, so cant do planets with it without trick.

im curious if you just report issue or you need to have it z-up-axis-based (not standard based)

@pspeed, I don’t know… I doubt that the root cause is related to terrain itself. Until terrain is in default position, and camera is looking on it from z+, everything works flawlessly.

I experimented a bit with different camera and terrain positions — most of the time it hadn’t impacted ray collision either. However, setting camera to:

    camera.setLocation(new Vector3f(100f, 100f, 100f));
    camera.lookAt(new Vector3f(0f, 0f, 0f), new Vector3f(0f, 0f, 1f));

…and terrain:

terrain.rotate(FastMath.HALF_PI, 0, 0);

…leads ray collision to be unstable (by clicking on different terrain areas, it might be both hit or miss). Hope it’ll give more clues.

its like not normalized ray direction behaviour, but you have it normalized… odd.

@oxplay2 actually, yes, I was thinking about making z-up-axis-based system. And, well, I am about to refuse from this idea)

==

how about you just dont rotate it ?

@thetoucher

how about you just dont rotate it ?

So, am I got it right that terrain is better be oriented in z direction and rotating it is bad idea? I am not complaining, I am okay with that. Just trying to understand)

Based on what @pspeed said, and what you reported, this sounds like the case to me.

This issue is probably only limited to Terrain, i doubt it would effect any other Spatial.

So, am I got it right that terrain is better be oriented in z direction and rotating it is bad idea? I am not complaining, I am okay with that. Just trying to understand)

there are many topics/articles. (related to y-up axis)

there is one:

We should unhide the code so people can check it themselves… oh, wait… it’s all right there at the top of the forum. :wink:

You guys don’t have to take my word for it. Just look into the TerrainQuad source. I just know that it implements its own “optimized” ray collision and your description makes me think it might not be transforming the ray properly before doing that. It could be wrong.

I will offer this:
I wrote the first Mythruna engine with z up because in the sim world that’s what I was used to and for any sane person used to maps it makes the most sense.

I then spent two years where 5-10% of my time was fixing bugs in MY code related to y-up versus z-up.

…when I rewrote the Mythruna engine, I just relented and went with y up. Life got a lot simpler.

1 Like

to make it even more simply to understand.

we use 2D, we got y-axis as UP.

Why then not y-axis up in 3D? we leave x/y same as in 2D and just add z-axis. y-axis is still up same like in 2D.

its IMO much more logical than z-axis up

When you look at a map do you think of north/south as Z?

For anything dealing with maps, the world, simulations based on maps, etc… Y up is very foreign and strange. Lat/long, UTM, etc… are all in the x,y plane. Elevation is Z.

Many scene graphs are even built this way. World space is z up, view space is y up. And everything works just fine. JME chose differently and so we deal with it… and soooo many things are built this way in JME and hard to work against.

1 Like