ios - ARKit - 对象未放置

标签 ios swift xcode ios11 arkit

我正在尝试使用 ARKit 构建家具放置 AR 应用程序, 我的项目中有 .scn 椅子及其 PNG 纹理,我的应用程序应该检测水平面,然后当用户点击时,将对象放置在点击的位置。

但是当我点击时,该对象并未放置。

View Controller :

    import UIKit
import SceneKit
import ARKit

class ViewController: UIViewController {

    @IBOutlet weak var sceneView: ARSCNView!

    override func viewDidLoad() {
        super.viewDidLoad()

        addTapGestureToSceneView()

        configureLighting()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        setUpSceneView()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        sceneView.session.pause()
    }

    func setUpSceneView() {
        let configuration = ARWorldTrackingConfiguration()
        configuration.planeDetection = .horizontal

        sceneView.session.run(configuration)

        sceneView.delegate = self
        sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints]
    }

    func configureLighting() {
        sceneView.autoenablesDefaultLighting = true
        sceneView.automaticallyUpdatesLighting = true
    }

    @objc func addShipToSceneView(withGestureRecognizer recognizer: UIGestureRecognizer) {
        let tapLocation = recognizer.location(in: sceneView)
        let hitTestResults = sceneView.hitTest(tapLocation, types: .existingPlaneUsingExtent)

        guard let hitTestResult = hitTestResults.first else { return }
        let translation = hitTestResult.worldTransform.translation
        let x = translation.x
        let y = translation.y
        let z = translation.z

        guard let scene = SCNScene(named: "art.scnassets/chair.scn"),
            let shipNode = scene.rootNode.childNode(withName: "chair_DIFFUSE", recursively: false)
            else {
                print("Failed to render")
                return
        }


        shipNode.position = SCNVector3(x,y,z)
        sceneView.scene.rootNode.addChildNode(shipNode)
    }

    func addTapGestureToSceneView() {
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.addShipToSceneView(withGestureRecognizer:)))
        sceneView.addGestureRecognizer(tapGestureRecognizer)
    }
}

extension float4x4 {
    var translation: float3 {
        let translation = self.columns.3
        return float3(translation.x, translation.y, translation.z)
    }
}

extension UIColor {
    open class var transparentLightBlue: UIColor {
        return UIColor(red: 90/255, green: 200/255, blue: 250/255, alpha: 0.50)
    }
}

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

        // 2
        let width = CGFloat(planeAnchor.extent.x)
        let height = CGFloat(planeAnchor.extent.z)
        let plane = SCNPlane(width: width, height: height)

        // 3
        plane.materials.first?.diffuse.contents = UIColor.transparentLightBlue

        // 4
        let planeNode = SCNNode(geometry: plane)

        // 5
        let x = CGFloat(planeAnchor.center.x)
        let y = CGFloat(planeAnchor.center.y)
        let z = CGFloat(planeAnchor.center.z)
        planeNode.position = SCNVector3(x,y,z)
        planeNode.eulerAngles.x = -.pi / 2

        // 6
        node.addChildNode(planeNode)
    }

    func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
        // 1
        guard let planeAnchor = anchor as?  ARPlaneAnchor,
            let planeNode = node.childNodes.first,
            let plane = planeNode.geometry as? SCNPlane
            else { return }

        // 2
        let width = CGFloat(planeAnchor.extent.x)
        let height = CGFloat(planeAnchor.extent.z)
        plane.width = width
        plane.height = height

        // 3
        let x = CGFloat(planeAnchor.center.x)
        let y = CGFloat(planeAnchor.center.y)
        let z = CGFloat(planeAnchor.center.z)
        planeNode.position = SCNVector3(x, y, z)
    }
}

因此,当我点击放置对象时,我会打印“无法渲染”,并且控制台中没有打印任何其他内容!

enter image description here

enter image description here

最佳答案

经过一些代码调整后,我用以下几行代码解决了这个问题:

// Create a new scene
    let scene = SCNScene(named: "art.scnassets/chair.scn")!

    let node = scene.rootNode.childNode(withName: "chair", recursively: true)!
    node.position = SCNVector3(x,y,z)

    scene.rootNode.addChildNode(node)

    //shipNode.position = SCNVector3(x,y,z)
    sceneView.scene = scene

而不是:

guard let scene = SCNScene(named: "art.scnassets/chair.scn"),
        let shipNode = scene.rootNode.childNode(withName: "chair_DIFFUSE", recursively: false)
        else {
            print("Failed to render")
            return
    }


    shipNode.position = SCNVector3(x,y,z)
    sceneView.scene.rootNode.addChildNode(shipNode)

关于ios - ARKit - 对象未放置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49694199/

相关文章:

xcode - 没有 @NSApplicationMain 的 OSX 应用程序

objective-c - NSBlock操作没有被取消

ios - Xcode动态实时更新折线图

ios - 当我尝试呈现 View 时收到此警告 "attempt to present ViewController whose view is not in the window hierarchy"

ios - OS Sierra 10.12 上从终端重新签名 IPA 分段故障 11 错误

ios - AudioSystemSounds 的 XCode 6 错误?

用于查看 3D STEP 文件 (.stp) 的 iOS 库

ios - UIActivityViewController 在使用 sourceView 或 barButtonItem 的 iPad 上崩溃

ios - 如何根据值在模型对象数组中进行搜索

xcode - 在 Xcode 中搜索文件