gpt4 book ai didi

ios - 定位 ARKIT 模型

转载 作者:行者123 更新时间:2023-12-01 21:59:54 25 4
gpt4 key购买 nike

我在屏幕上定位模型时遇到了一些麻烦。模型出现了,但它出现在我上方而不是在我面前。理想情况下,我希望模型出现在被点击的地方。请帮忙!

此处的此函数从 AWS 成功下载模型:

 private func dowloadModel(){
let url = URL(string: "url_string")!

URLSession.shared.dataTask(with: url) { data, response, error in

if let error = error{
print(error.localizedDescription)
return
}

if let data = data{
print(data)

let documentDirectories = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)

if let documentDirectory = documentDirectories.first{

let fileURL = documentDirectory.appendingPathComponent("Food.scn")
let dataNS : NSData? = data as NSData

try! dataNS?.write(to: fileURL, options: .atomic)

print("Saved!")
}
}

}.resume()
}

在这里,我将模型渲染到屏幕上:
private func registerGestureRecogniser(){
print("Tapped")
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
self.sceneView.addGestureRecognizer(tapGestureRecognizer)
}

这是点击的功能:
 @objc func handleTap(gesture: UITapGestureRecognizer) {

let documentDirectories = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)

if let documentDirectory = documentDirectories.first{
let fileURL = documentDirectory.appendingPathComponent("Food.scn")

do{
let scene = try SCNScene(url: fileURL, options: nil)
let node = scene.rootNode.childNode(withName: "Burger", recursively: true)!

node.position = SCNVector3Make(0, 0, 0);

self.sceneView.scene.rootNode.addChildNode(node)
}
catch{
print(error)
}

}
}

我也得到错误:
Error: Failed to load <C3DImage

最佳答案

当你这样做

node.position = SCNVector3Make(0, 0, 0);
self.sceneView.scene.rootNode.addChildNode(node)

您将模型节点定位在场景的 rootNode 上,该位置由 ARKit 在场景开始时确定。

如果想让模型出现在摄像头前面,那么需要抓取摄像头变换( session.currentFrame?.camera.transform),修改 -z组件,并将其设置为节点的位置。或者,如果您想将模型放置在表面上,请进行光线转换并使用 raycastResult simdWorldPosition作为您节点的 simdWorldPosition .

肯定有 raycast的例子周围,​​但简而言之,您首先需要定义一个查询:
let bounds = sceneView.bounds
let screenCenter = CGPoint(x: bounds.midX, y: bounds.midY)
let query = sceneView.raycastQuery(from: screenCenter, allowing: .estimatedPlane, alignment: .horizontal)

上面定义了一个从屏幕中心延伸的光线转换,只找到水平表面。请探索 docs有关 allowing 的更多信息和 alignment选项。

然后您可以使用 session转换你的光线:
session.raycast(query)

这将返回 ARRaycastResult 的数组.您可以检查它们并根据需要进行选择,但我通常只使用 .first一个(注意:它可以是空的)。

然后你会想要使用你的 raycastResult 的翻译组件。转换并将其分配为 simdWorldPosition你的节点。请注意,您可以将整个变换分配给节点 simdWorldTransform但这也会改变您节点的方向,您可能想要也可能不想这样做。
if let raycastResult = session.raycast(query).first {
node.simdWorldPosition = raycastResult.worldTransform.translation
}

哦,另外,我发现这个小扩展很方便:
extension float4x4 {
/**
Treats matrix as a (right-hand column-major convention) transform matrix
and factors out the translation component of the transform.
*/
var translation: SIMD3<Float> {
let translation = columns.3
return SIMD3<Float>(translation.x, translation.y, translation.z)
}
}

这就是允许您执行 worldTransform.translation 的原因在我上面的代码中。

关于ios - 定位 ARKIT 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60303610/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com