SceneKit 中的连续变形动画
Successive Morphing Animation in SceneKit
我很难在 SceneKit 中通过不同的变形目标制作动画。
我有一个 morph-targets 数组,我想遍历并用它们之间的动画显示它们。
所以从一种几何图形到另一种几何图形,这很容易。
在 SCNMorpher Class Reference 中有一个为一个 Morph-Geometry (morpher.weights[0]) 做这个的例子:
let animation = CABasicAnimation(keyPath: "morpher.weights[0]")
animation.fromValue = 0.0;
animation.toValue = 1.0;
animation.autoreverses = true;
animation.repeatCount = Float.infinity;
animation.duration = 5;
我想做的是,为连续变形制作动画。我尝试为每个目标设置几个动画。但是在完成第一个动画后,第一个目标的权重再次设置为 0。
override func viewDidLoad() {
super.viewDidLoad()
// create a new scene
let scene = SCNScene()
let vbasic_geom: [Vertex] = [
[ [0, 0, 0], [+1.0, +0.0, +0.0] ],
[ [0, 2, 0], [+1.0, +0.0, +0.0] ],
[ [2, 2, 0], [+1.0, +0.0, +0.0] ]
]
let vmorph1: [Vertex] = [
[ [0, 0, 0], [+1.0, +0.0, +0.0] ],
[ [0, 4, 0], [+1.0, +0.0, +0.0] ],
[ [2, 2, 0], [+1.0, +0.0, +0.0] ]
]
let vmorph2: [Vertex] = [
[ [0, 0, 0], [+1.0, +0.0, +0.0] ],
[ [0, 2, 0], [+1.0, +0.0, +0.0] ],
[ [4, 2, 0], [+1.0, +0.0, +0.0] ]
]
let basic_geom = gen_geometry(vbasic_geom)
let morph1 = gen_geometry(vmorph1)
let morph2 = gen_geometry(vmorph2)
let morpher = SCNMorpher()
morpher.targets = [morph1, morph2]
let object = SCNNode(geometry: basic_geom)
object.morpher = morpher
//needed for model-layer refresh; implicit animation
morpher.setWeight(1.0, forTargetAtIndex: 0)
morpher.setWeight(1.0, forTargetAtIndex: 1)
//set up animations
let animation = CABasicAnimation(keyPath: "morpher.weights[0]")
animation.fromValue = 0.0
animation.toValue = 1.0
animation.duration = 5
animation.beginTime = 0.0
animation.removedOnCompletion = false
let animation2 = CABasicAnimation(keyPath: "morpher.weights[1]")
animation2.fromValue = 0.0;
animation2.toValue = 1.0
animation2.duration = 5
animation2.beginTime = 5.0
animation.removedOnCompletion = false
let animationgroup = CAAnimationGroup()
animationgroup.duration = 10.0
animationgroup.autoreverses = false
animationgroup.repeatCount = 10000;
animationgroup.animations = [animation, animation2]
object.addAnimation(animationgroup, forKey: "morpher.weights")
scene.rootNode.addChildNode(object)
Output GIF
尝试了几种解决方案,但我从未成功过:
也许可以将“keyPath: "morpher.weights[0]"”更改为“morpher.weights”并将 from- 和 toValues 设置为类似数组的内容。包括更改 valueFunction.
因为动画发生在表示层上,所以它必须是一种将已经动画的属性保留为最终值的方法。它尝试了 "removedOnCompletion",但似乎没有用。
有人有线索或解决方案吗?
我可以 post 一个 link,到整个代码,如果这是必要的 - 不要认为这里要求它。
这是 CAAnimation 的一个常见问题 - 不仅仅是 SceneKit:默认情况下,显式动画在完成时被删除,并且表示值被重置为模型值(显式动画永远不会修改)。
有 2 个解决方案:
- 改为使用隐式动画(带有
将触发下一个动画的完成块)。
- 将 removedOnCompletion 设置为 NO 并将 fillMode 设置为 FillForward。
对于 #2 可选:您可以为动画设置委托,并在将模型值同步到 presentationValue 后删除 animationDidStop 中的动画。
我很难在 SceneKit 中通过不同的变形目标制作动画。 我有一个 morph-targets 数组,我想遍历并用它们之间的动画显示它们。
所以从一种几何图形到另一种几何图形,这很容易。 在 SCNMorpher Class Reference 中有一个为一个 Morph-Geometry (morpher.weights[0]) 做这个的例子:
let animation = CABasicAnimation(keyPath: "morpher.weights[0]")
animation.fromValue = 0.0;
animation.toValue = 1.0;
animation.autoreverses = true;
animation.repeatCount = Float.infinity;
animation.duration = 5;
我想做的是,为连续变形制作动画。我尝试为每个目标设置几个动画。但是在完成第一个动画后,第一个目标的权重再次设置为 0。
override func viewDidLoad() {
super.viewDidLoad()
// create a new scene
let scene = SCNScene()
let vbasic_geom: [Vertex] = [
[ [0, 0, 0], [+1.0, +0.0, +0.0] ],
[ [0, 2, 0], [+1.0, +0.0, +0.0] ],
[ [2, 2, 0], [+1.0, +0.0, +0.0] ]
]
let vmorph1: [Vertex] = [
[ [0, 0, 0], [+1.0, +0.0, +0.0] ],
[ [0, 4, 0], [+1.0, +0.0, +0.0] ],
[ [2, 2, 0], [+1.0, +0.0, +0.0] ]
]
let vmorph2: [Vertex] = [
[ [0, 0, 0], [+1.0, +0.0, +0.0] ],
[ [0, 2, 0], [+1.0, +0.0, +0.0] ],
[ [4, 2, 0], [+1.0, +0.0, +0.0] ]
]
let basic_geom = gen_geometry(vbasic_geom)
let morph1 = gen_geometry(vmorph1)
let morph2 = gen_geometry(vmorph2)
let morpher = SCNMorpher()
morpher.targets = [morph1, morph2]
let object = SCNNode(geometry: basic_geom)
object.morpher = morpher
//needed for model-layer refresh; implicit animation
morpher.setWeight(1.0, forTargetAtIndex: 0)
morpher.setWeight(1.0, forTargetAtIndex: 1)
//set up animations
let animation = CABasicAnimation(keyPath: "morpher.weights[0]")
animation.fromValue = 0.0
animation.toValue = 1.0
animation.duration = 5
animation.beginTime = 0.0
animation.removedOnCompletion = false
let animation2 = CABasicAnimation(keyPath: "morpher.weights[1]")
animation2.fromValue = 0.0;
animation2.toValue = 1.0
animation2.duration = 5
animation2.beginTime = 5.0
animation.removedOnCompletion = false
let animationgroup = CAAnimationGroup()
animationgroup.duration = 10.0
animationgroup.autoreverses = false
animationgroup.repeatCount = 10000;
animationgroup.animations = [animation, animation2]
object.addAnimation(animationgroup, forKey: "morpher.weights")
scene.rootNode.addChildNode(object)
Output GIF
尝试了几种解决方案,但我从未成功过:
也许可以将“keyPath: "morpher.weights[0]"”更改为“morpher.weights”并将 from- 和 toValues 设置为类似数组的内容。包括更改 valueFunction.
因为动画发生在表示层上,所以它必须是一种将已经动画的属性保留为最终值的方法。它尝试了 "removedOnCompletion",但似乎没有用。
有人有线索或解决方案吗?
我可以 post 一个 link,到整个代码,如果这是必要的 - 不要认为这里要求它。
这是 CAAnimation 的一个常见问题 - 不仅仅是 SceneKit:默认情况下,显式动画在完成时被删除,并且表示值被重置为模型值(显式动画永远不会修改)。 有 2 个解决方案:
- 改为使用隐式动画(带有 将触发下一个动画的完成块)。
- 将 removedOnCompletion 设置为 NO 并将 fillMode 设置为 FillForward。
对于 #2 可选:您可以为动画设置委托,并在将模型值同步到 presentationValue 后删除 animationDidStop 中的动画。