处理我的第一个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)
}
不确定这是否是正确的做法?如果你们有正确的方法,请告诉我
答案 0 :(得分: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()
课程。
答案 1 :(得分:0)
Apple的焦点方形平滑行为是由于" virtualObjectLoader" class与" updateAtTime"和" didUpdate"渲染器函数的实现
只需看看这三个元素,您就会找到正确的方法
如果有任何问题
,请在添加这些概念后发布您的代码