[Disregard] Note for worldToLocal()

I’m placing this note here for any future people that might find the worldToLocal() method behaving strangly. And that node is:
Scaling a node with i.e. scale() will affect worldToLocal() so it no longer works as it should for subnodes as the units are scaled across all of them. It appears the situation is a lot weirder than previously thought.
It appears that I am merely a dumbass.

I was trying to get it to work for two days and it wouldn’t give the right coord no matter what I freaking did, like everything I knew about geometry was a lie and it drove me insane. :confounded:

Then I randomly realised I had scaled a parent node a while ago and that was the problem. In case this happens to anyone else I’d like to spare them the trouble, thus the note.

2 Likes

You’ll need to show a specific example as it should work fine as long as you don’t do non-uniform scaling. Non-uniform scaling doesn’t really work in JME.

Hmm, funny enough when I tried to reproduce it in a mcve it worked exactly as It should (first time I saw it work this well) no matter how many nodes I layered it in with translations, rotations and scaling.
(the Arrow is set up to lookAt the local point)


However if I only use spatial.worldToLocal(target.getWorldTranslation()) in my game it comes up completely wrong:

So a while ago I came up with this additional code that fixes it for my game since I presumed that worldToLocal ignored rotations and I had to do that myself (this is what the scale was actually throwing off):

spatial.getWorldRotation().mult(spatial.worldToLocal(target.getWorldTranslation().add(spatial.getWorldTranslation()),new Vector3f()));

But if I try to use it in the mcve it comes up completely wrong:


I have absolutely no idea whatsoever how this is even remotely possible. I don’t even use any scaling on nodes anymore anywhere at all(in the game). What could I have messed up so badly…

Hard to say without a test case the illustrates the issue. Especially since you’ve only really shown examples of translation but your pictures are showing something where (I think) the error is that something is pointing in the wrong direction… which would require doing something with rotation also?

A more concise example would go a long way.

Well the rotation is the end result I need, there’s always some node that needs to allign z to a world point, but for that I need to pass the correct point to the lookAt method. So I really just need to get to the point (hah!) and that was only a way I chose to visualise it.

Well that’s the main problem. I can’t seem to reproduce it anywhere except in my gazillion class project where it resides and something obscure appears to be causing it so I don’t even know what to look for. If I could narrow it down I’d fix it already. :stuck_out_tongue:

I’ll try to get the list of everything that is a parent of the node in question and try to reproduce it again I guess, but if you guys get any hunches I’d very much like to hear them.
Then again this problem doesn’t really affect anything atm since I’ve made workarounds for it, but I do have a feeling that this will come and bit me in the ass later on if I don’t fix it now. Perhaps that time I’ll finally realise what the hell is going on…

I finally got it into a short example: http://pastebin.com/Q9Uj7QW6 (Jme 3.0). It appears that the problem is very local. If one uses lookAt on a Geometry as I did when testing then its pretty much guaranteed to work, but the problem occurs when you have a Geometry aligned inside a Node and then try to make the Node lookAt a point the results will be…weird.

As I usually have a Node that contains a few geometetries (like a gun, a laserbeam, a particleemitter, etc.) the Node must rotate itself instead of all the children seperatly so this is essential to an increasingly large amount of things.
My previous solution still works, but I’d be very much interested in an explanation if there is one.

That’s because you are having pivot look at something in its own local space… but it exists in its parent’s local space and that’s really where you want to be looking for rotation.

Try calling the lookAt(oops) getWorldToLocal method from container. It gives me the same results.

This:

//should work but doesn't        
pivot.lookAt(pivot.worldToLocal(tgt.getWorldTranslation(), new Vector3f()), Vector3f.UNIT_Y);

Is like trying to look at your own ear. “Turn pivot to face its own ear.”

pivot.lookAt(pivot.getParent().worldToLocal(tgt.getWorldTranslation(), new Vector3f()), Vector3f.UNIT_Y);

Yep, that doesn’t work, the container is the parent :unamused: . (And was what I meant, typo)

Doesn’t work how?

lookAt() will rotate a spatial to face something in its own parent’s space. Not it’s local space… because that would be like trying to look at your own ear. You’ll twist your head off trying to do that. In other words, if you make five calls repeatedly, and you have the right calls, then you should get the same answer every time for the same inputs. Your original code would give you a different answer every time because the point you’d try to look at was always changing.

Actually, it seems that lookAt() is already written to look at things in world space… so remove the worldToLocal.

WaitWhat.

Well.

Fuck.

I wasted about 2 weeks of my life overall on somehow missing this.

According to the javadoc… and according to the source code. I just happened to look at both just now… it’s easy. You can too. :wink:

And am doing so a lot recently too, due to the javadocs being mostly useless in descriptions.

Your “mostly” mileage may vary. I’ve found the JME javadocs to be “mostly” excellent.

In this case they are crystal clear:

lookAt is a convenience method for auto-setting the local
rotation based on a position in world space and an up vector. It computes the rotation
to transform the z-axis to point onto ‘position’ and the y-axis to ‘up’.
Unlike Quaternion.lookAt(com.jme3.math.Vector3f, com.jme3.math.Vector3f)
this method takes a world position to look at and not a relative direction.

Note : 28/01/2013 this method has been fixed as it was not taking into account the parent rotation.
This was resulting in improper rotation when the spatial had rotated parent nodes.
This method is intended to work in world space, so no matter what parent graph the
spatial has, it will look at the given position in world space.

If you find missing javadoc, pull requests are welcome.

1 Like

I remember reading this some time ago, and I kind of only remembered the line about quaternions and I think I was actually using some spatial.getLocalRotation().lookAt()s, but then it somehow all got messed up in my head.

Don’t mind if I do.