Bone/Head Tracking - Blender Game Engine Tutorial

Hi,
I posted this on gameblender.org awhile ago [link], and decided to post it here as well.
Thanks to the GE devs (ideasman42) for making the ability to do this.

This tutorial will show you how to make a bone in your armature track another object in the scene, useful for head tracking.
Here’s the final result;
bone tracking tutorial final.blend(192.46 KB)
This tutorial was made with Blender 2.49b.

I tried to target this tutorial at beginners as well but if I didn’t do a good job please let me know. :slight_smile:

Setup: I provided a simple scene you can download to follow along with the tutorial.
bone tracking tutorial setup.blend(190.98 KB)

Step 1: Add the tracking bone.

I like to work in side view [ numPad-3 ], and orthographic [ numPad-5 ]
http://img215.imageshack.us/img215/9259/sideview3.png
Select the Armature, go into edit mode [tab],
hit [space] than [add bone].
Name the bone “Tracker” hit the [N] key for transform properties.
http://img215.imageshack.us/img215/4521/name2w.png

The bone must be pointing down the +Y axis.

So select the top of the bone and move it down using grab [G] and holding [ctrl] to snap.
http://img215.imageshack.us/img215/2034/yaxis3.png

Step 2: Add a constraint to the head bone.

Now go into pose mode.
http://img137.imageshack.us/img137/9677/posemode.jpg
Select the head bone, and add a “ChildOf” constraint.
Setup the constraint like this.
http://img137.imageshack.us/img137/3171/childof.png
A Copy Rotation constraint also works, but ChildOf works better.

Step 3: Add a dummy action.
In the action editor, add a new action (without any key frames) and name it “dummy”.

Step 4: Add an object to track.
This is already done in the setup file.
I used a cube parented to an empty that continually rotates.

Step 5: Add the python script.
The python script is already included with the setup file and is called: “bone_track.py”
Setup the logic bricks as follows
http://img137.imageshack.us/img137/7203/logicsetup2.png
An always sensor with true pulse enabled.
A python controller with the name of the script.
And an action actuator with the name of the dummy action.

Information on the methods use in the script can be found in the Game Engine Python API
Mathutils
getChannel() setChannel()
getVectTo()
toTrackQuat()

Note:
To mix the dummy action with other actions, the dummy must be above all other action actuators.
http://img137.imageshack.us/img137/3946/dummyontop.png

This is my first tutorial so If there are any problems or inconsistencies, or if you have any suggestions for improvement please let me know.
Maybe the tutorial wasn’t even necessary?

Anyway,
Have fun and I hope this helps someone. :slight_smile:

I’ve been trying to get something like this working for a while. A very useful and easy to follow tutorial. Thanks!

Thanks for sharing :slight_smile:

One thing I should point out with this though is that it doesn’t work if your character’s up axis is variable. (I guess that kind of obvious though).

Good job! What about limiting the rotation, because the head can go all the way around ha ha! I’ll just limit it myself :wink:

Thanks a lot for this!

Hey PhilB I did some rotation limitation… I’m not sure if this is the best way to do it, but it works perfectly!

Look at the .blend and tell me what you think?
Rotation Limit .blend

OR

Rotation Limit .blend

EDIT: Can you make it so it takes some time for it to track to the cube? I don’t know how to do that, I’m just learning how to use the mathsis module… (I don’t even know how to spell it) lol

Hey, that works good Linkxgl!

Here’s an alternate tracking solution that may be better,
It allows for slow tracking, and armature rotation, but it still needs some work : )
bone tracking Slow w Rotation5.blend(409.6 KB)

This uses a separate object to do the tracking using the trackTo actuator,
the trackBone copies the rotation of the object.

Plus the Head-bone is using the “Copy Rotation” constraint instead of “Child Of”.

btw, Matt_Goles posted another solution for bone tracking here.
http://blenderartists.org/forum/showthread.php?t=156872

Attachments

bone tracking Slow w Rotation5.blend (410 KB)

Hey, has anyone gotten this tutorial to work with Blender 2.63?

I opened it up and managed to update the script enough to stop all the error messages that were showing up in the system console, but now the script runs with no errors and the cube that the bones are supposed to track rotate around in a circle, but the bones don’t move.

Can someone help. I am new to blender and python, and I would really like to figure out how to use setChannel with blender 2.63.
I am posting the modified code from the bone tracking tutorial final.blend file linked in the first post below.

Bone tracking final example.

By PhilB

Modified by gamerglen

The tutorial is at

http://www.gameblender.org/viewtopic.php?f=44&t=1395

Not to be redistributed without permission.

import bge
from mathutils import *

cont = bge.logic.getCurrentController()
own = cont.owner

scene = bge.logic.getCurrentScene()

trackObj = scene.objects[‘OBCube’]

This is the object the bone will be tracking.

trackBone = “Tracker”

act = cont.actuators[‘dummy_action’]

loc,size,quat = act.getChannel(trackBone)

Gets the location, size and quaternion rotation

from the tracker bone.

align_vector = Vector(own.getVectTo(trackObj)[1])

Returns the global vector from the track object.

align_quat = align_vector.to_track_quat(“Y” , “Z”)

Returns the quaternion rotation from the vector

for setChennel() which excepts quaternion rotation

act.setChannel(trackBone, loc, size, align_quat)

cont.activate(act)

Thanks, gamerglen

I changed the script to Blender 2.59. The Script is also working in Blender 2.6x, but setChannel is buggy and not working since Blender 2.60.
But you don’t need a script to make this working, all you need is a copy rotation constraint on the bone and a run armature actuator.

bone tracking Slow w Rotation 2.59.blend (521 KB)
bone tracking Slow w Rotation 2.63a.blend (603 KB)

Thanks for the reply HG1.

I was able to run the 2.63a.blend, and it did what I was expecting, but it does not use a python controller. However, I was not able to get the 2.59.blend to run as I expected, and it has a python controller. Do I need to install blender 2.59 for the 2.59 blend to work properly? Do both of these blend files work for you? Does setChannel not work for Blender 2.63a?

http://projects.blender.org/tracker/index.php?func=detail&aid=28843&group_id=9&atid=306

Do I need to install blender 2.59 for the 2.59 blend to work properly?

Yes. I have written in the previous post why.

Maybe i can replace the setChannel method with the new BL_ArmatureChannel

Edit:
Here i changed the script to use the new BL_ArmatureChannel.
bone tracking Slow w Rotation 2.63a Script.blend (600 KB)

This works for arms too in the blender game engine keying the influence of a ik bone constraint.

can be useful?


from mathutils import Matrix, Vector, Quaternion
class Armature:
    def alignBoneToMatrix(arm, bone, m3, fac=1.0) :
        """ 
        armature                      [obj], 
        bone                          [str], 
        orientation to copy from      [matrix 3x3], 
        fac(from 0.0 to 1.0)     [float],
        """
        b = arm.channels[bone]
        bWQ = arm.worldOrientation.to_quaternion() * b.pose_matrix.to_quaternion()
        qDif = bWQ.rotation_difference(m3.to_quaternion())
        q1 = Quaternion(b.rotation_quaternion)
        q2 = q1 * qDif
        if fac == 1.0 :
            b.rotation_quaternion = q2
        else :
            q3 = q1.slerp(q2, fac)
            b.rotation_quaternion = q3







example usage:

arm = cont.owner # armature
cube = sce.objects[“Cube”]
Armature.alignAxisToMatrix(arm, “Bone”, cube.worldOrientation, 0.1)

bit redundant?

^
Does that include limits? So the player can’t spin its head 360 degrees?

edit:

this just limit the rotation , to put AFTER some function to align the bone
(in fact the bone here update immediately so is possible using 2 function different fortunately)


from mathutils import Matrix, Quaternion, Euler

def limitBoneRotation(arm,bone,limits):
    b = arm.channels[bone]
    q = Quaternion( b.rotation_quaternion )
    x, y, z = q.to_euler()
    xx, yy, zz = limits
    x = min(max(-xx, x), xx)
    y = min(max(-yy, y), yy)
    z = min(max(-zz, z), zz)
    q = Euler((x,y,z)).to_quaternion()
    b.rotation_quaternion = q

example usage :

arm = cont.owner
limitBoneRotation(arm, “Bone”, [0.5, 0.0, 0.5])

to avoid this you have to go in BONE SPACE (not armature spaces)
and make the to_track_quat() from there.