Trying to copy bone rotations to a cube

Hi everybody :),
I am trying to copy bone rotations to a cube through a python script. Because the constraints from the “Object Constraints” panel doesn’t work in the BGE.
I have written a little script, but it doesn’t work. Maybe the syntax is not correct. Or maybe it’s not possible to copy rotations from a bone to an object. The Bone from armature ist animated through an animtion (which is trigged through the actuator logic brick “Action”)

import bge

def main():
    scene = bge.logic.getCurrentScene()

    Cube1 = scene.objects["cube1"]
    RefObject = scene.objects["Armature"].pose.bones["Bone"]

    Cube1.worldOrientation = RefObject.worldOrientation

What do you think ?

You can download my blend file, to see what I mean exactly.
test5.blend (502 KB)

Thanks !

Thank you Guramarx,
your script works !!
Thank you :slight_smile:

Besides it works on blender 2.66 but not on 2.70 :confused:

I 've updated the script to copy also the location of the bone:

import bge

def main():
    scene = bge.logic.getCurrentScene()

    Cube1 = scene.objects["cube1"]
    RefObject = scene.objects["Armature"].channels["Bone"]
    ArmaRefObject = scene.objects["Armature"]

    Cube1.worldOrientation = RefObject.rotation_quaternion
    Cube1.worldPosition = RefObject.location + ArmaRefObject.worldPosition

And it works almost: the only trouble ist that spatial coordinates reference (xyz axis) from the bone don’t match with spatial coordinates reference (xyz axis) from the cube; so that the cube is moving left/right when the bone is going up and down.

Again my updated blend file, if you want to have a quick look
test6.blend (503 KB)

Any idea ?

Thank you ! :slight_smile:

To begin with, I’ve next to no idea how matrices work :no: I’ve yet progress much so I can’t really help you much when it comes to mathematics but try this

import bge

def main():
    scene = bge.logic.getCurrentScene()

    Cube1 = scene.objects["cube1"]
    RefObject = scene.objects["Armature"].channels["Bone"]
    ArmaRefObject = scene.objects["Armature"]
    arm_m4 = ArmaRefObject.worldTransform
    bones_worldTransform = arm_m4 * RefObject.pose_matrix
    
    Cube1.worldOrientation = RefObject.rotation_quaternion 
    Cube1.worldPosition = bones_worldTransform * RefObject.location 

I modified the code based on the ones in the thread I posted earlier, I can’t really tell if I’m doing this correctly or wrongly

Hi Guramarx,
it is better. Thank you for your help. I know much less than you about python scripting so don’t worry :D.

I thought actually that the cube was copying right the movement of the bone, but at least it’s not the case. I have weight parented a mesh to the bone to make bone’s movements visible. And as we can see on this video capture it doesn’t match completly unfortunatly:
[video]https://youtu.be/b7rcrwMDlnc[/video]

The blend file can be download here
test8.blend (529 KB)

So it seems realy not easy to realise :confused:

parent a empty to the bone

use

cube.worldOrientation = empty.worldOrientation

then go have a beer.

@@BluePrintRandom, it works! I tried that method earlier but gave up and was wondering why it didn’t work, and it turns out I was parenting with “object/armature deform” to the bone and that kept everything from working lol, Thanks for the tips

@@sunyx instruction above and parent the empty to the armature with CTRL+P and “Bone” selected, the rest is just changing your code

I match rotation with angV for the rigdoll using the same idea

jackii thought of it first.

just dug this up
https://developer.blender.org/T42919

Thank you @guramarx !
Yes, it works.

I go have a beer now ! :yes:

if you read that bug report, just adding copy rotation to a object targeting the bone and setting it to zero fixes the bone python,

its something to do with threading,

This thead was helpful to me, so I wanted to jump in and give my answer/fix.

Unfortunately, parenting objects to Bones in the BGE can cause issues with armature animated meshes. Especially when Blending animations via script. I have worked out a fix to directly copy location and rotation of any bone in a scene:


def main():
    scene = bge.logic.getCurrentScene()

    lght = scene.objects["light"]
    trgtbone = scene.objects["Armature"].channels["R_Equip"]
    ArmaRefObject = scene.objects["Armature"]
    
    axisfix = ArmaRefObject.worldOrientation.to_euler() 
    
    tgx = trgtbone.rotation_euler[0] + axisfix[0]
    tgy = trgtbone.rotation_euler[1] + axisfix[2]
    tgz = trgtbone.rotation_euler[2]*-1  + axisfix[1]
    
    #resolve the location of the object
    lght.worldOrientation = [tgx, tgz, tgy]
    lght.worldPosition = trgtbone.location + ArmaRefObject.worldPosition
2 Likes