我正在使用iOS SceneKit框架構建360視頻查看器。如何使用平移手勢在SceneKit中使用四元數旋轉攝像機
我想使用UIPanGestureRecognizer來控制相機的方向。
SCNNode■找幾個屬性,我們可以使用,以指定它們的旋轉:rotation
(旋轉矩陣),orientation
(四元),eulerAngles
(每個軸的角度)。
我讀過的一切都說避免使用歐拉角度以避免gimbal lock。
我想使用四元數有幾個原因,我不會在這裏進入。
我無法正常工作。相機控制幾乎是我想要的地方,但有些地方出了問題。儘管我試圖影響X軸和Y軸,但看起來好像相機正在圍繞Z軸旋轉。
我相信這個問題與我的四元數乘法邏輯有關。
func didPan(recognizer: UIPanGestureRecognizer)
{
switch recognizer.state
{
case .Began:
self.previousPanTranslation = .zero
case .Changed:
guard let previous = self.previousPanTranslation else
{
assertionFailure("Attempt to unwrap previous pan translation failed.")
return
}
// Calculate how much translation occurred between this step and the previous step
let translation = recognizer.translationInView(recognizer.view)
let translationDelta = CGPoint(x: translation.x - previous.x, y: translation.y - previous.y)
// Use the pan translation along the x axis to adjust the camera's rotation about the y axis.
let yScalar = Float(translationDelta.x/self.view.bounds.size.width)
let yRadians = yScalar * self.dynamicType.MaxPanGestureRotation
// Use the pan translation along the y axis to adjust the camera's rotation about the x axis.
let xScalar = Float(translationDelta.y/self.view.bounds.size.height)
let xRadians = xScalar * self.dynamicType.MaxPanGestureRotation
// Use the radian values to construct quaternions
let x = GLKQuaternionMakeWithAngleAndAxis(xRadians, 1, 0, 0)
let y = GLKQuaternionMakeWithAngleAndAxis(yRadians, 0, 1, 0)
let z = GLKQuaternionMakeWithAngleAndAxis(0, 0, 0, 1)
let combination = GLKQuaternionMultiply(z, GLKQuaternionMultiply(y, x))
// Multiply the quaternions to obtain an updated orientation
let scnOrientation = self.cameraNode.orientation
let glkOrientation = GLKQuaternionMake(scnOrientation.x, scnOrientation.y, scnOrientation.z, scnOrientation.w)
let q = GLKQuaternionMultiply(combination, glkOrientation)
// And finally set the current orientation to the updated orientation
self.cameraNode.orientation = SCNQuaternion(x: q.x, y: q.y, z: q.z, w: q.w)
self.previousPanTranslation = translation
case .Ended, .Cancelled, .Failed:
self.previousPanTranslation = nil
case .Possible:
break
}
}
我的代碼是開源的位置:https://github.com/alfiehanssen/360Player/
退房的pan-gesture
分支,特別是: https://github.com/alfiehanssen/360Player/tree/pan-gesture
如果你拉下來的代碼,我相信你必須在設備上運行它,而不是模擬器。
我這裏張貼的視頻演示錯誤(請EX請使用低分辨率的視頻文件): https://vimeo.com/174346191
在此先感謝您的幫助!