如何使用 RealityKit 将 3D 模型放置在参考图像之上?
How to place a 3D model on top of a reference image with RealityKit?
我想在识别时将本地设备中的 3D 模型放置在参考图像之上。为此,我尝试了以下方法:
- 将参考图像添加到会话配置中:
override func viewDidLoad() {
super.viewDidLoad()
arView.session.delegate = self
// Check if the device supports the AR experience
if (!ARConfiguration.isSupported) {
TLogger.shared.error_objc("Device does not support Augmented Reality")
return
}
guard let qrCodeReferenceImage = UIImage(named: "QRCode") else { return }
let detectionImages: Set<ARReferenceImage> = convertToReferenceImages([qrCodeReferenceImage])
let configuration = ARWorldTrackingConfiguration()
configuration.detectionImages = detectionImages
arView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
}
- 使用
ARSessionDelegate
在检测到参考图像时收到通知,并将 3D 模型放置在与他 ARImageAnchor
相同的位置:
func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
for anchor in anchors {
guard let imageAnchor = anchor as? ARImageAnchor else { return }
let position = imageAnchor.transform
addEntity(self.localModelPath!, position)
}
}
func addEntity(_ modelPath: URL, _ position: float4x4) {
// Load 3D Object as Entity
let entity = try! Entity.load(contentsOf: modelPath)
// Create the Anchor which gets added to the AR Scene
let anchor = AnchorEntity(world: position)
anchor.addChild(entity)
anchor.transform.matrix = position
arView.scene.addAnchor(anchor)
}
但是,每当我尝试将包含我的 3D 模型(实体)的锚点放置在特定位置时,它都不会出现在 arView 中。看起来模型正在加载,因为在执行 addEntity
函数时丢失了几帧。当我没有特别设置锚点位置时,模型出现在镜头前。
谁能在这里指引我正确的方向?
解决方案一
要使您的代码正常工作,请删除此行:
anchor.transform.matrix = position
@TimLangner – "...But I want to make the model appear on top of the reference image and not at any other location..."
如您所见,我的测试球体已经出现在参考图像之上。更改其位置时,请记住,如果 QR 是垂直的,则图像锚点的 Y 轴指向相机,如果 QR 码在水平面上,则指向上方。
确保枢轴点位于应有的位置。
在我的例子中(你可以看到我正在使用 AppClipCode),要将球体向上移动 30 厘米,我必须沿负 Z 方向移动。
entity.position.z = anchor.position.z - 0.3
方案二
在我看来,最简单和高效的解决方案是使用 RealityKit 的原生 ,而无需在委托方法中实现 ARImageAnchor
。
AnchorEntity(.image(group: "GroupName", name: "forModel"))
这是一个代码:
import UIKit
import RealityKit
class ViewController: UIViewController {
@IBOutlet var arView: ARView!
override func viewDidLoad() {
super.viewDidLoad()
let entity = ModelEntity(mesh: .generateSphere(radius: 0.1))
let anchor = AnchorEntity(.image(group: "AR Resources",
name: "appClipCode"))
anchor.addChild(entity)
entity.position.z = anchor.position.z - 0.3
arView.scene.anchors.append(anchor)
}
}
我想在识别时将本地设备中的 3D 模型放置在参考图像之上。为此,我尝试了以下方法:
- 将参考图像添加到会话配置中:
override func viewDidLoad() {
super.viewDidLoad()
arView.session.delegate = self
// Check if the device supports the AR experience
if (!ARConfiguration.isSupported) {
TLogger.shared.error_objc("Device does not support Augmented Reality")
return
}
guard let qrCodeReferenceImage = UIImage(named: "QRCode") else { return }
let detectionImages: Set<ARReferenceImage> = convertToReferenceImages([qrCodeReferenceImage])
let configuration = ARWorldTrackingConfiguration()
configuration.detectionImages = detectionImages
arView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
}
- 使用
ARSessionDelegate
在检测到参考图像时收到通知,并将 3D 模型放置在与他ARImageAnchor
相同的位置:
func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
for anchor in anchors {
guard let imageAnchor = anchor as? ARImageAnchor else { return }
let position = imageAnchor.transform
addEntity(self.localModelPath!, position)
}
}
func addEntity(_ modelPath: URL, _ position: float4x4) {
// Load 3D Object as Entity
let entity = try! Entity.load(contentsOf: modelPath)
// Create the Anchor which gets added to the AR Scene
let anchor = AnchorEntity(world: position)
anchor.addChild(entity)
anchor.transform.matrix = position
arView.scene.addAnchor(anchor)
}
但是,每当我尝试将包含我的 3D 模型(实体)的锚点放置在特定位置时,它都不会出现在 arView 中。看起来模型正在加载,因为在执行 addEntity
函数时丢失了几帧。当我没有特别设置锚点位置时,模型出现在镜头前。
谁能在这里指引我正确的方向?
解决方案一
要使您的代码正常工作,请删除此行:
anchor.transform.matrix = position
@TimLangner – "...But I want to make the model appear on top of the reference image and not at any other location..."
如您所见,我的测试球体已经出现在参考图像之上。更改其位置时,请记住,如果 QR 是垂直的,则图像锚点的 Y 轴指向相机,如果 QR 码在水平面上,则指向上方。
确保枢轴点位于应有的位置。
在我的例子中(你可以看到我正在使用 AppClipCode),要将球体向上移动 30 厘米,我必须沿负 Z 方向移动。
entity.position.z = anchor.position.z - 0.3
方案二
在我看来,最简单和高效的解决方案是使用 RealityKit 的原生 ARImageAnchor
。
AnchorEntity(.image(group: "GroupName", name: "forModel"))
这是一个代码:
import UIKit
import RealityKit
class ViewController: UIViewController {
@IBOutlet var arView: ARView!
override func viewDidLoad() {
super.viewDidLoad()
let entity = ModelEntity(mesh: .generateSphere(radius: 0.1))
let anchor = AnchorEntity(.image(group: "AR Resources",
name: "appClipCode"))
anchor.addChild(entity)
entity.position.z = anchor.position.z - 0.3
arView.scene.anchors.append(anchor)
}
}