Управление движением объекта в ARKit относительно движущейся и вращающейся плоскости - PullRequest
0 голосов
/ 14 февраля 2019

Я работаю над проектом ARKit, где мне нужно управлять движением объекта (белый прямоугольник) на плоскости (синий квадрат).

enter image description here

Характеристики окружающей среды:

  • Коробка может перемещаться только в 2D по оси X и Z
  • Плоскость может вращаться в 3D из центра на 3ось
  • Самолет может двигаться во всех направлениях в ARWorld.
  • пользователь может перемещаться по плоскости во всех направлениях (очевидно, что некоторые позиции будут труднодостижимы, но как плоскостьможет перемещаться, это также может быть выше или ниже пользователя).
  • Пользователь может вращать устройство своими руками вокруг 3-х осей устройства (определяемых угловыми углами устройства).

Движение коробки осуществляется с помощью смахивания устройства.Какой бы ни была позиция пользователя или плоскости, проведите пальцем по экрану, чтобы переместить коробку в направлении касания относительно того, что видит пользователь на экране, что необязательно в том же направлении в координатном пространстве бокса (вверх поустройство может находиться прямо в плоскости, если, например, пользователь переместился на 90 ° влево от плоскости или если плоскость повернулась на 90 ° вправо, когда пользователь все еще находится в исходном месте, в случае запускауказать плоскость перед пользователем, как на картинке выше).Возможные комбинации бесконечны.

Я изо всех сил пытаюсь найти решение.

Я нашел решение просто, чтобы управлять движением пользователя вокруг плоскости, как описано ниже, через поле, поворот и поворот камеры, заданные свойством EulerAngles

func DefineARMovement(Level: LevelClass, NextMovement: inout eTypeMovement)
{
    let LevelNode = (MainPlayer.Level as! Level3DClass).TransformNode

        // Calculation of the angle of the camera taking into account the possible rotation of the plane. 
        // Works only if plane is rotating around Y axis.
    var CameraAngleBoardRef = SCNVector3.init(
        AngleDiff(AngleA: 90 - VCPlayAR.CameraAngles.x, AngleB: Float(RadiansToDegrees(Double(LevelNode.eulerAngles.x)).rounded(.up).RoundTo(Places: 0))),
        AngleDiff(AngleA: VCPlayAR.CameraAngles.y, AngleB: Float(RadiansToDegrees(Double(LevelNode.eulerAngles.y)).rounded(.up).RoundTo(Places: 0))),
        AngleDiff(AngleA: VCPlayAR.CameraAngles.z, AngleB: Float(RadiansToDegrees(Double(LevelNode.eulerAngles.z)).rounded(.up).RoundTo(Places: 0))))

    switch CameraAngleBoardRef.y
    {
    case _ where CameraAngleBoardRef.y > 315 || CameraAngleBoardRef.y < 45:
        break

    case _ where CameraAngleBoardRef.y > 45 && CameraAngleBoardRef.y < 135:
        switch NextMovement
        {
        case .Up:
            NextMovement = .Left

        case .Down:
            NextMovement = .Right

        case .Right:
            NextMovement = .Up

        case .Left:
            NextMovement = .Down

        default:
            break
      }

    case _ where CameraAngleBoardRef.y > 135 && CameraAngleBoardRef.y < 225:
        NextMovement = NextMovement.Inverse()

    case _ where CameraAngleBoardRef.y > 225 && CameraAngleBoardRef.y < 315:
        switch NextMovement
        {
        case .Up:
            NextMovement = .Right

        case .Down:
            NextMovement = .Left

        case .Right:
            NextMovement = .Down

        case .Left:
            NextMovement = .Up

        default:
            break
        }

    default:
        break
    }

    if CameraAngleBoardRef.x > 180 { NextMovement = NextMovement.Inverse() }
    if CameraAngleBoardRef.z > 180 { NextMovement = NextMovement.Inverse() }
}

Но как только я начинаю вращать плоскость в 3D, я теряюсь ...

Интуитивно ясказал бы, что мне нужно:

  • , чтобы определить положение ARCamera в координатном пространстве плоского узла: легко с помощью свойства convertPosition узла
  • , чтобы определить новые EulerAnglesARCamera также в координатном пространстве плоского узла, чтобы учесть начальные EulerAngles ARCamera в ARWorld
  • для имитации положения ARCamera на виртуальной сфере (та, что на рисунке выше сцентр плоскости как центр сферы), с его новыми EulerAngles
  • для определения для каждой зоны сферы и диапазоном ARCamera new EulerAngles, набор правил, которые переводят движение смахивания на устройство в реальное движение куба.

Моя проблема в том, что я не знаю, как определить, какие EulerAngles ARCamera вкоординатное пространство плоского узла.

Я также не понимаю, как можно использовать свойство камеры Orientation или Rotation, зная, что в ARCamera доступны только свойства Transform и EulerAngles (и я нене знаю, как извлечь ориентацию и / или вращение из этих свойств ...)

Если кто-то думает о более простом решении или уже существующем алгоритме, мне также интересно

...