motionbuilder 使用总结

本文介绍MotionBuilder软件中Python脚本的应用,包括安装额外Python库的方法、规范化动捕数据的脚本实现及从BVH格式转换到FBX格式的过程。适用于希望提高MotionBuilder使用效率的专业人士。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

脚本篇

安装额外的python库需要 mobupy.exe -m pip install
执行脚本的窗口在window->Python Editor

常用的记录整理

正规化动捕数据

def normalize_trans_rots(trans,rots,refid=0):
    r = sciR.from_euler("xyz", rots, degrees=True).as_matrix()
    r1 = r[refid]

    b1 = r1[0]
    b2 = np.array([0,1,0])

    b1 = b1 - (b1*b2).sum(-1) * b2
    b1 = b1 / np.linalg.norm(b1)
    b3 = np.cross(b1, b2)

    rref = np.vstack((b1, b2, b3)).T # inv
    
    r = np.einsum('cd,bda->bca', rref, r)
    trans = np.einsum('cd,bd->bc', rref, trans)
    rots = sciR.from_matrix(r).as_euler("xyz", degrees=True)
    
    basetrans = trans[refid:refid+1].copy()
    #print(  basetrans, trans[:5] )
    basetrans[:, 1] = 0
    trans = trans - basetrans
    #print(  basetrans, trans[:5] )
    print( r[refid] )
    return trans,rots

bvh2fbx

@ECHO off

set exe="D:\soft\progm\mb2022\MotionBuilder 2022/bin/x64/motionbuilder.exe"

%exe% -batch -console  -verbosePython scripts/bvh2fbx.py 

python 脚本,需要创建 tmp 文件夹,并把 bvh 文件夹放进去

import sys, os, logging
import pyfbsdk


#import numpy as np

logging.basicConfig(
    filename="tmp/compile_results.log",
    filemode="w",
    format="%(asctime)s %(levelname)-8s %(message)s",
    level=logging.DEBUG,
)

console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
console.setFormatter(logging.Formatter("%(asctime)s %(levelname)-8s %(message)s"))
logging.getLogger("").addHandler(console)


def bvh2fbx(animation_file, output_file, template_file, sound_file=None):

    pyfbsdk.FBApplication().FileNew()
    if template_file:
        logging.info("Loading %s..." % str(template_file))

        if not pyfbsdk.FBApplication().FileOpen(str(template_file)):
            raise IOError("Could not open file: {}".format(str(template_file)))

    if sound_file is not None:
        # Load Audio
        logging.info("Loading %s..." % str(sound_file))
        audio = pyfbsdk.FBAudioClip(sound_file)
        if audio is None:
            raise IOError("Could not open file: {}".format(str(sound_file)))

        # Rescale Timespan
        pyfbsdk.FBSystem().CurrentTake.LocalTimeSpan = pyfbsdk.FBTimeSpan(
            pyfbsdk.FBTime(0), audio.Duration
        )

    # Set FPS
    #pyfbsdk.FBPlayerControl().SetTransportFps(pyfbsdk.FBTimeMode.kFBTimeModeCustom, 60) # 
    pyfbsdk.FBPlayerControl().SetTransportFps(pyfbsdk.FBTimeMode.kFBTimeMode30Frames) 
    pyfbsdk.FBPlayerControl().SnapMode = (
        pyfbsdk.FBTransportSnapMode.kFBTransportSnapModeSnapOnFrames
    )

    # Load BVH
    if not pyfbsdk.FBApplication().FileImport(animation_file, True):
        raise IOError("Could not open file: {}".format(str(animation_file)))

    # Save FBX
    pyfbsdk.FBApplication().FileSave(output_file)


def main(input_file, output_file=None):
    try:
        logging.info("======")
        logging.info("BVH2FBX")
        logging.info("======")
        template_file = None

        if not output_file:
            output_file = input_file.replace(".bvh", ".fbx")
        #else:
        #    output_file = os.path.join(output_file, os.path.basename(input_file)).replace(".bvh", ".fbx")

        print(input_file, output_file)

        bvh2fbx(
            input_file,
            output_file,
            template_file,
            sound_file=None
        )

        pyfbsdk.FBApplication().FileExit()

    except Exception as e:
        logging.exception("FAILED:")
        raise e


import sys
logging.info(os.getcwd())

import os

import glob

#din, dout = sys.argv[1:3]
din, dout="tmp/bvh", "tmp/fbx"
logging.info("======")
for fin in glob.glob(f"{din}/*.bvh"):
    fin = os.path.abspath(fin)
    nm = os.path.relpath(fin, din)
    fout = os.path.abspath(dout+"/"+nm.replace(".bvh", ".fbx"))
    _dout = os.path.dirname(fout)
    if not os.path.exists(_dout):
        os.makedirs(_dout)
    logging.info(fin +" --- " + fout  + " --- " + _dout)
    main(fin, fout)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值