我正在尝试使用ARKit,而我正试图在用户周围放置一些模型。所以我想要的是,当应用程序启动它时,只需在用户周围放置一些模型,这样他就需要找到它们。
当他移动例如10米时,我想再次添加一些随机模型。我以为我可以这样做:
let cameraTransform = self.sceneView.session.currentFrame?.camera.transform
let cameraCoordinates = MDLTransform(matrix: cameraTransform!)
let camX = CGFloat(cameraCoordinates.translation.x)
let camY = CGFloat(cameraCoordinates.translation.y)
let cameraPosition = CGPoint(x: camX, y: camY)
let anchors = self.sceneView.hitTest(cameraPosition, types: [.featurePoint, .estimatedHorizontalPlane])
if let hit = anchors.first {
let hitTransform = SCNMatrix4(hit.worldTransform)
let hitPosition = SCNVector3Make(hitTransform.m41, hitTransform.m42, hitTransform.m43)
self.sceneView.session.add(anchor: ARAnchor(transform: hit.worldTransform))
return Coordinate(hitPosition.x, hitPosition.y, hitPosition.z)
}
return Coordinate(0, 0, 0)
}
问题是有时它找不到任何锚点然后我不知道该怎么做。当它找到一些锚点时,它会随机地放在我身后而不是在我面前但在我身后。我不知道为什么,因为从来没有转动相机所以它找不到任何锚点。
有没有更好的方法将随机模型放在现实世界中?
答案 0 :(得分:3)
为了实现这一目标,您需要使用session(_:didUpdate:)委托方法:
func session(_ session: ARSession, didUpdate frame: ARFrame) {
guard let cameraTransform = session.currentFrame?.camera.transform else { return }
let cameraPosition = SCNVector3(
/* At this moment you could be sure, that camera properly oriented in world coordinates */
cameraTransform.columns.3.x,
cameraTransform.columns.3.y,
cameraTransform.columns.3.z
)
/* Now you have cameraPosition with x,y,z coordinates and you can calculate distance between those to points */
let randomPoint = CGPoint(
/* Here you can make random point for hitTest. */
x: CGFloat(arc4random()) / CGFloat(UInt32.max),
y: CGFloat(arc4random()) / CGFloat(UInt32.max)
)
guard let testResult = frame.hitTest(randomPoint, types: .featurePoint).first else { return }
let objectPoint = SCNVector3(
/* Converting 4x4 matrix into x,y,z point */
testResult.worldTransform.columns.3.x,
testResult.worldTransform.columns.3.y,
testResult.worldTransform.columns.3.z
)
/* do whatever you need with this object point */
}
它允许您在相机位置更新时放置对象:
如果您提供自己的显示来渲染,请实现此方法 AR体验。提供的ARFrame对象包含最新图像 从设备摄像头捕获,您可以将其渲染为场景 背景,以及有关相机参数和锚点的信息 您可以使用转换来渲染虚拟内容 相机图像。
真的重要,你在hitTest
方法中随机选择点,这一点总是在镜头前。
请勿忘记在hitTest method中使用0到1.0的CGPoint坐标系:
归一化图像坐标空间中的一个点。 (点(0,0) 代表图像的左上角,以及点(1,1) 代表右下角。)
如果你想每隔10米放置一个物体,你可以保存相机位置(用session(_:didUpdate:)
方法)并检查x+z
坐标是否已经变得足够远,以放置新物体。
注意:强>
我假设您正在使用世界跟踪会话:
let configuration = ARWorldTrackingSessionConfiguration()
session.run(configuration, options: [.resetTracking, .removeExistingAnchors])