Skip to content

Commit

Permalink
Deprecate Quaternion
Browse files Browse the repository at this point in the history
  • Loading branch information
nicklockwood committed Jan 29, 2024
1 parent b33dff8 commit 1004551
Show file tree
Hide file tree
Showing 9 changed files with 305 additions and 110 deletions.
19 changes: 11 additions & 8 deletions Sources/Euclid+SIMD.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,12 @@ public extension simd_quatd {
/// Creates a simd quaternion from a Euclid `Rotation`.
/// - Parameter rotation: A Euclid rotation.
init(_ rotation: Rotation) {
self.init(rotation.quaternion)
self = rotation.storage
}

/// Creates a simd quaternion from a Euclid `Quaternion`.
/// - Parameter quaternion: A Euclid quaternion.
@available(*, deprecated)
init(_ quaternion: Quaternion) {
self = quaternion.storage
}
Expand All @@ -95,35 +96,37 @@ public extension simd_quatf {
/// Creates a simd float quaternion from a Euclid `Rotation`.
/// - Parameter rotation: A Euclid rotation.
init(_ rotation: Rotation) {
self.init(rotation.quaternion)
self.init(vector: simd_float4(rotation.storage.vector))
}

/// Creates a simd float quaternion from a Euclid `Quaternion`.
/// - Parameter q: A Euclid quaternion.
init(_ q: Quaternion) {
self.init(ix: Float(q.x), iy: Float(q.y), iz: Float(q.z), r: Float(q.w))
/// - Parameter quaternion: A Euclid quaternion.
@available(*, deprecated)
init(_ quaternion: Quaternion) {
self.init(vector: simd_float4(quaternion.storage.vector))
}
}

public extension Rotation {
/// Creates a `Rotation` from a simd quaternion.
/// - Parameter quaternion: A simd quaternion.
init(_ quaternion: simd_quatd) {
self.init(Quaternion(quaternion))
self.init(storage: quaternion)
}

/// Creates a `Rotation` from a simd quaternion.
/// - Parameter quaternion: A simd quaternion.
init(_ quaternion: simd_quatf) {
self.init(Quaternion(quaternion))
self.init(simd_quatd(vector: simd_double4(quaternion.vector)))
}
}

@available(*, deprecated)
public extension Quaternion {
/// Creates a `Quaternion` from a simd quaternion.
/// - Parameter quaternion: A simd quaternion.
init(_ quaternion: simd_quatd) {
self.storage = quaternion
self.init(storage: quaternion)
}

/// Creates a `Quaternion` from a simd quaternion.
Expand Down
10 changes: 6 additions & 4 deletions Sources/Euclid+SceneKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,15 @@ public extension SCNQuaternion {
/// > Note: ``SCNQuaternion`` is actually just a typealias for ``SCNVector4`` so be
/// careful to avoid type ambiguity when using this value.
init(_ rotation: Rotation) {
self.init(rotation.quaternion)
self.init(rotation.x, rotation.y, rotation.z, rotation.w)
}

/// Creates a new SceneKit quaternion from a Euclid `Quaternion`
/// - Parameter quaternion: The quaternion to convert.
///
/// > Note: ``SCNQuaternion`` is actually just a typealias for ``SCNVector4`` so be
/// careful to avoid type ambiguity when using this value.
@available(*, deprecated)
init(_ quaternion: Quaternion) {
self.init(quaternion.x, quaternion.y, quaternion.z, quaternion.w)
}
Expand Down Expand Up @@ -504,12 +505,13 @@ public extension Vector {

public extension Rotation {
/// Creates a rotation from a SceneKit quaternion.
/// - Parameter quaternion: The `SCNQuaternion` to convert.
init(_ quaternion: SCNQuaternion) {
self.init(.init(quaternion))
/// - Parameter q: The `SCNQuaternion` to convert.
init(_ q: SCNQuaternion) {
self.init(Double(q.x), Double(q.y), Double(q.z), Double(q.w))
}
}

@available(*, deprecated)
public extension Quaternion {
/// Creates a Euclid `Quaternion` from a SceneKit quaternion.
/// - Parameter q: The `SCNQuaternion` to convert.
Expand Down
33 changes: 22 additions & 11 deletions Sources/Quaternion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import simd
///
/// In addition to being more compact than a 3x3 rotation matrix, quaternions also avoid a
/// problem known as gymbal lock.
@available(*, deprecated, message: "Use Rotation instead")
public struct Quaternion: Sendable {
var storage: simd_quatd

Expand Down Expand Up @@ -70,17 +71,19 @@ public struct Quaternion: Sendable {
}
}

@available(*, deprecated)
extension Quaternion: Hashable {
public func hash(into hasher: inout Hasher) {
hasher.combine(storage.vector)
}
}

@available(*, deprecated)
public extension Quaternion {
/// Creates a quaternion from raw component values.
init(_ x: Double, _ y: Double, _ z: Double, _ w: Double) {
let vector = simd_normalize(simd_double4(x, y, z, w))
self.init(simd_quatd(vector: vector))
self.init(storage: simd_quatd(vector: vector))
}

/// The axis of rotation.
Expand Down Expand Up @@ -120,7 +123,7 @@ public extension Quaternion {
if storage.vector == .zero {
return self
}
return .init(simd_normalize(storage))
return .init(storage: simd_normalize(storage))
}

/// Performs a spherical interpolation between two quaternions.
Expand All @@ -129,17 +132,17 @@ public extension Quaternion {
/// - t: The normalized extent of interpolation, from 0 to 1.
/// - Returns: The interpolated quaternion.
func slerp(_ q: Quaternion, _ t: Double) -> Quaternion {
.init(simd_slerp(storage, q.storage, t))
.init(storage: simd_slerp(storage, q.storage, t))
}

/// Returns the reverse quaternion rotation.
static prefix func - (q: Quaternion) -> Quaternion {
.init(simd_inverse(q.storage))
.init(storage: simd_inverse(q.storage))
}

/// Returns the sum of two quaternion rotations.
static func + (lhs: Quaternion, rhs: Quaternion) -> Quaternion {
.init(lhs.storage + rhs.storage)
.init(storage: lhs.storage + rhs.storage)
}

/// Adds the quaternion rotation on the right to the one on the left.
Expand All @@ -149,7 +152,7 @@ public extension Quaternion {

/// Returns the difference between two quaternion rotations,.
static func - (lhs: Quaternion, rhs: Quaternion) -> Quaternion {
.init(lhs.storage - rhs.storage)
.init(storage: lhs.storage - rhs.storage)
}

/// Subtracts the quaternion rotation on the right from the one on the left.
Expand All @@ -159,7 +162,7 @@ public extension Quaternion {

/// Returns the product of two quaternions (i.e. the effect of rotating the left by the right).
static func * (lhs: Quaternion, rhs: Quaternion) -> Quaternion {
.init(lhs.storage * rhs.storage)
.init(storage: lhs.storage * rhs.storage)
}

/// Multiplies the quaternion rotation on the left by the one on the right.
Expand All @@ -169,7 +172,7 @@ public extension Quaternion {

/// Returns a quaternion with its components multiplied by the specified value.
static func * (lhs: Quaternion, rhs: Double) -> Quaternion {
.init(lhs.storage * rhs)
.init(storage: lhs.storage * rhs)
}

/// Multiplies the components of the quaternion by the specified value.
Expand All @@ -179,7 +182,7 @@ public extension Quaternion {

/// Returns a quaternion with its components divided by the specified value.
static func / (lhs: Quaternion, rhs: Double) -> Quaternion {
.init(lhs.storage / rhs)
.init(storage: lhs.storage / rhs)
}

/// Divides the components of the vector by the specified value.
Expand All @@ -188,15 +191,16 @@ public extension Quaternion {
}
}

@available(*, deprecated)
extension Quaternion {
init(unchecked x: Double, _ y: Double, _ z: Double, _ w: Double) {
self.init(simd_quatd(vector: simd_double4(x, y, z, w)))
self.init(storage: simd_quatd(vector: simd_double4(x, y, z, w)))
assert(isNormalized || lengthSquared == 0)
}

init(unchecked axis: Vector, angle: Angle) {
assert(axis.isNormalized)
self.init(simd_quatd(
self.init(storage: simd_quatd(
angle: -angle.radians,
axis: .init(axis.x, axis.y, axis.z)
))
Expand All @@ -212,6 +216,7 @@ extension Quaternion {
///
/// In addition to being more compact than a 3x3 rotation matrix, quaternions also avoid a
/// problem known as gymbal lock.
@available(*, deprecated, message: "Use Rotation instead")
public struct Quaternion: Hashable, Sendable {
/// The quaternion component values.
public var x, y, z, w: Double
Expand All @@ -226,6 +231,7 @@ public struct Quaternion: Hashable, Sendable {
}
}

@available(*, deprecated)
public extension Quaternion {
/// The axis of rotation.
var axis: Vector {
Expand Down Expand Up @@ -354,6 +360,7 @@ public extension Quaternion {
}
}

@available(*, deprecated)
extension Quaternion {
init(unchecked x: Double, _ y: Double, _ z: Double, _ w: Double) {
self.x = x
Expand All @@ -373,6 +380,7 @@ extension Quaternion {

#endif

@available(*, deprecated)
extension Quaternion: Codable {
private enum CodingKeys: CodingKey {
case x, y, z, w
Expand Down Expand Up @@ -409,6 +417,7 @@ extension Quaternion: Codable {
}
}

@available(*, deprecated)
public extension Quaternion {
/// The zero quaternion.
static let zero = Quaternion(unchecked: 0, 0, 0, 0)
Expand Down Expand Up @@ -503,6 +512,7 @@ public extension Quaternion {
}
}

@available(*, deprecated)
extension Quaternion: UnkeyedCodable {
func encode(to container: inout UnkeyedEncodingContainer) throws {
try container.encode(x)
Expand All @@ -520,6 +530,7 @@ extension Quaternion: UnkeyedCodable {
}
}

@available(*, deprecated)
extension Quaternion {
/// Approximate equality
func isEqual(to other: Quaternion, withPrecision p: Double = epsilon) -> Bool {
Expand Down
Loading

0 comments on commit 1004551

Please sign in to comment.