快速添加自定义几何体(视图)到SceneKit中的scnnode

问题描述 投票:0回答:1

我有一个用 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)
ios swift swiftui scenekit scnnode
1个回答
0
投票

要使用自定义 SwiftUI 视图作为 SceneKit 中

SCNNode
的几何图形,您可以首先将 SwiftUI 视图渲染为
UIImage
。这可以通过创建视图快照来完成。

一旦获得

UIImage
,您就可以将其作为纹理应用到
SCNMaterial
SCNNode

例如,请参阅 Benoit Layer
 中的“
更新 SceneKit
中的 SCNMaterial 纹理”。

最后,为您的SCNPlane创建一个几何

(例如,
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 上下文中不会进行交互。

© www.soinside.com 2019 - 2024. All rights reserved.