Pyrr
Pyrr copied to clipboard
confused about matrix and @ operator in numpy
Hi,
I'm confused about matrix multiplication. I used to use "*" operator to perform my matrix multiplications, coming from a first C++/glm experience. it seems that in python 3.5+, numpy matrix multiplication should use @ operator.
However:
rot_y = pyrr.Matrix44.from_z_rotation(time.perf_counter() * 2)
translate = pyrr.Matrix44.from_translation([0.5,0.5,0])
scale=pyrr.Matrix44.from_scale([0.5,0.5,0.5])
model=scale @ translate @ rot_y # line 1 first rotate, then translate, then scale
model=rot_y * translate * scale # line 2 first rotate, then translate, then scale
model=rot_y @ translate @ scale # line 3 first scale, then translates, then rotates
model=scale * translate * rot_y # line 4 first scale, then translates, then rotates
it seems that "*" is performing matrix multiplication in the "reverse order"? wasn't it supposed to perform element wise multiplication? what is the correct notation?
I used to have perfectly decent results with
projM=pyrr.Matrix44.look_at(eye,target, up)
viewM=pyrr.Matrix44.perspective_projection(fovy, aspect, near, far)
modelM=(whatever)
ModelViewProjection=projM*viewM*modelM
but using the @ operator, i have to reverse the order of matrices to get the same results
ModelViewProjection=modelM@viewM@projM
what is the correct way to proceed? (in shader, obviously, gl_Position=ModelViewProjection*vec4(position, 1.0) )
Looks like the object interface
m1 * m2
expands to
multiply(m2, m1)
which then expands to
np.dot(m2, m1)
I'm not sure what the reasoning for it was, it's obviously inappropriate.
I also found this confusing. Matrix44.from_translation((x, y, z))
returns a matrix, say A. A stores (x, y, z) in A[3, 0:3], which I didn't know at first. I performed A @ another_matrix44
(to transform every column of another_matrix44) as did with numpy array, which leads to the wrong answer. After I read the documentation, I realized that pyrr does this by "*" operator. Simultaneously, I found A[3, 0:3] actually stores translation. So I wrote another_matrix44.transpose() * A
, which is wrong again. It took me a few hours to figure out how to do it right. I didn't fully recognize what I am doing until I cloned and read the source code. Sad story 😥
PRs are welcome