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 fbx2egg_animation(fbx_path, egg_path): manager, scene = FbxCommon.InitializeSdkObjects() FbxCommon.LoadScene(manager, scene, fbx_path) prepare_scene(scene) data = EggData() data.addChild(EggCoordinateSystem(CSYupRight)) skeleton = EggTable("<skeleton>") walking = EggTable("walking") # TODO: get name from animation layer walking.setTableType(EggTable.stringTableType("bundle")) walking.addChild(skeleton) table = EggTable() table.addChild(walking) for layer in get_anim_layers(scene): traverse_animation_curves(scene, scene.GetRootNode(), layer, skeleton) data.addChild(table) data.writeEgg(egg_path)
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)