Browse Source

Work on the work-in-progress script.

master
poikilos 3 years ago
parent
commit
fbe1170b29
  1. 52
      utilities/blender/hierarchy_of_empties_to_bones.py

52
utilities/blender/hierarchy_of_empties_to_bones.py

@ -18,6 +18,8 @@ Usage:
''' '''
import bpy import bpy
from mathutils import Vector, Quaternion from mathutils import Vector, Quaternion
import mathutils
import math
context = bpy.context context = bpy.context
print("") print("")
print("[ EnlivenMinetest/utilities/blender/hierarchy_of_empties_to_bones.py ] started") print("[ EnlivenMinetest/utilities/blender/hierarchy_of_empties_to_bones.py ] started")
@ -27,6 +29,7 @@ armature_display_type = 'OCTAHEDRAL'
# ^ Can be: ('OCTAHEDRAL', 'STICK', 'BBONE', 'ENVELOPE', 'WIRE') # ^ Can be: ('OCTAHEDRAL', 'STICK', 'BBONE', 'ENVELOPE', 'WIRE')
# default: 'OCTAHEDRAL' # default: 'OCTAHEDRAL'
def mat3_to_vec_roll(mat): def mat3_to_vec_roll(mat):
''' '''
Convert a mat3 to a tuple containing a vec and roll. Convert a mat3 to a tuple containing a vec and roll.
@ -105,6 +108,7 @@ def vec_roll_to_mat3(vec, roll):
mat = rMatrix * bMatrix mat = rMatrix * bMatrix
return mat return mat
def getFirstChild(parentName): def getFirstChild(parentName):
for obj in bpy.data.objects: for obj in bpy.data.objects:
if obj.parent is None: if obj.parent is None:
@ -113,6 +117,7 @@ def getFirstChild(parentName):
return obj return obj
return None return None
def getRealRotation_broken(cumulative_rotation, empty): def getRealRotation_broken(cumulative_rotation, empty):
if cumulative_rotation is None: if cumulative_rotation is None:
cumulative_rotation = Quaternion((1, 0, 0, 0)) cumulative_rotation = Quaternion((1, 0, 0, 0))
@ -164,6 +169,19 @@ def getRealRotation(empty):
raise NotImplementedError("Fake recursion isn't implemented for hierarchies this deep.") raise NotImplementedError("Fake recursion isn't implemented for hierarchies this deep.")
def vectorDiff(v1, v2):
if len(v1) != len(v2):
raise ValueError("v1 length is {} but v2 length is {}".format(len(v1), len(v2)))
if len(v1) == 4:
return Vector((v1[0]-v2[0], v1[1]-v2[1], v1[2]-v2[2], v1[3]-v2[3]))
elif len(v1) == 3:
return Vector((v1[0]-v2[0], v1[1]-v2[1], v1[2]-v2[2]))
else:
raise ValueError("v1 and v1 are of length {} but that is not a known valid location vector length.".format(len(v1)))
return None
def makeSameChildren(empty, armature, parent_bone, parent_empty, cumulative_rotation, cumulative_scale, depth=0): def makeSameChildren(empty, armature, parent_bone, parent_empty, cumulative_rotation, cumulative_scale, depth=0):
''' '''
Make a new bone for the given empty, then do the same Make a new bone for the given empty, then do the same
@ -212,8 +230,9 @@ def makeSameChildren(empty, armature, parent_bone, parent_empty, cumulative_rota
# create bone at armature origin and set its length # create bone at armature origin and set its length
scale = cumulative_scale * empty.scale.z scale = cumulative_scale * empty.scale.z
boneLength = length * scale
current_bone.head = [0, 0, 0] current_bone.head = [0, 0, 0]
current_bone.tail = [0, 0, length * scale] current_bone.tail = [0, 0, boneLength]
# rotate bone # rotate bone
# print(depth*" "+" - empty.rotation_quaternion:{}".format(Quaternion(empty.rotation_quaternion))) # print(depth*" "+" - empty.rotation_quaternion:{}".format(Quaternion(empty.rotation_quaternion)))
@ -231,15 +250,32 @@ def makeSameChildren(empty, armature, parent_bone, parent_empty, cumulative_rota
# transform_quat = parent_bone_quat_armature_space @ current_bone_quat_parent_space # transform_quat = parent_bone_quat_armature_space @ current_bone_quat_parent_space
# transform_quat = current_bone_quat_parent_space @ cumulative_rotation # transform_quat = current_bone_quat_parent_space @ cumulative_rotation
# transform_quat = Quaternion(empty.rotation_quaternion) @ Quaternion(empty.parent.rotation_quaternion) # transform_quat = Quaternion(empty.rotation_quaternion) @ Quaternion(empty.parent.rotation_quaternion)
transform_quat = getRealRotation(empty) # transform_quat = getRealRotation(empty)
# ^ getRealRotation(emtpy) gives same result as current_bone_quat_parent_space @ cumulative_rotation
# transform_quat = current_bone_quat_parent_space
# transform_quat = getRealRotation(empty)
transform_quat = empty.rotation_quaternion
current_bone.transform(transform_quat.to_matrix()) current_bone.transform(transform_quat.to_matrix())
# current_bone.tail = transform_quat.to_matrix() @ current_bone.tail
# matrix = transform_quat.to_matrix()
# tail, roll = mat3_to_vec_roll(matrix)
# current_bone.head = matrix.to_translation()
# ^ ValueError: Matrix.to_translation(): inappropriate matrix size
# tail, roll = mat3_to_vec_roll(matrix.to_3x3())
# current_bone.head = matrix.to_translation()
# ^ ValueError: Matrix.to_translation(): inappropriate matrix size
#current_bone.tail = tail*boneLength + bone.head
#current_bone.roll = roll
# set position # set position
# new_relative_loc = Quaternion(empty.location) # new_relative_loc = Quaternion(empty.location)
# ^ The empty.location is relative to the parent_empty's head # ^ The empty.location is relative to the parent_empty's head
# but must be made relative the parent_bone's tail. # but must be made relative the parent_bone's tail.
old_to_new = Vector(parent_bone.tail) - Vector(parent_empty.location) # old_to_new = Vector(parent_empty.location) - Vector(parent_bone.tail)
new_relative_loc = Vector(empty.location) - old_to_new old_to_new = vectorDiff(parent_empty.location, parent_bone.tail)
# new_relative_loc = old_to_new - Vector(empty.location)
new_relative_loc = vectorDiff(old_to_new, empty.location)
# uhoh_if_nonzero = Vector(parent_bone.head) - Vector(parent_empty.location) # uhoh_if_nonzero = Vector(parent_bone.head) - Vector(parent_empty.location)
# print(depth*" "+" - uhoh_if_nonzero:{}".format(uhoh_if_nonzero)) # print(depth*" "+" - uhoh_if_nonzero:{}".format(uhoh_if_nonzero))
# ^ It is nonzero :( # ^ It is nonzero :(
@ -248,7 +284,7 @@ def makeSameChildren(empty, armature, parent_bone, parent_empty, cumulative_rota
print(depth*" "+" - old_to_new:{}".format(old_to_new)) print(depth*" "+" - old_to_new:{}".format(old_to_new))
print(depth*" "+" - new_relative_loc:{}".format(new_relative_loc)) print(depth*" "+" - new_relative_loc:{}".format(new_relative_loc))
# print(depth*" "+" - current_bone_offset:{}".format(current_bone_offset)) # print(depth*" "+" - current_bone_offset:{}".format(current_bone_offset))
current_bone.translate(Vector(new_relative_loc)) current_bone.translate(new_relative_loc)
# connect # connect
current_bone.parent = parent_bone current_bone.parent = parent_bone
@ -290,8 +326,11 @@ def makeSameChildren(empty, armature, parent_bone, parent_empty, cumulative_rota
continue continue
makeSameChildren(child, armature, current_bone, empty, transform_quat, scale, depth=depth+1) makeSameChildren(child, armature, current_bone, empty, transform_quat, scale, depth=depth+1)
def makeSameChildrenFromRootEmpty(obj): def makeSameChildrenFromRootEmpty(obj):
# for obj in bpy.data.objects: if obj is None:
print("Nothing is selected.")
return
if obj.type != 'EMPTY': if obj.type != 'EMPTY':
print("non-Empty {} type: {} isn't compatible with this script".format(obj.name, obj.type)) print("non-Empty {} type: {} isn't compatible with this script".format(obj.name, obj.type))
return return
@ -326,5 +365,6 @@ def makeSameChildrenFromRootEmpty(obj):
# else: # else:
# print("{} parent: {}".format(obj.name, obj.parent)) # print("{} parent: {}".format(obj.name, obj.parent))
makeSameChildrenFromRootEmpty(context.view_layer.objects.active) makeSameChildrenFromRootEmpty(context.view_layer.objects.active)

Loading…
Cancel
Save