liam moseley
liam moseley

Reputation: 1

How to pull and push AR Object from user position?

I'm currently making an app in Swift Ui using ARKit and I have AR objects placed in positions and the user should be able to move them around the room. the objects always face the user. I have tried everything to get it to work. im currently using the pan function and have resorted to Chatgpt which was useless.

Also this is my first post on here so let me know if I need to attach anything else.

@objc func handlePan(_ gesture: UIPanGestureRecognizer) { guard let sceneView = gesture.view as? ARSCNView else { return } let translation = gesture.translation(in: sceneView) // Drag movement in screen space gesture.setTranslation(.zero, in: sceneView) // Reset for incremental updates

    // Hit test to detect the panel being interacted with
    let location = gesture.location(in: sceneView)
    if gesture.state == .began {
        let hitTestResults = sceneView.hitTest(location, options: nil)
        if let hitResult = hitTestResults.first {
            if let panel = panelController.panelsInScene.first(where: { $0.parentNode == hitResult.node || $0.iconNode == hitResult.node }) {
                panelToChange = panel
            }
        }
    }

    guard let panelToChange = panelToChange else { return }

    // Get the camera's transform for orientation
    guard let cameraTransform = sceneView.session.currentFrame?.camera.transform else { return }

    switch gesture.state {
    case .changed:
        // Handle movement based on mode
        if !buttonFunctions.movementModeBool {
            handlePushPullMovement(panelToChange.parentNode, translation: translation, cameraTransform: cameraTransform)
        } else {
            handleUpDownMovement(panelToChange.parentNode, translation: translation, cameraTransform: cameraTransform)
        }
    default:
        break
    }
}

private func handlePushPullMovement(_ node: SCNNode, translation: CGPoint, cameraTransform: simd_float4x4) {
    // Determine swipe direction
    let deltaZ = Float(translation.y) / 500 // Positive for down (pull), negative for up (push)

    // Get the direction vector from the object to the camera (user's position)
    let cameraPosition = SCNVector3(cameraTransform.columns.3.x, cameraTransform.columns.3.y, cameraTransform.columns.3.z) // Camera position
    let objectPosition = node.worldPosition // AR object position
    let directionToCamera = SCNVector3(
        x: cameraPosition.x - objectPosition.x,
        y: cameraPosition.y - objectPosition.y,
        z: cameraPosition.z - objectPosition.z
    )

    // Normalize the direction vector
    let length = sqrt(directionToCamera.x * directionToCamera.x +
                      directionToCamera.y * directionToCamera.y +
                      directionToCamera.z * directionToCamera.z)
    let normalizedDirection = SCNVector3(
        x: directionToCamera.x / length,
        y: directionToCamera.y / length,
        z: directionToCamera.z / length
    )

    // Apply the movement along the direction vector
    node.position = SCNVector3(
        x: node.position.x + normalizedDirection.x * deltaZ,
        y: node.position.y + normalizedDirection.y * deltaZ,
        z: node.position.z + normalizedDirection.z * deltaZ
    )
}



// Up and Down mode: Move panel up/down (Y-axis) and left/right (X-axis)
private func handleUpDownMovement(_ node: SCNNode, translation: CGPoint, cameraTransform: simd_float4x4) {
    // Scale translation values for smoother movement
    let deltaX = Float(translation.x) / 500
    let deltaY = Float(-translation.y) / 500 // Negative because drag up moves object upward

    // Extract camera orientation vectors
    let cameraRight = SCNVector3(cameraTransform.columns.0.x, cameraTransform.columns.0.y, cameraTransform.columns.0.z)

    // Calculate movement along X (left/right) and Y (up/down)
    let worldDeltaX = cameraRight.x * deltaX
    let worldDeltaY = deltaY // Directly map to the Y-axis

    // Update panel position
    node.position.x += worldDeltaX
    node.position.y += worldDeltaY
}

This is what I currently have but it moves backwards and forwards but it only moves like its stuck on its axis not towards me.

Ive tried quite a lot but the code is just starting to get more unreadable to the point where him not really sure what I have anymore.

Upvotes: 0

Views: 14

Answers (0)

Related Questions