是否可以在 SceneKit 中计算时间轴的“时间”变量的正弦值?
Is it possible to calculate a sine of timeline's `Time`variable in SceneKit?
对于 3D 立方体,我需要沿 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)
}
以下代码的问题在于它是在动画实例化时执行的,而不是在动画求值时执行的。即值 sin(t)
永远不会随时间改变。它被评估一次,结果将是线性插值的最终值。
let t = CACurrentMediaTime()
animation.toValue = NSValue(SCNVector3: SCNVector3(x: CGFloat(sin(t)*5),
y: CGFloat(0),
z: CGFloat(0)))
相反,CAAnimation
class 公开了 timingFunction
属性,这可能是您想要的。
在 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))
}
}
对于 3D 立方体,我需要沿 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)
}
以下代码的问题在于它是在动画实例化时执行的,而不是在动画求值时执行的。即值 sin(t)
永远不会随时间改变。它被评估一次,结果将是线性插值的最终值。
let t = CACurrentMediaTime()
animation.toValue = NSValue(SCNVector3: SCNVector3(x: CGFloat(sin(t)*5),
y: CGFloat(0),
z: CGFloat(0)))
相反,CAAnimation
class 公开了 timingFunction
属性,这可能是您想要的。
在 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))
}
}