Move entity to center of nonAR view

I'm recreating the ARQuickLook controller in code. One of its behaviors is to move the model to the visible center when entering Obj mode. I've hacked the ARViewContainer of the default Xcode Augmented Reality App to demonstrate what I'm trying to do. I think that moving the entity to 0,0,0 will generally not do the right thing because the world origin will be elsewhere. What I'm not clear on is how to specify the translation for entity.move() in the code. I'm assuming I'll need to raycast using a CGPoint describing view center to obtain the appropriate translation but I'm not sure about the details. Thanks for any help with this.

struct ARViewContainer: UIViewRepresentable {
    let arView = ARView(frame: .zero)
    let boxAnchor = try! Experience.loadBox()

    func makeUIView(context: Context) -> ARView {
        arView.scene.anchors.append(boxAnchor)
        return arView
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {
          DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
              arView.environment.background = .color(.white)
              arView.cameraMode = .nonAR
              if let entity = boxAnchor.children.first {
                 let translation = SIMD3<Float>(x: 0, y: 0, z: 0 )
                 let transform = Transform(scale: .one, rotation: simd_quatf(), translation: translation)
                
                 entity.move(to: transform, relativeTo: nil, duration: 2, timingFunction: .easeInOut)
              }
         }
    }
}

Replies

Hello spiff,

You have access to the following pieces of information:

  1. Where the object is in world space.
  2. Where the camera is in world space.
  3. The direction the camera is facing in world space.
  4. The distance that you want the object to be from the camera when you go into nonAR mode.

So, before you switch to nonAR, the position that you will want the object to be at is going to be as follows:

(world space camera position) + normalized(world space camera direction) * (distance you want the object to be from the camera when you go into nonAR mode)

You can then animate the object from its current position to the position you just calculated (which ought to place it directly in the center of the viewport at whatever distance you specified).

Thanks for the explanation, gchiste.

Would it be possible to provide some example code to determine the target transform? While I understand your answer, I'm flailing a little trying to make it work.

Thanks again, Spiff

Hey Spiff,

Sure, here is a short snippet that calculates the destination position:

func calculateDestination(distance: Float) -> SIMD3<Float> {

        // The current world position of the camera.
        let cameraPosition = arView.cameraTransform.translation

        // The "forward" direction of the camera in world space. (this direction is already normalized, so there is no need to re-normalize it)
        let cameraForward = arView.cameraTransform.matrix.columns.2[SIMD3(0,1,2)]

        // The camera "sees" in the opposite direction of the "forward" direction, so negate it.
        let viewDirection = -cameraForward
        
        // Calculate the destination.
        let destination = cameraPosition + viewDirection * distance

        return destination
}

Then, to use it:

// The current position of the anchor in world space. (Note that anchor transforms are relative to their parents, this anchor just happens to be top-level)
let start = anchor.transform

// One meter in front of the camera in world space.
let destination = Transform(scale: start.scale, rotation: start.rotation, translation: calculateDestination(distance: 1))

// Define the animation from start to destination.
let animation = FromToByAnimation(name: "My Animation", from: start, to: destination, duration: 0.2, timing: .easeIn, bindTarget: .transform)

// Create the animation resource.
let resource = try! AnimationResource.generate(with: animation)

// Play the animation.
anchor.playAnimation(resource)

Thank you. It doesn't center the object but with your help I'm closer to that goal. Thanks again!

  • dup response due to forum web site weirdness -