【问题标题】:ARKit – Adding box to anchor?ARKit – 添加框到锚点?
【发布时间】:2021-04-24 05:59:04
【问题描述】:

我想创建一个简单的对象(框)并将其显示在某个位置,但我能找到的所有内容都与使用 renderer() 方法有关。

有没有更简单的方法来使用锚点?只需将锚点添加到我的SCNBox 对象?

let rect = SCNBox(width: 10.0, height: 10.0, length: 10.0, chamferRadius: 0)
rect.firstMaterial?.diffuse.contents = UIImage(named: "test.png") 
let anchor = ARWorldAnchor( /* ... created with 4 columns */ )
// here how to add the rect object to the anchor ?
session.add(anchor: anchor)

【问题讨论】:

    标签: swift augmented-reality scenekit arkit


    【解决方案1】:

    ARKit |场景套件

    正如您在代码中建议的那样,我在 ARWorldAnchor 类中创建了一个自定义锚点。要自动跟踪该锚点,您需要 renderer(_:didAdd:for:)session(_:didAdd:) 实例方法告诉代理新的 AR 锚点已添加到会话中。这就是为什么当你希望你的锚点/锚点被跟踪时,有必要在 ARKit/SceneKit 中使用 renderer(_:didAdd:for:)renderer(_:didUpdate:for:)

    import ARKit
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var sceneView: ARSCNView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            sceneView.delegate = self
    
            let config = ARWorldTrackingConfiguration()
            sceneView.session.run(config)
    
            let worldAnchor = ARWorldAnchor(column3: [0, 0,-1, 1])
            sceneView.session.add(anchor: worldAnchor)
        }
    }
    
    extension ViewController: ARSCNViewDelegate {
    
        func renderer(_ renderer: SCNSceneRenderer,
                     didAdd node: SCNNode,
                      for anchor: ARAnchor) {
    
            guard let worldAnchor = anchor as? ARWorldAnchor else { return }
    
            let myNode = SCNNode()
            myNode.geometry = SCNBox(width: 0.1, height: 0.1, 
                                    length: 0.1, chamferRadius: 0)
            let path = "texture.jpg"
            myNode.geometry?.firstMaterial?.diffuse.contents = UIImage(named: path)
            node.addChildNode(myNode)
        }
    }
    
    class ARWorldAnchor: ARAnchor {
    
        init(column0: SIMD4<Float> = [1, 0, 0, 0],
             column1: SIMD4<Float> = [0, 1, 0, 0],
             column2: SIMD4<Float> = [0, 0, 1, 0],
             column3: SIMD4<Float> = [0, 0, 0, 1]) {
    
            let transform = simd_float4x4(columns: (column0,
                                                    column1, 
                                                    column2,
                                                    column3))
    
            let worldAnchor = ARAnchor(name: "World Anchor",
                                  transform: transform)
    
            super.init(anchor: worldAnchor)
        }
    
        required init(anchor: ARAnchor) {
            super.init(anchor: anchor)
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            fatalError("Hasn't been implemented yet...")
        }
    }
    

    RealityKit

    您所说的一种更简单的方法是在 RealityKit 中。当您使用AnchorEntity 绑定一个盒子时,它将在运行会话期间自动跟踪。如您所见,与 ARKit/SceneKit 对相比,样板代码最少。

    import UIKit
    import RealityKit
    
    class ViewController: UIViewController {
        
        @IBOutlet var arView: ARView!
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            let box: MeshResource = .generateBox(size: 0.1)
            var material = SimpleMaterial()
            material.baseColor = try! .texture(.load(named: "texture.jpg"))
            let entity = ModelEntity(mesh: box, materials: [material])
            
            let anchor = AnchorEntity(world: [0, 0,-1])
            anchor.addChild(entity)
            arView.scene.anchors.append(anchor)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-11-28
      • 1970-01-01
      • 2023-04-10
      • 2018-07-19
      • 1970-01-01
      • 1970-01-01
      • 2010-10-19
      • 2012-11-27
      • 2021-11-18
      相关资源
      最近更新 更多