Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set entity in front of screen with Reality kit?

The new reality kit camera transform appears to be misleading. When I set an entity’s transform to the camera’s, it is not following the front of the screen, instead, it is always near the world origin. There used to be pointOfView in scnview. What should I do to create the same effect

like image 295
Illuminator Avatar asked Jan 26 '23 17:01

Illuminator


1 Answers

If you want an entity to follow the camera and always be in front of the camera, the simplest way to achieve this is using an AnchorEntity:

    let box = ModelEntity(
      mesh: MeshResource.generateBox(size: 0.05),
      materials: [SimpleMaterial(color: .red, isMetallic: true)]
    )

    let cameraAnchor = AnchorEntity(.camera)
    cameraAnchor.addChild(box)
    arView.scene.addAnchor(cameraAnchor)

    // Move the box in front of the camera slightly, otherwise
    // it will be centered on the camera position and we will
    // be inside the box and not be able to see it
    box.transform.translation = [0, 0, -0.5]

However if you want to use the cameraTransform property, this seemed to work fine for me:

var c: Cancellable?
var boxAnchor: AnchorEntity?

struct ARViewContainer: UIViewRepresentable {

  func makeUIView(context: Context) -> ARView {

    let arView = ARView(frame: .zero)

    let box = ModelEntity(
      mesh: MeshResource.generateBox(size: 0.05),
      materials: [SimpleMaterial(color: .red, isMetallic: true)]
    )

    boxAnchor = AnchorEntity(world: [0,0,0])
    arView.scene.addAnchor(boxAnchor!)
    boxAnchor!.addChild(box)

    c = arView.scene.subscribe(to: SceneEvents.Update.self) { (event) in
      guard let boxAnchor = boxAnchor else {
        return
      }

      // Translation matrix that moves the box 1m in front of the camera
      let translate = float4x4(
        [1,0,0,0],
        [0,1,0,0],
        [0,0,1,0],
        [0,0,-1,1]
      )

      // Transformed applied right to left
      let finalMatrix = arView.cameraTransform.matrix * translate

      boxAnchor.setTransformMatrix(finalMatrix, relativeTo: nil)

    }

    return arView

  }

    func updateUIView(_ uiView: ARView, context: Context) {}
}
like image 151
Mark D Avatar answered Feb 11 '23 07:02

Mark D