从 Collada (.dae) 文件(在 Maya 中创建)导入的 SceneKit 键控混合形状动画未播放

Posted

技术标签:

【中文标题】从 Collada (.dae) 文件(在 Maya 中创建)导入的 SceneKit 键控混合形状动画未播放【英文标题】:SceneKit keyed blend shape animation imported from Collada (.dae) file (created in Maya) not playing 【发布时间】:2018-10-08 18:02:04 【问题描述】:

我正在使用 Maya 创建动画以在 SceneKit 中使用。我正在使用 Maya 的内置 FBX DAE 导出器导出为 COLLADA 文件 (.dae)。

节点变换上的动画都可以完美运行。例如,如果我们有平移、旋转或缩放的动画(或这些动画的组合),则动画会正确导入节点。

但是,当我基于键控混合形状输入导入动画时,动画无法播放。

在 Xcode 中,如果我单击 .dae 文件并开始查看属性,节点就在那里,并且附加了混合形状(几何变形器),并且它是可操作的。

此外,还列出了一个动画,如果我查看节点内的属性,动画也会列在那里。

如果我遍历 SCNNode 的 animationKeys 属性,就会有一个动画,并且它具有正确的时间量。但我似乎无法让它工作。

在 Xcode 方面,我已经尝试过:

在 Xcode 中提示更新 .dae 文件时说“更新”。

出现提示时不更新 .dae 文件

将 Jon Allee 的 Collada Morph Adjuster 应用于 .dae 文件,然后将其提供给 Xcode。

加载为 SCNSceneSource 而不是 SCNScene

在 Maya 方面,我尝试了几种创建/导出过程的变体:

尝试了“删除单个键”复选框(有和没有)

尝试了导出窗口中的“烘焙动画”设置

尝试选中和取消选中“Deformed models”和“Blend Shapes

在导出窗口的“Collada”选项下,我尝试过检查和不检查“Single Matrix”。我现在通常检查“Single Matrix”,否则我会在 Xcode 中获得一堆动画。但是,检查或不检查此选项 not 似乎对 SceneKit 的行为有任何影响。变换动画以任何一种方式工作,而混合形状动画则不能以任何方式工作。

我还仔细查看了几十个 Stack Overflow 问题——这不是重复的问题,以及 Apple 论坛中的问题并且我没有想法。

我整理了一个 quick sample project,它演示了工作和非工作,并包括源 Maya 文件以及几个解释器视频。

我正在使用:

Maya 2018.2(剪辑 ID:201711281015-8e846c9074)

Xcode 9.3 (9E145)

ma​​cOS High Sierra 10.13.4

iOS 11.3.1

代码sn-p:

let scene = SCNScene()

let fileName = "anim.scnassets/cube-blend.dae"
let modelName = "pCube2"

guard let nodeScene = SCNScene(named: fileName) else 
    fatalError("COULD NOT OPEN SCENE FILE \(fileName)")
   
guard let node = nodeScene.rootNode.childNode(withName: modelName, recursively: true) else 
    fatalError("COULD NOT FIND NODE \(modelName) in file \(fileName)")
   
scene.rootNode.addChildNode(node)

这就是加载和运行其他动画所需的全部内容。

更新 1: 我将此作为错误提交给 Apple,Apple 进行了测试并回来说 Maya 正在生成一个伪造的 .dae 文件。

具体来说,他们写道:

cube-blend.dae 包含混合形状动画,但目标语法 不正确:pCube2-lib-morph-weights(Weight_0_0)。这是一 导出器问题(我们尝试在 Modo 中导入此文件 [无法打开] 和 Cinema4D [正确加载但没有动画])。

这是 Maya 导出器中的一个错误。

根据我自己的测试,我倾向于同意他们的观点,尽管很难理解动画中使用的***软件之一是如何完全损坏导出器的。

我尝试在此处粘贴实际的 COLLADA .dae 文件,但它太大了。这是一个保管箱链接: cube-blend.dae

这是关于:

的部分
<library_animations>
    <animation id="pCube2-anim" name="pCube2"><animation><source id="pCube2-Matrix-animation-input"><float_array id="pCube2-Matrix-animation-input-array" count="25">

0.041667 0.083333 0.125000 0.166667 0.208333 0.250000 0.291667 0.333333 0.375000 0.416667 0.458333 0.500000 0.541667 0.583333 0.625000 0.666667
0.708333 0.750000 0.791667 0.833333 0.875000 0.916667 0.958333 1.000000 1.041667</float_array><technique_common><accessor source="#pCube2-Matrix-animation-input-array" count="25"><param name="TIME" type="float"/></accessor></technique_common></source><source id="pCube2-Matrix-animation-output-transform"><float_array id="pCube2-Matrix-animation-output-transform-array" count="400">

0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000
0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 0.010000 0.000000 0.000000 0.000000 0.000000 1.000000</float_array><technique_common><accessor source="#pCube2-Matrix-animation-output-transform-array" count="25" stride="16"><param type="float4x4"/></accessor></technique_common></source><source id="pCube2-Interpolations"><Name_array id="pCube2-Interpolations-array" count="25">
 LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR
LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR
LINEAR LINEAR</Name_array><technique_common><accessor source="#pCube2-Interpolations-array" count="25"><param type="name"/></accessor></technique_common></source><sampler id="pCube2-Matrix-animation-transform"><input semantic="INPUT" source="#pCube2-Matrix-animation-input"/><input semantic="OUTPUT" source="#pCube2-Matrix-animation-output-transform"/><input semantic="INTERPOLATION" source="#pCube2-Interpolations"/></sampler><channel source="#pCube2-Matrix-animation-transform" target="pCube2/matrix"/></animation><animation><source id="pCube2-lib-morph-weights-animation-inputWeight_0_0"><float_array id="pCube2-lib-morph-weights-animation-inputWeight_0_0-array" count="5">

0.041667 1.041667 1.541667 1.583333 3.875000</float_array><technique_common><accessor source="#pCube2-lib-morph-weights-animation-inputWeight_0_0-array" count="5"><param name="TIME" type="float"/></accessor></technique_common></source><source id="pCube2-lib-morph-weights-animation-outputWeight_0_0"><float_array id="pCube2-lib-morph-weights-animation-outputWeight_0_0-array" count="5">

0.000000 0.788732 1.000000 1.000000 0.000000</float_array><technique_common><accessor source="#pCube2-lib-morph-weights-animation-outputWeight_0_0-array" count="5"><param name="Weight_0_0" type="float"/></accessor></technique_common></source><source id="pCube2-lib-morph-weights-animation-intanWeight_0_0"><float_array id="pCube2-lib-morph-weights-animation-intanWeight_0_0-array" count="5">

0.000000 0.222222 0.000000 0.000000 0.000000</float_array><technique_common><accessor source="#pCube2-lib-morph-weights-animation-intanWeight_0_0-array" count="5"><param name="Weight_0_0" type="float"/></accessor></technique_common></source><source id="pCube2-lib-morph-weights-animation-outtanWeight_0_0"><float_array id="pCube2-lib-morph-weights-animation-outtanWeight_0_0-array" count="5">

0.000000 0.111111 0.000000 0.000000 0.000000</float_array><technique_common><accessor source="#pCube2-lib-morph-weights-animation-outtanWeight_0_0-array" count="5"><param name="Weight_0_0" type="float"/></accessor></technique_common></source><source id="pCube2-lib-morph-weights-animation-interpolationWeight_0_0"><Name_array id="pCube2-lib-morph-weights-animation-interpolationWeight_0_0-array" count="5">
 BEZIER BEZIER BEZIER BEZIER BEZIER</Name_array><technique_common><accessor source="#pCube2-lib-morph-weights-animation-interpolationWeight_0_0-array" count="5"><param type="name"/></accessor></technique_common></source><sampler id="pCube2-lib-morph-weights-animationWeight_0_0"><input semantic="INPUT" source="#pCube2-lib-morph-weights-animation-inputWeight_0_0"/><input semantic="OUTPUT" source="#pCube2-lib-morph-weights-animation-outputWeight_0_0"/><input semantic="IN_TANGENT" source="#pCube2-lib-morph-weights-animation-intanWeight_0_0"/><input semantic="OUT_TANGENT" source="#pCube2-lib-morph-weights-animation-outtanWeight_0_0"/><input semantic="INTERPOLATION" source="#pCube2-lib-morph-weights-animation-interpolationWeight_0_0"/></sampler><channel source="#pCube2-lib-morph-weights-animationWeight_0_0" target="pCube2-lib-morph-weights(Weight_0_0)"/></animation></animation>
  </library_animations>

更新 2: 苹果工程师还表示“用“pCube2-lib-morph-weights(0)”替换目标“pCube2-lib-morph-weights(Weight_0_0)”是可行的。然而,在我的测试中,我无法证实这一点。

知道在动画块中应该如何引用混合形状权重吗?

谢谢!

【问题讨论】:

我不确定它是否应该在您使用的导出/导入路径中工作......但用于 blendshape 动画的 SceneKit API 是 SCNMorpher。您是否检查过导入资产中的任何节点是否附加了morpher @rickster - 感谢您的回复 - SCNMorpher 实际上工作得很好。我可以用它们的重量驱动它们,它们按预期运行。我试图做的这个动画基本上是混合形状(SCNMorpher)加权的预编程序列。我希望 SceneKit 可以处理它,因为它是一种非常常见的动画制作方式,但 Apple 的文档在这个主题上没有任何帮助。 我也面临与此类似的问题。但就我而言,我使用的是 Cinema4d。如果我使用从 Blender 导出的模型,它适用于 XCode。当我对 Cinema 4D 做同样的事情时,Xcode 不起作用。 Blender 导出模型的大小是 Cinema 4D 导出模型的三倍。你能解释一下如何解决这个动画问题 【参考方案1】:

您可以在 Maya 中使用 Script Editor 烘焙动画,然后将其导出为 .dae 格式。有时Edit Export Preset 窗口中的烘焙选项不起作用。

所以,选择带有动画 blendshape 的 3d 模型并执行以下 python 命令:

import maya.cmds as cmds

cmds.bakeSimulation('pFace1', t=(1,96), sb=1, at=["rx","ry","rz"], hi="below") # obsolete command

# 'pFace1' = a name of your geo in DAG ;
# t = timerange in frames ;
# sb = sampleBy (amount to sample) ;
# at = list of attributes to select ;
# hi = hierarchy. Valid values are "above", "below", "both", "none" ;

cmds.bakeResults('pFace1', t=(1,96), simulation=True) 
# brand new command

或者直接使用主菜单:EditKeysBake Simulation

另一个可靠的做法是使用OBJ sequence exporter(.obj 文件的填充序列)。

【讨论】:

我会检查一下,但我有几个问题——问题 #1:对于属性列表,我假设 tx/ty/tz 是翻译。那正确吗?我问这个是因为纯翻译的动画可以正确导出(并正确导入 Xcode/SceneKit),但我遇到的问题是混合形状目标权重的动画。问题#2:层次结构的上/下/两者/无之间有什么区别?问题#3:我发现的 bakeSimulation MEL 文档没有提供更多细节,还说它已被弃用,而是使用 bakeResults。 #2。例如below 选项指定要烘焙的键集将包括所选对象的动画曲线以及层次结构中它下方的所有对象。 Bothabovebelow 它在层次结构中。 None 表示参数关闭。 #1。只有rxryrz 是该命令的实际属性。你是绝对正确的。 r 意思是 relative 我想。 #3。我添加了一个新命令bakeResults。但旧的也很好用。

以上是关于从 Collada (.dae) 文件(在 Maya 中创建)导入的 SceneKit 键控混合形状动画未播放的主要内容,如果未能解决你的问题,请参考以下文章

从 A-Frame 或 JS 更新 Collada (.dae) 文件代码

使用 SceneKit 从 DAE/COLLADA 中提取动画顶点

GLES/Java Collada(.dae) 骨架导入

将 collada (dae) 文件加载到 SCNNode (Swift - SceneKit)

如何使用 openGL 在 android studio 中渲染 .dae(collada) 文件

Blender 如何解释 Collada 文件 (.dae) 以进行装配?