I have the pose bone at a location and I would like for it to rotate to face a point enter image description here


Pos1 = Vector(bone.location)
#The point location (local)
Pos2 = Vector(10,10,10)
diff = Pos2 - Pos1
quat = diff.rotation_difference(pos1)
bone.rotation_quaternion = quat

But it doesn't seem to line up



The rotation difference returns how much to rotate from direction to direction. The result needs to be applied to current direction.

Setting the direction absolutely from the rotation difference result will only work for the case when initial value is 0.

By using matrices, will work for whatever rotation type the pose bone has.

Test script. Rotates the context pose bone to point to the head of the pose bone named "Target".

import bpy
from bpy import context
from mathutils import Matrix

rig = context.object
target = rig.pose.bones.get("Target")

pb = context.active_pose_bone

v = target.head - pb.head
bv = pb.tail - pb.head

rd = bv.rotation_difference(v)

M = (
    Matrix.Translation(pb.head) @
    rd.to_matrix().to_4x4() @
pb.matrix = M @ pb.matrix

Emulating the constraint.

Can roll the bone around its Y axis in result above and it will still point to target.

POSE space is one of the more "tricky" spaces since it is defined by the head, tail and roll of each bone as set in edit mode.

To get but one roll result

q = v.to_track_quat('Y', 'Z')

makes a quaternion from vector v that points its $Y$ direction to vector with $X$ axis up.

There is a handy convert_space method available on all objects.

>>> rig
>>> rig.convert_space(
Object.convert_space(pose_bone=None, matrix=((0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)), from_space='WORLD', to_space='WORLD')
Convert (transform) the given matrix from one space to another
  • $\begingroup$ What do mean by get one roll result? Do I need to get the rotational difference between the current quaternion and the roll quaternion? $\endgroup$ Apr 1 at 6:13
  • $\begingroup$ Thank you for your thoughtful answer. People like you are amazing :) $\endgroup$ Apr 19 at 16:52

In Pose Mode select the bone that is supposed to rotate, then in Bone Constraint Properties tab (1) add (2) a Track To (3) constraint. Choose a target (4) - if it's another bone, the target should be the Armature containing it; once you select the Armature, you will be able to specify the Bone (5). You may need to tinker with other properties to orientate the bone properly (particularly the Track Axis and Up properties).


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.