我是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
}
}
谢谢
.....................................
答案 0 :(得分:0)
您正在调用DidAdd Node(for:Anchor :),每个Image 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))
飞机现在应该彼此堆叠。