//===----------------------------------------------------------*- swift -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2017 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // simd module overlays for Swift //===----------------------------------------------------------------------===// import Swift import Darwin @_exported import simd %for scalar in ['Float','Double']: % quat = 'simd_quat' + ('f' if scalar == 'Float' else 'd') % vec3 = str.lower(scalar) + '3' % vec4 = str.lower(scalar) + '4' % mat3 = 'simd_' + str.lower(scalar) + '3x3' % mat4 = 'simd_' + str.lower(scalar) + '4x4' extension ${quat} { /// Construct a quaternion from components. /// /// - Parameters: /// - ix: The x-component of the imaginary (vector) part. /// - iy: The y-component of the imaginary (vector) part. /// - iz: The z-component of the imaginary (vector) part. /// - r: The real (scalar) part. @_transparent public init(ix: ${scalar}, iy: ${scalar}, iz: ${scalar}, r: ${scalar}) { self.init(vector: ${vec4}(ix, iy, iz, r)) } /// Construct a quaternion from real and imaginary parts. @_transparent public init(real: ${scalar}, imag: ${vec3}) { self.init(vector: simd_make_${vec4}(imag, real)) } /// A quaternion whose action is a rotation by `angle` radians about `axis`. /// /// - Parameters: /// - angle: The angle to rotate by measured in radians. /// - axis: The axis to rotate around. @_transparent public init(angle: ${scalar}, axis: ${vec3}) { self = simd_quaternion(angle, axis) } /// A quaternion whose action rotates the vector `from` onto the vector `to`. @_transparent public init(from: ${vec3}, to: ${vec3}) { self = simd_quaternion(from, to) } /// Construct a quaternion from `rotationMatrix`. @_transparent public init(_ rotationMatrix: ${mat3}) { self = simd_quaternion(rotationMatrix) } /// Construct a quaternion from `rotationMatrix`. @_transparent public init(_ rotationMatrix: ${mat4}) { self = simd_quaternion(rotationMatrix) } /// The real (scalar) part of `self`. public var real: ${scalar} { @_transparent get { return vector.w } @_transparent set { vector.w = newValue } } /// The imaginary (vector) part of `self`. public var imag: ${vec3} { @_transparent get { return simd_make_${vec3}(vector) } @_transparent set { vector = simd_make_${vec4}(newValue, vector.w) } } /// The angle (in radians) by which `self`'s action rotates. @_transparent public var angle: ${scalar} { return simd_angle(self) } /// The normalized axis about which `self`'s action rotates. @_transparent public var axis: ${vec3} { return simd_axis(self) } /// The conjugate of `self`. @_transparent public var conjugate: ${quat} { return simd_conjugate(self) } /// The inverse of `self`. @_transparent public var inverse: ${quat} { return simd_inverse(self) } /// The unit quaternion obtained by normalizing `self`. @_transparent public var normalized: ${quat} { return simd_normalize(self) } /// The length of the quaternion interpreted as a 4d vector. @_transparent public var length: ${scalar} { return simd_length(self) } /// Applies the rotation represented by a unit quaternion to the vector and /// returns the result. @_transparent public func act(_ vector: ${vec3}) -> ${vec3} { return simd_act(self, vector) } } extension ${mat3} { /// Construct a 3x3 matrix from `quaternion`. public init(_ quaternion: ${quat}) { self = simd_matrix3x3(quaternion) } } extension ${mat4} { /// Construct a 4x4 matrix from `quaternion`. public init(_ quaternion: ${quat}) { self = simd_matrix4x4(quaternion) } } extension ${quat} : CustomDebugStringConvertible { public var debugDescription: String { return "${quat}(real: \(real), imag: \(imag))" } } extension ${quat} : Equatable { @_transparent public static func ==(lhs: ${quat}, rhs: ${quat}) -> Bool { return lhs.vector == rhs.vector } } extension ${quat} { /// The sum of `lhs` and `rhs`. @_transparent public static func +(lhs: ${quat}, rhs: ${quat}) -> ${quat} { return simd_add(lhs, rhs) } /// Add `rhs` to `lhs`. @_transparent public static func +=(lhs: inout ${quat}, rhs: ${quat}) { lhs = lhs + rhs } /// The difference of `lhs` and `rhs`. @_transparent public static func -(lhs: ${quat}, rhs: ${quat}) -> ${quat} { return simd_sub(lhs, rhs) } /// Subtract `rhs` from `lhs`. @_transparent public static func -=(lhs: inout ${quat}, rhs: ${quat}) { lhs = lhs - rhs } /// The negation of `rhs`. @_transparent public static prefix func -(rhs: ${quat}) -> ${quat} { return simd_sub(${quat}(), rhs) } /// The product of `lhs` and `rhs`. @_transparent public static func *(lhs: ${quat}, rhs: ${quat}) -> ${quat} { return simd_mul(lhs, rhs) } /// The product of `lhs` and `rhs`. @_transparent public static func *(lhs: ${scalar}, rhs: ${quat}) -> ${quat} { return simd_mul(lhs, rhs) } /// The product of `lhs` and `rhs`. @_transparent public static func *(lhs: ${quat}, rhs: ${scalar}) -> ${quat} { return simd_mul(lhs, rhs) } /// Multiply `lhs` by `rhs`. @_transparent public static func *=(lhs: inout ${quat}, rhs: ${quat}) { lhs = lhs * rhs } /// Multiply `lhs` by `rhs`. @_transparent public static func *=(lhs: inout ${quat}, rhs: ${scalar}) { lhs = lhs * rhs } /// The quotient of `lhs` and `rhs`. @_transparent public static func /(lhs: ${quat}, rhs: ${quat}) -> ${quat} { return simd_mul(lhs, rhs.inverse) } /// The quotient of `lhs` and `rhs`. @_transparent public static func /(lhs: ${quat}, rhs: ${scalar}) -> ${quat} { return ${quat}(vector: lhs.vector/rhs) } /// Divide `lhs` by `rhs`. @_transparent public static func /=(lhs: inout ${quat}, rhs: ${quat}) { lhs = lhs / rhs } /// Divide `lhs` by `rhs`. @_transparent public static func /=(lhs: inout ${quat}, rhs: ${scalar}) { lhs = lhs / rhs } } /// The dot product of the quaternions `p` and `q` interpreted as /// four-dimensional vectors. @_transparent public func dot(_ lhs: ${quat}, _ rhs: ${quat}) -> ${scalar} { return simd_dot(lhs, rhs) } /// Logarithm of the quaternion `q`. /// /// We can write a quaternion `q` in the form: `r(cos(t) + sin(t)v)` where /// `r` is the length of `q`, `t` is an angle, and `v` is a unit 3-vector. /// The logarithm of `q` is `log(r) + tv`, just like the logarithm of the /// complex number `r*(cos(t) + i sin(t))` is `log(r) + it`. public func log(_ q: ${quat}) -> ${quat} { return __tg_log(q) } /// Inverse function of `log`; the exponential map on quaternions. @_transparent public func exp(_ q: ${quat}) -> ${quat} { return __tg_exp(q) } %end # for scalar