Created
May 14, 2023 17:15
-
-
Save boxheadroom/2d544e5b04c504f0b31c6867bba4cea1 to your computer and use it in GitHub Desktop.
Mixamo からダウンロードしたモーションパックを Godotで読み込みやすくglbに変換
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import bpy | |
import os, sys,glob | |
#HELP | |
print("""convert mixamo fbx to gltf for godot | |
blender.exe -P fbx_concat_cli.py --tpose <tpose.fbx> --animdir <dirname> | |
--tpose tpose fbx with mesh | |
--dir directory contains fbx (pack) with animation | |
""") | |
############### | |
#SUB ROUTINE | |
def change_area_type(t): | |
"'NLA_EDITOR' " | |
# NLAエディタに移行 | |
print("***",t) | |
if bpy.context.area: | |
for area in bpy.context.screen.areas: | |
if area.type == t: | |
print("---") | |
bpy.context.area = area | |
break | |
#エラーになる | |
#bpy.context.area.type = 'NLA_EDITOR' | |
def select(obj): | |
####### objを選択する | |
#選択なし | |
bpy.ops.object.select_all(action="DESELECT") | |
# シーンから特定のオブジェクトを取得する | |
#obj = bpy.data.objects["ObjectName"] | |
# Tposeをアクティブにする | |
bpy.context.view_layer.objects.active = obj | |
# Tposeを選択する | |
obj.select_set(True) | |
def delete(obj): | |
"delete object from scene" | |
for d in obj.data: | |
bpy.data.objects.remove(d) | |
obj.data = None | |
bpy.data.objects.remove(obj) | |
return | |
# シーンから削除するオブジェクトを取得 | |
#obj = bpy.data.objects["ObjectName"],link=True) | |
# オブジェクトが参照するメッシュを取得 | |
# オブジェクトからメッシュの参照を解除する | |
obj.data = None | |
# メッシュを削除する | |
bpy.data.meshes.remove(mesh, do_unlink=True) | |
bpy.data.meshes.remove(obj, do_unlink=True) | |
bpy.data.objects.remove(obj, do_unlink=True) | |
def delete(obj): | |
""" | |
オブジェクトobjとその子孫オブジェクトを再帰的に削除する | |
""" | |
if obj is None: | |
return | |
# objに子オブジェクトがある場合は再帰的に削除する | |
for child in obj.children: | |
delete(child) | |
# objがデータに参照されている場合は、参照関係を解除する | |
if obj.data is not None and obj.users > 0: | |
obj.user_clear() | |
#オブジェクト名を削除する前に保存 | |
nm=obj.name | |
# objを削除する | |
bpy.data.objects.remove(obj, do_unlink=True) | |
# objが所属するコレクションからも削除する | |
for collection in bpy.data.collections: | |
if nm in collection.objects: | |
collection.objects.unlink(obj) | |
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1) | |
######### BEGIN ############# | |
""" | |
# 3D ビューポートを作成します | |
#print("+") | |
#bpy.context.screen.areas.new(type='VIEW_3D') | |
#print("++") | |
""" | |
change_area_type('VIEW_3D') | |
last="" | |
args={} | |
for a in sys.argv: | |
if last.startswith("--"): | |
args[last[2:]]=a | |
last=a | |
#全部消す | |
bpy.ops.object.select_all(action='SELECT') | |
bpy.ops.object.delete(use_global=False) | |
# ファイル名から拡張子を取り除く | |
filename = os.path.splitext(args["tpose"])[0] | |
# fbx(Tpose)ファイルをBlenderに読み込む | |
bpy.ops.import_scene.fbx(filepath=args["tpose"]) | |
# アクティブオブジェクト(Tpose)を取得する | |
obj1 = bpy.context.view_layer.objects.active | |
#Tポーズの元々のアクション | |
action1 = bpy.data.actions[0] | |
action1.name="Tpose" | |
flist=glob.glob(os.path.join(args["animdir"],"*.fbx")) | |
for fn in flist: | |
change_area_type("VIEW_3D") | |
ddummy, fbody = os.path.split(fn) | |
nm,ext=os.path.splitext(fbody) | |
# 追加したいアニメーションを含むファイルを読み込む | |
bpy.ops.import_scene.fbx(filepath=fn) | |
# アクティブオブジェクトを取得する | |
obj2 = bpy.context.view_layer.objects.active | |
#アクション名をファイル名に | |
obj2.animation_data.action.name=nm | |
#obj1 を選択 | |
select(obj1) | |
change_area_type('NLA_EDITOR') | |
# アクションを追加するトラックを作成 | |
track = obj1.animation_data.nla_tracks.new() | |
track.name = nm | |
strip = track.strips.new(nm, 0, obj2.animation_data.action) | |
print("****") | |
change_area_type("VIEW_3D") | |
print("*****") | |
#アニメーションを付け替え終わったので | |
#要らなくなったobj2を削除 | |
#delete(obj2) | |
print("del",obj2) | |
print(bpy.data.objects.remove(obj2, do_unlink=True)) | |
obj2=None | |
print("******") | |
#bpy.context.area.type="VIEW_3D" | |
if bpy.context.area: | |
for area in bpy.context.screen.areas: | |
if area.type == "VIEW_3D": | |
print("-----") | |
bpy.context.area = area | |
break | |
delete(bpy.data.objects['Alpha_Joints.001']) | |
delete(bpy.data.objects['Alpha_Surface.001']) | |
# glTF 2.0としてエクスポートする | |
select(obj1) | |
bpy.ops.export_scene.gltf(filepath=filename + ".glb", export_format='GLB') | |
#END | |
print("DONE") | |
#参考にする公式ドキュメント関連ページ | |
REF=""" | |
Types (bpy.types) Shared Enum Items Space Type Items | |
https://docs.blender.org/api/current/bpy_types_enum_items/space_type_items.html | |
Operators (bpy.ops) Nla Operators | |
https://docs.blender.org/api/current/bpy.ops.nla.html | |
Operators (bpy.ops) Object Operators | |
https://docs.blender.org/api/current/bpy.ops.object.html | |
Operators (bpy.ops) | |
https://docs.blender.org/api/current/bpy.ops.html | |
Types (bpy.types) BlendData(bpy_struct) | |
https://docs.blender.org/api/current/bpy.types.BlendData.html#bpy.types.BlendData | |
""" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment