ARKit 将节点放置在手指按下的位置
ARKit place node where finger press is
我正在使用 ARKit 开发一个 ios 应用程序,我想知道如何在我将手指按在屏幕上但距离屏幕大约 0.5m 的位置创建一个节点。我知道我必须考虑设备的方向,但我仍然很困惑从哪里开始。任何帮助都会很棒!谢谢。
从一些不需要 ARKit 的简单解决方案开始:
var scnV : SCNView!
var scnN = SCNNode()
var depthForZ = 0.50
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch01 = touches.first!
let t_Point = touch01.location(in: scnV)
scnN.position = scnV.unprojectPoint(SCNVector3(x:Float(t_Point.x), y:Float(t_Point.y), z:depthForZ))
}
如果需要 ARKit,您可以在代码中的某处继续:
var trans = matrix_identity_float4x4
trans.columns.3.x = Float(t_Point.x)
trans.columns.3.y = Float(t_Point.y)
trans.columns.3.z = depthForZ
let transForA = simd_mul(scN.transform, trans)
let newA = ARAnchor(transform: transForA)
scnV.session.add(anchor: newA)
或者用之前的 transForA 结构更新 ARSession 创建的 SCNNode 的转换
我希望这能帮助你开始一个基本的项目
解决方法很简单。
将您需要的节点作为子节点添加到位置向量为 (0,0,1) 的相机。
现在,保存您创建的那个节点的世界位置,并立即从相机中删除子节点。
再次将您的节点添加为具有已保存世界位置的根节点的子节点。
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let boxNode = SCNNode.init()
let boxGeometry = SCNBox.init(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
boxGeometry.materials.first?.diffuse.contents = UIColor.red
boxNode.geometry = boxGeometry
boxNode.position = SCNVector3.init(0, 0, -0.5)
self.sceneView.pointOfView?.addChildNode(boxNode)
let boxPosition = boxNode.worldPosition
boxNode.removeFromParentNode()
boxNode.worldPosition = boxPosition
self.sceneView.scene.rootNode.addChildNode(boxNode)
}
编辑:
解决方案需要稍作修改。
要获得世界位置,请在相机前创建一个 planeNode(不需要时可以将其删除)。并在 sceneView 上执行 hitTestResult 以获取 worldPosition。
let planeGeometry = SCNPlane.init(width: 10, height: 10)
planeGeometry.materials.first?.transparency = 0
planeNode.geometry = planeGeometry
planeNode.position = SCNVector3.init(0, 0, -1)
planeNode.name = "HitTestPlane"
self.sceneView.pointOfView?.addChildNode(planeNode)
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let loc = touches.first?.location(in: self.sceneView)
let hitTextResult = self.sceneView.hitTest(loc!, options: [:])
for result in hitTextResult {
if result.node.name == "HitTestPlane" {
let hitPosition = SCNVector3.init(result.worldCoordinates.x, result.worldCoordinates.y, result.worldCoordinates.z)
let boxNode = SCNNode.init()
let boxGeometry = SCNBox.init(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
boxGeometry.materials.first?.diffuse.contents = UIColor.red
boxNode.geometry = boxGeometry
boxNode.position = hitPosition
self.sceneView.scene.rootNode.addChildNode(boxNode)
}
}
}
我正在使用 ARKit 开发一个 ios 应用程序,我想知道如何在我将手指按在屏幕上但距离屏幕大约 0.5m 的位置创建一个节点。我知道我必须考虑设备的方向,但我仍然很困惑从哪里开始。任何帮助都会很棒!谢谢。
从一些不需要 ARKit 的简单解决方案开始:
var scnV : SCNView!
var scnN = SCNNode()
var depthForZ = 0.50
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch01 = touches.first!
let t_Point = touch01.location(in: scnV)
scnN.position = scnV.unprojectPoint(SCNVector3(x:Float(t_Point.x), y:Float(t_Point.y), z:depthForZ))
}
如果需要 ARKit,您可以在代码中的某处继续:
var trans = matrix_identity_float4x4
trans.columns.3.x = Float(t_Point.x)
trans.columns.3.y = Float(t_Point.y)
trans.columns.3.z = depthForZ
let transForA = simd_mul(scN.transform, trans)
let newA = ARAnchor(transform: transForA)
scnV.session.add(anchor: newA)
或者用之前的 transForA 结构更新 ARSession 创建的 SCNNode 的转换
我希望这能帮助你开始一个基本的项目
解决方法很简单。
将您需要的节点作为子节点添加到位置向量为 (0,0,1) 的相机。 现在,保存您创建的那个节点的世界位置,并立即从相机中删除子节点。
再次将您的节点添加为具有已保存世界位置的根节点的子节点。
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let boxNode = SCNNode.init()
let boxGeometry = SCNBox.init(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
boxGeometry.materials.first?.diffuse.contents = UIColor.red
boxNode.geometry = boxGeometry
boxNode.position = SCNVector3.init(0, 0, -0.5)
self.sceneView.pointOfView?.addChildNode(boxNode)
let boxPosition = boxNode.worldPosition
boxNode.removeFromParentNode()
boxNode.worldPosition = boxPosition
self.sceneView.scene.rootNode.addChildNode(boxNode)
}
编辑:
解决方案需要稍作修改。 要获得世界位置,请在相机前创建一个 planeNode(不需要时可以将其删除)。并在 sceneView 上执行 hitTestResult 以获取 worldPosition。
let planeGeometry = SCNPlane.init(width: 10, height: 10)
planeGeometry.materials.first?.transparency = 0
planeNode.geometry = planeGeometry
planeNode.position = SCNVector3.init(0, 0, -1)
planeNode.name = "HitTestPlane"
self.sceneView.pointOfView?.addChildNode(planeNode)
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let loc = touches.first?.location(in: self.sceneView)
let hitTextResult = self.sceneView.hitTest(loc!, options: [:])
for result in hitTextResult {
if result.node.name == "HitTestPlane" {
let hitPosition = SCNVector3.init(result.worldCoordinates.x, result.worldCoordinates.y, result.worldCoordinates.z)
let boxNode = SCNNode.init()
let boxGeometry = SCNBox.init(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
boxGeometry.materials.first?.diffuse.contents = UIColor.red
boxNode.geometry = boxGeometry
boxNode.position = hitPosition
self.sceneView.scene.rootNode.addChildNode(boxNode)
}
}
}