【问题标题】:generate a specific number of SCNPlane [Swift, ARkit]生成特定数量的 SCNPlane [Swift, ARkit]
【发布时间】:2019-02-03 16:31:47
【问题描述】:

我是 swift 和 ARkit 的初学者,我想生成特定数量的 SCNPlane,例如 10 个。我尝试了多种方式,但我只得到了一个 SCNPlane。

我需要怎么做才能在代码中放置多个 SCNPlane 而它们之间没有任何重叠?

这是我的代码部分:

//
//  MarkViewController.swift
//  Jawwab
//
//  Created by Nora Almunaif on 26/05/1440 AH.
//  Copyright © 1440 atheer. All rights reserved.
//

import UIKit
import SceneKit
import ARKit

class MarkViewController: UIViewController {

    @IBOutlet weak var sceneView: ARSCNView!



    lazy var bookNode: SCNNode = {
        let text = SCNText(string: "only for testing", extrusionDepth: 1)
        let material = SCNMaterial()
        material.diffuse.contents = UIColor.black
        text.materials = [material]

        let node = SCNNode()
        node.position = SCNVector3(0, 0, 0)
        node.scale = SCNVector3(0.0009, 0.0009, 0.0009)
        node.geometry = text



        let minVec = node.boundingBox.min
        let maxVec = node.boundingBox.max
        let bound = SCNVector3Make(maxVec.x - minVec.x,
                                   maxVec.y - minVec.y,
                                   maxVec.z - minVec.z);

        let plane = SCNPlane(width: CGFloat(bound.x + 25),
                             height: CGFloat(bound.y + 8))
        plane.cornerRadius = 5
        plane.firstMaterial?.diffuse.contents = UIColor.gray.withAlphaComponent(0.8)

        let planeNode = SCNNode(geometry: plane)
        planeNode.position = SCNVector3(CGFloat( minVec.x - 10) + CGFloat(bound.x) / 2 ,
                                        CGFloat( minVec.y) + CGFloat(bound.y) / 2,CGFloat(minVec.z - 0.01))

        node.addChildNode(planeNode)
        planeNode.name = "text"
        return node
    }()




    override func viewDidLoad() {
        super.viewDidLoad()


        self.sceneView.delegate = self as? ARSCNViewDelegate
        sceneView.showsStatistics = true

        self.configureLighting()
    }



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

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

        resetTrackingConfiguration()
    }


    func resetTrackingConfiguration() {
        guard let referenceImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil)
            else {
                print("No image detected");
                return }
        let configuration = ARWorldTrackingConfiguration()
        configuration.detectionImages = referenceImages
        let options: ARSession.RunOptions = [.resetTracking, .removeExistingAnchors]
        sceneView.session.run(configuration, options: options)
        //  label.text = "Move camera around to detect images"
    }



}
@available(iOS 12.0, *)
extension MarkViewController: ARSCNViewDelegate {

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        DispatchQueue.main.async {
            guard let imageAnchor = anchor as? ARImageAnchor,
                let imageName = imageAnchor.referenceImage.name else { return }
            var i=0
            while i<5 {
            let overlayNode = self.getNode(withImageName: imageName)

            let minVec = overlayNode.boundingBox.min
            let maxVec = overlayNode.boundingBox.max
            let bound = SCNVector3Make(maxVec.x - minVec.x,
                                       maxVec.y - minVec.y,
                                       maxVec.z - minVec.z);

            let plane = SCNPlane(width: CGFloat(bound.x),
                                 height: CGFloat(bound.y))
            plane.cornerRadius = 5
            plane.firstMaterial?.diffuse.contents = UIColor.gray.withAlphaComponent(0.8)

            let planeNode = SCNNode(geometry: plane)
            planeNode.position = SCNVector3(CGFloat( minVec.x - 10) + CGFloat(bound.x) / 2 ,
                                            CGFloat( minVec.y) + CGFloat(bound.y) / 2,CGFloat(minVec.z - 0.01))


            let image = UIImage(named: "flag")
            planeNode.geometry?.firstMaterial?.diffuse.contents = image


            planeNode.name = "text"

            self.sceneView.scene.rootNode.addChildNode(overlayNode)
            self.sceneView.autoenablesDefaultLighting = true
            i = i + 1
            }

        }
    }




    func getPlaneNode(withReferenceImage image: ARReferenceImage) -> SCNNode {
        let plane = SCNPlane(width: image.physicalSize.width,
                             height: image.physicalSize.height)
        let node = SCNNode(geometry: plane)
        return node
    }

    func getNode(withImageName name: String) -> SCNNode {
        var node = SCNNode()
        switch name {
        case "Book":
            node = bookNode
        default:
            break
        }
        return node
    }



}

谢谢你

.....................................

【问题讨论】:

    标签: swift arkit


    【解决方案1】:

    您正在调用 DidAdd Node(for:Anchor:) ,每个图像锚点只会调用一次。查看您的代码,您在完全相同的位置创建了 5 次完全相同的几何图形,因此看起来只有一个。尝试根据从 0 到 5 的 i 来改变位置。

     planeNode.position = SCNVector3(CGFloat( minVec.x - 10) + CGFloat(bound.x) / 2 , CGFloat( minVec.y) + CGFloat(bound.y) + i / 2,CGFloat(minVec.z - 0.01))
    

    这些飞机现在应该堆叠在一起。

    【讨论】:

      猜你喜欢
      • 2020-06-04
      • 1970-01-01
      • 2018-12-09
      • 2017-12-29
      • 1970-01-01
      • 2018-12-22
      • 1970-01-01
      • 2020-09-16
      • 2013-10-15
      相关资源
      最近更新 更多