According to WWDC 2013 What's new in SceneKit target geometries for morphers can be contained in a .dae file:
All the morphing information and animations can be loaded from a DAE file or you can create everything programmatically."
I have a collada .dae file that contains morph controllers. The file was created by Blender's Collada exporter, with "Include Shape Keys" selected. This converts Blender's shape keys into Collada's morph controllers. When I inspect the resulting file, I can see the shape keys listed after the main geometry in <library_geometries>
. The headers look like this:
<geometry id="Octopus-mesh_morph_Rest" name="Rest">
<mesh>
<source id="Octopus-mesh_morph_Rest-positions">
where Rest
is the name of the shape key. The geometry for the shape key/ morph target then follows this header.
After all the geometry is defined, there's the <library_controllers>
:
<library_controllers>
<controller id="Octopus-morph" name="Octopus-morph">
<morph source="#Octopus-mesh" method="NORMALIZED">
<source id="Octopus-targets">
<IDREF_array id="Octopus-targets-array" count="1">Octopus-mesh_morph_Rest</IDREF_array>
<technique_common>
<accessor source="#Octopus-targets-array" count="1" stride="1">
<param name="IDREF" type="IDREF"/>
</accessor>
</technique_common>
</source>
<source id="Octopus-weights">
<float_array id="Octopus-weights-array" count="1">0</float_array>
<technique_common>
<accessor source="#Octopus-weights-array" count="1" stride="1">
<param name="MORPH_WEIGHT" type="float"/>
</accessor>
</technique_common>
</source>
<targets>
<input semantic="MORPH_TARGET" source="#Octopus-targets"/>
<input semantic="MORPH_WEIGHT" source="#Octopus-weights"/>
</targets>
</morph>
</controller>
</library_controllers>
How can I access these morph controllers from within SceneKit? In the Xcode Scene Editor, there's no indication that the morph controllers have been recognised, eg pressing play does nothing, the animations folder is empty, and there's no additional geometries besides the base geometry.
When I load the node, it has no morpher
property attached, and no animation keys. I've tried searching the tree for entries named "Rest" but nothing is there.
let collada = SCNScene(named: "octopus.dae", inDirectory: "art.scnassets", options: nil)
let octopus = collada?.rootNode.childNodeWithName("Octopus", recursively: true)
octopus?.position = SCNVector3(0,-2,0)
print(octopus?.morpher?.animationKeys) //nil
print(octopus?.animationKeys) //Optional([])
Has anyone managed to load SCNMorpher targets from the morph controllers of a Collada .dae file? Could it be an issue with the Blender .dae exporter? Objective-C answers as well as Swift welcome. Thanks.
EDIT
I also tried using NSBundle
to load the .dae, and placing the .dae both inside and outside the art.scnassets
folder, to see if it makes a difference, but still no dice:
let collada = NSBundle.mainBundle().URLForResource("octopus", withExtension: "dae")!
let sceneSource = SCNSceneSource(URL: collada, options: [
SCNSceneSourceAnimationImportPolicyKey : SCNSceneSourceAnimationImportPolicyDoNotPlay
])
let octopusDae = sceneSource?.entryWithIdentifier("Octopus", withClass: SCNNode.self)
//let deform = sceneSource?.entryWithIdentifier("Rest", withClass: SCNGeometry.self)
print(sceneSource?.entriesPassingTest(){(entry, id, stop) in return id.containsString("Rest") })
print(octopusDae!.morpher)
print(octopusDae!.animationKeys)
EDIT 2
I have managed to get this working with .obj files, by saving each shape-key as a separate .obj file. But I would really like to get this working with Blender's .dae files as it would make iterative development and working with models with lots of shape-keys that much easier (plus, there are some strange quirks to working with Blender .obj files in SceneKit, eg all the texture coordinates seem to be flipped vertically). All the geometry I need is in the .dae file. I just can't get SceneKit to see it.