#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

struct Globals
{
    float4x4 uMVP;
    packed_float3 uChunkOrigin;
    float uDayLight;
    float uAmbient;
    float uAlphaCutoff;
    char _m5_pad[8];
    packed_float3 uFogColor;
    float uFogStart;
    float uFogEnd;
    int uDynLightCount;
    float4 uDynLightPosRadius0;
    float4 uDynLightPosRadius1;
    float4 uDynLightPosRadius2;
    float4 uDynLightPosRadius3;
    float4 uDynLightColor0;
    float4 uDynLightColor1;
    float4 uDynLightColor2;
    float4 uDynLightColor3;
    int uFogMode;
    float uFogDensity;
    float uFogHeightFalloff;
    float uTime;
    float uWaveAmp;
    char _m22_pad[12];
    packed_float3 uCamPos;
    float uTrip;
    float uTripTime;
};

struct main0_out
{
    float2 vUV [[user(locn0)]];
    float vLayer [[user(locn1)]];
    float vShade [[user(locn2)]];
    float vDist [[user(locn3)]];
    float3 vWorld [[user(locn4)]];
    float vLiquid [[user(locn5)]];
    float4 gl_Position [[position]];
};

struct main0_in
{
    uint2 aPacked [[attribute(0)]];
};

vertex main0_out main0(main0_in in [[stage_in]], constant Globals& _173 [[buffer(0)]])
{
    main0_out out = {};
    uint px = in.aPacked.x & 1023u;
    uint pz = (in.aPacked.x >> 10u) & 1023u;
    uint py = ((in.aPacked.x >> 20u) & 4095u) | ((in.aPacked.y & 3u) << 12u);
    float3 aPos = float3(float(px), float(py), float(pz)) / float3(32.0);
    uint layer = (in.aPacked.y >> 2u) & 1023u;
    float shade = float((in.aPacked.y >> 12u) & 63u) / 63.0;
    float skyLight = float((in.aPacked.y >> 18u) & 15u) / 15.0;
    float blockLight = float((in.aPacked.y >> 22u) & 15u) / 15.0;
    uint axis = (in.aPacked.y >> 26u) & 3u;
    bool explicitUV = ((in.aPacked.y >> 28u) & 1u) != 0u;
    bool liquid = ((in.aPacked.y >> 31u) & 1u) != 0u;
    out.vLiquid = float(liquid);
    if (explicitUV)
    {
        out.vUV = float2(float((in.aPacked.y >> 29u) & 1u), float((in.aPacked.y >> 30u) & 1u));
    }
    else
    {
        if (axis == 0u)
        {
            out.vUV = float2(aPos.z, -aPos.y);
        }
        else
        {
            if (axis == 1u)
            {
                out.vUV = float2(aPos.x, -aPos.z);
            }
            else
            {
                out.vUV = float2(aPos.x, -aPos.y);
            }
        }
    }
    out.vLayer = float(layer);
    float sky = skyLight * _173.uDayLight;
    float light = fast::max(sky, blockLight);
    float bright = mix(_173.uAmbient, 1.0, light);
    out.vShade = shade * bright;
    float3 world = aPos + float3(_173.uChunkOrigin);
    out.vWorld = world;
    float3 posW = world;
    if (_173.uTrip > 0.001000000047497451305389404296875)
    {
        float3 center = floor(world) + float3(0.5);
        float3 local = world - center;
        float beat = sin(dot(center, float3(0.310000002384185791015625, 0.4699999988079071044921875, 0.23000000417232513427734375)) + (_173.uTripTime * 2.2000000476837158203125));
        float stretch = 1.0 + ((beat * 0.36000001430511474609375) * _173.uTrip);
        float squash = rsqrt(fast::max(stretch, 0.3499999940395355224609375));
        posW = center + (local * float3(squash, stretch, squash));
        posW.x += ((sin((center.y * 0.550000011920928955078125) + (_173.uTripTime * 1.2999999523162841796875)) * 0.100000001490116119384765625) * _173.uTrip);
        posW.z += ((cos((center.x * 0.430000007152557373046875) - (_173.uTripTime * 1.10000002384185791015625)) * 0.100000001490116119384765625) * _173.uTrip);
    }
    if (liquid)
    {
        posW.y += (((sin((world.x * 0.89999997615814208984375) + (_173.uTime * 1.7000000476837158203125)) + cos((world.z * 1.10000002384185791015625) + (_173.uTime * 1.2999999523162841796875))) * 0.04500000178813934326171875) * _173.uWaveAmp);
    }
    float4 clip = _173.uMVP * float4(posW, 1.0);
    out.vDist = length(world - float3(_173.uCamPos));
    out.gl_Position = clip;
    out.gl_Position.z = (out.gl_Position.z + out.gl_Position.w) * 0.5;
    return out;
}

