视口?还是相机?视野?旋转 iOS 设备上的变化

Posted

技术标签:

【中文标题】视口?还是相机?视野?旋转 iOS 设备上的变化【英文标题】:Viewport? or Camera? of Field of View? changes on rotating iOS device 【发布时间】:2020-01-02 01:14:41 【问题描述】:

我的应用中有一个使用 SceneKit 视图的 3d 世界。

我需要支持所有 ios 设备和方向。

我不了解 3d 数学、矩阵,也不真正了解相机和其他东西,但我已经构建了一个 3d 世界,并且我有一个可以工作的相机,并且可以使用 Pan Gesture 环绕世界中心的物体。

我的问题是,当我将设备从纵向旋转到横向时,SceneKit 视图会自动改变它的视角(我不确定 - 相机?还是世界本身?)和看起来很接近的对象,现在回到远方。

我想要发生的是,无论旋转“视口”如何?还是相机?还是世界观?保持不变,并且相机与物体的距离没有“看起来”不同,即物体在视觉上保持在同一个地方。

我没有做过任何矩阵操作或设置任何复杂的东西。

我知道 SceneKit 的单位是米,所以我的对象大小正确,相机距离它的米数是正确的......看起来“正确”

我不明白为什么这一切都会改变。

是的,SceneKit 视图使用 AutoLayout 约束来紧贴屏幕边缘。

这是我的相机设置:

private func setupCamera() -> SCNNode 
    let camera = SCNCamera()
    camera.usesOrthographicProjection = false
    camera.orthographicScale          = 9
    camera.zNear                      = 0.01
    camera.zFar                       = 9500
    camera.focalLength                = 50
    camera.focusDistance              = 33
    camera.fieldOfView                = 100
    let cameraNode                    = SCNNode()
    cameraNode.position               = SCNVector3(x:0, y:0, z: 500.0)
    cameraNode.camera                 = camera
    self.cameraNode                   = cameraNode
    let cameraOrbit                   = SCNNode()

    cameraOrbit.addChildNode(self.cameraNode!)

    return cameraOrbit

我发现“解决”这个问题的唯一方法是让 SceneKit 视图始终为正方形,并调整其大小,使其始终是设备宽度或高度中最大的,并使其中心位于屏幕中心。

但这种方法不适用于应用程序的其他部分,因此我知道我需要“正确”地执行此操作。

那么请有人提供代码或告诉我我需要了解什么,以便在设备旋转时调用的函数中,即override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) 然后我可以更正此自动更改并保持视图的“透视”相同.

谢谢。

【问题讨论】:

【参考方案1】:

在玩了 4 天的约束、手动移动框架和各种东西后,我已经修复了它。

我用 0 个常量将 scenekitview 限制为 superview,所以它始终是屏幕的大小。

那么我要做的就是解决这个问题……叹息。

我只需将“sensorHeight”减半,然后它就可以完美运行了。

if UIDevice.current.orientation == .landscapeLeft  || 
   UIDevice.current.orientation == .landscapeRight

    self.cameraNode?.camera?.sensorHeight  = 12

else

    self.cameraNode?.camera?.sensorHeight  = 24

编辑:

由于屏幕尺寸的限制,默认视野意味着你有鱼眼效果。

将 FoV 降低到几乎一半可以解决这个问题,现在物体旋转时不会发生扭曲:

    camera.fieldOfView = 50

【讨论】:

【参考方案2】:

从ios11你也可以告诉scenekit使用哪个投影。

这为我解决了它并且与纵横比无关。

camera.projectionDirection = isPortrait ? .vertical : .horizontal 

【讨论】:

以上是关于视口?还是相机?视野?旋转 iOS 设备上的变化的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用相机意图捕获的图像会在 Android 上的某些设备上旋转?

计算不在相机视野范围内的模型的方法

android中三星设备上的相机捕捉方向

谷歌街景旋转相机与设备陀螺仪

对相机的理解及使用多相机绘制只旋转的坐标系

在Swift中旋转设备时iOS 8 uitableviewcell高度发生变化