如何将Collada .dae文件的变形控制器中的SCNMorpher目标加载到SceneKit中?

时间:2016-05-30 00:09:14

标签: animation blender scenekit collada

根据WWDC 2013 What's new in SceneKit,变形器的目标几何可以包含在.dae文件中:

  

所有变形信息和动画都可以从DAE文件加载,或者您可以通过编程方式创建所有内容。“

我有一个包含变形控制器的collada .dae文件。该文件由Blender的Collada导出器创建,选择了“包含形状键”。这会将Blender的形状键转换为Collada的变形控制器。当我检查生成的文件时,我可以看到<library_geometries>中主要几何体后面列出的形状键。标题如下所示:

<geometry id="Octopus-mesh_morph_Rest" name="Rest">
  <mesh>
    <source id="Octopus-mesh_morph_Rest-positions">

其中Rest是形状键的名称。然后,形状键/变形目标的几何图形将跟随此标题。

在定义了所有几何体之后,有<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>

如何从SceneKit中访问这些变形控制器?在Xcode场景编辑器中,没有任何迹象表明变形控制器已被识别,例如按下播放无效,动画文件夹为空,除基础几何体外没有其他几何形状。

当我加载节点时,它没有附加morpher属性,也没有动画键。我已经尝试在树上搜索名为“Rest”的条目,但没有任何内容。

    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([])

有没有人设法从Collada .dae文件的变形控制器加载SCNMorpher目标?这可能是Blender .dae出口商的问题吗? Objective-C答案以及Swift欢迎。感谢。

修改

我还尝试使用NSBundle来加载.dae,并将.dae放在art.scnassets文件夹的内部和外部,以查看它是否有所作为,但仍然没有骰子:

    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)

编辑2

我已经设法通过将每个shape-key保存为单独的.obj文件来使用.obj文件。但是我真的希望能够使用Blender的.dae文件,因为它可以进行迭代开发,并且可以更容易地处理具有大量形状键的模型(另外,在SceneKit中使用Blender .obj文件有一些奇怪的怪癖例如,所有纹理坐标似乎都是垂直翻转的)。我需要的所有几何都在.dae文件中。我只是无法让SceneKit看到它。

1 个答案:

答案 0 :(得分:3)

Blender并不是在需要它们的节点下编写instance_controllers。请参阅Blender问题:T50807。

如果您只想从形状键加载SCNMorphers,可以使用引用library_controllers下相应条目的instance_controller替换受影响节点下的instance_geometry元素。

<node id="Cube" name="Cube" type="NODE">
    <matrix sid="transform">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>
    <instance_geometry url="#Cube-mesh" name="Cube">
      <bind_material>
        <technique_common>
          <instance_material symbol="Material-material" target="#Material-material"/>
        </technique_common>
      </bind_material>
    </instance_geometry>
  </node>

变为:

  <node id="Cube" name="Cube" type="NODE">
    <matrix sid="transform">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>
    <instance_controller url="#Cube-morph" name="Cube-morph">
      <bind_material>
        <technique_common>
          <instance_material symbol="Material-material" target="#Material-material"/>
        </technique_common>
      </bind_material>
    </instance_controller>
  </node>

SceneKit有自己的问题。据我所知,它不能正确导入Collada文件,该文件的节点既有SCNSkinner(又名Blender骨架)又有SCNMorhper(又名Blender形状键)。 Blender不会导出这个,但您可以通过使用Collada CTS测试文件来查看问题。 Morph_on_skin,skin_on_morph,morph_on_morph在SceneKit中都有问题。

我制作了一个修复缺少SCNMorphers的简单案例的工具。可在此处找到:https://github.com/JonAllee/ColladaMorphAdjuster