Я работаю над проектом ARKit, где мне нужно управлять движением объекта (белый прямоугольник) на плоскости (синий квадрат).
![enter image description here](https://i.stack.imgur.com/0dhjy.png)
Характеристики окружающей среды:
- Коробка может перемещаться только в 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 (и я нене знаю, как извлечь ориентацию и / или вращение из этих свойств ...)
Если кто-то думает о более простом решении или уже существующем алгоритме, мне также интересно