mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
...as detected by initializing an individual field without having initialized the whole object (via `self = value`). This only applies in pre-Swift-5 mode because the next commit will treat all cross-module struct initializers as delegating in Swift 5.
271 lines
7.0 KiB
Swift
271 lines
7.0 KiB
Swift
//===----------------------------------------------------------*- 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
|