swift - 视口?还是相机?视野?旋转 iOS 设备上的变化
问题描述
我有一个在我的应用程序中使用 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)
我可以更正此自动更改并保持视图的“透视”相同。
谢谢你。
解决方案
经过4天的约束,手动移动框架和各种东西,我已经修复了它。
我将scenekitview限制为0常量的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
推荐阅读
- types - 如何检查子函数是否存在(聚合物)
- excel - 使用 VBA 仅刷新彭博数据的一个工作表
- puppet - Puppet - 函数 'hiera_array' 已弃用,取而代之的是使用 'lookup'
- vim - vim 脚本 - 构建当前/主文件
- getstream-io - 将活动发送到多个通知源
- xpages-ssjs - 在嵌套重复控件中使用 HashMap 基于键获取值
- c++ - 对图像应用透视 - 单应性
- javascript - 如何使用从客户端传递的参数
- python - 使用通配符 Python 查找复杂的子字符串
- python - 在 python 中分组,列具有 N/A 值