MEL and Python procedure to invert a 4x4 matrix in Maya
MEL & Python script code to compute the inverse of a matrix represented as an array of 16 floats - 04/2023 - #Jumble
Some may ask: "But, why??". To that, I would answer: "Why not?" 💩
proc float[] invertRowMajor(float $m[]) { float $invOut[17]; // Extra element to indicate if the inversion failed or not: $invOut[16] = 1; float $inv[16]; $inv[ 0] = $m[5] * $m[10] * $m[15] - $m[5] * $m[14] * $m[11] - $m[6] * $m[9] * $m[15] + $m[6] * $m[13] * $m[11] + $m[7] * $m[9] * $m[14] - $m[7] * $m[13] * $m[10]; $inv[ 1] = -$m[1] * $m[10] * $m[15] + $m[1] * $m[14] * $m[11] + $m[2] * $m[9] * $m[15] - $m[2] * $m[13] * $m[11] - $m[3] * $m[9] * $m[14] + $m[3] * $m[13] * $m[10]; $inv[ 2] = $m[1] * $m[ 6] * $m[15] - $m[1] * $m[14] * $m[ 7] - $m[2] * $m[5] * $m[15] + $m[2] * $m[13] * $m[ 7] + $m[3] * $m[5] * $m[14] - $m[3] * $m[13] * $m[ 6]; $inv[ 3] = -$m[1] * $m[ 6] * $m[11] + $m[1] * $m[10] * $m[ 7] + $m[2] * $m[5] * $m[11] - $m[2] * $m[ 9] * $m[ 7] - $m[3] * $m[5] * $m[10] + $m[3] * $m[ 9] * $m[ 6]; $inv[ 4] = -$m[4] * $m[10] * $m[15] + $m[4] * $m[14] * $m[11] + $m[6] * $m[8] * $m[15] - $m[6] * $m[12] * $m[11] - $m[7] * $m[8] * $m[14] + $m[7] * $m[12] * $m[10]; $inv[ 5] = $m[0] * $m[10] * $m[15] - $m[0] * $m[14] * $m[11] - $m[2] * $m[8] * $m[15] + $m[2] * $m[12] * $m[11] + $m[3] * $m[8] * $m[14] - $m[3] * $m[12] * $m[10]; $inv[ 6] = -$m[0] * $m[ 6] * $m[15] + $m[0] * $m[14] * $m[ 7] + $m[2] * $m[4] * $m[15] - $m[2] * $m[12] * $m[ 7] - $m[3] * $m[4] * $m[14] + $m[3] * $m[12] * $m[ 6]; $inv[ 7] = $m[0] * $m[ 6] * $m[11] - $m[0] * $m[10] * $m[ 7] - $m[2] * $m[4] * $m[11] + $m[2] * $m[ 8] * $m[ 7] + $m[3] * $m[4] * $m[10] - $m[3] * $m[ 8] * $m[ 6]; $inv[ 8] = $m[4] * $m[ 9] * $m[15] - $m[4] * $m[13] * $m[11] - $m[5] * $m[8] * $m[15] + $m[5] * $m[12] * $m[11] + $m[7] * $m[8] * $m[13] - $m[7] * $m[12] * $m[ 9]; $inv[ 9] = -$m[0] * $m[ 9] * $m[15] + $m[0] * $m[13] * $m[11] + $m[1] * $m[8] * $m[15] - $m[1] * $m[12] * $m[11] - $m[3] * $m[8] * $m[13] + $m[3] * $m[12] * $m[ 9]; $inv[10] = $m[0] * $m[ 5] * $m[15] - $m[0] * $m[13] * $m[ 7] - $m[1] * $m[4] * $m[15] + $m[1] * $m[12] * $m[ 7] + $m[3] * $m[4] * $m[13] - $m[3] * $m[12] * $m[ 5]; $inv[11] = -$m[0] * $m[ 5] * $m[11] + $m[0] * $m[ 9] * $m[ 7] + $m[1] * $m[4] * $m[11] - $m[1] * $m[ 8] * $m[ 7] - $m[3] * $m[4] * $m[ 9] + $m[3] * $m[ 8] * $m[ 5]; $inv[12] = -$m[4] * $m[ 9] * $m[14] + $m[4] * $m[13] * $m[10] + $m[5] * $m[8] * $m[14] - $m[5] * $m[12] * $m[10] - $m[6] * $m[8] * $m[13] + $m[6] * $m[12] * $m[ 9]; $inv[13] = $m[0] * $m[ 9] * $m[14] - $m[0] * $m[13] * $m[10] - $m[1] * $m[8] * $m[14] + $m[1] * $m[12] * $m[10] + $m[2] * $m[8] * $m[13] - $m[2] * $m[12] * $m[ 9]; $inv[14] = -$m[0] * $m[ 5] * $m[14] + $m[0] * $m[13] * $m[ 6] + $m[1] * $m[4] * $m[14] - $m[1] * $m[12] * $m[ 6] - $m[2] * $m[4] * $m[13] + $m[2] * $m[12] * $m[ 5]; $inv[15] = $m[0] * $m[ 5] * $m[10] - $m[0] * $m[ 9] * $m[ 6] - $m[1] * $m[4] * $m[10] + $m[1] * $m[ 8] * $m[ 6] + $m[2] * $m[4] * $m[ 9] - $m[2] * $m[ 8] * $m[ 5]; float $det = $m[0] * $inv[0] + $m[4] * $inv[1] + $m[8] * $inv[2] + $m[12] * $inv[3]; if($det == 0){ $invOut[16] = -1; return $invOut; } $det = 1.0 / $det; for($i = 0; $i < 16; $i++) $invOut[ $i ] = $inv[ $i ] * $det; return $invOut; }
But if we are being serious this is how you use Python in Maya to invert a matrix:
from maya.api.OpenMaya import MMatrix from typing import List def floatToMatrix(floatList : List[float]) -> MMatrix: # convert list of 16 floats to an OpenMaya MMatrix matrix = MMatrix() for i in range(16): matrix[i] = floatList[i] return matrix def matrixToFloatList(matrix : MMatrix) -> List[float] : # converts MMatrix to a list of 16 floats return [matrix[i] for i in range(16)] prebindMatrix : List[float] = cmds.getAttr("%s.bindPreMatrix[%s]" % ("skinCluster25", 0)) print( prebindMatrix ) matInv : MMatrix = floatToMatrix(prebindMatrix).inverse() print( matrixToFloatList(matInv) )
Related:
https://forums.cgsociety.org/t/mel-inverse-matrices/880267
No comments