"Blender Matrix Object"

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

thanks

reed

Hi,

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]]

If you do a:


import Blender

obj = Blender.Object.GetSelected()
print obj[0].getMatrix()

You should see what the matrix object looks like. Note that I haven’t tested the above code fragment, but it should give you an impression :slight_smile:

With regards,
Michel

since i have been working with the blender matrix i have found a couple of things

first off there are 4 set numbersand the three locations:

[X,X,X,0.0]
[X,X,X,0.0]
[X,X,X,0.0]
[LocX,LocY,LocZ,0.0]

the nine X’s make up the rotation matrix which i’m currently working on getting an idea of what goes where.

MacBlender

Two things:

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?-)

~Toni

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]

here ya go everyone, the blender matrix cracked.

[[cos(Y)*cos(Z), cos(Y)*sin(Z), -sin(Y), 0.0]
[sin(X)*sin(Y)*cos(Z)-cos(X)*sin(Z), sin(X)*sin(Y)*sin(Z)-cos(X)*cos(Z), cos(Y)*sin(X), 0.0]
[cos(X)*sin(Y)*cos(Z)-sin(X)*sin(Z), cos(X)*sin(Y)*sin(Z)-sin(X)*cos(Z), cos(Y)*cos(X), 0.0]
[LocX, LocY, LocZ, 1.0]]

trust me it works but don’t ask me to tell you how to get XYZ because i’m still workign on it

XYZ are the global Euler rotation angles.

Martin

i know that

it just wadign through all that trig thats the problem

It’s actually a lot easier to understand if you put it this way.

The 3x3 matrix represent the position of the X, Y and Z axis after going through the same transformations (rotation and scaling) as the object.

Martin

ok here it is, after 4 hours of trig equations and sleeping through 3.5 of it :smiley:

Euler Rotation from the Object.getMatrix() command:


X = atan(Matrix[1][2]/Matrix[2][2])
Y = -asin(Matrix[0][2])
Z = atan(Matrix[0][1]/Matrix[0][0])


make sure to remember that Object.getEuler() and Object.setEuler(x,y,z) don’t seem to work but i’m sure that the guys makign 2.29 are fixing that.

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.

Martin

hey i never said that they were perfect just that they work

Have a look at a previous thread I started about the blender matrix.

https://blenderartists.org/forum/viewtopic.php?t=7398

JMS posted a link from his webpages detailing the rotation/scaling matrix.

http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_pythonresizerot.htm

Cheers Stephen