视口? 或相机? 视野? 旋转 iOS 设备上的更改



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

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

我不懂3D数学,矩阵,也不真正理解相机之类的东西,但是我已经建立了一个3D世界,我有一个可以工作的相机,并且用平移手势环绕世界中心的物体。

我的问题是,当我将设备从纵向旋转到横向时,SceneKit 视图会自动更改它的视角(我不确定的是相机?还是世界本身?(,而看起来很近的物体现在又回到了远处。

我想发生的是,无论旋转如何,"视口"?还是相机?还是世界视角?保持不变,相机与物体的距离不会"看起来"不同,即物体在视觉上停留在同一位置。

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

我知道 SceneKit 的单位是米,所以我的对象尺寸正确,摄像机距离它的正确米数......它看起来"正确">

我不明白的是,为什么景观会发生变化。

是的,SceneKit 视图使用自动布局约束来拥抱屏幕边缘。

这是我的相机设置:

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),我可以更正此自动更改并保持视图的"视角"相同。

谢谢。

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

我使用 0 个常量将 scenekitview 限制为超级视图,因此它始终是屏幕的大小。

然后我所要做的就是解决这个问题,那就是一条线......叹息。

我只需要将"传感器高度"减半,然后它就可以完美地工作了。

if UIDevice.current.orientation == .landscapeLeft  || 
UIDevice.current.orientation == .landscapeRight
{
self.cameraNode?.camera?.sensorHeight  = 12
}
else
{
self.cameraNode?.camera?.sensorHeight  = 24
}

编辑:

由于屏幕大小的限制,默认视野意味着您具有鱼眼效果。

将 FoV 降低到几乎一半的固化,现在物体旋转而不会失真:

camera.fieldOfView = 50

从ios11中,您还可以告诉Scenekit要使用哪种投影。

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

camera.projectionDirection = isPortrait ? .vertical : .horizontal 

最新更新