I have set up some custom camera controls in my SceneKit game. I am having a problem with my pan gesture auto-adapting based on the cameras y euler angle. The pan gesture I have works by panning the camera on the x and z axis (by using the gestures translation) The problem is, despite the cameras rotation, the camera will continue to pan on the x and z axis. I want it so that the camera pans on the axis its facing.
here are my gestures I am using to pan/rotate:
panning:
var previousTranslation = SCNVector3(x: 0.0,y: 15,z: 0.0)
var lastWidthRatio:Float = 0
var angle:Float = 0
@objc func pan(gesture: UIPanGestureRecognizer) {
gesture.minimumNumberOfTouches = 1
gesture.maximumNumberOfTouches = 1
if gesture.numberOfTouches == 1 {
let view = self.view as! SCNView
let node = view.scene!.rootNode.childNode(withName: "Node", recursively: false)
let secondNode = view.scene!.rootNode.childNode(withName: "CameraHandler", recursively: false)
let translation = gesture.translation(in: view)
let constant: Float = 30.0
angle = secondNode!.eulerAngles.y
//these were the previous values I was using to handle panning, they worked but provided really jittery movement. You can change the direction they rotate by multiplying the sine/cosine .pi values by any integer.
//var translateX = Float(translation.y) * sin(.pi) / cos(.pi) - Float(translation.x) * cos(.pi)
//var translateY = Float(translation.y) * cos(.pi) / cos(.pi) + Float(translation.x) * sin(.pi)
//these ones work a lot smoother
var translateX = Float(translation.x) * Float(Double.pi / 180)
var translateY = Float(translation.y) * Float(Double.pi / 180)
translateX = translateX * constant
translateY = translateY * constant
switch gesture.state {
case .began:
previousTranslation = node!.position
break;
case .changed:
node!.position = SCNVector3Make((previousTranslation.x + translateX), previousTranslation.y, (previousTranslation.z + translateY))
break
default: break
}
}
}
rotation:
@objc func rotate(gesture: UIPanGestureRecognizer) {
gesture.minimumNumberOfTouches = 2
gesture.maximumNumberOfTouches = 2
if gesture.numberOfTouches == 2 {
let view = self.view as! SCNView
let node = view.scene!.rootNode.childNode(withName: "CameraHandler", recursively: false)
let translate = gesture.translation(in: view)
var widthRatio:Float = 0
widthRatio = Float(translate.x / 10) * Float(Double.pi / 180)
switch gesture.state {
case .began:
lastWidthRatio = node!.eulerAngles.y
break
case .changed:
node!.eulerAngles.y = lastWidthRatio + widthRatio
print(node!.eulerAngles.y)
break
default: break
}
}
}
the CameraHandler
Node is the parent node of the Camera
Node. It all works, it just doesnt work like I want it to. Hopefully this is clear enough for you guys to understand.