Derzeit bin ich verwirrt in Bezug auf die Herstellung einer Funktionalität von 3D-Kompass. Mit SceneKit geladen I ein Pfeil Objekt und dann abgerufene Sensordaten wie der Code (Der Effekt ist this video)So implementieren Sie einen 3D-Kompass mit SceneKit
let motionManager = CMMotionManager()
motionManager.deviceMotionUpdateInterval = 1.0/60.0
if motionManager.isDeviceMotionAvailable {
motionManager.startDeviceMotionUpdates(to: OperationQueue.main, withHandler: { (devMotion, error) -> Void in
arrow.orientation = SCNQuaternion(-CGFloat((motionManager.deviceMotion?.attitude.quaternion.x)!), -CGFloat((motionManager.deviceMotion?.attitude.quaternion.y)!), -CGFloat((motionManager.deviceMotion?.attitude.quaternion.z)!), CGFloat((motionManager.deviceMotion?.attitude.quaternion.w)!))
})}
Nachdem dies geschehen, wenn der Benutzer das Gerät in jeder Achse zu drehen, kann der Pfeil als drehbar Gut. Da dies ein 3D-Kompass ist, brauche ich den Pfeil, um die Richtung zu zeigen. Also habe ich die Überschriftsdaten über CLLocationManager geholt, und dann kommt das Problem.
Der obige Code funktioniert perfekt in 2D wie das Bild unten, es zeigt die Ostrichtung korrekt. Aber ich will es in 3D-Umgebung, also tat ich wie unter
motionManager.deviceMotionUpdateInterval = 1.0/60.0
if motionManager.isDeviceMotionAvailable {
motionManager.startDeviceMotionUpdates(to: OperationQueue.main, withHandler: { (devMotion, error) -> Void in
arrow.orientation = orient(q: (motionManager.deviceMotion?.attitude.quaternion)!, angle: heading)
}
func orient(q:CMQuaternion,angle:Float) -> SCNQuaternion{
GLKQuaternionMakeWithAngleAndAxis(GLKMathDegreesToRadians(-angle), 0, 0, 1)
let gq1: GLKQuaternion = GLKQuaternionMakeWithAngleAndAxis(GLKMathDegreesToRadians(-angle), 0, 0, 1)
// add a rotation in z axis
let gq2: GLKQuaternion = GLKQuaternionMake(Float(q.x), Float(q.y), Float(q.z), Float(q.w))
// the current orientation
let qp: GLKQuaternion = GLKQuaternionMultiply(gq1, gq2)
// get the "new" orientation
var rq = CMQuaternion()
rq.x = Double(qp.x)
rq.y = Double(qp.y)
rq.z = Double(qp.z)
rq.w = Double(qp.w)
return SCNVector4(-Float(rq.x), -Float(rq.y), -Float(rq.z), Float(rq.w))
}
Es ist ein Bug (this video Shows), wenn ich das Gerät um die z-Achse drehen, immer noch der Pfeil um y-Achse dreht. Habe ich etwas falsch gemacht?