如何使用 SceneKit 从 COLLADA (.dae) 文件中获取几何图形

Posted

技术标签:

【中文标题】如何使用 SceneKit 从 COLLADA (.dae) 文件中获取几何图形【英文标题】:How to get a geometry from a COLLADA (.dae) file with SceneKit 【发布时间】:2017-01-19 07:58:07 【问题描述】:

我需要读取 COLLADA 文件中的 <geometry> 以创建变形目标数组并将网格从基础几何体动画化到目标几何体。

我只能从嵌入在节点中的基本几何图形访问几何图形(COLLADA 文件只有一个<node>):

planeNode.geometry = scene!.rootNode.childNodeWithName("Plane", recursively: true)!.geometry

这是 COLLADA 文件的完整源代码(有 3 个几何图形和 1 个节点,但只能访问 1 个几何图形):

<?xml version="1.0" encoding="utf-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
  <asset>
    <contributor>
      <author>Blender User</author>
      <authoring_tool>Blender 2.77.0 commit date:2016-04-05, commit time:18:12, hash:abf6f08</authoring_tool>
    </contributor>
    <unit name="meter" meter="1"/>
    <up_axis>Z_UP</up_axis>
  </asset>
  <library_images/>
  <library_geometries>
    <geometry id="Plane-mesh" name="Plane">
      <mesh>
        <source id="Plane-mesh-positions">
          <float_array id="Plane-mesh-positions-array" count="12">-1 -1 0 1 -1 0 -1 1 0 1 1 0</float_array>
          <technique_common>
            <accessor source="#Plane-mesh-positions-array" count="4" stride="3">
              <param name="X" type="float"/>
              <param name="Y" type="float"/>
              <param name="Z" type="float"/>
            </accessor>
          </technique_common>
        </source>
        <source id="Plane-mesh-normals">
          <float_array id="Plane-mesh-normals-array" count="3">0 0 1</float_array>
          <technique_common>
            <accessor source="#Plane-mesh-normals-array" count="1" stride="3">
              <param name="X" type="float"/>
              <param name="Y" type="float"/>
              <param name="Z" type="float"/>
            </accessor>
          </technique_common>
        </source>
        <vertices id="Plane-mesh-vertices">
          <input semantic="POSITION" source="#Plane-mesh-positions"/>
        </vertices>
        <polylist count="2">
          <input semantic="VERTEX" source="#Plane-mesh-vertices" offset="0"/>
          <input semantic="NORMAL" source="#Plane-mesh-normals" offset="1"/>
          <vcount>3 3 </vcount>
          <p>1 0 2 0 0 0 1 0 3 0 2 0</p>
        </polylist>
      </mesh>
    </geometry>
    <geometry id="Plane-mesh_morph_Key1" name="Key1">
      <mesh>
        <source id="Plane-mesh_morph_Key1-positions">
          <float_array id="Plane-mesh_morph_Key1-positions-array" count="12">-1 -1 0 1 -1 0 -1 1 0 1 2 0</float_array>
          <technique_common>
            <accessor source="#Plane-mesh_morph_Key1-positions-array" count="4" stride="3">
              <param name="X" type="float"/>
              <param name="Y" type="float"/>
              <param name="Z" type="float"/>
            </accessor>
          </technique_common>
        </source>
        <source id="Plane-mesh_morph_Key1-normals">
          <float_array id="Plane-mesh_morph_Key1-normals-array" count="6">0 0 1 0 0 1</float_array>
          <technique_common>
            <accessor source="#Plane-mesh_morph_Key1-normals-array" count="2" stride="3">
              <param name="X" type="float"/>
              <param name="Y" type="float"/>
              <param name="Z" type="float"/>
            </accessor>
          </technique_common>
        </source>
        <vertices id="Plane-mesh_morph_Key1-vertices">
          <input semantic="POSITION" source="#Plane-mesh_morph_Key1-positions"/>
        </vertices>
        <polylist count="2">
          <input semantic="VERTEX" source="#Plane-mesh_morph_Key1-vertices" offset="0"/>
          <input semantic="NORMAL" source="#Plane-mesh_morph_Key1-normals" offset="1"/>
          <vcount>3 3 </vcount>
          <p>1 0 2 0 0 0 1 1 3 1 2 1</p>
        </polylist>
      </mesh>
    </geometry>
    <geometry id="Plane-mesh_morph_Key2" name="Key2">
      <mesh>
        <source id="Plane-mesh_morph_Key2-positions">
          <float_array id="Plane-mesh_morph_Key2-positions-array" count="12">-1 -1 0 1 -1 0 -1 1 0 2 1 0</float_array>
          <technique_common>
            <accessor source="#Plane-mesh_morph_Key2-positions-array" count="4" stride="3">
              <param name="X" type="float"/>
              <param name="Y" type="float"/>
              <param name="Z" type="float"/>
            </accessor>
          </technique_common>
        </source>
        <source id="Plane-mesh_morph_Key2-normals">
          <float_array id="Plane-mesh_morph_Key2-normals-array" count="3">0 0 1</float_array>
          <technique_common>
            <accessor source="#Plane-mesh_morph_Key2-normals-array" count="1" stride="3">
              <param name="X" type="float"/>
              <param name="Y" type="float"/>
              <param name="Z" type="float"/>
            </accessor>
          </technique_common>
        </source>
        <vertices id="Plane-mesh_morph_Key2-vertices">
          <input semantic="POSITION" source="#Plane-mesh_morph_Key2-positions"/>
        </vertices>
        <polylist count="2">
          <input semantic="VERTEX" source="#Plane-mesh_morph_Key2-vertices" offset="0"/>
          <input semantic="NORMAL" source="#Plane-mesh_morph_Key2-normals" offset="1"/>
          <vcount>3 3 </vcount>
          <p>1 0 2 0 0 0 1 0 3 0 2 0</p>
        </polylist>
      </mesh>
    </geometry>
  </library_geometries>
  <library_controllers>
    <controller id="Plane-morph" name="Plane-morph">
      <morph source="#Plane-mesh" method="NORMALIZED">
        <source id="Plane-targets">
          <IDREF_array id="Plane-targets-array" count="2">Plane-mesh_morph_Key1 Plane-mesh_morph_Key2</IDREF_array>
          <technique_common>
            <accessor source="#Plane-targets-array" count="2" stride="1">
              <param name="IDREF" type="IDREF"/>
            </accessor>
          </technique_common>
        </source>
        <source id="Plane-weights">
          <float_array id="Plane-weights-array" count="2">0 0</float_array>
          <technique_common>
            <accessor source="#Plane-weights-array" count="2" stride="1">
              <param name="MORPH_WEIGHT" type="float"/>
            </accessor>
          </technique_common>
        </source>
        <targets>
          <input semantic="MORPH_TARGET" source="#Plane-targets"/>
          <input semantic="MORPH_WEIGHT" source="#Plane-weights"/>
        </targets>
      </morph>
    </controller>
  </library_controllers>
  <library_visual_scenes>
    <visual_scene id="Scene" name="Scene">
      <node id="Plane" name="Plane" type="NODE">
        <matrix sid="transform">1 0 0 0 0 -4.37114e-8 -1 0 0 1 -4.37114e-8 0 0 0 0 1</matrix>
        <instance_geometry url="#Plane-mesh" name="Plane"/>
      </node>
    </visual_scene>
  </library_visual_scenes>
  <scene>
    <instance_visual_scene url="#Scene"/>
  </scene>
</COLLADA>

感谢任何帮助。谢谢!

【问题讨论】:

不幸的是 SceneKit 不读取几何标签,因此我们必须创建具有相关几何图形的节点,然后隐藏它们。不是最好的,但由于缺乏更好的工作方式。这里的工作代码:link 【参考方案1】:

您可以使用entryWithIdentifier:withClass: 检索不在场景图中的对象。或者,在您的创作工具中,您可以将变形器附加到节点,然后使用节点的morpher 属性来检索其目标几何图形。

【讨论】:

谢谢@mnuages。你能用代码帮我理解第二个选项吗? 我已经尝试了第一个选项,但仍然只能访问一个几何 func loadGeometriesFromSceneSource(sceneSource: SCNSceneSource) let identifiers = sceneSource.identifiersOfEntriesWithClass(SCNGeometry.self) as [String] for identifier in identifiers print(identifier) // it only gets me the Base Geometry morphs.append(sceneSource.entryWithIdentifier(identifier, withClass: SCNGeometry.self)!) 我做错了什么?...

以上是关于如何使用 SceneKit 从 COLLADA (.dae) 文件中获取几何图形的主要内容,如果未能解决你的问题,请参考以下文章

使用 SceneKit 从 DAE/COLLADA 中提取动画顶点

从scenekit中的网络服务器加载collada文件

从 Collada (.dae) 文件(在 Maya 中创建)导入的 SceneKit 键控混合形状动画未播放

将 collada (dae) 文件加载到 SCNNode (Swift - SceneKit)

SceneKit - 停止连续循环 Collada 动画

带有子节点的 SceneKit Collada 动画