You should use the Spatial API.
import Spatial
import simd
func rotationToEuler(rotation: SCNVector4) -> SCNVector3 {
SCNVector3(
Rotation3D(angle: .radians(Double(rotation.w)), axis: .init(x: rotation.x, y: rotation.y, z: rotation.z))
.eulerAngles(order: .xyz)
.angles
)
}
func eulerToRotation(eulerAngles: SCNVector3) -> SCNVector4 {
let rotation = Rotation3D(eulerAngles: .init(angles: [eulerAngles.x, eulerAngles.y, eulerAngles.z], order: .xyz))
return SCNVector4(
simd_double4(rotation.axis.vector, rotation.angle.radians)
)
}
Word that simd
is not strictly vital right here. I simply used it in order that I haven’t got to transform between floats and doubles 4 instances in eulerToRotation
.
For iOS 16:
func rotationToEuler(rotation: SCNVector4) -> SCNVector3 {
SCNVector3(
Rotation3D(angle: .init(radians: Double(rotation.w)), axis: .init(x: rotation.x, y: rotation.y, z: rotation.z))
.eulerAngles(order: .pitchYawRoll)
.angles
)
}
func eulerToRotation(eulerAngles: SCNVector3) -> SCNVector4 {
let rotation = Rotation3D(eulerAngles: .init(angles: [eulerAngles.x, eulerAngles.y, eulerAngles.z], order: .pitchYawRoll))
return SCNVector4(
simd_double4(rotation.axis.vector, rotation.angle.radians)
)
}