![]() |
Attention | Topic was automatically imported from the old Question2Answer platform. |
![]() |
Asked By | kanator |
I have been hammering at this for a few weeks now and have not been able to figure it out.
I am creating an importer for Hash Animation Master models.
I am loading all the bones and I am assigning the parents of each bone. But when I do that they start appearing in the wrong places with the wrong rotation.
If I just create the bones and do not assign the parent bone they appear in the correct location and rotation.
The problem I am having is that I have not been able to figure out how to properly convert their global position and rotation to the position and rotation when under a parent bone.
How to convert the location to local rotation?
I just was able to place the bones in the right position(local to parent position) when assigning their parents, but still cannot figure out how to properly convert the rotation to local.
This is what I did to place the bones in the correct position after parenting them.
Note in the code “bone” is an object of a class type I created that holds the global position, rotation, and parent bone. This is what is used to create the bones in the skeleton
1-First, create all the bones in the skeleton as global bones. Make sure the bones are being created from the main parent to the deepest child. This way we ensure that every parent bone index in the skeleton is smaller than their child’s bone index(This is required by Godot).
func _add_bone_globaly(bone)->void:
var t:Transform = Transform(Basis(bone.rotation), bone.start)
t = t.scaled(Vector3(1,1,1))
_skeleton.add_bone(bone.name)
bone.bone_id_in_skeleton = _skeleton.find_bone(bone.name)
_skeleton.set_bone_rest(bone.bone_id_in_skeleton, t)
bone.acumulated_basis = _skeleton.get_bone_global_pose(bone.bone_id_in_skeleton).basis
_add_bone_tip(bone)#for debugging purposes
if bone.children.size() > 0:
for i in range(bone.children.size()):
_add_bone_globaly(bone.children[i])
pass
func _add_bone_tip(bone)->void:#For debugging purposes in order to be able to see the full bone
var bone_global:Transform = Transform(bone.rotation, bone.start)
_skeleton.add_bone(bone.name + "-" + "Tip")
var tip = _skeleton.find_bone(bone.name + "-" + "Tip")
var tip_local_translation:Vector3 = bone_global.xform_inv(bone.end)
_skeleton.set_bone_rest(tip, Transform(Vector3(0,0,0),tip_local_translation))
_skeleton.set_bone_parent(tip, bone.bone_id_in_skeleton)
pass
2-Go through all the bones and assign their parent in the skeleton and converting the their global position/origin into a local position/origin to the parent bone.
func _assign_bone_parent(bone)->void:
if bone.parent == null: return
var parent_local:Transform = _skeleton.get_bone_global_pose(bone.parent.bone_id_in_skeleton)
var child_global:Transform = _skeleton.get_bone_rest(bone.bone_id_in_skeleton)
var t:Transform = Transform(Vector3(), parent_local.xform_inv(child_global.origin))
t = t.scaled(Vector3(1,1,1))
_skeleton.set_bone_parent(bone.bone_id_in_skeleton, bone.parent.bone_id_in_skeleton)
_skeleton.set_bone_rest(bone.bone_id_in_skeleton, t)
pass
How to convert the location to local rotation?
kanator | 2020-01-25 14:13