/*! @header * @copyright 2015-2016 Apple, Inc. All rights reserved. * @unsorted */ #ifndef SIMD_TYPES #define SIMD_TYPES #include #if SIMD_COMPILER_HAS_REQUIRED_FEATURES /*! @group Matrices * @discussion * This header defines nine matrix types for each of float and double, which * are intended for use together with the vector types defined in * . * * For compatibility with common graphics libraries, these matrices are stored * in column-major order, and implemented as arrays of column vectors. * Column-major storage order may seem a little strange if you aren't used to * it, but for most usage the memory layout of the matrices shouldn't matter * at all; instead you should think of matrices as abstract mathematical * objects that you use to perform arithmetic without worrying about the * details of the underlying representation. * * WARNING: vectors of length three are internally represented as length four * vectors with one element of padding (for alignment purposes). This means * that when a floatNx3 or doubleNx3 is viewed as a vector, it appears to * have 4*N elements instead of the expected 3*N (with one padding element * at the end of each column). The matrix elements are laid out in memory * as follows: * * { 0, 1, 2, x, 3, 4, 5, x, ... } * * (where the scalar indices used above indicate the conceptual column- * major storage order). If you aren't monkeying around with the internal * storage details of matrices, you don't need to worry about this at all. * Consider this yet another good reason to avoid doing so. */ /*! @abstract A matrix with 2 rows and 2 columns. */ typedef struct { simd_half2 columns[2]; } simd_half2x2; /*! @abstract A matrix with 2 rows and 3 columns. */ typedef struct { simd_half2 columns[3]; } simd_half3x2; /*! @abstract A matrix with 2 rows and 4 columns. */ typedef struct { simd_half2 columns[4]; } simd_half4x2; /*! @abstract A matrix with 3 rows and 2 columns. */ typedef struct { simd_half3 columns[2]; } simd_half2x3; /*! @abstract A matrix with 3 rows and 3 columns. */ typedef struct { simd_half3 columns[3]; } simd_half3x3; /*! @abstract A matrix with 3 rows and 4 columns. */ typedef struct { simd_half3 columns[4]; } simd_half4x3; /*! @abstract A matrix with 4 rows and 2 columns. */ typedef struct { simd_half4 columns[2]; } simd_half2x4; /*! @abstract A matrix with 4 rows and 3 columns. */ typedef struct { simd_half4 columns[3]; } simd_half3x4; /*! @abstract A matrix with 4 rows and 4 columns. */ typedef struct { simd_half4 columns[4]; } simd_half4x4; /*! @abstract A matrix with 2 rows and 2 columns. */ typedef struct { simd_float2 columns[2]; } simd_float2x2; /*! @abstract A matrix with 2 rows and 3 columns. */ typedef struct { simd_float2 columns[3]; } simd_float3x2; /*! @abstract A matrix with 2 rows and 4 columns. */ typedef struct { simd_float2 columns[4]; } simd_float4x2; /*! @abstract A matrix with 3 rows and 2 columns. */ typedef struct { simd_float3 columns[2]; } simd_float2x3; /*! @abstract A matrix with 3 rows and 3 columns. */ typedef struct { simd_float3 columns[3]; } simd_float3x3; /*! @abstract A matrix with 3 rows and 4 columns. */ typedef struct { simd_float3 columns[4]; } simd_float4x3; /*! @abstract A matrix with 4 rows and 2 columns. */ typedef struct { simd_float4 columns[2]; } simd_float2x4; /*! @abstract A matrix with 4 rows and 3 columns. */ typedef struct { simd_float4 columns[3]; } simd_float3x4; /*! @abstract A matrix with 4 rows and 4 columns. */ typedef struct { simd_float4 columns[4]; } simd_float4x4; /*! @abstract A matrix with 2 rows and 2 columns. */ typedef struct { simd_double2 columns[2]; } simd_double2x2; /*! @abstract A matrix with 2 rows and 3 columns. */ typedef struct { simd_double2 columns[3]; } simd_double3x2; /*! @abstract A matrix with 2 rows and 4 columns. */ typedef struct { simd_double2 columns[4]; } simd_double4x2; /*! @abstract A matrix with 3 rows and 2 columns. */ typedef struct { simd_double3 columns[2]; } simd_double2x3; /*! @abstract A matrix with 3 rows and 3 columns. */ typedef struct { simd_double3 columns[3]; } simd_double3x3; /*! @abstract A matrix with 3 rows and 4 columns. */ typedef struct { simd_double3 columns[4]; } simd_double4x3; /*! @abstract A matrix with 4 rows and 2 columns. */ typedef struct { simd_double4 columns[2]; } simd_double2x4; /*! @abstract A matrix with 4 rows and 3 columns. */ typedef struct { simd_double4 columns[3]; } simd_double3x4; /*! @abstract A matrix with 4 rows and 4 columns. */ typedef struct { simd_double4 columns[4]; } simd_double4x4; /*! @group Quaternions * @discussion Unlike vectors, quaternions are not raw clang extended-vector * types, because if they were you'd be able to intermix them with vectors * in arithmetic operations freely, but the arithmetic would not do what you * want it to do (it would simply perform the arithmetic operation * componentwise on the quaternion and vector). * * Quaternions aren't unions in C/Obj-C, because then the C++ types couldn't * inherit from the C types, which would make intermixing rather painful (you * can't inherit from a union). This means that we can't provide nice member * access like .real and .imag; you need to use functions to access the pieces * of a quaternion instead. * * This also means that you need to use functions instead of operators to do * arithmetic with quaternions in C and Obj-C. In C++, we are able to provide * operator overloads for arithmetic. * * Internally, a quaternion is represented as a vector of four elements. The * first three elements are the "imaginary" (or "vector") part of the * quaternion, and the last element is the "real" (or "scalar") part. As with * everything simd, you will generally get better performance if you avoid * using the internal storage details of the type, and instead treat these * quaternions as abstract mathematical objects once they are created. * * While the C types are defined here, the operations on quaternions and the * C++ quaternion types are defined in */ /*! @abstract A half-precision quaternion. */ typedef struct { simd_half4 vector; } simd_quath; /*! @abstract A single-precision quaternion. */ typedef struct { simd_float4 vector; } simd_quatf; /*! @abstract A double-precision quaternion. */ typedef struct { simd_double4 vector; } simd_quatd; #endif /* SIMD_COMPILER_HAS_REQUIRED_FEATURES */ #endif /* SIMD_TYPES */