0
$\begingroup$

So I wanted to adjust a posebone using Python script, and I ran into something wierd:

import bpy

def Twist(mat):
    mat[0][2] = 0
    mat[1][2] = -1 #line5
    mat[2][2] = 0
    mat[3][2] = 0 #line7
    return

matrix = bpy.data.objects.get('Armature').pose.bones['Bone'].matrix

Twist(matrix)

print (matrix)

this is the test bone I used

This small piece of code acts wierd for the test bone I used, since at first it dose nothing; yet, if I siwtch line 5 and line 7, it actually twists the target posebone z axis towards global -y, resulting into a kinda "mirrored" bone. In short, somehow the order of value assignment actually matters, and I wonder why.

Could it be some hidden update mechanics (of class matrix perhaps?) that I don't know that caused this? And how should I properly manipulate posebones if what I did was wrong?

FYI: Here is the .blend file:

$\endgroup$
1
  • $\begingroup$ I've explained how to work with bones and matrices in this LINK $\endgroup$ Commented Aug 15, 2022 at 10:47

2 Answers 2

1
$\begingroup$

I see you want to hack the system! No Blender will not allow you to do this. Blender allows setting up modifications to matrix only if they may set up using loc/rot/scale triples. No shear or twist is allowed. After setting up one number, Blender decompose the matrix to set loc/rot/scale. Sometimes is feasible, sometimes - not, so that you have this results.

$\endgroup$
2
  • $\begingroup$ Oh please forgive me Mr. Blendersystem, I really didn't mean it! I did solve the problem tho, and I posted my solution, but I am still confused about how the system works. Is there a legit way to modify a posebone matrix directly? $\endgroup$
    – Bobo
    Commented Aug 15, 2022 at 10:28
  • $\begingroup$ Blender police recommend you using matrix operators, instead of manually editing them $\endgroup$
    – Crantisz
    Commented Aug 15, 2022 at 10:30
0
$\begingroup$

Even though I still don't have any clue about the root cause, I acutally managed to solve this problem. Here is the code:

import bpy

def Twist(mat):
    if (mat[1][2] - 1.0) < 0.1:
        for i in range(0, 4):
            mat[i][0] *= -1
    mat[0][2] = 0.0
    mat[1][2] = -1.0
    mat[2][2] = 0.0
    mat[3][2] = 0.0
    return

matrix = bpy.data.objects.get('Armature').pose.bones['Bone'].matrix.copy() #add a copy() here so that our "matrix" is free of owner and welcomes changes

Twist(matrix)

print(matrix)

bpy.data.objects.get('Armature').pose.bones['Bone'].matrix = matrix

And here is my best guess: the matrix of a pose bone is bound under some mysterious update mechanics to keep it legit, orthogonal or anything. If I want to take 5 baby steps trying to make one legit matrix into another legit matrix, then Blender says no because I created an illegal posebone matrix during the process. So, what I did was to make a copy of the posebone matrix, do whatever I wanted as long as the final result was legit, and assgin the modified legit matrix copy to the bone. It works~

Update: found a more elegent way:

import bpy
from mathutils import Matrix
from math import pi

mat = bpy.data.objects.get('Armature').pose.bones['Bone'].matrix
mat = mat @ Matrix.Rotation(pi, 4, 'Y') # either rotate posebone around local Y axis
mat = Matrix.Rotation(pi, 4, 'Y') @ mat # or rotate posebone around parent Y axis, pick one
bpy.data.objects.get('Armature').pose.bones['Bone'].matrix = mat
print(mat)

Now I can rotate my posebone however I want, I guess?

P.S. Linear Algebra is really a pain to be reckoned with.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .