SCNCamera 限制轨迹球旋转 [英] SCNCamera limit arcball rotation

查看:30
本文介绍了SCNCamera 限制轨迹球旋转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 SCNCamera 的场景设置,可以围绕一个对象旋转.

I have a scene setup with SCNCamera that rotates around an object.

限制相机可以围绕对象实现的旋转范围的最佳方法是什么?

What would be the best way to limit the extents of rotation the camera can achieve around the object?

示例:我如何将旋转限制在单个半球而不是围绕整个球体旋转?

Example: instead of being able to rotate around a whole sphere, how would I limit rotation to a single hemisphere?

我的第一次尝试是查看 .allowsCameraControl 是否有任何限制.找不到任何东西.

My first attempt was to see if there was any clamps for .allowsCameraControl. Could not find anything.

然后我尝试适应 c# Unity:鼠标轨道脚本,没有运气.

I then tried adapting c# Unity : mouse orbit script, no luck.

有关如何处理或解决此问题的一些指示会很棒.

Some pointers on how to approach or solve this would great.

Boilerplate Arcball 感谢 这个答案.

Boilerplate Arcball thanks to this answer.

var lastWidthRatio: Float = 0
var lastHeightRatio: Float = 0

let camera = SCNCamera()
let cameraNode = SCNNode()
let cameraOrbit = SCNNode()

override func viewDidLoad() {
    super.viewDidLoad()

    // create a new scene
    let scene = SCNScene(named: "art.scnassets/ship.scn")!

    // create and add a camera to the scene

    camera.usesOrthographicProjection = true
    camera.orthographicScale = 9
    camera.zNear = 0
    camera.zFar = 100

    cameraNode.position = SCNVector3(x: 0, y: 0, z: 50)
    cameraNode.camera = camera

    cameraOrbit.addChildNode(cameraNode)
    scene.rootNode.addChildNode(cameraOrbit)

    // retrieve the ship node
    let ship = scene.rootNode.childNodeWithName("ship", recursively: true)!

    // retrieve the SCNView
    let scnView = self.view as! SCNView

    // set the scene to the view
    scnView.scene = scene

    // add a tap gesture recognizer
    let gesture = UIPanGestureRecognizer(target: self, action: "panDetected:");
    scnView.addGestureRecognizer(gesture);
}


func panDetected(sender: UIPanGestureRecognizer) {
    let translation = sender.translationInView(sender.view!)
    let widthRatio = Float(translation.x) / Float(sender.view!.frame.size.width) + lastWidthRatio
    let heightRatio = Float(translation.y) / Float(sender.view!.frame.size.height) + lastHeightRatio
    self.cameraOrbit.eulerAngles.y = Float(-2 * M_PI) * widthRatio
    self.cameraOrbit.eulerAngles.x = Float(-M_PI) * heightRatio

    print(Float(-2 * M_PI) * widthRatio)
    if (sender.state == .Ended) {
        lastWidthRatio = widthRatio % 1
        lastHeightRatio = heightRatio % 1
    }
}

推荐答案

看起来您就快到了,只需使用来自你引用的答案.

It looks like you're almost there, using just the @Rickster code from the answer you cited.

您可以在以下几行中进行更改:

The change you could make would be in these lines:

self.cameraOrbit.eulerAngles.y = Float(-2 * M_PI) * widthRatio
self.cameraOrbit.eulerAngles.x = Float(-M_PI) * heightRatio

隐含地允许俯仰和偏航覆盖整个领域.这就是你可以做你的限制的地方.例如,而不是允许间距 (eulerAngles.x) 从 0 变化到-π,你可以做

which implicitly allow pitch and yaw to cover the entire sphere. That's where you can do your limiting. For instance, instead of allowing the pitch (eulerAngles.x) to vary from 0 to -π, you could do

self.cameraOrbit.eulerAngles.x = Float(-M_PI_2) + Float(-M_PI_2) * heightRatio

在 -π/2 和 -π 之间平滑变化,使用全屏垂直滚动以覆盖该范围.或者你可以把这两行中的硬最小/最大限制/检查以约束到地球的特定区域.

to vary smoothly between -π/2 and -π, using full screen vertical scrolling to cover that range. Or you could put hard min/max limits/checks in those two lines to constrain to a particular area of the globe.

(编辑以解决惯性评论)

对于旋转阻尼或惯性,我会使用内置的 SceneKit Physics 来处理它,并且可能将相机放在一个不可见的(无几何体)SCNNode 上.那个相机节点变成了一个万向节,类似于这个项目中采用的方法:完全用 RubyMotion 和 SceneKit 创建的交互式七英尺地球.

For rotational damping, or inertia, I'd approach it by using the built in SceneKit Physics, and perhaps put the camera on an invisible (no geometry) SCNNode. That camera node becomes a gimbal, similar to the approach taken in this project: An interactive seven-foot globe created entirely in RubyMotion and SceneKit.

虚拟万向节然后获得一个带有一些阻尼SCNPhysicsBody(你添加它,默认情况下它没有一个).或者,也许您将物理放在中心对象上,并为该对象提供一些 angularDamping.

The virtual gimbal then gets an SCNPhysicsBody (you add that, it doesn't come with one by default) with some damping. Or perhaps you put the physics on your central object, and give that object some angularDamping.

这篇关于SCNCamera 限制轨迹球旋转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆