【问题标题】:Swift SceneKit set max/min camera zoomSwift SceneKit 设置最大/最小相机变焦
【发布时间】:2021-09-07 07:10:23
【问题描述】:

我创建了一个球体,并希望为默认相机控制设置缩放的最大值和最小值 (sceneView.allowsCameraControl = true)

如何设置用户可以缩放球体的最大/最小值?

编辑: 我在SCNCamera 中找到了zNearzFar 属性,但我使用正交投影,在这个投影中zNearzFar 没有工作(

// Set scene settings
sceneView.scene = scene

cameraOrbit = SCNNode()
cameraNode = SCNNode()
cameraNode.name = "camera"
camera = SCNCamera()

// camera stuff
camera.usesOrthographicProjection = true
camera.orthographicScale = 5
camera.zNear = 1
camera.zFar = 100


// initially position is far away as we will animate moving into the globe
cameraNode.position = SCNVector3(x: 0, y: 0, z: 50)
cameraNode.camera = camera
cameraOrbit = SCNNode()
cameraOrbit.addChildNode(cameraNode)
scene.rootNode.addChildNode(cameraNode)

// Material
let blueMaterial = SCNMaterial()
blueMaterial.diffuse.contents = UIImage(named: "earth2")
blueMaterial.shininess = 0.05
blueMaterial.multiply.contents = UIColor(displayP3Red: 0.7, green: 0.7, blue: 0.7, alpha: 1.0)

let sphere = SCNSphere(radius: 2)
sphere.segmentCount = 300
sphere.firstMaterial?.diffuse.contents = UIColor.red
earthNode = SCNNode(geometry: sphere)
earthNode.name = "sphere"
earthNode.geometry?.materials = [blueMaterial]
scene.rootNode.addChildNode(earthNode)
earthNode.rotation = SCNVector4(0, 1, 0, 0)

let lightNode = SCNNode()
let light = SCNLight()
light.type = .ambient
light.intensity = 200

lightNode.light = light
scene.rootNode.addChildNode(lightNode)

sceneView.allowsCameraControl = true
sceneView.backgroundColor = UIColor.clear
sceneView.cameraControlConfiguration.allowsTranslation = true
sceneView.cameraControlConfiguration.rotationSensitivity = 0.4

【问题讨论】:

    标签: swift scenekit


    【解决方案1】:

    不要使用allowCameraControl - 它的功能有限。

    创建您自己的相机类:

    class Camera
    {
        var data = Data.sharedInstance
        var util = Util.sharedInstance
        var gameDefaults = Defaults()
        
        var cameraEye = SCNNode()
        var cameraFocus = SCNNode()
            
        var centerX: Int = 100
        var strafeDelta: Float = 0.8
        var zoomLevel: Int = 35
        var zoomLevelMax: Int = 35              // Max number of zoom levels
        
        //********************************************************************
        init()
        {
            cameraEye.name = "Camera Eye"
            cameraFocus.name = "Camera Focus"
            
            cameraFocus.isHidden = true
            cameraFocus.position  =  SCNVector3(x: 0, y: 0, z: 0)
            
            cameraEye.camera = SCNCamera()
            cameraEye.constraints = []
            cameraEye.position = SCNVector3(x: 0, y: 15, z: 0.1)
            
            let vConstraint = SCNLookAtConstraint(target: cameraFocus)
            vConstraint.isGimbalLockEnabled = true
            cameraEye.constraints = [vConstraint]
        }
        //********************************************************************
        func reset()
        {
            centerX = 100
            cameraFocus.position  =  SCNVector3(x: 0, y: 0, z: 0)
            cameraEye.constraints = []
            cameraEye.position = SCNVector3(x: 0, y: 32, z: 0.1)
            cameraFocus.position = SCNVector3Make(0, 0, 0)
            
            let vConstraint = SCNLookAtConstraint(target: cameraFocus)
            vConstraint.isGimbalLockEnabled = true
            cameraEye.constraints = [vConstraint]
        }
        //********************************************************************
        func strafeRight()
        {
            if(centerX + 1 < 112)
            {
                centerX += 1
                cameraEye.position.x += strafeDelta
                cameraFocus.position.x += strafeDelta
            }
        }
        //********************************************************************
        func strafeLeft()
        {
            if(centerX - 1 > 90)
            {
                centerX -= 1
                cameraEye.position.x -= strafeDelta
                cameraFocus.position.x -= strafeDelta
            }
        }
        //********************************************************************
    }
    

    这个例子有扫射,但缩放是类似的——只是将眼睛移近目标。将最远距离设置为默认值,然后根据百分比或 lerp 将眼睛移近。

    编辑

    //**************************************************************************
        func dragBegins(vRecognizer: UIPanGestureRecognizer)
        {
            if(data.gameState == .run)
            {
                if(vRecognizer.numberOfTouches == 2) { dragMode = .strafe }
            }
        }
        //**************************************************************************
        func dragChanges(vRecognizer: UIPanGestureRecognizer)
        {
            if(data.gameState == .run)
            {
                if(dragMode == .strafe && vRecognizer.numberOfTouches == 1)
                {
                    dragMode = .none
                    return
                }
                
                switch(dragMode)
                {
                case .strafe:
                    gNodes.camera.strafe(vX: Float(currentLocation.x), vY: Float(currentLocation.y))
                    break
                case .none:
                    break
                default:
                    break
                }
            }
        }
        //**************************************************************************
        func dragEnds(vRecognizer: UIPanGestureRecognizer)
        {
            if(data.gameState == .run)
            {
                switch(dragMode)
                {
                case .strafe:
                    break
                default:
                    break
                }
            }
            dragMode = .none
        }
    

    【讨论】:

    • 非常感谢你!您知道如何执行此功能:用两根手指平移以在其本地 xy 平面上平移相机吗?当 allowCameraControl 处于活动状态时,我可以用两根手指移动我的球体
    • developer.apple.com/documentation/scenekit/scnview/… - 你看到这个文档了吗?我不知道它是新的还是我在做场景包时没有看到它,但它可能会有所帮助。
    • 如果有帮助,我可以为您的视图控制器示例提供 handleTap 和拖动。我为这些问题创建了一个 3d 数学库,但我不知道场景包等价物。对不起
    • 是的,我看到了这个文档,它对我没有帮助(是的,谢谢,示例可能对我有帮助
    猜你喜欢
    • 1970-01-01
    • 2018-06-27
    • 2014-01-24
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 2011-08-11
    • 2013-10-05
    相关资源
    最近更新 更多