| //===----------------------------------------------------------*- 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 |
| import SIMDOperators |
| @_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 |