| #pragma clang diagnostic ignored "-Wmissing-prototypes" |
| |
| #include <metal_stdlib> |
| #include <simd/simd.h> |
| |
| using namespace metal; |
| |
| struct UBO |
| { |
| float4x4 uMVP; |
| float3 rotDeg; |
| float3 rotRad; |
| int2 bits; |
| }; |
| |
| struct main0_out |
| { |
| float3 vNormal [[user(locn0)]]; |
| float3 vRotDeg [[user(locn1)]]; |
| float3 vRotRad [[user(locn2)]]; |
| int2 vLSB [[user(locn3)]]; |
| int2 vMSB [[user(locn4)]]; |
| float4 gl_Position [[position]]; |
| }; |
| |
| struct main0_in |
| { |
| float4 aVertex [[attribute(0)]]; |
| float3 aNormal [[attribute(1)]]; |
| }; |
| |
| // Implementation of the GLSL radians() function |
| template<typename T> |
| T radians(T d) |
| { |
| return d * T(0.01745329251); |
| } |
| |
| // Implementation of the GLSL degrees() function |
| template<typename T> |
| T degrees(T r) |
| { |
| return r * T(57.2957795131); |
| } |
| |
| // Implementation of the GLSL findLSB() function |
| template<typename T> |
| T findLSB(T x) |
| { |
| return select(ctz(x), T(-1), x == T(0)); |
| } |
| |
| // Implementation of the signed GLSL findMSB() function |
| template<typename T> |
| T findSMSB(T x) |
| { |
| T v = select(x, T(-1) - x, x < T(0)); |
| return select(clz(T(0)) - (clz(v) + T(1)), T(-1), v == T(0)); |
| } |
| |
| // Returns the determinant of a 2x2 matrix. |
| inline float spvDet2x2(float a1, float a2, float b1, float b2) |
| { |
| return a1 * b2 - b1 * a2; |
| } |
| |
| // Returns the determinant of a 3x3 matrix. |
| inline float spvDet3x3(float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3) |
| { |
| return a1 * spvDet2x2(b2, b3, c2, c3) - b1 * spvDet2x2(a2, a3, c2, c3) + c1 * spvDet2x2(a2, a3, b2, b3); |
| } |
| |
| // Returns the inverse of a matrix, by using the algorithm of calculating the classical |
| // adjoint and dividing by the determinant. The contents of the matrix are changed. |
| float4x4 spvInverse4x4(float4x4 m) |
| { |
| float4x4 adj; // The adjoint matrix (inverse after dividing by determinant) |
| |
| // Create the transpose of the cofactors, as the classical adjoint of the matrix. |
| adj[0][0] = spvDet3x3(m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], m[3][3]); |
| adj[0][1] = -spvDet3x3(m[0][1], m[0][2], m[0][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], m[3][3]); |
| adj[0][2] = spvDet3x3(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[3][1], m[3][2], m[3][3]); |
| adj[0][3] = -spvDet3x3(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3]); |
| |
| adj[1][0] = -spvDet3x3(m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], m[3][3]); |
| adj[1][1] = spvDet3x3(m[0][0], m[0][2], m[0][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], m[3][3]); |
| adj[1][2] = -spvDet3x3(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[3][0], m[3][2], m[3][3]); |
| adj[1][3] = spvDet3x3(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], m[2][3]); |
| |
| adj[2][0] = spvDet3x3(m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], m[3][3]); |
| adj[2][1] = -spvDet3x3(m[0][0], m[0][1], m[0][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], m[3][3]); |
| adj[2][2] = spvDet3x3(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[3][0], m[3][1], m[3][3]); |
| adj[2][3] = -spvDet3x3(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], m[2][3]); |
| |
| adj[3][0] = -spvDet3x3(m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], m[3][2]); |
| adj[3][1] = spvDet3x3(m[0][0], m[0][1], m[0][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], m[3][2]); |
| adj[3][2] = -spvDet3x3(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[3][0], m[3][1], m[3][2]); |
| adj[3][3] = spvDet3x3(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2]); |
| |
| // Calculate the determinant as a combination of the cofactors of the first row. |
| float det = (adj[0][0] * m[0][0]) + (adj[0][1] * m[1][0]) + (adj[0][2] * m[2][0]) + (adj[0][3] * m[3][0]); |
| |
| // Divide the classical adjoint matrix by the determinant. |
| // If determinant is zero, matrix is not invertable, so leave it unchanged. |
| return (det != 0.0f) ? (adj * (1.0f / det)) : m; |
| } |
| |
| vertex main0_out main0(main0_in in [[stage_in]], constant UBO& _18 [[buffer(0)]]) |
| { |
| main0_out out = {}; |
| out.gl_Position = spvInverse4x4(_18.uMVP) * in.aVertex; |
| out.vNormal = in.aNormal; |
| out.vRotDeg = degrees(_18.rotRad); |
| out.vRotRad = radians(_18.rotDeg); |
| out.vLSB = findLSB(_18.bits); |
| out.vMSB = findSMSB(_18.bits); |
| return out; |
| } |
| |