无法将 3D 模型作为 SCNGeometry 提供给 MDLMesh 容器
Can't feed a MDLMesh container with 3D model as SCNGeometry
我正在创建 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 文件。然后,您可以从 scene
的 rootNode
的子节点获取几何图形。
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
语句之外的 tvNode
和 geometry
声明。
我没有确切的答案,但在你的情况下我会做的是检查 refNode
.
的层次结构
加载后打个断点,用调试器看看有没有children。那些 children 有什么几何形状吗?他们有children几何学吗?
创建3D资产时,有时多个部分会被分组到一个parent节点上,而在很多情况下parent节点是空的。
是 Maya 二进制文件中的错误,还是 usdz
转换的错误 – 我不清楚。 Xcode 没有在 Scene graph
的最简单层次结构中看到对象的正确名称:它只显示 Helicopter
而不是 pHelicopter1
。我的 3D 对象是使用多边形 Extrude
工具从 pCube1
制作的。
这是最终代码,它运行良好:
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!")
}
我正在创建 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 文件。然后,您可以从 scene
的 rootNode
的子节点获取几何图形。
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
语句之外的 tvNode
和 geometry
声明。
我没有确切的答案,但在你的情况下我会做的是检查 refNode
.
加载后打个断点,用调试器看看有没有children。那些 children 有什么几何形状吗?他们有children几何学吗?
创建3D资产时,有时多个部分会被分组到一个parent节点上,而在很多情况下parent节点是空的。
是 Maya 二进制文件中的错误,还是 usdz
转换的错误 – 我不清楚。 Xcode 没有在 Scene graph
的最简单层次结构中看到对象的正确名称:它只显示 Helicopter
而不是 pHelicopter1
。我的 3D 对象是使用多边形 Extrude
工具从 pCube1
制作的。
这是最终代码,它运行良好:
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!")
}