Swift SceneKit 设置 max/min 相机缩放
Swift SceneKit set max/min camera zoom
我创建了一个球体,想为默认相机控制设置缩放的最大值和最小值(sceneView.allowsCameraControl = true
)
如何设置用户可以缩放球体的最大/最小值?
编辑:
我在 SCNCamera
中找到了 zNear
和 zFar
属性,但我使用正交投影,在这个投影中 zNear
和 zFar
没有工作(
// 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
不要使用 allowsCameraControl - 它的功能有限。
创建你自己的相机class:
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
}
我创建了一个球体,想为默认相机控制设置缩放的最大值和最小值(sceneView.allowsCameraControl = true
)
如何设置用户可以缩放球体的最大/最小值?
编辑:
我在 SCNCamera
中找到了 zNear
和 zFar
属性,但我使用正交投影,在这个投影中 zNear
和 zFar
没有工作(
// 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
不要使用 allowsCameraControl - 它的功能有限。
创建你自己的相机class:
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
}