我有一个用 SceneKit 构建的交互式地球仪。地球是一个 SCNNode,代表土地的点也是 SCNNode,并且是地球的子节点。我想添加一个自定义视图作为地球仪孩子之一的几何图形。我知道如何添加具有球形几何形状的节点并更改其颜色等等。我不确定如何使用自定义视图(swift ui)来显示节点的几何形状。
let lowerCircle = SCNSphere(radius: dotRadius * 5)
lowerCircle.firstMaterial?.diffuse.contents = GenericColor(cgColor: UIColor.white.cgColor)
lowerCircle.firstMaterial?.lightingModel = SCNMaterial.LightingModel.constant
let dotNode = SCNNode(geometry: lowerCircle)
dotNode.name = "NewYorkDot"
dotNode.position = textureMap[i].position
positions.append(dotNode.position)
dotNodes.append(dotNode)
要使用自定义 SwiftUI 视图作为 SceneKit 中
SCNNode
的几何图形,您可以首先将 SwiftUI 视图渲染为 UIImage
。这可以通过创建视图快照来完成。
一旦获得
UIImage
,您就可以将其作为纹理应用到 SCNMaterial
的 SCNNode
。中的“更新 SceneKit 中的
SCNMaterial
纹理”。
(例如,
SCNNode
),并将具有自定义纹理的材质应用于该几何。
过程是:
[ SwiftUI View ]
│
├─ Render to UIImage
│
[ UIImage ]
│
├─ Apply as Texture to Material
│
[ SCNMaterial ]
│
├─ Attach to SCNPlane or other geometry
│
[ SCNNode ]
您的 SwiftUI 视图
UIImage
将是:
import SwiftUI
extension View {
func snapshot() -> UIImage {
let controller = UIHostingController(rootView: self)
let view = controller.view
let targetSize = controller.view.intrinsicContentSize
view?.bounds = CGRect(x: 0, y: 0, width: targetSize.width, height: targetSize.height)
view?.backgroundColor = .clear
let renderer = UIGraphicsImageRenderer(size: targetSize)
return renderer.image { _ in
view?.drawHierarchy(in: controller.view.bounds, afterScreenUpdates: true)
}
}
}
然后应用自定义几何形状:
import SceneKit
import SwiftUI
// Example SwiftUI View
struct CustomView: View {
var body: some View {
Text("Hello World")
.frame(width: 100, height: 100)
.background(Color.red)
}
}
// Convert SwiftUI view to UIImage
let image = CustomView().snapshot()
// Create material with this image
let material = SCNMaterial()
material.diffuse.contents = image
// Create a geometry, e.g., SCNPlane
let plane = SCNPlane(width: 1.0, height: 1.0)
plane.materials = [material]
// Create a SCNNode with this geometry
let customNode = SCNNode(geometry: plane)
// Position and add the custom node as needed
customNode.position = SCNVector3(x: 0, y: 0, z: 0)
dotNode.addChildNode(customNode)
但是:SwiftUI 视图会渲染为静态图像,因此它们在 SceneKit 上下文中不会进行交互。