我在寻找什么?
我的需求简单来说就是:
- 使用ARKit,使用iPhone相机检测一个对象
- 找到该对象在虚拟空间中的位置
- 使用SceneKit在虚拟空间中放置一个3D对象。该3D对象应该在标记后面。
例如,使用相机检测一个小图像/标记在3D空间中的位置,然后在虚拟空间中在此标记的后面放置另一个3D球模型(因此球将被用户隐藏,因为标记/图像在前面)。
我目前能做到什么?
- 我能够使用ARKit检测标记/图像
- 我能够在屏幕上定位一个球形3D模型。
我的问题是什么?
我无法将球定位在被检测标记/图像的后面。
当球在标记前面时,球可以正确地隐藏标记。您可以从侧面看到图中的球在标记的前面。如下所示:
但当球在标记的后面时,相反的情况并没有发生。球始终看起来在前面挡住了标记。我希望标记可以隐藏球。因此,场景没有尊重球位置的z深度。如下所示:
代码
请参考注释
override func viewDidLoad() {
super.viewDidLoad()
sceneView.delegate = self
sceneView.autoenablesDefaultLighting = true
//This loads my 3d model.
let ballScene = SCNScene(named: "art.scnassets/ball.scn")
ballNode = ballScene?.rootNode
//The model I have is too big. Scaling it here.
ballNode?.scale = SCNVector3Make(0.1, 0.1, 0.1)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//I am trying to detect a marker/image. So ImageTracking configuration is enough
let configuration = ARImageTrackingConfiguration()
//Load the image/marker and set it as tracking image
//There is only one image in this set
if let trackingImages = ARReferenceImage.referenceImages(inGroupNamed: "Markers",
bundle: Bundle.main) {
configuration.trackingImages = trackingImages
configuration.maximumNumberOfTrackedImages = 1
}
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
sceneView.session.pause()
}
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
let node = SCNNode()
if anchor is ARImageAnchor {
//my image is detected
if let ballNode = self.ballNode {
//for some reason changing the y position translate the ball in z direction
//Positive y value moves it towards the screen (infront the marker)
ballNode.position = SCNVector3(0.0, -0.02, 0.0)
//Negative y value moves it away from the screen (behind the marker)
ballNode.position = SCNVector3(0.0, -0.02, 0.0)
node.addChildNode(ballNode)
}
}
return node
}
如何使场景遵循z轴位置?换句话说,如何在使用ARKit框架检测到的图像/标记后显示3D模型在其后面?
我正在iOS 12上运行,使用Xcode 10.3。如果需要其他信息,请告诉我。