def get_transforms(fbx_node, fbx_layer): rotation_order = fbx_node.GetRotationOrder(fbx.FbxNode.eSourcePivot) translation_curve = fbx_node.LclTranslation.GetCurve(fbx_layer, True) rotation_curve = fbx_node.LclRotation.GetCurve(fbx_layer, True) scaling_curve = fbx_node.LclScaling.GetCurve(fbx_layer, True) translation_count = translation_curve.KeyGetCount() rotation_count = rotation_curve.KeyGetCount() scaling_count = scaling_curve.KeyGetCount() key_count = max(translation_count, rotation_count, scaling_count) # order = convert_fbx_rotation_order[rotation_order] order = EggXfmSAnim.getStandardOrder() # srpht # order = "shprt" for key_index in range(key_count): key_time = fbx.FbxTime() key_time.SetFrame(key_index) translation = convert_fbx_vector4(fbx_node.EvaluateLocalTranslation(key_time)) rotation = convert_fbx_vector4(fbx_node.EvaluateLocalRotation(key_time)) scaling = convert_fbx_vector4(fbx_node.EvaluateLocalScaling(key_time)) rotation = normalize_rotation_order(rotation_order, rotation) # transform = fbx_node.EvaluateLocalTransform(key_time) # translation = convert_fbx_vector4(transform.GetT()) # rotation = convert_fbx_vector4(transform.GetR()) # scaling = convert_fbx_vector4(transform.GetS()) shear = VBase3D(0, 0, 0) mat = Mat4D() EggXfmSAnim.composeWithOrder(mat, scaling, shear, rotation, translation, order, CSYupRight) # TODO: read coordinate system from fbx yield mat
def traverse_animation_curves(fbx_scene, fbx_node, fbx_layer, egg_parent): for i in range(fbx_node.GetChildCount()): fbx_child = fbx_node.GetChild(i) if fbx_child.GetSkeleton() is None: continue xform_new = EggXfmSAnim("xform") xform_new.setOrder(EggXfmSAnim.getStandardOrder()) # xform_new.setOrder("shprt") xform_new.setFps(30) for transform in get_transforms(fbx_child, fbx_layer): xform_new.addData(transform) egg_table = EggTable(fbx_child.GetName()) egg_table.addChild(xform_new) egg_parent.addChild(egg_table) traverse_animation_curves(fbx_scene, fbx_child, fbx_layer, egg_table)
def make_action(self, node, armature): # <-- root table egg_root_table = EggTable('') # <-- animation bundle egg_animation = EggTable('Armature') egg_animation.set_table_type(EggTable.TT_bundle) # <-- skeleton table egg_skeleton = EggTable('<skeleton>') # setup bones egg_joints = {} egg_joints_anims = {} for bone_name, bone in armature.data.bones.items(): # <-- joint table egg_joint = EggTable(bone_name) # <-- xfm_anim_s egg_xfm_anim_s = EggXfmSAnim('xform', CS_zup_right) # set order from glTF # i, j, k - scale -> s # h, p, r - rotation # x, y, z - location -> ? # egg_xfm_anim_s.set_order('shprxyz') egg_xfm_anim_s.set_fps(bpy.context.scene.render.fps / bpy.context.scene.render.fps_base) egg_joint.add_child(egg_xfm_anim_s) egg_joints_anims[bone_name] = egg_xfm_anim_s # xfm_anim_s --> if bone.parent: egg_joints[bone.parent.name].add_child(egg_joint) else: # root bone egg_skeleton.add_child(egg_joint) egg_joints[bone_name] = egg_joint # joint table --> # set animation data frame_start = bpy.context.scene.frame_start frame_end = bpy.context.scene.frame_end if self._action and self._action in bpy.data.actions: action = bpy.data.actions[self._action] armature.animation_data.action = action frame_start, frame_end = action.frame_range frame = float(frame_start) frame_int = None while frame <= frame_end: # switch frame if frame_int != math.floor(frame): frame_int = math.floor(frame) bpy.context.scene.frame_current = frame_int bpy.context.scene.frame_set(frame_int) if isinstance(self._speed_scale, collections.Callable): speed_scale = self._speed_scale(frame_int) else: speed_scale = self._speed_scale # switch subframe if speed_scale != 1: bpy.context.scene.frame_subframe = frame - frame_int # save bone matrices for bone_name, bone in armature.pose.bones.items(): s_anim = egg_joints_anims[bone_name] bone_matrix = get_bone_matrix(bone, armature) # egg_joints_anims[bone_name].add_data(matrix_to_panda(bone_matrix)) i, j, k = bone_matrix.to_scale() s_anim.add_component_data('i', i) s_anim.add_component_data('j', j) s_anim.add_component_data('k', k) # if bone.parent: # p, r, h = tuple(map(math.degrees, bone_matrix.to_euler())) # YABEE # s_anim.add_component_data('h', h) # s_anim.add_component_data('p', p) # s_anim.add_component_data('r', r) # else: # h, r, p = tuple(map(math.degrees, bone_matrix.to_euler('XZY'))) # s_anim.add_component_data('h', -h) # s_anim.add_component_data('p', p) # s_anim.add_component_data('r', r) # hpr == zxy ? p, r, h = tuple(map(math.degrees, bone_matrix.to_euler('YXZ'))) s_anim.add_component_data('h', h) s_anim.add_component_data('p', p) s_anim.add_component_data('r', r) x, y, z = bone_matrix.to_translation() s_anim.add_component_data('x', x) s_anim.add_component_data('y', y) s_anim.add_component_data('z', z) # advance to the next frame frame += speed_scale egg_animation.add_child(egg_skeleton) # skeleton table --> egg_root_table.add_child(egg_animation) # animation bundle --> # root table --> node.add_child(egg_root_table)