I'm using Maya to create animations to use in SceneKit. I'm exporting as COLLADA file (.dae) using Maya's built-in FBX DAE exporter.
Animations on the node transform all work perfectly. For example, if we have an animation of the translation, rotation, or scale -- or a combination of those -- the animation imports correctly with the node.
However, when I import an animation based on keyed blend shape inputs, the animation doesn't play.
Within Xcode, if I click on the .dae file and start looking at attributes, the node is there and has the blend shape (geometry morpher) attached, and it is manipulable.
Additionally, an animation is listed, and if I look at attributes within the node, the animation is listed there as well.
If I iterate through the SCNNode's animationKeys property, an animation is there and it has the correct amount of time associated with it. But I can't seem to get it to work.
On the Xcode side of things, I have tried:
Saying "Update" when prompted to update the .dae file within Xcode.
Not updating the .dae file when prompted
Applying Jon Allee's Collada Morph Adjuster to the .dae file, before giving it to Xcode.
Loading as SCNSceneSource instead of SCNScene
On the Maya side of things, I've tried several variations on the creation/export process:
Tried the "remove single key" checkbox (with and without)
Tried the "bake animation" setting in the export window
Tried checking and unchecking "Deformed models" and "Blend Shapes"
Under the "Collada" option in the export window, I've tried with and without "Single Matrix" checked. I usually check "Single Matrix" now or I get a bunch of animations within Xcode. However, checking or not checking this option does not appear to have any effect on SceneKit's behavior. The transform animations work either way, and the blend shape animations don't work either way.
I've also looked at dozens of Stack Overflow questions carefully -- this is not a duplicate question, as well as ones in Apple's forums and am out of ideas.
I put together a quick sample project that demonstrates both the working and non-working, and includes the source Maya files as well as a couple of explainer videos.
I'm using:
Maya 2018.2 (Cut ID: 201711281015-8e846c9074)
Xcode 9.3 (9E145)
macOS High Sierra 10.13.4
iOS 11.3.1
Code snippet:
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)
This is all that's needed to load and run other animations.
UPDATE 1: I filed this as a bug with Apple who tested and came back and said the Maya is generating a bogus .dae file.
Specifically, they wrote:
cube-blend.dae contains a blend shape animation but the target syntax is incorrect: pCube2-lib-morph-weights(Weight_0_0). This is an exporter issue (we tried to import this file in Modo [can’t open it] and Cinema4D [loads correctly but with no animation]).
This is a bug in Maya’s exporter.
Based on my own tests, I'm inclined to agree with them, though it's hard to understand how one of the very top pieces of software used in animation has a completely broken exporter.
I tried to paste the actual COLLADA .dae file here but it's too big. Here's a dropbox link: cube-blend.dae
Here's the section on :
<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>
UPDATE 2:
Apple engineer also stated "Replacing the target “pCube2-lib-morph-weights(Weight_0_0)” by “pCube2-lib-morph-weights(0)” works". In my testing, however, I could not confirm this.
Any idea on how the blend shape weights are supposed to be referenced within the animation block?
Thanks!