SceneKit 相机节点在捏合手势时重置
Posted
技术标签:
【中文标题】SceneKit 相机节点在捏合手势时重置【英文标题】:SceneKit camera node resets on pinch gesture 【发布时间】:2016-07-26 21:00:28 【问题描述】:我试图在捏合手势上实现缩放,但是每次我第二次捏合时,模型都会自行重置。
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 的新手,所以我觉得这很奇怪。有人可以解释一下原因吗?
【问题讨论】:
什么是 bimScene 和 SNScene?节点? 【参考方案1】:你已经接近了,逻辑有点不对。
开始的情况很好,您需要“记住”开始捏合的比例,这可能是您上次缩放时设置的比例。
您更改后的案例有两个问题。
您计算的比例startScale = Double(100/zoom)
仅基于手势识别器比例,此比例仅适用于当前捏合(因此每次捏合都会重置)。这需要基于 GR 比例,以及在紧要关头开始时“记住”的比例。
您还将startScale
在更改后的大小写中重置为您的新值。这给出了“指数”类型的缩放效果;你不想要这个。
结束的案例只需要设置比例值,这样我们就可以记住下一个捏从什么开始。在这种情况下,它可能有点多余,您可能会使用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
【讨论】:
【参考方案2】:这是处理特定节点的缩放进出的另一种方法,如果需要在不改变相机视角的情况下实现这一点。
-(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);
【讨论】:
只是想说这是用于基本相机控制的钻石。非常感谢您提供了一个紧凑的、非常简单的块,它直接将手势识别器的放大率与节点的比例因子相关联。例如,我将其应用于我的相机节点,并且能够完美地复制放大/缩小变换。以上是关于SceneKit 相机节点在捏合手势时重置的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SceneKit 中将 allowCameraControl 与相机节点一起使用