#if defined NORMAL_MAPS
mat3 computeTBNMatrix(mat4 gbufferModelViewInverse, mat3 NormalMatrix, vec4 at_tangent, vec3 Normal)
{

    mat3 tbnMatrix;
    tbnMatrix[0] = mat3(gbufferModelViewInverse) * normalize(NormalMatrix * at_tangent.xyz);
    tbnMatrix[2] = mat3(gbufferModelViewInverse) * (normalize(NormalMatrix * Normal));
    tbnMatrix[1] = cross(tbnMatrix[0], tbnMatrix[2]) * (at_tangent.w < 0.0 ? -1.0 : 1.0);

    return tbnMatrix;
}
#endif

#ifdef LEAVES

vec3 wavingLeaves(vec3 viewPos)
{
    const float k_pi2wtMultiplier = 0.37699111843;
    float pi2wt = k_pi2wtMultiplier * frameTimeCounter;
    float t = 24.0;

#ifndef TIMEFREEZE
    t = pi2wt;
#endif

    float sin_t = sin(t * 2.2);
    float adjustedSinT = sin_t * 3.0 - 2.0;
    float magnitude = sin(t * 2.2 + viewPos.x + viewPos.z) * 0.0001 * 2.0;
    float combinedXZ = (viewPos.x + viewPos.z) * 0.5;

    vec3 wind = vec3(sin(t * 2.2 + combinedXZ + adjustedSinT + viewPos.y) * magnitude);

    return wind;
}

bool isFlower(int entityType, bool midc1)
{
    return (entityType == 2001 && midc1) || (entityType == 2011 && midc1);
}

bool isLeaves(int entityType, bool mid2)
{
    return (entityType == 2003 && mid2) || (entityType == 2013 && mid2);
}

vec3 computeWaveOffset(vec3 position, vec3 cameraPosition, vec4 vertex, vec4 MultiTexCoord, mat4 gbufferModelView)
{
    vec3 offsetWorldPos = vertex.xyz + cameraPosition;
    vec3 waveOffset = wavingLeaves(offsetWorldPos) * MultiTexCoord.y;
    vec3 worldPos = offsetWorldPos + waveOffset - cameraPosition;
    return mat3(gbufferModelView) * worldPos + gbufferModelView[3].xyz;
}

float computeTranslucent(int entityType)
{
    float translucent = 0.0;
    switch (entityType)
    {
    case 2001:
    case 2002:
    case 2004:
    case 2011:
        translucent = 1.0;
        break;
    case 2003:
    case 2005:
    case 2013:
    case 10010:
        translucent = 0.5;
        break;
    }
    return translucent;
}
#endif
#ifdef PBR
vec3 computeShinyAndSmoothval(int entityType)
{
    
    float smoothval = 0.0;
    float shiny = 0.0;

    switch (entityType)
    {
    case 9:
        smoothval = 0.9;
        shiny = 0.901961;
        break;
    case 10:
        smoothval = 0.9;
        shiny = 0.905882;
        break;
    case 11:
        smoothval = 0.9;
        shiny = 0.917647;
        break;
    case 12:
        smoothval = 0.7;
        shiny = 0.5;
        break;
    default:
        break;
    }

    return vec3(smoothval, shiny, 0.0); // The third component is a placeholder if needed
}
#endif