2017-05-19 22:14:08 +00:00
|
|
|
#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
|
|
|
|
{
|
2017-06-21 07:39:08 +00:00
|
|
|
float3 vNormal [[user(locn0)]];
|
2017-06-30 23:10:46 +00:00
|
|
|
float3 vRotDeg [[user(locn1)]];
|
|
|
|
float3 vRotRad [[user(locn2)]];
|
2017-06-21 07:39:08 +00:00
|
|
|
int2 vLSB [[user(locn3)]];
|
2017-06-30 23:10:46 +00:00
|
|
|
int2 vMSB [[user(locn4)]];
|
2017-05-19 22:14:08 +00:00
|
|
|
float4 gl_Position [[position]];
|
|
|
|
};
|
|
|
|
|
2018-06-12 15:41:35 +00:00
|
|
|
struct main0_in
|
|
|
|
{
|
|
|
|
float4 aVertex [[attribute(0)]];
|
|
|
|
float3 aNormal [[attribute(1)]];
|
|
|
|
};
|
|
|
|
|
2017-05-19 22:14:08 +00:00
|
|
|
// Implementation of the GLSL radians() function
|
|
|
|
template<typename T>
|
2019-09-23 22:05:04 +00:00
|
|
|
inline T radians(T d)
|
2017-05-19 22:14:08 +00:00
|
|
|
{
|
2018-03-07 09:24:21 +00:00
|
|
|
return d * T(0.01745329251);
|
2017-05-19 22:14:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Implementation of the GLSL degrees() function
|
|
|
|
template<typename T>
|
2019-09-23 22:05:04 +00:00
|
|
|
inline T degrees(T r)
|
2017-05-19 22:14:08 +00:00
|
|
|
{
|
2018-03-07 09:24:21 +00:00
|
|
|
return r * T(57.2957795131);
|
2017-05-19 22:14:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Implementation of the GLSL findLSB() function
|
|
|
|
template<typename T>
|
2019-09-23 22:05:04 +00:00
|
|
|
inline T spvFindLSB(T x)
|
2017-05-19 22:14:08 +00:00
|
|
|
{
|
2017-11-06 02:34:42 +00:00
|
|
|
return select(ctz(x), T(-1), x == T(0));
|
2017-05-19 22:14:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Implementation of the signed GLSL findMSB() function
|
|
|
|
template<typename T>
|
2019-09-23 22:05:04 +00:00
|
|
|
inline T spvFindSMSB(T x)
|
2017-05-19 22:14:08 +00:00
|
|
|
{
|
2017-11-06 02:34:42 +00:00
|
|
|
T v = select(x, T(-1) - x, x < T(0));
|
|
|
|
return select(clz(T(0)) - (clz(v) + T(1)), T(-1), v == T(0));
|
2017-05-19 22:14:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Returns the determinant of a 2x2 matrix.
|
2019-08-14 15:09:39 +00:00
|
|
|
static inline __attribute__((always_inline))
|
|
|
|
float spvDet2x2(float a1, float a2, float b1, float b2)
|
2017-05-19 22:14:08 +00:00
|
|
|
{
|
|
|
|
return a1 * b2 - b1 * a2;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns the determinant of a 3x3 matrix.
|
2019-08-14 15:09:39 +00:00
|
|
|
static inline __attribute__((always_inline))
|
|
|
|
float spvDet3x3(float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3)
|
2017-05-19 22:14:08 +00:00
|
|
|
{
|
|
|
|
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.
|
2019-08-14 15:09:39 +00:00
|
|
|
static inline __attribute__((always_inline))
|
|
|
|
float4x4 spvInverse4x4(float4x4 m)
|
2017-05-19 22:14:08 +00:00
|
|
|
{
|
|
|
|
float4x4 adj; // The adjoint matrix (inverse after dividing by determinant)
|
2018-02-23 15:48:16 +00:00
|
|
|
|
2017-05-19 22:14:08 +00:00
|
|
|
// 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]);
|
2018-02-23 15:48:16 +00:00
|
|
|
|
2017-05-19 22:14:08 +00:00
|
|
|
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]);
|
2018-02-23 15:48:16 +00:00
|
|
|
|
2017-05-19 22:14:08 +00:00
|
|
|
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]);
|
2018-02-23 15:48:16 +00:00
|
|
|
|
2017-05-19 22:14:08 +00:00
|
|
|
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]);
|
2018-02-23 15:48:16 +00:00
|
|
|
|
2017-05-19 22:14:08 +00:00
|
|
|
// 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]);
|
2018-02-23 15:48:16 +00:00
|
|
|
|
2017-05-19 22:14:08 +00:00
|
|
|
// 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);
|
2019-07-12 08:57:56 +00:00
|
|
|
out.vLSB = spvFindLSB(_18.bits);
|
|
|
|
out.vMSB = spvFindSMSB(_18.bits);
|
2017-05-19 22:14:08 +00:00
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|