我试图用Swift在SceneKit中执行SCNQuaternion Multiplication。以下代码在F#(Xamarin iOS开发)中。我试图将该代码翻译成Swift。
我被困在线上:让dqm = SCNQuaternion.Multiply ...... SceneKit没有名为multiply的成员。
知道我该怎么做吗?
let rr = CMAttitudeReferenceFrame.XArbitraryCorrectedZVertical
this.motion.DeviceMotionUpdateInterval <- float (1.0f / 30.0f)
this.motion.StartDeviceMotionUpdates (rr,NSOperationQueue.CurrentQueue, (fun d e ->
let a = this.motion.DeviceMotion.Attitude
let q = a.Quaternion
let dq = new SCNQuaternion(float32 q.x, float32 q.y, float32 q.z, float32 q.w)
let dqm = SCNQuaternion.Multiply (dq, SCNQuaternion.FromAxisAngle(SCNVector3.UnitZ, piover2))
camNode.Orientation <- dqm
()
))
答案 0 :(得分:7)
SceneKit不包含用于执行四元数数学的库。 SCNQuaternion
只是SCNVector4
的类型别名 - 换句话说,它是一个容纳四元数的四个系数的地方,但是您可以自己动手解释或使用它们。
在Xcode 9 / iOS 11 / macOS 10.13 High Sierra / etc中,有更好的方法来处理SceneKit中的四元数(和其他向量/矩阵数学):SIMD库包含两个四元数类型(用于double和float),和SceneKit复制所有SCNVector / SCNMatrix / SCNQuaternion访问器以提供SIMD版本。使用SIMD类型而不是SCN类型有很多很好的理由:
不幸的是,CoreMotion尚未(但是?)为其矢量/矩阵/四元数类型采用SIMD库,因此在使用SIMD之前,您需要将输入CMQuaternion
转换为simd_quatf
函数或基于SceneKit SIMD的API。如果您发现自己经常这样做,您可能需要对其进行扩展:
extension simd_quatf {
init(_ cmq: CMQuaternion) {
self.init(ix: Float(cmq.x), iy: Float(cmq.y), iz: Float(cmq.z), r: Float(cmq.w))
}
}
然后(假设我正在读你的F#),你的代码在Swift中会变成这样:
let zAxis = float3(x: 0, y: 0, z: 1)
let rotateAroundZ = simd_quatf(angle: .pi/2, axis: zAxis)
manager.startDeviceMotionUpdates(using: .xArbitraryZVertical, to: queue) { motion, error in
guard let motion = motion else { /* handle error and */ return }
let deviceQuaternion = simd_quatf(motion.attitude.quaternion)
cameraNode.simdOrientation = deviceQuaternion * rotateAroundZ
}
(*)一些有用的SIMD操作仍然是C风格的全局函数:检查
simd/quaternion.h
是否有slerp和Bézier插值等内容。
对于早期的Xcode / SDK版本......
在Xcode 9 / iOS 11 / macOS 10.13 / etc之前,SIMD中没有四元数,而且SceneKit中没有特定于SIMD的访问器。对于除四元数之外的所有内容,使用SCN类型,将它们按组件方式转换为等效的SIMD类型并在那里进行数学运算仍然很有用。
Apple确实在GLKit中发布了一个四元数库。使用GLKQuaternionMake
从GLKQuaternion
的四个组成部分中制作SCNQuaternion
。然后你可以将它乘以,slerp它,无论使用GLKQuaternion
函数。完成后,使用结果的组件制作另一个SCNQuaternion
。
在Swift 1.x(Xcode 6.x)中,Swift无法使用SIMD库。 GLKit数学是一个不错的替代品,但你最好只使用更新的Xcode - 记住你可以一直回到iOS 7 / macOS 10.9 Mavericks甚至使用Swift 4(并且SIMD库可以追溯到iOS 8 / macOS 10.10 Yosemite)。