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

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

导出插件设置

从Blender导出OGRE模型

Blender 运行 Python 脚本

打开控制台输出

从Blender批量导出OGRE模型骨骼动画_第1张图片

从Blender批量导出OGRE模型骨骼动画_第2张图片

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

从Blender批量导出OGRE模型骨骼动画_第3张图片

从Blender批量导出OGRE模型骨骼动画_第4张图片

选择文本编辑器

从Blender批量导出OGRE模型骨骼动画_第5张图片

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

从Blender批量导出OGRE模型骨骼动画_第6张图片

从Blender批量导出OGRE模型骨骼动画_第7张图片

Blender API 文档

Blender Python API

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

  1. 导出的动画名字默认为 my_animation

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

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

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

  5. 导出动画骨骼文件(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

从Blender批量导出OGRE模型骨骼动画_第8张图片

你可能感兴趣的:(OGRE,python,blender,ogre)