I am moving a specific node (a 40x.40y.1z cube) directly in front of the flyby camera, then facing it at the camera - and I have a question about rotating the node using Quaternion.opposite(). I can edit a few screenshots in later if needed, but I think I’m probably not understanding something basic about node rotation - that will hopefully be obvious to someone more 3d-math-savvy than myself.
Here is the code I’m using to get the camera location/direction, create the new node location, then get the rotation quaternion from the camera.
Vector3f location = camera.getLocation();
Vector3f direction = camera.getDirection().normalizeLocal();
final Vector3f snapPoint = location.add( direction.mult( 160 ) );
final Quaternion camRotation = camera.getRotation();
Then the code to move the node and rotate it to face the camera (called from the jme thread).
If I move backward (+z) and/or strafe right/left (+/- x), the translation/rotation makes sense on the moved node and it is lined up properly. As in, the camera is looking at the center of the cube, and cube edges are aligned with the view frustum.
However, if I move through all three dimensions (like backward, up, and to the right) and then move the node, the cube still moves to the snap point and is centered - but is skewed and not aligned with the frustum.
I noticed also if I use just the camRotation instead of camRotation.opposite(), the cube aligns correctly no matter where I move (the result is the camera looking at the back of the node, obviously).
I’m thinking I have to “flip” the quaternion around the axis the camera is looking or something like that?
Excellent, thanks heaps - works like a charm - rotation.mult( flip ).
Unfortunately, now I’m stuck on why it works.
Say I start by looking at the node where it’s initially added to the scene (0x, 0y,-100z). Then I pan straight down with the camera so I’m looking directly at -y and move the node - it still works. The node is technically moving and being rotated around the X axis to face the camera, right?
Quaternion multiplies are cumulative. So in a sense you are saying, first rotate like the camera and then rotate around the current (rotated) y-axis 180 degrees. rotation.mult(flip)
Just in case it wasn’t clear:
new Quaternion().fromAngles(0, FastMath.PI, 0)
…is rotating by PI around the y-axis. PI = 180 degrees.
If you then wanted it to be tipped down a little you could multiply again by:
new Quaternion().fromAngles(FastMath.QUARTER_PI/3, 0, 0)
…which is rotating around the x-axis by 15 degrees.
All taken together the cumulative rotation would be:
-whatever the camera rotation is
-then rotated 180 degrees around the local (rotated) y axis
-then rotated 15 degrees around the local (rotated) x axis
…and so on.
Each time you multiply a new quaternion into the chain, it is relative to all of the rotations up to that point.