[Bf-committers] Blender matrix headaches... :)

Ton Roosendaal ton at blender.org
Thu Jul 21 14:07:37 CEST 2005


Hi,

Using our arithb.c code for matrix multiplying is quite painful. During  
the armature recode I really got confused with it all the time, and  
trial and error coding there isn't very succesful. I always end up  
switching the arguments!

The most idiot part of our current API is this:

Mat3MulMat3 is premul, and Mat4MulMat4 is postmul!!!
Mat3MulSerie is postmul, and Mat4MulSerie is premul!!!

As a rule-of-thumb, I just flip args when I switch from 3x3 to 4x4  
matrix calls, but that's really idiot. I also notice weird things in  
the code, where probably entire parts of the code work with transposed  
matrices, just because the args were flipped.

Next to that we have code in Blender trying to make arithb.c into a  
"module", with a MTC_xxx() version of the same calls. Time to get rid  
of this issue once... so here's a proposal for a single arithb.c  
method.

***************** 1) column major ******************

Blender already follows the OpenGL convention. From opengl.org: "OpenGL  
matrices are 16-value arrays with base vectors laid out contiguously in  
memory. The translation components occupy the 13th, 14th, and 15th  
elements of the 16-element matrix."

Or in C: (mat[3][0], mat[3][1], mat[3][2]) is the translation vector.

***************** 2) Post-mul ordering *************

To get this difference clear, you can just look at the translation part  
of a matrix.

Suppose you have two 4x4 matrices:
"RotY" (rotate some degrees in Y axis)
"TransZ" (translate some units in Z axis)

M = RotY * TransZ
Delivers a matrix M which first rotates, then translates. The  
translation of M is identical to TransZ.

M = TransZ * RotY
Delivers a matrix M which translates first, then rotates. The  
translation of M is a rotated version of TransZ.

We'll call the last argument in above equations as being "post  
multiplied", and will stick in the API to that convention. Again, this  
follows OpenGL.

*************** 3) Notation *******************

With math being common in C code, and not module specific, I like to  
propose a minimalistic notation. The assumptions for the notation are:

- it's only operating on floats
- functions have as a first argument always the 'target', where result  
is written.
- functions allow the target argument to be used as 'source' too.
- first part of the function-name defines the operation, like:
   mul, inv, cpy
- second part describes the target and third part the sources, using  
notation like:
   m3 is matrix[3][3]
   m4 is matrix[4][4]
   v3 is vector[3]
   v4 is vector[4]


Matrix multiply examples:

	/* target = mat1 x mat2 */
	void mul_m3_m3m3 (float target[][3], float mat1[][3], float mat2[][3])
	void mul_m4_m4m4 (float target[][4], float mat1[][4], float mat2[][4])

Which will also allow premul or postmul operations on itself:

	mul_m4_m4m4 (viewmat, viewmat, obmat);

Vector example:

	void mul_v3_v3m4 (float *target, float *vec, float mat[][4])

Invert example:

	void inv_m4_m4 (float target[][4], float mat[][4])


And with a lot of variants like:

mul_m3_m3m4()
mul_m3_m4m3()
mul_m3_m4m4()

mul_m4_m3m3()
mul_m4_m3m4()
mul_m4_m4m3()

mul_v3_v3m3()
mul_v4_v4m4()

*************** Migration path *******************

I'd like to do my work in three steps.

1) Add the code to arithb.c. Use and test the new API with code I work  
on now anyway (armature, pose, etc)
2) Cleanup of arithb.c! Remove the MTC_xxxx convention
3) design conforming notation for the other calls (matToEul, QuatMul,  
etc)

The last step could be:

4) Actual migration/replacement of all calls (zr offered scripting  
help!)

But there's risk involved... doing it for the entire codebase in one go  
would leave huge parts badly tested, and might give surpises later on.  
Maybe this script can be posted here, and we do it on a per case basis.  
:)

-Ton-


------------------------------------------------------------------------ 
--
Ton Roosendaal  Blender Foundation ton at blender.org  
http://www.blender.org



More information about the Bf-committers mailing list