ARKIT: как перемещать объект в воздухе, как приложение GiPHY World - PullRequest
0 голосов
/ 04 мая 2018

Я реализовал методы для перемещения объекта, находящегося поверх поверхности, используя UIPanGesture и используя технику лучевой передачи по плоскости ... чтобы найти новую координату для объекта при перетаскивании.

Но что, если объект находится в воздухе, вы не можете излучать лучи против любого самолета. Я заметил, что приложение GIPHY World, позволяет переключаться между 2 режимами:

  1. Обнаружение самолета (где объекты разрешено размещать ТОЛЬКО на поверхность)
  2. Свободный режим (где объекты могут быть ТОЛЬКО размещены плавающими перед камерой)

Когда объект перемещается, пользователь может перемещаться по экрану в любом направлении, и объект будет следовать правильно, даже если вы двигаетесь физически. Я заметил, что вам не нужно прикасаться к объекту, чтобы переместить его, но пока вы перетаскиваете экран.

Интересно, можете ли вы, ребята, предложить какой-нибудь код для преобразования перетаскивания 2D-экрана в способ перемещения 3D-объекта. Ex.

  • Если вы находитесь перед объектом, перетаскивая на экране ВВЕРХ / ВНИЗ переместит объект в координате Z ... близко или далеко.
  • Но если вы физически двигаетесь в сторону ... и снова перетаскиваете на экране ВВЕРХ / ВНИЗ, объект теперь перемещается по координате X. <--- как они делают это? </li>

Вот видео о том, как это работает. https://youtu.be/16iMMuwjfIc

Здесь вы можете увидеть, что я пробовал, в ответе @ Vollan ниже. Вы можете увидеть, как репозиционирование не работает, как приложение GiPHY. https://youtu.be/ZoWj6WRBY58

1 Ответ

0 голосов
/ 04 мая 2018

Итак, прежде всего я перейду к перемещению объекта после того, как вы двигаетесь физически.

Когда вы размещаете узлы в реальности, вы можете выбрать, хотите ли вы сделать это с точки зрения камеры или если вы действительно хотите поставить его в мировое положение.

1: Мировое положение поместит начало координат осей Z, X, Y в то место, где находилась камера, когда вы начали сеанс AR. 2: Положение камеры означает, что источник будет следовать за вами и привязан к камере. Это приведет к тому, что Узел всегда будет 3D.

Теперь, если вы выбираете мировую позицию и решаете обойти узел или начальную позицию, например, на 90 градусов. Тогда у вас будет другой угол на начало оси, поскольку оси Z и X поменялись местами. Вызывает UP / DOWN в Z для преобразования в X.

Во-вторых, я использую этот код:

@objc func adjustWindow(_ gesture: UIPinchGestureRecognizer) {
    var startPosition: CGPoint = CGPoint(x: 0, y: 0)

    // Fetch location for touch in sceneView
    let location: CGPoint = gesture.location(in: sceneView)

    // Fetch targets at the current location
    let hits = self.sceneView.hitTest(location, options: nil)

    // Check if it's a node and it's a window node that has been touched
    guard let node = hits.first?.node, node.name == "name" else {return}

    // Make sure user is using 1 finger to move the view
    if gesture.numberOfTouches == 1 {
        switch gesture.state {
        case .failed, .cancelled, .ended:
            // Reset position after finished
            startPosition = CGPoint(x: 0, y: 0)
            break
        case .began:
            // Save start position, so that we can check how far the user have moved
            startPosition = location
        case .changed:
            // Fetch new x and y position
            let deltaX = Float(location.x - startPosition.x)/20
            let deltaY = Float(location.y - startPosition.y)/20

            // Transform and apply the new location
            let box = node.transform
            let translation = SCNMatrix4MakeTranslation(deltaX, deltaY, 1)
            let newTrans = SCNMatrix4Mult(box, translation)
            node.transform = newTrans

            node.localTranslate(by: SCNVector3Make(deltaX, deltaY, 1))
            // Set new location
            startPosition = location
        default:
            break
        }
        // Make sure user is using 2 fingers for scaling the view
    }
 }

Это первая версия этого сценария, которую я написал, и то, как она движется, вероятно, будет работать только в моем приложении, так как я немного повернул / наклонил свой объект в файле .DAE. Но у вас может быть идея получить ваше сенсорное местоположение и отслеживать изменения для него.

Реализация ARSessionDelegate и

 var matrix: matrix_float4x4!

    func session(_ session: ARSession, didUpdate frame: ARFrame) {
        // Fetch and store current camera position
        matrix = frame.camera.transform
    }

Будет отображать текущее положение камеры, поскольку оно обновляется при перемещении камеры. Я еще не разобрался, как это применить. Может быть, используя:

let translation = SCNMatrix4MakeTranslation(deltaX*matrix.m41, deltaY*matrix.m42, 1*matrix.m43)

Или что-то.

Удачи.

...