我正在创建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)
但编译器给我一个错误:
"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文件。然后,您可以从rootNode
的scene
的子节点获取几何体。
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!")
}
上面的代码也适用于tvNode
语句之外的geometry
和if let
声明。
我没有确切的答案,但我会在你的情况下做的是检查refNode
的层次结构。
加载后放置断点并使用调试器查看它是否有任何子节点。那些孩子有几何形状吗?他们有几何形象的孩子吗?
创建3D资源时,有时会在父节点上对多个部分进行分组,并且在许多情况下父节点为空。
是Maya二进制文件中的错误,还是usdz
转换的错误 - 我不确切知道。 Xcode没有在Scene graph
最简单的层次结构中看到对象的正确名称:它只显示了pHelicopter1
而不是Helicopter
。我的3D对象是由pCube1
使用多边形Extrude
工具制作的。
这是最终的代码,它工作正常:
import ARKit
import SceneKit.ModelIO
//..........................................................
var 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 mdlAsset = MDLAsset(url: refURL)
scene = SCNScene(mdlAsset: mdlAsset)
let helicopterNode = scene.rootNode.childNode(withName: "pHelicopter1",
recursively: true)
let geometry = helicopterNode!.geometry!
let mdlMesh = MDLMesh(scnGeometry: geometry)
try! mdlMesh.makeVerticesUniqueAndReturnError()
let flattenedGeometry = SCNGeometry(mdlMesh: mdlMesh)
let flattenedNode = SCNNode(geometry: flattenedGeometry)
scene.rootNode.addChildNode(flattenedNode)
} else {
print("Invalid path!")
}