为什么 ARKit MDLTransform 从相机变换中随机 return 0?
Why does ARKit MDLTransform randomly return 0 from camera transform?
我是 ARKit 的新手(准确地说是 2 天前),我试图在点击时在我的 ARSCNView 上放置一个节点,并且我能够在 50% 的时间内成功地这样做。另一半时间,屏幕上什么也没有出现。我已将其缩小为以下代码行:
func getCameraTransform(for camera: ARCamera) -> MDLTransform {
return MDLTransform(matrix: camera.transform)
}
当屏幕上什么都没有出现时,上面的函数是 returning transform.translation of float3(0.0, 0.0, 0.0)
我已经检查过 camera.transform 提供的值看起来像 simd_float4x4([[0.98134, 0.0198354, -0.191256, 0.0)], [-0.0129627 , 0.999227, 0.0371193, 0.0)], [0.191844, -0.0339474, 0.980838, 0.0)], [-0.482363, -0.00405288, -0.768801, 1.0)]]) transform.translation 为 0.
为什么这个 return 0 有时在我点击时却工作得很好?
完整代码如下:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard touches.first!.tapCount == 1 else { return }
let camera = sceneView.session.currentFrame!.camera
let transform = getCameraTransform(for: camera)
let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
let cube = SCNNode(geometry: boxGeometry)
// SOMETIMES TRANSFORM.TRANSLATION IS JUST 0s
let position = SCNVector3(
transform.translation.x,
transform.translation.y,
transform.translation.z
)
cube.position = position
sceneView.scene.rootNode.addChildNode(cube)
}
func getCameraTransform(for camera: ARCamera) -> MDLTransform {
return MDLTransform(matrix: camera.transform) // this is returning the 0 translation every other time
}
我认为换一种方式来解决这个问题可能会更好。我之前和测试都没有看到那个例子,它似乎不是你需要的。
因此,我将为您提供一些示例,以帮助您入门。
(1)根据相机当前帧将物体放置在某个位置:
/// Adds An SCNNode 3m Away From The Current Frame Of The Camera
func addNodeInFrontOfCamera(){
//1. Get The Current Frame Of The Camera
guard let currentTransform = augmentedRealitySession.currentFrame?.camera.transform else { return }
//2. Create An SCNNode
let nodeToAdd = SCNNode()
let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
boxGeometry.firstMaterial?.diffuse.contents = UIColor.red
nodeToAdd.geometry = boxGeometry
// Create A Transform With A Translation 1m In Front Of The Camera
var translation = matrix_identity_float4x4
//Change The X Value
translation.columns.3.x = 0
//Change The Y Value
translation.columns.3.y = 0
//Change The Z Value
translation.columns.3.z = -1
nodeToAdd.simdTransform = matrix_multiply(currentTransform, translation)
augmentedRealityView?.scene.rootNode.addChildNode(nodeToAdd)
}
(2) 根据场景中任何可用的特征点放置一个 SCNNode:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//1. Get The Current Touch Point
guard let currentTouchPoint = touches.first,
//2. Perform A Hit Test Against Any Feature Points
let result = augmentedRealityView.hitTest(currentTouchPoint.location(in: augmentedRealityView), types: .featurePoint).last else { return }
//3. Get The World Coordinates Of The Result
let transform = SCNMatrix4(result.worldTransform)
//4. Get The Positional Data From The Transform
let vectorFromTransform = SCNVector3(transform.m41, transform.m42, transform.m43)
//5. Create An SCNBox At The Point
let boxNode = SCNNode()
let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
boxNode.geometry = boxGeometry
boxNode.position = vectorFromTransform
augmentedRealityView.scene.rootNode.addChildNode(boxNode)
}
如果它不能解释您所经历的结果,我们深表歉意,但尽管如此,我希望它能有所帮助...
我是 ARKit 的新手(准确地说是 2 天前),我试图在点击时在我的 ARSCNView 上放置一个节点,并且我能够在 50% 的时间内成功地这样做。另一半时间,屏幕上什么也没有出现。我已将其缩小为以下代码行:
func getCameraTransform(for camera: ARCamera) -> MDLTransform {
return MDLTransform(matrix: camera.transform)
}
当屏幕上什么都没有出现时,上面的函数是 returning transform.translation of float3(0.0, 0.0, 0.0)
我已经检查过 camera.transform 提供的值看起来像 simd_float4x4([[0.98134, 0.0198354, -0.191256, 0.0)], [-0.0129627 , 0.999227, 0.0371193, 0.0)], [0.191844, -0.0339474, 0.980838, 0.0)], [-0.482363, -0.00405288, -0.768801, 1.0)]]) transform.translation 为 0.
为什么这个 return 0 有时在我点击时却工作得很好?
完整代码如下:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard touches.first!.tapCount == 1 else { return }
let camera = sceneView.session.currentFrame!.camera
let transform = getCameraTransform(for: camera)
let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
let cube = SCNNode(geometry: boxGeometry)
// SOMETIMES TRANSFORM.TRANSLATION IS JUST 0s
let position = SCNVector3(
transform.translation.x,
transform.translation.y,
transform.translation.z
)
cube.position = position
sceneView.scene.rootNode.addChildNode(cube)
}
func getCameraTransform(for camera: ARCamera) -> MDLTransform {
return MDLTransform(matrix: camera.transform) // this is returning the 0 translation every other time
}
我认为换一种方式来解决这个问题可能会更好。我之前和测试都没有看到那个例子,它似乎不是你需要的。
因此,我将为您提供一些示例,以帮助您入门。
(1)根据相机当前帧将物体放置在某个位置:
/// Adds An SCNNode 3m Away From The Current Frame Of The Camera
func addNodeInFrontOfCamera(){
//1. Get The Current Frame Of The Camera
guard let currentTransform = augmentedRealitySession.currentFrame?.camera.transform else { return }
//2. Create An SCNNode
let nodeToAdd = SCNNode()
let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
boxGeometry.firstMaterial?.diffuse.contents = UIColor.red
nodeToAdd.geometry = boxGeometry
// Create A Transform With A Translation 1m In Front Of The Camera
var translation = matrix_identity_float4x4
//Change The X Value
translation.columns.3.x = 0
//Change The Y Value
translation.columns.3.y = 0
//Change The Z Value
translation.columns.3.z = -1
nodeToAdd.simdTransform = matrix_multiply(currentTransform, translation)
augmentedRealityView?.scene.rootNode.addChildNode(nodeToAdd)
}
(2) 根据场景中任何可用的特征点放置一个 SCNNode:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//1. Get The Current Touch Point
guard let currentTouchPoint = touches.first,
//2. Perform A Hit Test Against Any Feature Points
let result = augmentedRealityView.hitTest(currentTouchPoint.location(in: augmentedRealityView), types: .featurePoint).last else { return }
//3. Get The World Coordinates Of The Result
let transform = SCNMatrix4(result.worldTransform)
//4. Get The Positional Data From The Transform
let vectorFromTransform = SCNVector3(transform.m41, transform.m42, transform.m43)
//5. Create An SCNBox At The Point
let boxNode = SCNNode()
let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
boxNode.geometry = boxGeometry
boxNode.position = vectorFromTransform
augmentedRealityView.scene.rootNode.addChildNode(boxNode)
}
如果它不能解释您所经历的结果,我们深表歉意,但尽管如此,我希望它能有所帮助...