如何指定相对于 ARImageAnchor 的子节点位置?
How do I specify a child node location relative to ARImageAnchor?
我有一个 RealityKit 应用程序正在执行一些基本的 AR 图像跟踪。它检测到一个矩形图像,我希望在图像的每个角放置一些球形点。我知道我可以使用 ModelEntity
自己创建球体,但我无法弄清楚如何从参考图像中指定这些球体相对于已建立的 ARImageAnchor
的位置。
我想我只需要一个与 SceneKit 的 addChildNode(SCNNode)
函数相对应的函数,它使用 SCNVector3Make()
来指定一个位置。我只是没能找到一种方法来建立相对位置并将子节点分配给这些 SceneKit 函数之外的 ARImageAnchor
。 RealityKit 中是否有内置的东西可以实现这一点,或者有没有办法使用 SceneKit 放置角点,同时仍然使用我当前的 RealityKit 设置进行 AR 参考图像跟踪?
尝试以下方法:
import ARKit
import RealityKit
class ViewController: UIViewController {
@IBOutlet var arView: ARView!
var anchorEntity = AnchorEntity()
let model_01 = ModelEntity(mesh: .generateSphere(radius: 0.03))
let model_02 = ModelEntity(mesh: .generateSphere(radius: 0.03))
let model_03 = ModelEntity(mesh: .generateSphere(radius: 0.03))
let model_04 = ModelEntity(mesh: .generateSphere(radius: 0.03))
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
arView.session.delegate = self
guard let reference = ARReferenceImage.referenceImages(
inGroupNamed: "AR Resources",
bundle: nil)
else { return }
let config = ARImageTrackingConfiguration()
config.trackingImages = reference
arView.session.run(config)
self.anchorEntity.addChild(model_01)
self.anchorEntity.addChild(model_02)
self.anchorEntity.addChild(model_03)
self.anchorEntity.addChild(model_04)
arView.scene.anchors.append(self.anchorEntity)
}
}
然后执行session(_:didUpdate:)
方法:
extension ViewController: ARSessionDelegate {
func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
guard let imageAnchor = anchors.first as? ARImageAnchor
else { return }
let width = Float(imageAnchor.referenceImage.physicalSize.width)
let height = Float(imageAnchor.referenceImage.physicalSize.height)
let x = imageAnchor.transform.columns.3.x
let y = imageAnchor.transform.columns.3.y
let z = imageAnchor.transform.columns.3.z
let lowerLeft = SIMD3<Float>(x - width/2, y - height/2, z)
let lowerRight = SIMD3<Float>(x + width/2, y - height/2, z)
let upperRight = SIMD3<Float>(x + width/2, y + height/2, z)
let upperLeft = SIMD3<Float>(x - width/2, y + height/2, z)
self.model_01.position = lowerLeft
self.model_02.position = lowerRight
self.model_03.position = upperRight
self.model_04.position = upperLeft
self.anchorEntity = AnchorEntity(anchor: imageAnchor)
}
}
我有一个 RealityKit 应用程序正在执行一些基本的 AR 图像跟踪。它检测到一个矩形图像,我希望在图像的每个角放置一些球形点。我知道我可以使用 ModelEntity
自己创建球体,但我无法弄清楚如何从参考图像中指定这些球体相对于已建立的 ARImageAnchor
的位置。
我想我只需要一个与 SceneKit 的 addChildNode(SCNNode)
函数相对应的函数,它使用 SCNVector3Make()
来指定一个位置。我只是没能找到一种方法来建立相对位置并将子节点分配给这些 SceneKit 函数之外的 ARImageAnchor
。 RealityKit 中是否有内置的东西可以实现这一点,或者有没有办法使用 SceneKit 放置角点,同时仍然使用我当前的 RealityKit 设置进行 AR 参考图像跟踪?
尝试以下方法:
import ARKit
import RealityKit
class ViewController: UIViewController {
@IBOutlet var arView: ARView!
var anchorEntity = AnchorEntity()
let model_01 = ModelEntity(mesh: .generateSphere(radius: 0.03))
let model_02 = ModelEntity(mesh: .generateSphere(radius: 0.03))
let model_03 = ModelEntity(mesh: .generateSphere(radius: 0.03))
let model_04 = ModelEntity(mesh: .generateSphere(radius: 0.03))
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
arView.session.delegate = self
guard let reference = ARReferenceImage.referenceImages(
inGroupNamed: "AR Resources",
bundle: nil)
else { return }
let config = ARImageTrackingConfiguration()
config.trackingImages = reference
arView.session.run(config)
self.anchorEntity.addChild(model_01)
self.anchorEntity.addChild(model_02)
self.anchorEntity.addChild(model_03)
self.anchorEntity.addChild(model_04)
arView.scene.anchors.append(self.anchorEntity)
}
}
然后执行session(_:didUpdate:)
方法:
extension ViewController: ARSessionDelegate {
func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
guard let imageAnchor = anchors.first as? ARImageAnchor
else { return }
let width = Float(imageAnchor.referenceImage.physicalSize.width)
let height = Float(imageAnchor.referenceImage.physicalSize.height)
let x = imageAnchor.transform.columns.3.x
let y = imageAnchor.transform.columns.3.y
let z = imageAnchor.transform.columns.3.z
let lowerLeft = SIMD3<Float>(x - width/2, y - height/2, z)
let lowerRight = SIMD3<Float>(x + width/2, y - height/2, z)
let upperRight = SIMD3<Float>(x + width/2, y + height/2, z)
let upperLeft = SIMD3<Float>(x - width/2, y + height/2, z)
self.model_01.position = lowerLeft
self.model_02.position = lowerRight
self.model_03.position = upperRight
self.model_04.position = upperLeft
self.anchorEntity = AnchorEntity(anchor: imageAnchor)
}
}