【问题标题】:How can I use OBJ file or CTM file instead of DAE file in SceneKit?如何在 SceneKit 中使用 OBJ 文件或 CTM 文件而不是 DAE 文件?
【发布时间】:2015-05-10 05:10:47
【问题描述】:

我以前在IOS上用openGL和metal渲染3d场景,我使用的文件格式是OBJ和CTM。这些天我正在尝试场景工具包。看来 SceneKit 只加载 DAE 文件。我在网上找到的所有demo都使用DAE文件,我在他们的代码中看不到顶点和面的数组。 如何加载 OBJ 文件或 CTM 文件而不是 DAE 文件?

【问题讨论】:

    标签: ios 3d scenekit


    【解决方案1】:

    您可以通过编写自己的导入器来做到这一点。看看SCNGeometry、SCNGeometrySource 和SCNGeometryElement。

    编辑: 从 iOS 9.0 和 OS X 10.11 SceneKit 开始可以打开 OBJ 文件或 Model I/O 支持的任何其他文件格式。您可以使用以前存在的 API(例如 +sceneNamed:)或新的 +sceneWithMDLAsset: 方法来执行此操作。

    【讨论】:

    • 如何从 SCNGeometryElement 导出所有网格?
    • 此答案需要针对 iOS 9 / OS X 10.11 进行更新。
    【解决方案2】:

    编辑:ModelIO 现在可能可以加载 OBJ 文件。我自己没有尝试过这条路。这个答案是在 iOS 9 和 OS X 10.11 之前写的:

    SceneKit 无法在 iOS 上加载 DAE 文件,实际上,它实际上将 DAE 文件预编译为 iOS 设备的内部格式。

    如果您想将您的 OBJ 转换为 DAE,您可以在 OS X 上编写一个简单的导入器/导出器来执行此操作 - 在 OS X 上,SceneKit 将实际读取 OBJ 文件(它没有记录,但它可以工作)并会编写 DAE。

    如果您想尝试自己阅读 OBJ,也可以在 github 上下载“Assimp”项目,但将其放入 SceneKit 对象需要一些工作。

    【讨论】:

    • 您现在可以使用 ModelIO 在 iOS(iOS 9+)上加载 OBJ 文件,如@halmueller 的回答中所述。但正如 Wil 所暗示的,您可能不应该。对于您的应用附带的任何资产(甚至通过您的应用在 AppStore 提交后提交,例如托管在您自己的服务器上的附加内容),最好在 Mac 上使用 Xcode 或您自己的基于 ModelIO/SceneKit 的工具进行预处理,然后发送.scn 在该设备上加载速度更快的文件。
    • 这是每个 iOS 开发人员至少了解一点 Mac 开发的一个很好的论据。这种实用程序(在 Mac 上)很方便。
    • “它实际上将 DAE 文件预编译为 iOS 设备的内部格式”——“内部格式”似乎只是 .scn 格式。可以使用let scene = SCNScene(named: "some_3d_model.dae") 在 iOS 上加载 DAE(刚刚使用 Xcode 8 对照 iOS 10.0.1 检查)。
    • 再深入研究一下。 iOS 编译的….app/some_3d_model.dae 是一个二进制plist,其中包含一个zippedData 条目和一堆ZIP 压缩数据,如果base64 解码和未压缩会生成一个contents 文件。 contents 文件是一个二进制 plist,看起来像 SceneKit 内部场景表示 - 有许多与 SceneKit API 1:1 匹配的键,例如 geometryElements、geometrySource、SCNMaterial 属性名称和scene 与 attributes、nodeTree、startTime 等,如 SCNScene/MDLAsset。 (真正的 .dae 是一个以 <COLLADA> 为根的 XML 文件。)
    【解决方案3】:

    从 iOS 9/OS X 10.11 开始,您可以使用 Model I/O 的 MDLAsset 导入 OBJ 文件(以及一些其他格式)。 How do you convert Wavefront OBJ file to an SCNNode with Model I/O 有示例代码。

    【讨论】:

      【解决方案4】:

      加载 OBJ 文件

      就像向 MDLAsset 传递一个有效的 URL 一样简单。

      private func nodeForURL(url: NSURL) -> SCNNode
      {
          let asset = MDLAsset(URL: url)
          let object = asset.objectAtIndex(0)
          let node = SCNNode(MDLObject: object)
      
          return node
      }
      

      这不仅会正确加载.obj 文件,还会加载引用的.mtl 文件。

      【讨论】:

        【解决方案5】:

        有关支持的文件格式的更多信息:

        SceneKit 支持以下 3D 文件格式,可以使用 Xcode 中的场景编辑器将其导入.scn 文件:

        DAE、OBJ、Alembic、STL 和 PLY 文件。

        来源:WWDC 2015 Session "Enhancements to SceneKit" 02:24

        【讨论】:

          猜你喜欢
          • 2015-01-18
          • 2015-10-16
          • 2020-05-03
          • 2016-08-02
          • 2017-01-19
          • 2018-02-05
          • 2015-06-13
          • 2018-03-11
          • 2018-08-12
          相关资源
          最近更新 更多