从Blender批量导出OGRE模型骨骼动画

    技术2024-03-22  107

    从Blender批量导出OGRE模型骨骼动画

    导出插件设置

    从Blender导出OGRE模型

    Blender 运行 Python 脚本

    打开控制台输出

    移动鼠标到箭头所指左下角, 当鼠标变为十字时候按住并往上拉

    选择文本编辑器

    新建文件, 打开代码提示, 就可以写代码了

    Blender API 文档

    Blender Python API

    批量导入FBX导出OGRE骨骼动画脚本

    导出的动画名字默认为 my_animation

    同个骨架内的子网格所带的骨骼和动画都一样, 即skeleton文件相同(请验证)

    导出很多无用文件, 未进行删除(只保证skeleton文件正确)

    动画过长的情况, 请调整模型骨骼动画去除空帧或手动导出

    导出动画骨骼文件(skeleton)以fbx文件名命名

    脚本

    import bpy import sys import os import re from os.path import join, split in_dir = "C:\\Users\\Ian\\Desktop\\data" filters = ["ss.fbx"] io_ogre = "D:\\blender2ogre\\io_ogre" path = "C:\\Users\\Ian\\Desktop\\tmp" action_list = [] def reset_blend(): candidate_list = [item.name for item in bpy.data.objects] for object_name in candidate_list: bpy.data.objects[object_name].select = True bpy.ops.object.delete() for item in bpy.data.meshes: bpy.data.meshes.remove(item) def export(name): namestr = name if name.find('_ogre') != -1: namestr = name[0:name.find('_ogre')] bpy.ops.object.mode_set(mode='OBJECT', toggle=False) for ob in bpy.data.objects: if ob.type != 'MESH': continue print(ob.name + 'type:' + ob.type + ' set mesh scale') bpy.ops.object.select_all(action='DESELECT') ob.select = True bpy.context.scene.objects.active = ob bpy.ops.object.transform_apply( location=False, scale=True, rotation=False) ob.select = False bpy.ops.object.select_all(action='DESELECT') for ob in bpy.data.objects: if ob.type != 'ARMATURE': continue print(ob.name + 'type:' + ob.type + ' set armature trans') bpy.ops.object.select_all(action='DESELECT') ob.select = True bpy.context.scene.objects.active = ob bpy.ops.object.transform_apply( location=True, scale=False, rotation=True) ob.select = False bpy.ops.object.select_all(action='DESELECT') for ob in bpy.data.objects: if ob.type != 'MESH': continue print(ob.name + 'type:' + ob.type + ' set armature trans') bpy.ops.object.select_all(action='DESELECT') ob.select = True bpy.context.scene.objects.active = ob bpy.ops.object.transform_apply( location=True, scale=False, rotation=True) ob.select = False bpy.ops.object.select_all(action='DESELECT') for ob in bpy.data.objects: if ob.type != 'MESH' or len(ob.material_slots) == 0: continue bpy.ops.object.select_all(action='DESELECT') ob.select = True bpy.context.scene.objects.active = ob matslots = len(ob.material_slots) print("# Object", ob.name, "has", matslots, "material slot(s)") if ob.find_armature(): ob.data.name = namestr for i in range(0, matslots): bpy.context.object.active_material_index = i bpy.ops.object.material_slot_remove() bpy.ops.object.select_all(action='DESELECT') first_frame = 0 last_frame = -9999 for action in bpy.data.actions : if action.name in action_list: continue print(action.name, action.frame_range[0], action.frame_range[1]) action_list.append(action.name) if action.frame_range[1] > last_frame: last_frame = action.frame_range[1] #if action.frame_range[0] < first_frame : #first_frame = action.frame_range[0] print ("first frame : ",first_frame, "\nlast frame : ", last_frame,"\nduration : ",last_frame-first_frame) scn = bpy.context.scene scn.frame_start = first_frame scn.frame_end = last_frame filepath = path+"\\"+namestr+"_"+str(last_frame) os.makedirs(filepath, exist_ok=True, mode=0o775) dot_scene(filepath) reset_blend() def convert(path, filters): need_file_items = [] need_file_names = [] filterDict = {} for item in filters: filterDict[item] = True file_lst = os.listdir(path) for item in file_lst: fileName, fileExtension = os.path.splitext(item) if fileExtension == ".fbx" or ".FBX" and (not item in filterDict): need_file_items.append(item) need_file_names.append(fileName) n = len(need_file_items) for i in range(n): item = need_file_items[i] itemName = need_file_names[i] ufilename = path + "\\" + item bpy.ops.import_scene.fbx( filepath=ufilename, directory=path, filter_glob="*.fbx") export(itemName) sys.path.append(io_ogre) from io_ogre.ogre.skeleton import dot_skeleton from io_ogre.ogre.mesh import dot_mesh from io_ogre.ogre.scene import dot_scene from io_ogre import config reset_blend() convert(in_dir, filters) print('Success!')

    Run Script

    Processed: 0.009, SQL: 9