【问题标题】:How do I load SCNMorpher targets from a Collada .dae file's morph controllers into SceneKit?如何将 SCNMorpher 目标从 Collada .dae 文件的变形控制器加载到 SceneKit?
【发布时间】:2016-09-27 17:16:45
【问题描述】:

根据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 是形状键的名称。形状键/变形目标的几何形状随后跟随此标题。

定义完所有几何图形后,就有了&lt;library_controllers&gt;:

<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 看到它。

【问题讨论】:

    标签: animation blender scenekit collada


    【解决方案1】:

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

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

    <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 有其自身的问题。据我所知,它不会正确导入具有 SCNSkinner(又名 Blender 骨架)和 SCNMorhper(又名 Blender 形状键)的节点的 Collada 文件。 Blender 不会导出此文件,但您可以使用 Collada CTS 测试文件查看问题。 Morph_on_skin、skin_on_morph、morph_on_morph 在 SceneKit 中都有问题。

    我制作了一个工具来修复缺少 SCNMorpher 的简单情况。可以在这里找到:https://github.com/JonAllee/ColladaMorphAdjuster

    【讨论】:

    • 嘿乔恩,伟大的工作。这真的解决了我的问题。我认识到,我的模型的文件大小显着增加(5mb 到 100mb)。我的模型有很多用于面部表情的形状键(我认为大约 50 个)。添加实例控制器真的会对文件大小产生如此大的影响吗?
    • 乔恩,您的意思是,在使用您的工具时,与骨架和 shapekeys 混合将无法实际工作或正确翻译?我尝试过使用 shapekeys 并没有得到更正的 dae。
    猜你喜欢
    • 2014-10-12
    • 2015-01-12
    • 2017-01-19
    • 2014-10-10
    • 2016-12-05
    • 2021-03-25
    • 2018-10-08
    • 1970-01-01
    • 2018-03-12
    相关资源
    最近更新 更多