The Python API docs for 2.28 mention a “blender matrix object” as the return of Object.getMatrix. Where is the documentation for this? (Did it change at all between 2.27 and 2.28?)
I need to check that I am converting to quaternions correctly
The matrix object should’ve not changed between 2.27 and 2.28. I’ve ported most of the old code for that part over to the new API.
A matrix object is a list of 4 lists of 4 float values: [[x,x,x,x],[x,x,x,x],[x,x,x,x],[x,x,x,x]]
a) I was told on irc (by Ton I think) that the last value should always be 1, dunno the reason though. Hopefully I don’t remember wrong :o
b) The thing that cuts it in the middle can be used for scaling.
So at the moment I’m using it like this:
[[self.scale,0,0,0],
[0,self.scale,0,0],
[0,0,self.scale,0],
[self.xyz[0],self.xyz[1],self.xyz[2],1]]
to be able to position and scale the bone. Oh this is in the game engine using the setChannel command for an Action actuator, so perhaps doesn’t apply here?
I’d also like to know how the rotation works, some sin() cos() should be put in I guess – will try out and/or read some 3d rot. matrix tutorial at some point…
There was also the idea of extending the Python API to support these common operations (scale, rotate) for bones … anyone?-)
OK, well, for now I will assume it’s a standard rotation/translation/scale transform, with axes that match the little legend in the 3D window… see what happens (I was getting some strange diagonal orientations earlier though when I loaded my script’s output into another viewer, but maybe I need to convert to degrees for that viewer.)
Toni-- Here is the code I’m currently testing (but I diddn’t write it)
def matrixToQuaternion(m):
tr = m[0][0] + m[1][1] + m[2][2] + 1
if tr > 0:
s = 0.5 / math.sqrt (tr)
w = 0.25 / s
x = (m[2][1] - m[1][2]) * s
y = (m[0][2] - m[2][0]) * s
z = (m[1][0] - m[0][1]) * s
else:
i = 0
if m[1][1] > m[0][0]: i = 1
if m[2][2] > m[i][i]: i = 2
if i == 0:
s = math.sqrt ((m[0][0] - (mat.m[1][1] + mat.m[2][2])) + 1.0)
x = s * 0.5
if s != 0.0: s = 0.5 / s
y = (m[1][2] + m[1][0]) * s
z = (m[0][2] + m[2][0]) * s
w = (m[1][2] - m[2][1]) * s
elif i == 1:
s = math.sqrt ((m[1][1] - (m[2][2] + m[0][0])) + 1.0)
y = 0.5 * s
if s != 0.0: s = 0.5 / s
x = (m[0][1] + m[1][0]) * s
z = (m[1][2] + m[2][1]) * s
w = (m[0][2] - m[2][0]) * s
elif i == 2:
s = math.sqrt ((m[2][2] - (m[0][0] + m[1][1])) + 1.0)
z = 0.5 * s
if s != 0.0: s = 0.5 / s
x = (m[0][2] + m[2][0]) * s
y = (m[1][2] + m[2][1]) * s
w = (m[0][1] - m[1][0]) * s
square= x*x + y*y + z*z
if square > 0.0: dist = 1.0 / math.sqrt(square)
else: dist = 1
x *= dist;
y *= dist;
z *= dist;
if w > 1: w = w - 2
elif w < -1: w = w + 2
return [x, y, z, w]
That will not work when matrix [0][0] or [2][2] are zero. Those situations are called gimbal locks and solving them invole choosing between some solutions involving 90 degrees rotation that might not always be right.