首页 文章

创建类似于Apple焦点方块的对象放置指示器

提问于
浏览
1

在我的第一个ARKit项目上工作,我使用水平平面检测将3d模型放置在水平平面上 .

我正在尝试使用焦点方块,但作为一个Swift新手,我无法想象如何使用它 . 所以我想创建自己的静态指标 .

我的方法是创建一个SCNPlane作为指标 . 但是,我的SCNPlane不像Apple的焦点方块那样快速移动,所以我需要帮助我的代码 .

这是我的代码:

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    guard let planeAnchor = anchor as? ARPlaneAnchor else { return }

    // Create a SceneKit plane to visualize the node using its position and extent.
    let plane = SCNPlane(width: CGFloat(0.1), height: CGFloat(0.1))
    let planeNode = SCNNode(geometry: plane)
    let planeMaterial = SCNMaterial()
    planeMaterial.diffuse.contents = UIColor.gray.withAlphaComponent(0.3)
    plane.materials = [planeMaterial]
    planeNode.position = SCNVector3Make(planeAnchor.center.x, 0, planeAnchor.center.z)

    // SCNPlanes are vertically oriented in their local coordinate space.
    // Rotate it to match the horizontal orientation of the ARPlaneAnchor.
    planeNode.transform = SCNMatrix4MakeRotation(-Float.pi / 2, 1, 0, 0)

    // ARKit owns the node corresponding to the anchor, so make the plane a child node.
    node.addChildNode(planeNode)
}

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    guard let planeAnchor = anchor as?  ARPlaneAnchor,
        let planeNode = node.childNodes.first,
        let plane = planeNode.geometry as? SCNPlane
        else { return }
    let x = CGFloat(planeAnchor.center.x)
    let y = CGFloat(planeAnchor.center.y)
    let z = CGFloat(planeAnchor.center.z)
    planeNode.position = SCNVector3(x, y, z)
}

不确定这是否是正确的方法?如果你们有正确的方法,请告诉我

2 回答

  • 0

    我想它必须大致以这种方式工作:

    class ViewController: UIViewController {
    
        @IBOutlet var sceneView: ARSCNView!
        var focusSquare = FocusSquare() // custom class instantiation
    
        // ............................
    
        var session: ARSession {
            return sceneView.session
        }
        override func viewDidLoad() {
            super.viewDidLoad()   
            sceneView.delegate = self
            sceneView.session.delegate = self
    
            sceneView.scene.rootNode.addChildNode(focusSquare)
        }    
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
            resetTracking()
        } 
        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            session.pause()
        }
        func resetTracking() {
            virtualObjectInteraction.selectedObject = nil     
            let configuration = ARWorldTrackingConfiguration()
            configuration.planeDetection = [.horizontal, .vertical]
            session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
            statusViewController.scheduleMessage("PLEASE, FIND A SURFACE", inSeconds: 5.0, messageType: .planeEstimation)
        }
        func updateFocusSquare(isObjectVisible: Bool) {
            if isObjectVisible {
                focusSquare.hide()
            } else {
                focusSquare.unhide()
                statusViewController.scheduleMessage("MOVE LEFT-RIGHT", inSeconds: 5.0, messageType: .focusSquare)
            }
            if let camera = session.currentFrame?.camera, case .normal = camera.trackingState,
                let result = self.sceneView.smartHitTest(screenCenter) {
                updateQueue.async {
                    self.sceneView.scene.rootNode.addChildNode(self.focusSquare)
                    self.focusSquare.state = .detecting(hitTestResult: result, camera: camera)
            }
                addObjectButton.isHidden = false
                statusViewController.cancelScheduledMessage(for: .focusSquare)
            } else {
                updateQueue.async {
                    self.focusSquare.state = .initializing
                    self.sceneView.pointOfView?.addChildNode(self.focusSquare)
                }
                addObjectButton.isHidden = true
            }
        }
    }
    

    您可以下载Apple的示例项目here,您可以在其中查看如何创建 FocusSquare() 类 .

  • 0

    Apple的焦点方形平滑行为是由于“virtualObjectLoader”类与渲染器函数的“updateAtTime”和“didUpdate”实现相结合

    只需看看这三个元素,您就会找到正确的方法

    如果有任何问题,请在添加这些概念后发布您的代码

相关问题