I see that your globe is centered in a SCNScene
, the place the digital camera is positioned to take a look at the globe. And you’ve got constraints that aren’t functioning as anticipated.
SCNLookAtConstraint
is designed to make a node orient itself in the direction of one other node. Whereas it gives a function like isGimbalLockEnabled
to stop gimbal lock, it doesn’t supply direct management over proscribing rotation angles on particular axes
It’s extra suited to eventualities the place you need the digital camera to all the time face a goal, slightly than controlling its tilt or horizontal rotation limits.
As a substitute of utilizing SCNLookAtConstraint
, attempt to use SCNTransformConstraint
to regulate the digital camera’s orientation. Outline a spread for allowed rotation across the y-axis (horizontal rotation).
SCNTransformConstraint
means that you can outline customized constraints on the node’s transformation, together with its orientation. That allows you to exactly management the rotation round particular axes, corresponding to limiting rotation to a sure vary across the x-axis (tilt) whereas permitting free rotation across the y-axis (horizontal rotation). And you’ll apply customized logic to find out the allowed rotation.
In your case, restrict the lean of the globe to +/- 30 levels across the x-axis.
personal func setupCamera() {
self.cameraNode = SCNNode()
cameraNode.digital camera = SCNCamera()
cameraNode.place = SCNVector3(x: 0, y: 0, z: 5)
let constraint = SCNTransformConstraint.orientationConstraint(inWorldSpace: true) { (_, orientation) -> SCNQuaternion in
let clampedX = max(min(orientation.x, 0.261799), -0.261799) // Clamping to +/- 30 levels in radians
return SCNQuaternion(x: clampedX, y: orientation.y, z: 0, w: orientation.w)
}
cameraNode.constraints = [constraint]
sceneView.scene?.rootNode.addChildNode(cameraNode)
}
The max(min())
perform clamps the rotation to +/- 30 levels (transformed to radians). Rotation across the y-axis (horizontal rotation) stays unrestricted.