SceneKit 相机节点在捏手势时重置
SceneKit camera node resets on pinch gesture
我正在尝试通过捏合手势实现缩放,但是每次我第二次捏合时,模型都会自行重置。
func zoom(scale: Double){
self.cameraNode.camera!.xFov = scale
self.cameraNode.camera!.yFov = scale
}
func handlePinch(gestureRecognize: UIPinchGestureRecognizer) {
if gestureRecognize.numberOfTouches() == 2 {
let zoom = gestureRecognize.scale
if (gestureRecognize.state == UIGestureRecognizerState.Began){
startScale = lastScale
bimScene.zoom(startScale)
}
if (gestureRecognize.state == UIGestureRecognizerState.Changed){
startScale = Double(100/zoom)
bimScene.zoom(startScale)
}
if (gestureRecognize.state == UIGestureRecognizerState.Ended){
lastScale = startScale
}
}
}
我对scenekit还是个新手,所以我觉得这很奇怪。有人能解释一下这是什么原因吗?
你很接近,逻辑有点不对。
开始的情况很好,您需要 'remember' 缩放开始时的比例,这可能是您上次缩放时设置的比例。
您更改的案例有两个问题。
- 您计算的比例
startScale = Double(100/zoom)
仅基于手势识别器比例,该比例仅适用于当前捏合(因此每次捏合都会重置)。这个需要根据GR尺度,夹点开始的尺度'remembered'。
- 您还将更改后的大小写中的
startScale
重置为您的新值。这给出了 'exponential' 类型的缩放效果;你不想要这个。
结束的案例只需要设置缩放值,这样我们就可以记住下一次捏合要从什么开始。在这种情况下,它可能有点多余,您可能会逃脱 startScale = startScale * zoom
并且在开始的情况下什么也没有。
尚未测试以下内容,但希望它能给您一些想法。您传递给 zoom
函数的值实际上是一个视野角度,因此我将其重命名以区别于各种比例。 FOV 将在 30-60 度左右,而比例更像是在 0.1 - 10 的范围内(非常粗略)。
func handlePinch(gestureRecognize: UIPinchGestureRecognizer) {
if gestureRecognize.numberOfTouches() == 2 {
let zoom = gestureRecognize.scale
if (gestureRecognize.state == UIGestureRecognizerState.Began){
startScale = lastScale
} else if (gestureRecognize.state == UIGestureRecognizerState.Changed){
let fov = Double(100/(startScale * zoom))
bimScene.zoom(fov)
} else {
lastScale = startScale * zoom
}
}
}
这是另一种处理特定节点缩放 in-out 的方法,如果需要在不改变相机视角的情况下实现这一点。
-(void)handlePinch:(UIPinchGestureRecognizer*)gestureRecognizer {
if (gestureRecognizer.numberOfTouches == 2) {
CGFloat zoom = gestureRecognizer.scale;
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
lastScale = yourNode.scale.x;
} else if (gestureRecognizer.state == UIGestureRecognizerStateChanged) {
double final = lastScale * zoom;
yourNode.scale = SCNVector3Make(final, final, final);
}
}
}
我正在尝试通过捏合手势实现缩放,但是每次我第二次捏合时,模型都会自行重置。
func zoom(scale: Double){
self.cameraNode.camera!.xFov = scale
self.cameraNode.camera!.yFov = scale
}
func handlePinch(gestureRecognize: UIPinchGestureRecognizer) {
if gestureRecognize.numberOfTouches() == 2 {
let zoom = gestureRecognize.scale
if (gestureRecognize.state == UIGestureRecognizerState.Began){
startScale = lastScale
bimScene.zoom(startScale)
}
if (gestureRecognize.state == UIGestureRecognizerState.Changed){
startScale = Double(100/zoom)
bimScene.zoom(startScale)
}
if (gestureRecognize.state == UIGestureRecognizerState.Ended){
lastScale = startScale
}
}
}
我对scenekit还是个新手,所以我觉得这很奇怪。有人能解释一下这是什么原因吗?
你很接近,逻辑有点不对。
开始的情况很好,您需要 'remember' 缩放开始时的比例,这可能是您上次缩放时设置的比例。
您更改的案例有两个问题。
- 您计算的比例
startScale = Double(100/zoom)
仅基于手势识别器比例,该比例仅适用于当前捏合(因此每次捏合都会重置)。这个需要根据GR尺度,夹点开始的尺度'remembered'。 - 您还将更改后的大小写中的
startScale
重置为您的新值。这给出了 'exponential' 类型的缩放效果;你不想要这个。
结束的案例只需要设置缩放值,这样我们就可以记住下一次捏合要从什么开始。在这种情况下,它可能有点多余,您可能会逃脱 startScale = startScale * zoom
并且在开始的情况下什么也没有。
尚未测试以下内容,但希望它能给您一些想法。您传递给 zoom
函数的值实际上是一个视野角度,因此我将其重命名以区别于各种比例。 FOV 将在 30-60 度左右,而比例更像是在 0.1 - 10 的范围内(非常粗略)。
func handlePinch(gestureRecognize: UIPinchGestureRecognizer) {
if gestureRecognize.numberOfTouches() == 2 {
let zoom = gestureRecognize.scale
if (gestureRecognize.state == UIGestureRecognizerState.Began){
startScale = lastScale
} else if (gestureRecognize.state == UIGestureRecognizerState.Changed){
let fov = Double(100/(startScale * zoom))
bimScene.zoom(fov)
} else {
lastScale = startScale * zoom
}
}
}
这是另一种处理特定节点缩放 in-out 的方法,如果需要在不改变相机视角的情况下实现这一点。
-(void)handlePinch:(UIPinchGestureRecognizer*)gestureRecognizer {
if (gestureRecognizer.numberOfTouches == 2) {
CGFloat zoom = gestureRecognizer.scale;
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
lastScale = yourNode.scale.x;
} else if (gestureRecognizer.state == UIGestureRecognizerStateChanged) {
double final = lastScale * zoom;
yourNode.scale = SCNVector3Make(final, final, final);
}
}
}