[SOLVED] Match camera rotation to object’s rotation?

Hi all, this should be simple but I’ve wasted hours trying with no success, so I"m putting it out to the brains trust…



I want to be able to set my SimpleApplication’s camera’s rotation to match the rotation of an object in Blender. (I’m not exporting the blender object into my scene - I am exporting the rotation angles to a text file which I’m reading.)



I have tried all permutations of using AngleAxis, Angles, Quaternion, taking into account Blender’s swapping of axes, and also remembering to convert to DEG_TO_RAD… but to no avail!



My final test was to actually import the object into my scene, and use the following code to set the camera’s rotation to match it:

[java]

main.getCamera().setRotation(rootNode.getChild(“testObject”).getLocalRotation());[/java]



But my camera STILL doesn’t point in the same direction as the testObject.



What am I missing???



Thanks in advance for any help.

What you want to do is set the direction of the camera in the same direction as your spatial: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:math_for_dummies

Basically cam.lookAt(spatial.getWorldRotation().multLocal(Vector3f.UNIT_Z.clone()), spatial.getWorldRotation().multLocal(Vector3f.UNIT_Y.clone()));

Okay, thanks. I see the principle, but now my Blender scene has become corrupted with “bad meshes” (God knows why… I didn’t change a bloody thing!!) and now I can’t import any more. I’m tired and I’m going to bed, so I’ll let you know how it went tomorrow haha.



:expressionless:

Right… 2 days later I finally got it working.



Normen, thanks for your help, but your example didn’t work for me (was still off by a tilt of 90degrees - even after much fiddling), and while I think I understand the principle of the “lookAt(angle, up)” method, I have to confess I don’t understand…

  • why lookAt () would be any more effective than simply copying the rotation quaternion of an object directly (as the CameraControl does with the following code: cam.setRotation(spatial.getWorldRotation());
  • why multiplying the rotation quaternion by the UNIT_Z and UNIT_Y vectors generates the direction and up vectors (I just can’t picture how this works in my mind)
  • whether, in your example, I should have applied .clone() to the “getWorldRotation()” calls to prevent them from accumulating on the original object’s rotation.



    However… this is not another sob story, but a tale of success!!



    I managed to achieve my original aim of setting the JME3 camera’s rotation to match a numeric description exported from Blender by script using the following means (for the benefit of others who want to do the same thing)…



    Problems:
  • Blender’s z&y axes are transposed, and the y is negative.
  • Blender’s camera views down the -Y axis (whereas I gather JME’s doesn’t)



    Solution:
  1. Set Blender object’s rotation mode to “Quaternion”.
  2. Convert Blender’s W, X, Y, Z to a JME Quaternion(X, Z, -Y, W);
  3. Multiply the result by Quaternion().fromAngles(90FastMath.DEG_TO_RAD,180FastMath.DEG_TO_RAD,0) to account for the different view axis.
  4. That’s it!



    Thanks again, and sorry for bitching about the “attitude” in that other thread - I’m a lot happier now haha.



    :slight_smile:
  1. Because you do not cope with issues like gimbal lock or euler angles
  2. Like explained in math for dummies, a Quaternion is a relative rotation. For spatials this relative rotation is defined from z-forward/y-up. So by multiplying the quaternion of the spatial rotation with UNIT_Z you get the direction vector.
  3. If you perform a mathematical operation like add or substract or mult then you also get a new copy for the result.

At the risk of pressing this too far…

1) Because you do not cope with issues like gimbal lock or euler angles

But surely if you're just setting a rotation with setRotation(), as opposed to rotating BY a set of angles, then the rotation is absolute (or, relative to no rotation), and gimbal lock is not an issue? If that's not right, then I seriously have to re-evaluate what I've taken from the Maths for Dummies.

2) Like explained in math for dummies, a Quaternion is a relative rotation. For spatials this relative rotation is defined from z-forward/y-up. So by multiplying the quaternion of the spatial rotation with UNIT_Z you get the direction vector.

Okay. Had to re-re-read it, but I get it: rotating a quaternion by a vector yields a vector. Better to think of it as rotating the vector by the quaternion? Fine.

3) If you perform a mathematical operation like add or substract or mult then you also get a new copy for the result.

Yeah, but doesn't multLocal also apply the result to the object on which the method's called?
  1. Nope, its euler angles. No absolute >360° rotations.
  2. Yeah, thats why we made a tutorial, its not like this stuff is intuitively mastered.
  3. Yeah it does, but mult doesn’t. With that knowledge you can make your methods w/o having to clone()

Ok, so what does multiplying a Quaternion by a Scalar achieve? (not in Maths for Dummies unless I’ve missed it, and hours of Googling yields only formulas to do so, but not its purpose)



I’d have hoped it would be a multiplication of the angle around the same axis, but apparently not.



Trying to achieve: Rotate by fraction of a Quaternion*tpf.

Use Quaternion.slerp(). Check the methods and their javadoc, its helpful…

1 Like

Of course! I already knew that, d’oh! Honestly - I can feel my IQ decreasing every time I go near 3D rotation. :expressionless:



So, just out of interest, what is Scalar multiplication used for then?

@jonmonkey said:
So, just out of interest, what is Scalar multiplication used for then?

It has no signification for a Quaternion afaik (maybe i'm wrong).
But the quaternion class has the method because it was used has a vector4 in some parts of the engine until we made the Vector4f class.
1 Like

Excellent, I can ignore it completely then! :slight_smile:



Thanks Nehon & Normen…