AR 开发中那些好用的 simd 函数

1,763 阅读3分钟

类型与名称

OC

oc 中的 simd 向量类型疑似是直接借用了 c++ 中的 vector 类型,所以有了很多别名:

typedef __attribute__((__ext_vector_type__(2))) char simd_char2;

typedef ::simd_char2 char2;

typedef simd_char2 vector_char2;

矩阵也是有了很多别名:

typedef struct { simd_float2 columns[2]; } simd_float2x2;
typedef simd_float2x2 matrix_float2x2;
struct float2x2 : ::simd_float2x2;

Swift

Swift 中则是依靠 Math 框架下的 Vector 类型(如 SIMD3)

// 向量
public struct SIMD2<Scalar> : SIMD where Scalar : SIMDScalar
public typealias simd_char2 = SIMD2<Int8>
// 矩阵
public struct simd_float2x2
public typealias float2x2 = simd_float2x2
public typealias matrix_float2x2 = simd_float2x2

由于别名很多,也导致构建函数名有很多,同时也导致很多其他函数名有很多。

这里不做过多列举,只是说明一下,以免产生误会。一般在使用中,个人推荐优先使用 simd 开头的类型和函数。

常用方法

四元数构建方法

为什么要单独说四元数的构建?因为向量类型初始化太简单了,也只能从几个数来初始化;而矩阵类型的初始化方法往往又太难用了,很少有用 16 个数来初始化 4x4 矩阵的,一般处理旋转需要借助四元数。

    ///   从四元数分量构建,r 是实数部分
    public init(ix: Float, iy: Float, iz: Float, r: Float)

    /// 从虚部和实部构建
    public init(real: Float, imag: SIMD3<Float>)

    ///   轴角方式构建,angle 是弧度
    public init(angle: Float, axis: SIMD3<Float>)

    /// 两个向量构建, 从`from`转到 `to`.
    public init(from: SIMD3<Float>, to: SIMD3<Float>)

    /// 从 3x3 矩阵构建
    public init(_ rotationMatrix: simd_float3x3)

    /// 从 4x4 矩阵构建
    public init(_ rotationMatrix: simd_float4x4)

向量常用函数

// 向量规范化
public func simd_normalize(_ __x: simd_float2) -> simd_float2
// 点乘
public func simd_dot(_ __x: simd_float2, _ __y: simd_float2) -> Float
// 叉乘
public func simd_cross(_ __x: simd_float2, _ __y: simd_float2) -> simd_float3

// 向量长度
public func simd_length(_ __x: simd_float2) -> Float
// 向量长度平方
public func simd_length_squared(_ __x: simd_float2) -> Float
// 计算两个点的距离
public func simd_distance(_ __x: simd_float2, _ __y: simd_float2) -> Float
// 计算两个点的距离平方
public func simd_distance_squared(_ __x: simd_float2, _ __y: simd_float2) -> Float

矩阵常用函数

// 矩阵缩放
public func matrix_scale(_ __a: Float, _ __x: simd_float2x2) -> simd_float2x2

// 矩阵与实数乘法(全部缩放)
public func simd_mul(_ __a: Float, _ __x: simd_float2x2) -> simd_float2x2

// 矩阵与向量乘法
public func simd_mul(_ __x: simd_float2x2, _ __y: simd_float2) -> simd_float2
public func matrix_multiply(_ __x: simd_float2x2, _ __y: simd_float2) -> simd_float2

// 矩阵与矩阵乘法
public func simd_mul(_ __x: simd_float2x2, _ __y: simd_float2x2) -> simd_float2x2
public func matrix_multiply(_ __x: simd_float2x2, _ __y: simd_float2x2) -> simd_float2x2


// 两个矩阵线性插值
public func simd_linear_combination(_ __a: Float, _ __x: simd_float2x2, _ __b: Float, _ __y: simd_float2x2) -> simd_float2x2

// 矩阵相加
public func simd_add(_ __x: simd_float2x2, _ __y: simd_float2x2) -> simd_float2x2

// 矩阵相减
public func simd_sub(_ __x: simd_float2x2, _ __y: simd_float2x2) -> simd_float2x2

// 矩阵转置
public func simd_transpose(_ __x: simd_float2x2) -> simd_float2x2

// 矩阵的逆
public func simd_inverse(_ __x: simd_float2x2) -> simd_float2x2

// 矩阵相等
public func simd_equal(_ __x: simd_float2x2, _ __y: simd_float2x2) -> simd_bool
// 矩阵各元素几乎相等,tol 为允许的误差
public func simd_almost_equal_elements(_ __x: simd_float2x2, _ __y: simd_float2x2, _ __tol: Float) -> simd_bool
public func simd_almost_equal_elements_relative(_ __x: simd_float2x2, _ __y: simd_float2x2, _ __tol: Float) -> simd_bool

四元数常用函数

// 四元数加法
public func simd_add(_ p: simd_quatf, _ q: simd_quatf) -> simd_quatf

// 四元减法
public func simd_sub(_ p: simd_quatf, _ q: simd_quatf) -> simd_quatf

// 四元数与四元数乘法(叉乘)
public func simd_mul(_ p: simd_quatf, _ q: simd_quatf) -> simd_quatf

// 四元数与实数乘法(缩放)
public func simd_mul(_ q: simd_quatf, _ a: Float) -> simd_quatf
public func simd_mul(_ a: Float, _ q: simd_quatf) -> simd_quatf

// 四元数共轭(就是让四元数的向量部分取负,四元数和它的共轭代表相反的角位移,因为相当于旋转轴反向,即向相反方向旋转)
public func simd_conjugate(_ q: simd_quatf) -> simd_quatf

// 四元数的逆(四元数的逆定义为四元数的共轭除以它的模)一般使用单位四元数,此时它的逆和共轭其实是相等的。
public func simd_inverse(_ q: simd_quatf) -> simd_quatf

// 相反数
public func simd_negate(_ q: simd_quatf) -> simd_quatf

// 四元数点乘(点乘结果是标量,两个单位四元数点乘的结果区间为[-1,1]。点乘结果的绝对值越大,相乘的两个四元数代表的角位移越相似。)
public func simd_dot(_ p: simd_quatf, _ q: simd_quatf) -> Float

// 四元数长度
public func simd_length(_ q: simd_quatf) -> Float

// 四元数规范化
public func simd_normalize(_ q: simd_quatf) -> simd_quatf

// 四元数线性插值
public func simd_slerp(_ q0: simd_quatf, _ q1: simd_quatf, _ t: Float) -> simd_quatf
public func simd_slerp_longest(_ q0: simd_quatf, _ q1: simd_quatf, _ t: Float) -> simd_quatf

// 四元数球形立方插值
public func simd_spline(_ q0: simd_quatf, _ q1: simd_quatf, _ q2: simd_quatf, _ q3: simd_quatf, _ t: Float) -> simd_quatf
// 四元数球形立方贝赛尔插值
public func simd_bezier(_ q0: simd_quatf, _ q1: simd_quatf, _ q2: simd_quatf, _ q3: simd_quatf, _ t: Float) -> simd_quatf