Disclaimer: it is night time here and the question might be stupid
My positioning system is placing nodes like myNode.setLocalRotation(rootObj.getFacing().mult(child1Obj.getFacing).mult(...);
so every object stores its own rotation relative to parent’s (this way it seems easier to control angle limits etc). Now, if I have a point that I need my end-object to look at, how to get the very last quaternion to mult? Looks like I can’t use one lookAt() as this will be only the last quaternion in the chain, and will be multiplied many times so resulting rotation will be mess. I don’t want to store hierarchy in nodes, and it seems not a good idea to implement overriding the chain with a single rotation (since it will require at least splitting placement code by different systems). I tried fromAngleAxis, but the problem is the same, how to get right angle… What else… well, I probably could un-rotate them all one-by-one, starting from DIRECTION_Z, and then apply lookAt? Uh… doesn’t seem very elegant way… please point me at some approach, thanks!
Not exactly sure why you are doing what you are doing… but what I think you want is a “change of basis”.
If you want some child to look at a point or direction then you need to transform that world direction into local space. Usually this is a matter of multiplying it by the parent’s inverse rotation first.
ah, yep, so “un-rotate” once… I’ll try to explore further. What am I doing is trying to do tracking with certain rotation limits for each how to name it… joint?
Off the top of my head, it’s something like:
Quaternion worldDir = …
Quaternion parentWorldRotation = …
Quaternion local = parentWorldRotation.inverse().mult(worldDir);
So this means that I have to refer to Node to get world rotation… is this possible to do it in logic without resembling Node, say, on server? Like I do for local rotations by storing just quaternions and operating with them. I know that’s an ancient question where to split logic from visual part… but JME does a lot of neat math stuff, so I want to use what I can
In the case where you need to do a world to local transformation, you are going to have to accumulate the transforms back to the root. There is really no way around that. But just go up each parent and multiply the quaternions together. You don’t really care about translation or anything in this case presuming you’ve already got it down to a direction.
Something like…
Quaternion worldRot = new Quaternion();
for( parent = getParent(start); parent != null; parent = getParent(parent) ) {
worldRot = localRot.mult(worldRot);
}
Note the mult() is flipped local mult world instead of world mult local because we are going up backwards.
Thanks for that, I’ll try it. The world rotations/translations seem to be the right answer (I tried to get them from the Nodes so far - and whoa, all works like a charm). Thanks for the hints!
update:
Doesn’t seem to work with just local rotations… I didn’t change worldDir quat (it’s generated based on Nodes just as before), and I’m now having just one parent with its one quat, but that quat is a local one, so inverting it doesn’t give same result as inverting world one if I take it from Node… unless I’m missing something… and parent is not at origin
Where you are doesn’t change how you are facing.
The only way “local versus world” matters is if local is not the same as world… but you need world. So unless “local is supposed to be the same as world” then your comment doesn’t make sense. And if it is supposed to be the same then it isn’t.
…but at this point I’d have to see code to comment further. I’ve done exactly as you describe many times in different cases.
Looks like my debugging tools were misleading, indeed inverse order works just as well as getting worldrot directly. Thanks!