Files
swift-mirror/stdlib/public/Darwin/simd/Quaternion.swift.gyb
Saleem Abdulrasool 41d9c2cc59 stdlib: restructure for OS family layout of SDK overlay
The SDK directory is now confusing as the Windows target also has a SDK
overlay.  In order to make this more uniform, move the SDK directory to
Darwin which covers the fact that this covers the XNU family of OSes.
The Windows directory contains the SDK overlay for the Windows target.
2018-12-06 11:32:05 -08:00

272 lines
7.1 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
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