генерировать определенное количество SCNPlane [Swift, ARkit] - PullRequest
0 голосов
/ 01 февраля 2019

Я новичок в 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
    }



}

И спасибо

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

1 Ответ

0 голосов
/ 03 февраля 2019

Вы вызываете узел DidAdd (для: Anchor :), который будет вызываться только один раз для привязки изображения.Глядя на свой код, вы создаете в 5 раз одну и ту же геометрию в одной и той же позиции, так что похоже, что есть только одна.попытайтесь изменить положение в соответствии с i, которое идет от 0 до 5.

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

, теперь самолеты должны складываться друг на друга.

...