Blender camera rotation

This has bugged me for months now and I am at a dead end. I am trying to take the Blender camera’s quaternion and import it into JME, making the java ingame camera face the same way.

First off, is there anyone who’s simply done this before and can help? I have been reluctant for a long time to post about this as there are multiple threads with solutions, none of which seem to work for me, importing the .blend directly also will not work so currently I’m working by simply typing values from blender into netbeans.

As far as I can tell the “default” if you like starting positions for the cameras are

So I have been using

quat.fromAngles(FastMath.DEG_TO_RAD*-90, 0, FastMath.DEG_TO_RAD*180);

To correct for this.

As for the axis, I think the blender -jme difference is

x = x
y = z;
z = -y

Despite this I cannot solve it. I have been using Euler angles until recently, working with YZX in blender as JME uses that order, but no matter how I swap X Y and Z values to account for the difference I can’t make it work.

I’ve also tried quats, but to be honest recently I’ve been using trial and error since I know so little about them and if simply swapping values will work for the difference in axis.

This is what has popped up most on the forum to convert the Blender → JME quat, but for me there is no luck, with or without multiplying by my correction quat (I’ve tried multiplying 1 by the other and vice-versa)

new Quaternion(-rot3.getZ(), rot3.getW(), rot3.getX(), -rot3.getY()));

Like I said I’ve been reluctant to ask but can’t achieve something I thought would be simple and I cant carry on without this, so any help would be MUCH appreciated

Quaternions are WAAAAY too magic to be swapping values like that. Unless you can wrap your brain around how to translate 3D imaginary space into a 4D unit sphere and back, it’s probably best not to bother with quaternion values.

If you have the option of a 3x3 matrix then your task will be much easier. I don’t remember if blender shows this or not but it’s really trivially, even visually, to swap a rotation matrix around from one set of coordinate axes to another.

Edit: note that it’s probably also possible to do with euler angles but you will have to keep track of whether the left/right hands are swapped for a particular axis to negate them… even when swapping them around for order. Also, there is an inherent assumption in the 3 euler values of which order is used as the euler angles actually represent three separate rotations. And you’ll get different values depending on which order that you use. So even once you figure out how to flip y for z and which to negate… then you will need to make it three separate quaternions with a fromAngles() for each euler component and then try all 6 combinations (3 * 2 * 1) of ordering.

1 Like

I fighted against the same issue with Xbuf (relatime preview in blender + exporter/importer).

I’ll not be able to search in the code today, but you can take a look to xbuf code (xbuf · GitHub). but camera in xbuf follow a third orientation (from FAQ)

Coordinate system : Right Handled

  • object : Y up, Z forward, X left
  • camera : Y up, Z lookAt direction, X left
1 Like

Thank you both for the replies.

Python was a pain up the ass but I have now got the rotation matrix and successfully used it in JME.

I figured it’s worth posting in case someone else wants it, since it has come up a few times. This code goes in the blender text editor

import bpy
import mathutils

selection_names = bpy.context.selected_objects

print("cams")
for i in selection_names:
            print(i.matrix_world)

This prints a 4x4 matrix with rotation and translation in the final column for every selected object (for me it freezes if I select all with a, so I suggest selecting cameras individually or by type). Individual bits of it can be printed with

print(i.matrix_world[0][1])

And so on, the translation being in [0][3], [1][3] and [2][3]

I copy these from the blender console, paste into a txt, load it and use the “Scanner” object to feed them in (not even slightly worried about performance since its a tool)

 //Position
                    Vector3f pos = new Vector3f();
                    pos.x = (float)in.nextDouble();
                    pos.z = (float)in.nextDouble();
                    pos.y = (float)in.nextDouble();
                    pos.z *=-1f;
                    
                    //Rotation
                    Quaternion bquat = new Quaternion();
                    
                    Matrix3f m = new Matrix3f();
                    Vector3f r1 = new Vector3f((float)in.nextDouble(), (float)in.nextDouble(), (float)in.nextDouble());
                    Vector3f r2 = new Vector3f((float)in.nextDouble(), (float)in.nextDouble(), (float)in.nextDouble());
                    Vector3f r3 = new Vector3f((float)in.nextDouble(), (float)in.nextDouble(), (float)in.nextDouble());
                    
                    m.setRow(0, r1);
                    m.setRow(1, r3);
                    m.setRow(2, r2.negate());
                    
                    bquat.fromRotationMatrix(m);
                    
                    bquat.multLocal(new Quaternion().fromAngles(0, FastMath.DEG_TO_RAD*180f, 0));

The quaternion bquat is the quaternion to set the camera exactly as it is in blender.

(I haven’t overlapped it with an image yet, only tested it with 10 or so camera angles judging by eye)