Get the transformations(world location, rotation, scale) of a bone.

Hi, i am making a script for my game, basically spawn objects and put it the transformations of a bone.

for get the bone i use:

armature.channels["bone"]

I use another object for use in the scene.addObject, so i need to put the transformations of the bone to this object.

I can get the position in this way:


armature = own.children[0]
bone = armature.channels["bone"]


worldPosition = bone.pose_head + armature.worldPosition
        
reference.worldPosition = worldPosition

But i think is there a way for make it more efficient, in with this method i only get the position, i no have idea of how get the orientation, and I have not started with the scale.

Maybe the way is use a matrix 4x4, I was reading the BL_ArmatureChannel and is there methods for get a 4x4 matrix of the bone, and with obj.worldTransforms one can get/set a matrix 4x4 for the position/rotation/scale, but this matrix 4x4 of the bone is local(how convert a matrix 4x4 local to world?), and i don’t know not much of matrix.

And maybe is there another way, i dont know.

Could you parent the object to Armature when add the object? When you add the object if it has the correct vertex group I think it get the transformation doing nothing

I do not remember have done something like that, it is only my opinion.

That scripts its for a NPC.
When the NPC die, unparent the armature of the dynamic cube, delete the dynamic cube, spawn all objects for the physics of the ragdoll, copy the transformations of the bones to the added objects, set the constraints to the added objects(for get the position of the bones at the momento of the dead), activate the armature(for activate the constraint of the bones, for get the transforms of the added objects).

I can also use empty and parent it to the bones, and get the tranformations of the empty, but i want to keep everything arranged,simple, and with the least number of objects.

And what about add object and just after adding make the object track to (in 0 tics) the next bone… if you use the correct axis the object will be instantly aligned in the corretc direction. It is not valid for last bones, but you could use empties for this ones.

I don’t know if i explained this well.

I understand, but the track to only work with objects, not bones, can track empties and i can parent the empty to the bones, but is best just parent the empties to the bones, and copy the transformations of the bone to the added objects(not use track to), but as I said, i dont want to use empties, because i want to keep everything arranged,simple, and with the least number of objects.

OK, my apologizes but I have not any other ideas :slight_smile:

I appreciate you trying to give me Ideas, but i want to keep the original question :slight_smile:

You might want the bone pose matrix, which can multipy the objects world matrix to get the world position

Sent from my Nexus 5 using Tapatalk

As I said in the main post, maybe use a matrix 4x4(location, rotation, scalling) is the way, i don’t know much about matrix.

Using the pose_matrix of the BL_ArmatureChannel class:


bone = armature.channels["bone"]
matrix_local = bone.pose_matrix

returns a matrix 4x4 but is local(use the armature space, and for use it in the addObject need to be global), and I do not understand much what you mean because your description is too short, maybe do you can help me a little bit about this?

if one have the matrix ready, it can be used directly with the scene.addObject() function.

try this:


import bge
arm = bge.logic.getCurrentController().owner

arm_m4 = arm.worldTransform
for bone in arm.channels:
    head = arm_m4 * bone.pose_head
    tail = arm_m4 * bone.pose_tail
    bge.render.drawLine(head,tail,[1,1,1])

:wink:

PS:
to get the matrice 4x4 (inm global coord):


import bge
arm = bge.logic.getCurrentController().owner

arm_m4 = arm.worldTransform
bones_worldTransform = [(arm_m4 * bone.pose_matrix) for bone in arm.channels]

print( bones_worldTransform)

obj.worldTransform * pose_mat

Sent from my Nexus 5 using Tapatalk

Tapatalk want $ for each letter ? :smiley: :wink:

Thank MarcoIT and agoose77, the method work good.