10

I'm trying to understand the difference between the different element introduced in ArKit and their maybe equivalents in SceneKit:

  • SCNNode.simdTransform vs SCNNode.transform. In ARKit, it seems that people use SCNNode.simdTransform instead of SCNNode.transform. How do they differ? simdTransform seems to use column major order, while transform (SCNMatrix4) is row major. How do I convert one to the other? Just transpose? I've the impression that the tracking doesn't work as well if I use transform instead of simdTransform. Is that expected or just an impression? If I set one property, what happens if I then set the other one?

  • ARFrame.camera vs Scene.pointOfView: Looking at their transforms, they seem to be a bit different:

.

// ARFrame.camera.transform (matrix_float4x4)
-0.01 0.99  -0.11 0.02
-0.99 0.00  0.11  0.06
0.10  0.11  0.98  0.0
0.0   0.0   0.0   1.0

// sceneView.pointOfView.transform (SCNMatrix4)
// or sceneView.pointOfView.simdTransform^T (matrix_float4x4)
0.99  0     0.11   0
0.01  0.99  -0.12  0
-0.11 0.11  0.98   0
0.03  0.6   0.0    0.99

Are they the same minus one rotation?

Guig
  • 9,891
  • 7
  • 64
  • 126
  • 1
    _"I've the impression that the tracking doesn't work as well if I use transform instead of simdTransform. Is that expected or just an impression?"_ ;-) Only you can tell if it was just your impression or that you had hard evidence e.g. by seeing Xcode logs stating _[Technique] World tracking performance is being affected by resource constraints_ Tell us if it was the latter, that would be very interesting. – PDK Aug 08 '17 at 15:50

2 Answers2

6

Both SceneKit and ARKit include symbols defined as SIMD types. Since ARKit imports SceneKit, the SIMD symbols defined in SceneKit are accessible to both. SIMD types enable parallel computation, so using them can improve the performance of your app's update logic. As you've found, there isn't always a convenient way to convert between a SIMD type and its older SceneKit or Core Graphics equivalent, so you'll usually get cleaner code by consistently using SIMD where possible.

Updating any property that affects the transform of a node also updates its other transform properties. This goes for local and world coordinates as well.

The camera property of ARFrame describes the device's hardware camera, not the virtual camera used to render the scene. While I would expect a close correspondence, my guess is you're polling the ARCamera instance before the SCNCamera instance has been updated during the render loop. If you can, I recommend driving those updates from the appropriate delegate methods, since you'll know the relevant data is up to date.

  • 1
    Good summary. See also [this answer](https://stackoverflow.com/a/45182794/957768) for more on `ARAnchor` vs `SCNNode` positioning. – rickster Jul 19 '17 at 07:20
0

I don't think that SCNMatrix4 is following the row major convention as you say. Consider the following:

func makeTranslationMatrix(tx: Float, ty: Float, tz: Float) -> simd_float4x4 {
    var matrix = matrix_identity_float4x4

    matrix[3, 0] = tx
    matrix[3, 1] = ty
    matrix[3, 2] = tz

    return matrix
}

var T1 = makeTranslationMatrix(tx: 1, ty: 2, tz: 3)
print(T1.columns.0)
print(T1.columns.1) 
print(T1.columns.2) 
print(T1.columns.3) 
/*
T1
float4(1.0, 0.0, 0.0, 0.0)
float4(0.0, 1.0, 0.0, 0.0)
float4(0.0, 0.0, 1.0, 0.0)
float4(1.0, 2.0, 3.0, 1.0)
*/

var sceneT1 = SCNMatrix4MakeTranslation(1, 2, 3)
print("\(sceneT1.m11), \(sceneT1.m12), \(sceneT1.m13), \(sceneT1.m14)")
print("\(sceneT1.m21), \(sceneT1.m22), \(sceneT1.m23), \(sceneT1.m24)")
print("\(sceneT1.m31), \(sceneT1.m32), \(sceneT1.m33), \(sceneT1.m34)")
print("\(sceneT1.m41), \(sceneT1.m42), \(sceneT1.m43), \(sceneT1.m44)")
/*
sceneT1
1.0, 0.0, 0.0, 0.0
0.0, 1.0, 0.0, 0.0
0.0, 0.0, 1.0, 0.0
1.0, 2.0, 3.0, 1.0
*/

As you can see, the translation values for SCNMatrix4 are stored in m41, m42, m43 - in the 4th column. It may be possible that these values are stored in m41, m42, m43 due to the matrix being transposed and then they actually store the translation values in the 4th row. This question covers that confusion.

oneiros
  • 3,527
  • 12
  • 44
  • 71