Можно ли рассчитать синус переменной времени на временной шкале в SceneKit? - PullRequest
0 голосов
/ 19 мая 2018

Мне нужно движение пинг-понга вдоль оси X для трехмерного куба.Поэтому я применил тригонометрическую функцию sine к переменной time для параметра x.Но нет пинг-понга, только скалярное.

Любая помощь приветствуется!

override func awakeFromNib() {
    super.awakeFromNib()

    .......

    //CFTimeInterval derived by calling `mach_absolute_time()` and converting the result to seconds.
    let t = CACurrentMediaTime()

    animation.toValue = NSValue(SCNVector3: SCNVector3(x: CGFloat(sin(t)*5), 
                                                       y: CGFloat(0), 
                                                       z: CGFloat(0)))

    animation.duration = 60
    animation.repeatCount = MAXFLOAT    
    cube.addAnimation(animation, forKey: nil)
}

enter image description here

enter image description here

Ответы [ 2 ]

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

Можно рассчитать синус времени шкалы времени в SceneKit.Для этого мне нужно создать расширение для SCNAction (в Swift 4.1):

let pi = CGFloat(Double.pi)

extension SCNAction {

    static func oscillation(amplitude a: CGFloat, 
                           timePeriod t: CGFloat) -> SCNAction {

        let action = SCNAction.customAction(duration: Double(t)) { node, currentTime in
            let offset = a * sin(2 * pi * currentTime / t)
            node.position.x = offset
        }
        return action
    }
}

class GameViewController: NSViewController, SCNSceneRendererDelegate {

    let box = SCNNode()
    // ..................

    override func viewDidLoad() {
        super.viewDidLoad()

        // ..................
        box.geometry = SCNBox()
        scene.rootNode.addChildNode(box)

        let oscillate = SCNAction.oscillation(amplitude: 4, timePeriod: 1)
        box.runAction(SCNAction.repeatForever(oscillate))
    }
}
0 голосов
/ 19 мая 2018

Проблема со следующим кодом заключается в том, что он выполняется, когда анимация создается , а не когда оценивается .Это значение sin(t) никогда не изменится со временем.Он оценивается один раз, и результатом будет окончательное значение для линейной интерполяции.

let t = CACurrentMediaTime()
animation.toValue = NSValue(SCNVector3: SCNVector3(x: CGFloat(sin(t)*5), 
                                                   y: CGFloat(0), 
                                                   z: CGFloat(0)))

Вместо этого класс CAAnimation предоставляет свойство timingFunction, которое, скорее всего, того, что вам нужно.

...