我正在创建一个应用程序,该应用程序将在检测到图像后不断更新平面节点的坐标。但是,我想知道我将如何做。我的代码如下:
extension ViewController: ARSCNViewDelegate {
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
DispatchQueue.main.async {
guard let imageAnchor = anchor as? ARImageAnchor,
var imageName = imageAnchor.referenceImage.name else { return }
let planeNode = self.getPlaneNode(withReferenceImage: imageAnchor.referenceImage)
planeNode.opacity = 1.0
planeNode.eulerAngles.x = -.pi / 2
planeNode.runAction(self.fadeAction)
node.addChildNode(planeNode)
let nodeCam = self.sceneView.session.currentFrame!.camera
let cameraTransform = nodeCam.transform
planeNode.position.x = cameraTransform.columns.3.x + 1
planeNode.position.y = cameraTransform.columns.3.y + 1
if imageName == "sample" {
self.imageOne.text = "\"\(imageName)\""
self.instructions.text = "IMAGE DETECTED: \"\(imageName)\""
self.coordinateView.isHidden = false
self.updateOne.isHidden = false
self.coordinateX.text = "X: " + String(planeNode.position.x)
self.coordinateY.text = "Y: " + String(planeNode.position.y)
}
我要如何使当平面节点移动时与X坐标和Y坐标相对应的标签不断变化和更新?我尝试过重复循环,其中:
repeat {
self.coordinateX.text = "X: " + String(planeNode.position.x)
self.coordinateY.text = "Y: " + String(planeNode.position.y)
} while imageName == "sample"
但这只会导致代码在检测到图像时冻结。有什么建议么?
答案 0 :(得分:0)
这里有两个选项;您可以设置一个DispatchSource来注册计划的事件并建立处理程序。该处理程序可以是将点设置到标签中的函数。示例:
YDKJS book series
如果您认为数据会在短时间内大量更新/更改,那么此方法非常有用。
如果您认为这种情况不会发生,那么我将使用“ didSet”来监视变量并在“ didSet”函数中设置该函数。
答案 1 :(得分:0)
让我们说我有一个ARReferenceImage
,叫做BlackMirrorz
。
在以下ARSCNViewDelegate
中。方法,当检测到ARReferenceImage
时,我正在加载模型:
//-------------------------
//MARK: - ARSCNViewDelegate
//-------------------------
extension ViewController: ARSCNViewDelegate{
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
//1. Check We Have A Valid Image Anchor
guard let imageAnchor = anchor as? ARImageAnchor else { return }
//2. Get The Detected Reference Image
let referenceImage = imageAnchor.referenceImage
//3. Load Our Model Only If Our Reference Image Name Is Valid & The Model Hasnt Already Been Placed
if let matchedTargetImageName = referenceImage.name, matchedTargetImageName == "BlackMirrorz" && !modelPlaced {
//a. Set Our Model To The Size Of The ReferenceImage
let model = SCNNode(geometry: SCNPlane(width: referenceImage.physicalSize.width, height: referenceImage.physicalSize.height))
//b. Rotate It
model.eulerAngles.x = -.pi/2
//c. Add It To Our Node
node.addChildNode(model)
//d. Name Our Node
node.name = matchedTargetImageName
}
}
}
最重要的是代码的最后一行;我在其中为ARImageAnchor's
节点提供了名称,这将使我们以后可以轻松跟踪。
已经加载了我们的模型,然后我们可以使用以下ARSessionDelegate
方法:
func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) { }
简单地说:
告诉代表该会话已调整其中一个的属性 或更多锚点。
因此,很容易使用您的Labels
的当前坐标来更新任何SCNText's
,ARImageAnchor
等,
//--------------------------
//MARK: - ARSessionDelegate
//--------------------------
extension ViewController: ARSessionDelegate{
func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
//1. Enumerate Through Our Current ARAnchors
for anchor in anchors{
//2. If We Have An ARImageAnchor Then Get The Corresponding Node & Check That It's Name Is The One We Want To Track
if let imageAnchor = anchor as? ARImageAnchor,
let targetNode = self.augmentedRealityView.node(for: imageAnchor), targetNode.name == "BlackMirrorz"{
//3. Get The Transform For The Anchor And Log This To The Console Or Update Your Labels
print("""
Current Position X Of Anchor = \(imageAnchor.transform.columns.3.x)
Current Position Y Of Anchor = \(imageAnchor.transform.columns.3.y)
Current Position Z Of Anchor = \(imageAnchor.transform.columns.3.z)
""")
}
}
}
}
希望它会为您指明正确的方向...