This post is about using matrix functions in Houdini Python & VEX with examples. It is essential to know matrix especially when working on KineFX tools.
Matrix
The most important thing to note: Houdini's matrices are in row-major format!
VEX, python and UT_DMatrix4 (HDK) all store matrices in row-major format.
Vectors that are multiplied with matrices are treated as row vectors!
Example, p*M1*M2 means p is transformed by matrix M1 first, then transformed by M2.
If trying to use column-major format matrices to transform p (say, A*B*C) in Houdini, it needs to be p*C'*B'*A'. Note: C' is the transpose matrix of C.
hou.Matrix4 are typically used to represent a 3D transformation.
Translation Matrix
| 1 0 0 0 |
| 0 1 0 0 |
| 0 0 1 0 |
| tx ty tz 1 |
Rotation Matrix
rx | 1 0 0 |
| 0 cos sin |
| 0 -sin cos |
ry | cos 0 -sin |
| 0 1 0 |
| sin 0 cos |
rz | cos sin 0 |
| -sin cos 0 |
| 0 0 1 |
Scaling Matrix
| sx 0 0 0 |
| 0 sy 0 0 |
| 0 0 sz 0 |
| 0 0 0 1 |
When a matrix multiply the inverse of the matrix, it equals to an identity matrix.
When AB=BA=I, B is the inverse of A.
A & B are matrices, I is an identity matrix.
B = A.inverted()
Very useful for matrix calculations, for example, becasue p*M = pp, then M = p.inverted() * pp
Points (p)
In HOM (Houdini Object Model), use hou.Vector3 or hou.Vector4 ( with 4th component == 1).
To tranform a point, do p * m.
Vectors (v)
Here, a vector is a direction with a length but no fixed location in space.
In HOM, use hou.Vector4 ( with 4th component == 0).
Not recommended to represent Vectors by hou.Vector3 because when multiplied by a matrix4 they will be converted to hou.Vector4 with 4th component set to 1.0.
To transform a vector, do v * m.
Normals (n)
In HOM, use hou.Vector4 ( with 4th component == 0).
To transform a normal, do n * m.inverted().transposed().
For handling all situations including non-uniform scaling.
Object Node Transform
An object's final transform is defined by
final_transform = local_transform * pre_transform * parent_transform
Get world transform of an object node
world_transform = obj_node.worldTransform()
Build a translation transform
move_up_xform = hou.hmath.buildTranslate(0,1,0)
Here, it will be moved along +Y axis for 1 unit.
Then we can move up the object directly by modifying its world transform
node.setWorldTransform(world_transform * move_up_xform)
In the parameter pane, the Y translate value is now 1 because the pre-transform is not changed, then the local transform has to change.
KineFX
Geometry (SOP) level rigging tools.
Pre-multiply & Post-multiply in KineFX
(To be updated.)
Examples
To get the transformation matrix from 3 points (say [1,0,0], [0,1,0], and [0,0,1], which can form a 3x3 matrix) and their transformed point values (which also can form a 3x3 matrix). We can use one of the above formulas.
When knowing this P*M = P_prime,
The transform matrix M = P.inverted() * P_prime.
Komentarze