1
votes

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!

1
I’m not sure if it’s supposed to work in the export/import path you’re taking... but the SceneKit API for blendshape animation is SCNMorpher. Have you checked to see if any of the nodes in your imported asset have a morpher attached?rickster
@rickster - Thanks for the response -- the SCNMorphers actually work just fine. I can drive those with their weights and they operate as expected. This animation I am trying to do is basically pre-programmed sequences of blend shape (SCNMorpher) weighting. I would EXPECT that SceneKit could handle it, as it is a very common way of animating, but Apple's documentation is unhelpfully silent on the subject.drewster
I am also facing issue similar to this.. But in my case, I used Cinema4d. If I used exported model from Blender It works fine with XCode.. When I did the same with Cinema 4D Xcode did not work. Blender exported model has triple the size of Cinema 4D exported model. Can u explain how to fix this animation issueTommy

1 Answers

0
votes

You could bake an animation using Script Editor in Maya before exporting it as .dae format. Sometimes the baking option in Edit Export Preset window doesn't work.

So, select your 3d model with animated blendshape and execute this python command:

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

Or simply use a main menu: EditKeysBake Simulation.

Another robust practise is to use OBJ sequence exporter (a padded sequence of .obj files).