Ich baue ein 360-Video-Viewer mit dem iOS SceneKit Framework.So verwenden Sie eine Schwenkgeste zum Drehen einer Kamera in SceneKit mit quaternions
Ich möchte eine UIPanGestureRecognizer verwenden, um die Ausrichtung der Kamera zu steuern.
SCNNode s haben mehrere Eigenschaften, die wir ihre Rotation angeben können: rotation
(a Rotationsmatrix), orientation
(a Quaternion), eulerAngles
(pro Achswinkel).
Alles, was ich gelesen habe sagt, um die Verwendung von Euler Winkel zu vermeiden, um zu vermeiden, gimbal lock.
Ich möchte Quaternionen aus ein paar Gründen verwenden, auf die ich hier nicht eingehen werde.
Ich habe Probleme, dies richtig zu funktionieren. Kamerasteuerung ist fast wo ich es gerne hätte, aber da stimmt was nicht. Es sieht so aus, als ob die Kamera um die Z-Achse gedreht wird, obwohl ich versucht habe, nur die X- und Y-Achse zu beeinflussen.
Ich glaube, das Problem hat etwas mit meiner Quaternion-Multiplikationslogik zu tun. Ich habe nichts in den nächsten Jahren quaternion Zusammenhang getan :(Mein pan Geste Handler hier:
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
}
}
Mein Code Open Source ist hier: https://github.com/alfiehanssen/360Player/
Schauen Sie sich die pan-gesture
Zweig insbesondere: https://github.com/alfiehanssen/360Player/tree/pan-gesture
Wenn Sie den Code nach unten ziehen glaube ich, werden Sie es nicht auf einem Gerät laufen müssen als der Simulator.
ich ein Video hier gepostet, der den Bug demonstriert (bitte ex cuse die geringe resness der video datei): https://vimeo.com/174346191
Vielen Dank im Voraus für jede Hilfe!