How to use `unproject(_:from:to:ontoPlane:)` of Content of RealityView

When using ARView of RealityKit, I can code like this let results = arView.raycast(from: point, allowing: .estimatedPlane, alignment: .any) to get the 3D position of where I tap on the plane. In iOS 18, we can use RealityView and I found that unproject(_:from:to:ontoPlane:) may implement the same function, but I don't know how to set the ontoPlane parameter. Can someone help me with some code snippets?

Answered by Vision Pro Engineer in 814242022

Hello @NahtanMak,

The 4x4 definition of the plane is the transform matrix from world space onto the plane.

For example you have a point at the center of your 100x100 view, CGPoint(50,50). You want to unproject that onto the plane parallel to the XY plane (in world space) positioned at (0, 0, -5).

You'd make a transform matrix like this:

let t = Transform(rotation: simd_quatf(angle: .pi / 2.0,
                                       axis: SIMD3<Float>(1.0, 0.0, 0.0)),
                  translation: SIMD3<Float>(0.0, 0.0, -5.0))
let plane = t.matrix

First we create the Transform with the translation. That moves the plane to the required position.

The documentation for the API says the Y axis is the 'normal' of the plane. Currently the plane's normal is the +Z axis. So, we rotate by 90° around the X axis to have Y pointing at the camera. With that change the plane is defined with the Y axis being normal.

If your plane is more complex (i.e. something like a 45° off the z axis and 30° off the x axis, at (1,1,1)) then the transform matrix would be more complex but the idea is the same. You'd define a transform goes from world space to your plane, where the +Y axis is normal to the plane.

Please feel free to ask follow on questions if this doesn't make sense.

Accepted Answer

Hello @NahtanMak,

The 4x4 definition of the plane is the transform matrix from world space onto the plane.

For example you have a point at the center of your 100x100 view, CGPoint(50,50). You want to unproject that onto the plane parallel to the XY plane (in world space) positioned at (0, 0, -5).

You'd make a transform matrix like this:

let t = Transform(rotation: simd_quatf(angle: .pi / 2.0,
                                       axis: SIMD3<Float>(1.0, 0.0, 0.0)),
                  translation: SIMD3<Float>(0.0, 0.0, -5.0))
let plane = t.matrix

First we create the Transform with the translation. That moves the plane to the required position.

The documentation for the API says the Y axis is the 'normal' of the plane. Currently the plane's normal is the +Z axis. So, we rotate by 90° around the X axis to have Y pointing at the camera. With that change the plane is defined with the Y axis being normal.

If your plane is more complex (i.e. something like a 45° off the z axis and 30° off the x axis, at (1,1,1)) then the transform matrix would be more complex but the idea is the same. You'd define a transform goes from world space to your plane, where the +Y axis is normal to the plane.

Please feel free to ask follow on questions if this doesn't make sense.

How to use `unproject(_:from:to:ontoPlane:)` of Content of RealityView
 
 
Q