swift - 无法将 3D 模型作为 SCNGeometry 提供给 MDLMesh 容器

标签 swift scenekit augmented-reality arkit ios12

我正在创建 AR 应用程序(Xcode 10.1、Swift 4.2.1)。

我想将 USDZ 3D 对象加载到一个 SceneKit 的场景中,然后将其作为 MDL 网格进行处理。

这是我的代码:

import ARKit
import SceneKit.ModelIO

let scene = SCNScene(named: "art.scnassets/emptyScene.scn")!

if let filePath = Bundle.main.path(forResource: "Helicopter", 
                                        ofType: "usdz", 
                                   inDirectory: "art.scnassets") {

    let refURL = URL(fileURLWithPath: filePath)
    let refNode = SCNReferenceNode(url: refURL)
    refNode?.load()
    scene.rootNode.addChildNode(refNode!)
}

let helicopterGeo = refNode!.geometry

let mdlMesh = MDLMesh(scnGeometry: helicopterGeo!)      // ERROR APPEARS HERE
try! mdlMesh.makeVerticesUniqueAndReturnError()
let flattenedGeometry = SCNGeometry(mdlMesh: mdlMesh)
let flattenedNode = SCNNode(geometry: flattenedGeometry)
scene.rootNode.addChildNode(flattenedNode)


But compiler gives me an error:

"Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value"

问题是:我应该使用什么方法来分配一个"Helicopter.usdz"几何图形到helicopterGeo 常量?

请帮我找到解决方法!

您可以下载USDZ文件进行测试HERE .

最佳答案

这应该有效:

var scene: SCNScene!
if let filePath = Bundle.main.path(forResource: "Helicopter", 
                                    ofType: "usdz", 
                               inDirectory: "art.scnassets") {

    let refURL = URL(fileURLWithPath: filePath)
    let mdlAsset = MDLAsset(url: refURL)
    scene = SCNScene(mdlAsset: mdlAsset)

}

SCNReferenceNode 仅适用于 .scn 文件。然后,您可以从 scenerootNode 的子节点获取几何体。

let helicopterNode = scene.rootNode.childNode(withName: "helicopter", recursively: true)
let geometry = helicopterNode.geometry!

编辑

使用来自 AR Quick Look Gallery 的文件之一我设法让这段代码工作。我遇到的主要问题是特定子节点的名称,有一个名为“RetroTV”但它没有附加任何几何图形,它只是“RetroTVBody”和“RetroTVScreen”的父节点。唯一的问题是它没有加载几何体的纹理。

var scene: SCNScene!
if let filePath = Bundle.main.path(forResource: "retrotv",
                                   ofType: "usdz",
                                   inDirectory: "art.scnassets") {

    let refURL = URL(fileURLWithPath: filePath)
    let mdlAsset = MDLAsset(url: refURL)
    scene = SCNScene(mdlAsset: mdlAsset)

    let tvNode = scene.rootNode.childNode(withName: "RetroTVBody", recursively: true)
    let geometry = tvNode!.geometry!

} else {

    print("invalid path!")

}

上述代码也适用于 if let 语句之外的 tvNodegeometry 声明。

关于swift - 无法将 3D 模型作为 SCNGeometry 提供给 MDLMesh 容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52807356/

相关文章:

ios - HitTest (_ :options:) for SCNNodes without physicsBody swift

ios - SceneKit:使 block 更逼真或更像 3D

Android 增强现实工具包

swift - 无法转换类型 'NSAttributedString.DocumentAttributeKey' 的值, "DocumentReadingOptionKey"也不起作用

swift - 枚举中的方法在声明中不需要参数时要求参数

swift - 如何在 ARKit 2/SceneView 中扩展线段

android - Galaxy Tab 和基于标记的增强现实

android - 是否有适合在已知环境中识别物体的图像处理库/AR 技术?

ios - 构建失败 : Value of optional type '[SFUserAccount]?' not unwrapped

ios - 如何在 UITableView 或 UICollectionView 中使用变量 UIStackView?