惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AWS News Blog
AWS News Blog
Engineering at Meta
Engineering at Meta
T
Tailwind CSS Blog
博客园 - 【当耐特】
F
Fortinet All Blogs
博客园 - 司徒正美
Stack Overflow Blog
Stack Overflow Blog
罗磊的独立博客
Google DeepMind News
Google DeepMind News
博客园_首页
A
About on SuperTechFans
博客园 - 聂微东
N
Netflix TechBlog - Medium
MongoDB | Blog
MongoDB | Blog
H
Help Net Security
GbyAI
GbyAI
O
OpenAI News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Check Point Blog
S
Schneier on Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Apple Machine Learning Research
Apple Machine Learning Research
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Martin Fowler
Martin Fowler
J
Java Code Geeks
T
Tor Project blog
T
Threatpost
G
GRAHAM CLULEY
P
Privacy & Cybersecurity Law Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Y
Y Combinator Blog
The Register - Security
The Register - Security
阮一峰的网络日志
阮一峰的网络日志
D
Docker
Vercel News
Vercel News
I
Intezer
Microsoft Security Blog
Microsoft Security Blog
爱范儿
爱范儿
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Hacker News: Front Page
P
Privacy International News Feed
Cyberwarzone
Cyberwarzone
Spread Privacy
Spread Privacy
N
News and Events Feed by Topic
N
News | PayPal Newsroom
The GitHub Blog
The GitHub Blog
U
Unit 42
WordPress大学
WordPress大学
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Simon Willison's Weblog
Simon Willison's Weblog

智伤帝的个人博客

Maya 拍屏方案汇总 C++ 道法器术 C++ 基础入门 FBX 二进制数据解析 Maya RBF 算法应用 Maya 顶点色单通道笔刷 Maya CurveBrush 笔刷开发 Unreal C++ 工具开发最小实践 Maya C++ pyd 模块开发 Unreal C++ VScode 配置 Maya C++ mll hot reload 研究 Maya CMake 构建 C++ 插件编译环境 TA 工具人知乎分享 Python 代码规范 Python - Import 机制 Python doit 库 Python dependencies 库 Python blinker 库 Python marshmallow 库
Unreal Python 导出 MetaHuman 控制器关键帧
智伤帝 · 2022-06-24 · via 智伤帝的个人博客

前言

  MetaHuman 已经在数字人领域里面相当成熟的解决方案。
  并且 UE 官方开发了源码工程。
  目前 github 上有不少人演示自己套用 MetaHuman 动画的效果。
  于是我自己也尝试着想将它 UE 里面的控制器动画导出来。
  然而却发现行不通。

image.png

  它的控制器关键帧是在 sequencer 里面。
  最初是尝试将 sequencer 的资源全部导出成 FBX。
  然而控制器的关键帧并没有跟随导入到 FBX 当中。

  于是我想到可以用 unreal python 读取关键帧数据导出 json
   Maya 再读取数据设置关键帧到控制器上。

  有思路之后就好办。
  之前我也写过脚本来获取 sequencer 关键帧的。
  需要注意如果想要使用 unreal python 的 API 需要开启相应的 C++ 插件。

image.png

  否则 python 会获取不到相应的 API 报错。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

from collections import defaultdict
import json
import os


import unreal

DIR = os.path.dirname(os.path.abspath(__file__))

def unreal_progress(tasks, label="进度", total=None):
total = total if total else len(tasks)
with unreal.ScopedSlowTask(total, label) as task:
task.make_dialog(True)
for i, item in enumerate(tasks):
if task.should_cancel():
break
task.enter_progress_frame(1, "%s %s/%s" % (label, i, total))
yield item


def main():

sequence = unreal.load_asset('/Game/Sequencer/MetaHumanSample_Sequence.MetaHumanSample_Sequence')

binding_dict = defaultdict(list)
for binding in sequence.get_bindings():
binding_dict[binding.get_name()].append(binding)


for binding in unreal_progress(binding_dict.get("Face", []), "导出 Face 数据"):

keys_dict = {}
for track in binding.get_tracks():
for section in track.get_sections():
for channel in unreal_progress(section.get_channels(), "导出关键帧"):
if not channel.get_num_keys():
continue
keys = []
for key in channel.get_keys():
frame_time = key.get_time()
frame = frame_time.frame_number.value + frame_time.sub_frame
keys.append({"frame": frame, "value": key.get_value()})

keys_dict[channel.get_name()] = keys


name = binding.get_parent().get_name()
export_path = os.path.join(DIR, "{0}.json".format(name))
with open(export_path, "w") as wf:
json.dump(keys_dict, wf, indent=4)

  上面的脚本会定位 MetaHuman 的 sequence 资源,然后导出关键帧的信息为 json

  导出会在脚本目录输出两个 json 文件。
  Maya 可以解析这个这两个 json 将关键帧设置到 控制器上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

import json
import os
import traceback


import pymel.core as pm

DIR = os.path.dirname(os.path.abspath(__file__))


def progress(seq, status="", title=""):
pm.progressWindow(status=status, title=title, progress=0.0, isInterruptable=True)
total = len(seq)
for i, item in enumerate(seq):
try:
if pm.progressWindow(query=True, isCancelled=True):
break
pm.progressWindow(e=True, progress=float(i) / total * 100)
yield item
except:
traceback.print_exc()
pm.progressWindow(ep=1)
pm.progressWindow(ep=1)


def main():


with open(os.path.join(DIR, "BP_metahuman_001.json"), "r") as rf:
data = json.load(rf)

attr_map = {"location": "t", "rotation": "r"}
status = "Import Keyframe to metahuman controller"


pm.undoInfo(ock=1)
for channel, frame_list in progress(data.items(), status=status):

has_attr = channel.count(".")

if not has_attr:

ctrl_name = channel.rsplit("_", 1)[0]
attr = "ty"
else:
parts = iter(channel.split("."))
ctrl_name = next(parts, "")
param = next(parts, "")
axis = next(parts, "")
if not axis:

attr = "t"
axis = param
else:

attr = attr_map.get(param.lower())
attr += axis.split("_")[0].lower()


attribute = pm.PyNode(".".join([ctrl_name, attr]))
for frame_data in frame_list:
frame = frame_data.get("frame")
value = frame_data.get("value")
attribute.setKey(t=frame, v=value)

pm.undoInfo(cck=1)

  加载 unreal 导出的数据。

总结

  其实整个流程不复杂,有思路就很好处理。

版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 智伤帝的个人博客

打赏

  • 微信

    微信

  • 支付宝

    支付宝