Vector.angle(other)
There is also the mathutils.Vector.angle
method to calculate the angle between two vectors. (The equiv of the inverse cosine of the normalized dot product)
Alternative driver setup.
Really like the setup in @tetii's answer, particularly passing posebone and using its id data to get the armature object
Instead of passing one variable the pose bone pb
will use a variable mw
the matrix world of the armature object (data path matrix_world
), and another that is the matrix of the pose bone (datapath pose.bones["Bone"].matrix
)
The idea here is to keep the script expression "manageable" by using mw
in place of pb.id_data.matrix_world
and pbm
for pb.matrix
.
Worth noting there is only so far that paths work eg couldn't get the axis pose.bones["Bone"}.matrix.col[2]
to work as a driver variable datapath.
Still the expression is pretty small
(mw @ pbm.col[1]).to_3d().angle((0, 0, 1))
Where (mw @ pbm.col[1])
is the global space Y (down bone) vector, converted to 3d, and finally use angle method to return angle from global Z.
Always Test with a script
Ok have gone out of my way to remove the need for a text script method to contain the expression to the driver expression.
Strongly recommend using a driver namespace method to nut out, debug and test drivers. For complex expressions use a text script.
A handy little trick is passing locals()
to a driver method, it's all the variables with the names you set. Also checking use self gives a way to see what object the driver is on, and finally stick in the datapath.
The expression is
test(self, locals(), "rotation_euler.x")
Script:
import bpy
def test(self, driver_locals, data_path=""):
print(f"DR:{repr(self.id_data)}.{data_path}")
for k, v in driver_locals.items():
print(k, repr(v))
return 0 # often use random() to indicate change
bpy.app.driver_namespace["test"] = test
Output
DR:Evaluated Object 'Cube.001'.rotation_euler.x
mw Matrix(((1.0, 0.0, 0.0, 4.08627986907959),
(0.0, 1.0, 0.0, -2.97157883644104),
(0.0, 0.0, 1.0, 0.36508551239967346),
(0.0, 0.0, 0.0, 1.0)))
pbm Matrix(((0.9408926963806152, -0.33870482444763184, -4.5507988488679985e-08, 0.0),
(-4.5507988488679985e-08, 7.941590496329809e-09, -1.0, 0.0),
(0.33870482444763184, 0.9408926963806152, -7.941590496329809e-09, 0.0),
(0.0, 0.0, 0.0, 1.0)))