assets/pipeline/export_anims.py

132 lines
4.6 KiB
Python

import bpy
from bpy.types import LayerCollection, Object, NlaTrack
# Enter object mode
bpy.ops.object.mode_set(mode='OBJECT')
# FIRST, toggle collections
collections_exportable = [
"insurrectionist", "infantry", "rigging", "geometry", "grapple", "baton", "helmet", "gun", "jetpack"
]
def toggle_collection(coll: LayerCollection):
# Iterate over all child LayerCollections
for child in coll.children.values():
c: LayerCollection = child
# Force include/exclude character-related collections so they're included/excluded from export
c.exclude = not (c.name in collections_exportable)
if c.name == "insurrectionist" or c.name == "infantry":
bpy.context.view_layer.active_layer_collection = c
toggle_collection(bpy.context.view_layer.layer_collection)
# Find rig to make it active, and select all objects
for objBase in bpy.context.scene.objects:
obj: Object = objBase
if obj.type == 'ARMATURE':
bpy.context.view_layer.objects.active = obj
if obj.visible_get():
obj.select_set(True)
# EXTREMELY UGLY HACK TO EXIT TWEAK MODE
# see: https://blender.stackexchange.com/questions/316547/how-to-override-context-area-using-script-when-running-blender-using-command-lin
# and https://blender.stackexchange.com/questions/6101/poll-failed-context-incorrect-example-bpy-ops-view3d-background-image-add
def get_view_nla(): # Get any window
for window_manager in bpy.data.window_managers:
for window in window_manager.windows:
for area in window.screen.areas:
area.type = 'NLA_EDITOR'
for region in area.regions:
if region.type == 'WINDOW':
return dict(window=window, workspace=window.workspace, screen=window.screen, area=area, region=region)
raise Exception('NLA context not found.')
# Forcibly override context to a window so we can access NLA editor
with bpy.context.temp_override(**get_view_nla()):
if bpy.context.scene.is_nla_tweakmode:
bpy.ops.nla.tweakmode_exit() # Exit tweakmode
# Go through all NLA tracks, unstar them and mute them
bpy.context.active_object.animation_data.nla_tracks.active = None # Make track inactive
for trackBase in bpy.context.active_object.animation_data.nla_tracks:
track: NlaTrack = trackBase
track.mute = True # Mute all tracks
track.is_solo = False # Disable solo view for all tracks
# Get export directory
path: str = bpy.data.filepath.replace('\\Shelby', '').replace('\\Tommy', '')
pathPrefix = max(path.rfind('animations/'), path.rfind('animations\\'))
pathStart = pathPrefix + len('animations/')
pathEnd = max(path.rfind('/'), path.rfind('\\'))
# Figure out who made these animations based on filepath
fileIndividual = ''
if 'tommy' in path:
fileIndividual = 'tommy'
elif 'shelby' in path:
fileIndividual = 'shelby'
elif 'alan' in path:
fileIndividual = 'alan'
# Build export filepath
dirName = path[pathStart:pathEnd]
filePath = path[:pathPrefix] + 'export\\' + dirName + '\\anims_' + dirName + '_' + fileIndividual + '.fbx'
# RIG MUST BE ACTIVE
armature = bpy.context.active_object.data
# Set all bone layers, INCLUDING mechanical bones, to be visible
for i in range(0, 29):
armature.layers[i] = True
for i in range(29,32):
armature.layers[i] = True
# Use BoneJuice to bake down all actions
# bpy.ops.bj.anim_bakeall()
# Make armature local so we can clear all constraints
# bpy.ops.object.mode_set(mode='OBJECT')
# bpy.ops.object.make_local(type='SELECT_OBDATA')
# Clear all posing and pose constraints
bpy.ops.object.mode_set(mode='POSE') # Enter pose mode
bpy.ops.pose.select_all(action='SELECT')
# bpy.ops.pose.constraints_clear() # Clear all constraints
bpy.ops.pose.transforms_clear() # Clear all transforms
# Export animations
bpy.ops.export_scene.fbx(
# I/O
filepath = filePath,
check_existing = False,
path_mode = 'STRIP',
batch_mode = 'OFF',
use_visible = True,
object_types = {'MESH', 'ARMATURE'},
axis_forward = '-Y',
axis_up = 'Z',
# Mesh Settings
use_mesh_modifiers = True,
use_mesh_modifiers_render = False,
use_triangles = True,
colors_type = 'NONE',
# Animation
use_armature_deform_only = True,
add_leaf_bones = True,
bake_anim = True,
bake_anim_use_all_bones = True,
bake_anim_use_nla_strips = False,
bake_anim_use_all_actions = True,
bake_anim_force_startend_keying = True,
bake_anim_simplify_factor = 0.0,
)
bpy.ops.pose.transforms_clear() # Clear all transforms
bpy.ops.object.mode_set(mode='OBJECT')
## FOR DEBUGGING, see https://blender.stackexchange.com/questions/93728/blender-script-run-print-to-console
# exit()