Как повернуть и заблокировать вращение SCNNode в градусах? - PullRequest
0 голосов
/ 07 июня 2019

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

У меня есть UIPanGestureRecognizer, который свободно вращает 3D-модель вокруг оси Y. Однако я изо всех сил пытаюсь заставить его блокироваться до целого числа, когда панорамирование остановлено, и я изо всех сил пытаюсь узнать его вращение в градусах от 0-359.

let translation = recognizer.translation(in: self.view)

var newAngleY = Double(translation.x) * (Double.pi) / 180.0
newAngleY += self.currentAngle

self.shipNode?.eulerAngles.y = Float(newAngleY)

if (recognizer.state == .ended)
{
   self.currentAngle = newAngleY
}

Он вращается свободно, но все попытки зафиксировать до ближайшего точного градуса и иметь возможность «узнать» его степень вращения в значении от 0 до 359.

Я знаю, что:

let degrees = newAngleY * ( 180 / Double.pi)

И я знаю, что если градусов> 360, то - = 360 (псевдокод)

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

1 Ответ

0 голосов
/ 12 июня 2019

Вы можете редактировать значение, когда происходит жест.

Довольно много вариантов, поэтому проще всего начать с:

Вы можете попробовать применить эйлер только тогда, когда состояние меняется И только тогда, когда .x> .x * (некоторое значение, например 1.1). Это обеспечит более гибкий подход, например:

 var currentLocation = CGPoint.zero
 var beginLocation = CGPoint.zero

 @objc func handlePan(recognizer: UIPanGestureRecognizer) {
    currentLocation = recognizer.location(in: gameScene)

    var newAngleY = Double(translation.x) * (Double.pi) / 180.0
    newAngleY += self.currentAngle

    switch recognizer.state
    {
     case UIGestureRecognizer.State.began: break
     case UIGestureRecognizer.State.changed:
         if(currentLocation.x > beginLocation.x * 1.1)
         {
           gNodes.bnode.eulerAngles.y = Float(newAngleY)
           beginLocation.x = currentLocation.x
         }
         if(currentLocation.x < beginLocation.x * 0.9) { .etc. }
         break
         case UIGestureRecognizer.State.ended:
           gNodes.bnode.eulerAngles.y = Float(newAngleY)
           break
    }
}

Затем вы можете переключиться на SCNAction (изменение математики), чтобы дать больше контроля, например

let vAction = SCNAction.rotateTo(x: 0, y: vAmount, z: 0, duration: 0)
bnode.runAction(vAction)
...