Blender中bpy骨骼创建脚本异常与多组姿态数据应用问题
Blender骨骼导入脚本问题:未知格式的骨骼四元数与向量数据应用
问题背景
我有一组包含骨骼名称、父骨骼名称、子骨骼名称的骨骼数据数组,每组骨骼还附带以下坐标数据:
Quaternion(RotationsToParent[i]) # RotationsToParent / 四元数 Vector(TranslationToParent[i]) # TranslationToParent / 三维向量 Quaternion(RotationsToOrigin[i]) # RotationsToOrigin / 四元数 Vector(TranslationToOrigin[i]) # TranslationToOrigin / 三维向量 Quaternion(RotationsToLocal[i]) # RotationsToLocal / 四元数 Vector(TranslationToLocal[i]) # TranslationToLocal / 三维向量
这些数据来自未知格式文件,只能通过变量名推断用途。但Blender的bpy文档里只提到通过Head/Tail创建骨骼,没有说明如何设置这些四元数和向量数据。
当前脚本与异常结果
我编写了一段骨骼放置脚本,但运行结果异常,代码如下:
import bpy from bpy.props import * from mathutils import Vector, Quaternion armature = bpy.data.armatures.new("Armature") rig = bpy.data.objects.new("Armature", armature) bpy.context.collection.objects.link(rig) bpy.context.view_layer.objects.active = rig bpy.ops.object.mode_set(mode = 'EDIT') BoneNames = [...] ChildBoneNames = [...] ParentBoneNames = [...] # 每组骨骼对应的数值 RotationsToParent = [...] # 四元数 TranslationToParent = [...] # 三维向量 RotationsToOrigin = [...] # 四元数 TranslationToOrigin = [...] # 三维向量 RotationsToLocal = [...] # 四元数 TranslationToLocal = [...] # 三维向量 for i, BONE in enumerate(BoneNames): BoneArrIndex = i BoneName = BONE CurrentRTP = Quaternion(RotationsToParent[BoneArrIndex]) # RotationsToParent / 四元数 CurrentTTP = Vector(TranslationToParent[BoneArrIndex]) # TranslationToParent / 三维向量 CurrentRTO = Quaternion(RotationsToOrigin[BoneArrIndex]) # RotationsToOrigin / 四元数 CurrentTTO = Vector(TranslationToOrigin[BoneArrIndex]) # TranslationToOrigin / 三维向量 CurrentRTL = Quaternion(RotationsToLocal[BoneArrIndex]) # RotationsToLocal / 四元数 CurrentTTL = Vector(TranslationToLocal[BoneArrIndex]) # TranslationToLocal / 三维向量 # 创建新骨骼 current_bone = armature.edit_bones.new(BoneName) print("@",BoneName) # 骨骼链中的第一根骨骼 if i == 0: print(i) # 在绑定原点创建骨骼并设置长度 current_bone.head = [0, 0, 0] length = list(TranslationToParent[ BoneArrIndex + 1 ])[0] current_bone.tail = [0, 0, length] quat_armature_space = CurrentRTO current_bone.transform(quat_armature_space.to_matrix(), scale=True, roll=True) # 设置位置 current_bone.translate(CurrentTTO) # 保存当前骨骼、尾部位置(下一根骨骼将移动到此处)和四元数旋转值 parent_bone = current_bone parent_bone_tail = current_bone.tail parent_bone_quat_armature_space = quat_armature_space # 骨骼链中的最后一根骨骼 elif i == (len(BoneNames) - 1): # 在绑定原点创建骨骼并设置长度 current_bone.head = [0, 0, 0] current_bone.tail = [0, 0, 1] # 旋转骨骼(绕原点?) # 和矩阵类似,四元数相乘可以累积旋转值 transform_quat = parent_bone_quat_armature_space @ CurrentRTO current_bone.transform(transform_quat.to_matrix(), scale=True, roll=True) # 设置位置(绕原点?) current_bone.translate(parent_bone_tail) # 连接到父骨骼 current_bone.parent = parent_bone current_bone.use_connect = True # 中间骨骼 else: # 在绑定原点创建骨骼并设置长度 current_bone.head = [0, 0, 0] length = list(TranslationToParent[ BoneArrIndex + 1 ])[0] current_bone.tail = [0, 0, length] # 旋转骨骼(绕原点?) # 和矩阵类似,四元数相乘可以累积旋转值 transform_quat = parent_bone_quat_armature_space @ CurrentRTO current_bone.transform(transform_quat.to_matrix(), scale=True, roll=True) # 设置位置(绕原点?) current_bone.translate(parent_bone_tail) # 连接到父骨骼 current_bone.parent = parent_bone current_bone.use_connect = True # 保存当前骨骼、尾部位置和四元数旋转值 parent_bone = current_bone parent_bone_tail = current_bone.tail parent_bone_quat_armature_space = transform_quat
我尝试将head/tail替换为其他Translation数据,但结果仍异常(骨骼形态混乱)。
调试进展(Edit1)
经过数小时调试更新脚本后,结果有所改善:仅应用RotationToOrigin与TranslateToOrigin时,骨骼方向一致但长度不对。但我仍不清楚该如何正确应用剩余的RotationToLocal、TranslationToLocal与RotationToParent数据,求指点正确的使用方式。(此时骨骼方向正确,但长度不一致)
内容的提问来源于stack exchange,提问作者berkay ercevik
相关产品推荐
相关产品推荐

