Alright. Good riddance. This worked for me:
NOTE: There's a BIT of oddness with raycasting to a tap gesture's location. Sometimes it fails, which is confusing to me given the tap succeeded. Maybe I'm not converting the locations correctly? Maybe it works better on device?
In a tap gesture handler, get the tap location on a collision shape with:
let worldPosition: SIMD3<Float> = value.convert(value.location3D, from: .local, to: .scene)
With a running WorldTrackingProvider you can get the current device pose with
worldTracking.queryDeviceAnchor(atTimestamp: CACurrentMediaTime())
Then process it like so to get it world-space:
let transform = Transform(matrix: pose.originFromAnchorTransform)
let locationOfDevice = transform.translation
You can then do a raycast to a tap location in world-coordinate-space like so:
let raycastResult = scene.raycast(from: locationOfDevice, to: worldPosition)
If successful, an entry in the raycast result will have normal information. Here I grab the first one
guard let result = raycastResult.first else {
print("NO RAYCAST HITS?????")
}
let normal = result.normal
Make a quaternion to rotate from identity to the normal vector's angle:
// Calculate the rotation quaternion to align the forward axis with the normal vector
let rotation = simd_quatf(from: SIMD3<Float>(0, 1, 0), to: normal)
Apply it to an entity:
cylinder.transform.rotation = rotation