[help][bge] set bone location

Hi,

I want to set the location of a bone.
Is there something like


scene.objects["armature"].children(<BONE>).setWorldPosition

you want to move a whole bone?

add a empty

go to bone constraints in the armature (like where you would add ik)

and do copy position, set to empty,

move empty. run armature

act = cont.actuators["armature"]
for boneCh in act.channelNames:
   act.setChannel(boneCh, loc, size, quat)
cont.activate(act)

This is in 2.49, it should be something similar in 2.5+

yeah, but its much much easier to align a object for me then to rotate a bone, (do bones have functions like alignAxisToVect and world.orientation.col[0] ?)

I think bones have location,size and quaternion. The quaternion represent a bone rotation in 3D. There are methods to convert to quaternion from euler or world orientation and vice versa.
I’m using bones quaternion to rotate the Krum’s head towards an object of interest, like a weapon on the ground.
Like this:

ob=trackObjloc,size,quat1 = act.getChannel(trackBone)


    
#Update rotation
M = Matrix( ob.localOrientation[0], ob.localOrientation[1], ob.localOrientation[2] )
quat = M.toQuat()     #Change in rotation of the object


#quat[0] = -quat[0]
quat[3] = -quat[3]#Some weird angle inversion, it works but I don't know why it is nescessary, think it is corrected in blender 2.5X


q1=quat[0]
q2=quat[1]
q3=quat[2]
q4=quat[3]


#print q1,q2,q3,q4    


#Update bone parameters
act.setChannel(trackBone, loc, size, [q1,q2,q3,q4])

Thanks haidme but i get the error


AttributeError: 'BL_ArmatureActuator' object has no attribute 'getChannel'

How to fix this?

There’s info abou this in the blender API. I’ve got code somewhere for what you need but I haven’t got access to my computer right now.

I think getchannel probably became channel…

Now i can set the rotation of the bone but how can is set the location? (.localPosition and .worldPosition do not work)


import bge
from mathutils import Vector, Matrix, Quaternion, Euler

def main():
  cont = bge.logic.getCurrentController()
  own = cont.owner
  scene = bge.logic.getCurrentScene()

  trackObj = scene.objects['handRTracker'] # the track object (Empty with trackto actuator)

  matrix = trackObj.localOrientation
  loc = trackObj.worldPosition
  quat = matrix.to_quaternion()
  chanel = own.channels["Hand.R.IK"] #IK of the right hand
  chanel.rotation_quaternion = [quat[0],quat[1],quat[2],quat[3]]
  #own.setChannel("Hand.R.IK",loc,1,quat) #No setChannel anymore? :(
  own.update()
main()

Any idea’s?

add a empty,

select the armature

go to pose mode

select the bone

in properties select bone constraints

select copy position , set target to empty

moving the empty moves the bone.

Thanks BluePrintRandom but is there a python way to solve this?

yes, move the object with python you are copying location from

you can add bone constraints with python via the armature channels if you want.

Any example on how to move a bone with python?

and it work x_x’?
i had some code(old) for rotation, but is much more complex that what you had posted
for the location not. (seem also more complex)

it anyway is :
arm.channels[namebone].location = 0,0,0

i can try to make some modification and see if do something , but usually each time that touch become broken

but it afaik is an offset of an offset . for that seem strange that the code posted work

ok, founded , it was a mess other reason


def move_bone_to(arm, bone, point):
    vec_arm = arm.worldTransform.inverted() * point
    vec_bon = bone.pose_matrix.inverted() * vec_arm
    bone.location = bone.location + vec_bon




def update(cont):
    own = cont.owner # <- armature
    point = own.scene.objects["Cube"].worldPosition
    move_bone_to(own, own.channels["Bone.002"], point)
    own.update()
    



http://www.blender.org/api/blender_python_api_2_74_5/bge.types.BL_ArmatureChannel.html?highlight=channel#bge.types.BL_ArmatureChannel.bone
Heres all the commands you need for working with bones…

if I do


print(bone.location)

It returns


<Vector 0.000, 0.000, 0.000>

How to solve this?

is the bone “disconnected” ? you ave do go in edit mode and remove the flag
otherwise cannot change position

And how do i do that?

select the armature object ,
press [TAB] (go in edit mode)
select the bone that you want move
properies -> bone -> relations -> [v] connected

this is written in “script style” : (no module)
called from the armature object


import bge
from mathutils import Vector, Matrix, Quaternion, Euler




    


def main():
    cont = bge.logic.getCurrentController()
    own = cont.owner # <- armature
    
    scene = own.scene
    target_object = scene.objects["___NAME_TARGET_HERE___"]
    
    
    
    target_position = target.worldPosition
    bone = own.channels["___NAME_BONE_HERE___"] 
    
    vec_arm = own.worldTransform.inverted() * target_position
    vec_bon = bone.pose_matrix.inverted() * vec_arm
    bone.location = bone.location + vec_bon # set the new offset of bone
    
    
    #update armature
    own.update()
    
main()