
uniform vec2 taaOffset;
uniform float frameTimeCounter;
uniform int isEyeInWater;
uniform mat4 gbufferModelViewInverse;
uniform mat4 gbufferModelView;

#ifndef MC_GL_VENDOR_INTEL
	#define attribute in
#endif

attribute vec4 at_tangent;

out vec4 viewPos;
out vec4 tint;
out vec2 texcoord;
out vec2 lightmap;

flat out mat3 tbnMatrix;

#include "/Settings.glsl"



vec3 applyHandSway(vec3 localPos) {

#ifdef HAND_SWAY_ENABLED

    float speed = frameTimeCounter * HAND_SWAY_SPEED;


    float waterFactor = (isEyeInWater > 0) ? HAND_SWAY_UNDERWATER_MULT : 1.0;


    float swayX = sin(speed * 3.0) * HAND_SWAY_STRENGTH * waterFactor;


    float swayY = cos(speed * 4.0) * HAND_SWAY_STRENGTH * HAND_SWAY_VERTICAL_MULT * waterFactor;


    float swayZ = sin(speed * 1.7 + 0.5) * HAND_SWAY_STRENGTH * 0.3 * waterFactor;

    localPos.x += swayX;
    localPos.y += swayY;
    localPos.z += swayZ;

#endif // HAND_SWAY_ENABLED

    return localPos;
}

// ============================================================
// BOB HAND — вертикальное покачивание руки при ходьбе
// Создаёт ощущение что игрок реально идёт
// ============================================================

vec3 applyHandBob(vec3 localPos) {

#ifdef HAND_BOB_ENABLED

    float t = frameTimeCounter * HAND_BOB_SPEED;

    // Бобинг при ходьбе — симметричное движение
    float bobY = abs(sin(t * 2.0)) * HAND_BOB_STRENGTH;
    float bobX = sin(t) * HAND_BOB_STRENGTH * 0.5;

    localPos.x += bobX;
    localPos.y -= bobY;

#endif // HAND_BOB_ENABLED

    return localPos;
}

void main() {
    tint     = gl_Color;
    texcoord = gl_MultiTexCoord0.xy;
    lightmap = clamp(gl_MultiTexCoord1.xy * (1.0 / 240.0), 0.0, 1.0);

    tbnMatrix[2] = normalize(gl_NormalMatrix * gl_Normal);
#ifdef MC_NORMAL_MAP
    tbnMatrix[0] = normalize(gl_NormalMatrix * at_tangent.xyz);
    tbnMatrix[1] = cross(tbnMatrix[0], tbnMatrix[2]) * sign(at_tangent.w);
#endif

    // =========================================================
    // Переходим в world space для анимации, затем обратно
    // Это НАСТОЯЩИЙ способ — вершины двигаются в 3D пространстве
    // =========================================================

    // World-space позиция вершины
    vec4 worldPos = gbufferModelViewInverse * (gl_ModelViewMatrix * gl_Vertex);

    // Применяем HandSway и Bob в локальном пространстве
    worldPos.xyz = applyHandSway(worldPos.xyz);
    worldPos.xyz = applyHandBob(worldPos.xyz);

    // Обратно в view space
    vec4 animatedViewPos = gbufferModelView * worldPos;

    // Дополнительное смещение руки вперёд/вверх/вбок (как в BSL/Astralex)
    animatedViewPos.z -= HAND_OFFSET_FORWARD;
    animatedViewPos.y += HAND_OFFSET_UP;
    animatedViewPos.x += HAND_OFFSET_SIDE;

    viewPos    = animatedViewPos;
    gl_Position = gl_ProjectionMatrix * animatedViewPos;

#ifdef TAA_ENABLED
    gl_Position.xy += taaOffset * gl_Position.w;
#endif
}
