backIndex

Xelagot action script

Matrix variables and operations

This page contains operations and conditional statements involving Matrix variables, introduced in version 3.416.

Notice that these matrices do not handle perspective transformations, they are meant to cover Scaling, Rotation and Translation. As byproduct of decomposition, Shearing may appear.

The system is as OpenGL, RWX and ActiveWorlds: coords are X to the right (west), Y upwards, Z out of the screen towards you (north). Rotations are right-handed.

All matrices are 4x4, containing rows, the last row representing translations. The last element of the first 3 rows is 0.0, the last element of the 4th row is 1.0.

x1 y1 z1  0
x2 y2 z2  0
x3 y3 z3  0
Tx Ty Tz  1

/m_matR = /m_mat Direct assignment of the contents of a matrix (/m_mat) to a matrix (/m_matR).
MatSet /m_matR /m_mat

assignment using vectors
MatSet /m_matR /v_vec1 /v_vec2 /v_vec3
MatSet /m_matR /v_vec1 /v_vec2 /v_vec3 /v_vec4

assignment using list of space separated elements
MatSet /m_matR <list of elements>
MatSet /m_matR $a
Assigns the elements of a matrix. The first step is to set /m_matR to identity.

The first is similar to the direct assignment.

The assignement using vectors assigns the contents of the first vector to the first row of the matrix (3 elements of the vector and 0.0 for the next element), the second vector to the second row, the third to the third row, and if specified, the 4th vector to the 4th row (in this case, the last element will be 1.0 instead of 0.0). The 4th row is the translation transfomation.

The assignement using the list of space separated elements can contain 9, 12 or 16 elements, either as Numeric variables or literal values. The literal elements can even be set into a string variable ($a).
Nine elements: the inner 3x3 matrix will be filled with these values, i.e. the first 3 elements of 1st, 2nd and 3rd row are modified. This notation can not be used if the matrix contains translations (4th row).
Twelve elements: following the POV practice, every 4th element is omitted from the list, since their specification is not needed.
Sixteen element: following the RWX tradition in Transform and TransformJoint, all 16 elements of the matrix are specified. Notice that the RWX convention is fully compatible with these matrices: the first four element make up the first row, the next four the next row, and so on. Please make sure that the 4th, 8th and 12th elements are 0.0, and that the last element is 1.0.

Note: Using assignments, matrices are 'filled' using external element sources, which can contain errors. There are action script statements to make matrices from scratch, scale them, rotate them, translate them. See the statements below.
recovering data to vectors
MatGet /v_vec1 /v_vec2 /v_vec3 /m_mat
MatGet /v_vec1 /v_vec2 /v_vec3 /v_vec4 /m_mat

recovering data to string
MatGet $a /m_mat
This statement will set the data of the matrix either to 3 or 4 vectors (4 is recommended, translations are in the 4th vector), or set all 16 elements to a string.
MatIdentity /m_matR The matrix is set to the identity matrix. This is the first step to do when you build up a matrix from scratch, like saying 'this matrix does nothing at all'.
MatScale /m_matR %x %y %x Matrix /m_matR gets scaled in the x, y, z axis. If you need a uniform scaling, set the three scaling variables to the same value. This is similar to the RWX Scale command.

Very important for purists: this statement does not scale the elements of the matrix, it applies a scaling transform to it (like it would apply a rotation or a translation).
MatRotate /m_matR %x %y %x %d
MatRotate /m_matR /v_xyz %d
Matrix /m_matR gets rotated around the %x %y %z or /v_xyz vector by %d degrees. This is similar to the RWX Rotate command.

MatTranslate /m_matR %x %y %z
MatTranslate /m_matR /v_vec
Matrix /m_matR gets translated by %x %y %z or /v_xyz vector. This is similar to the RWX Translate command (except that RWX uses decametres, action script uses metres).

MatScaling /m_matR %x %y %x Creates a Scaling matrix from scratch and stores it in /m_matR. If you need a uniform scaling, set the three scaling variables to the same value. This is similar to the RWX Scale command applied after Identity.

MatRotation /m_matR %x %y %x %d
MatRotation /m_matR /v_xyz %d
Creates a Rotation matrix around the %x %y %z or /v_xyz vector by %d degrees from scratch and stores it in /m_matR. This is similar to the RWX Rotate command applied after Identity.

MatTranslation /m_matR %x %y %z
MatTranslation /m_matR /v_vec
Creates a Translation matrix by %x %y %z or /v_xyz vector from scratch and stores it in /m_matR. This is similar to the RWX Translate command (except that RWX uses decametres, action script uses metres) applied after Identity.

MatDeterminant %d /m_mat Calculates the determinant of matrix /m_mat and stores it in %d.
MatInvert /m_matR Attempts to reverse the transformation in matrix /m_matR (i.e. to set the exact opposite transformation). If it fails, it sets the matrix to Identity. It will fail if the determinant is close to zero.
MatMul /m_matR /m_mat1 /m_mat2 Applies transformation /m_mat1, then transformation /m_mat2, and stores the result in /m_matR.
Note: most text books use a transposed notation, corresponding to the column convention: the first transformation is listed last, so that it is written
matR = mat2 . mat1

The Action Script uses the row convention, /m_mat1 is the first transformation applied, then /m_mat2 is applied
matR = mat1 . mat2

Applied to objects in a world, transforms are done from local to world coordinates.

If a vector is involved (it always is in the end, matrices are applied to them), the row convention would express this as
vecR = vec * mat1 * mat2 = vec * matR
or in script syntax:
MatMul /m_matR /m_mat1 /m_mat2
VecTransform /v_vecR /v_vec /m_matR

Examples.

var /m_mat, /v_vec1, /v_vec2, /v_vec3, /v_vec4

# full matrix with 16 elements (OpenGL and RWX style)
MatSet /m_mat 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0 0.0 -0.12 0.13 3.07 1.0
# show matrix
MatGet $a /m_mat
SayConcat $a

# same matrix, constructed with 12 elements (POV style)
MatSet /m_mat 1.0 0.0 0.0  0.0 1.0 0.0  0.0 0.0 1.0  -0.12 0.13 3.07
# show matrix
MatGet $a /m_mat
SayConcat $a

# a matrix with 9 elements can not be constructed if the last row contains a translation
# as in this case, but the translation can be added separately:
MatSet /m_mat 1.0 0.0 0.0  0.0 1.0 0.0  0.0 0.0 1.0
MatTranslate -0.12 0.13 3.07
# show matrix
MatGet $a /m_mat
SayConcat $a

# all these matrices are the same as
MatIdentity /m_mat
MatTranslate -0.12 0.13 3.07
# show matrix using concat
SayConcat /m_mat
# show matrix after splitting it into rows
MatGet /v_vec1 /v_vec2 /v_vec3 /v_vec4 /m_mat
SayConcat /v_vec1 " 0 " /v_vec2 " 0 " /v_vec3 " 0 " /v_vec4 " 1"

An example script using vectors and matrices to build a circle of objects can be found here.



backIndex