precision highp float;

float PI = 3.14159265358979323846;

// Per-instance attribute - grid coordinates for each arrow
attribute vec2 instanceGrid;

uniform sampler2D u_velocity;
uniform vec2 u_grid_size;
uniform float u_spacing;
uniform float u_arrow_scale;
uniform float u_scale_multiplier;

varying vec2 v_uv;
varying float v_velocity_magnitude;

void main() {
    // Calculate UV coordinates for velocity texture sampling
    // Normalize grid position to 0-1 range
    v_uv = instanceGrid / u_grid_size;

    // Sample velocity from texture
    vec2 velocity = texture2D(u_velocity, v_uv).rg;
    
    // Flip Y to match Three.js coordinate system
    velocity.y = -velocity.y;

    // Calculate rotation angle from velocity vector
    float angle = atan(velocity.y, velocity.x);
    angle -= PI / 2.;

    // Calculate scale based on velocity magnitude
    v_velocity_magnitude = length(velocity);
    float scale = u_arrow_scale + (v_velocity_magnitude / 50000.) * u_scale_multiplier;

    // Create 2D rotation matrix
    mat2 rotation = mat2(
        cos(angle), -sin(angle),
        sin(angle), cos(angle)
    );

    // Apply rotation and scale to arrow vertices
    vec2 rotatedPos = rotation * position.xy * scale;

    // Calculate world position from grid coordinates
    // Center the grid around origin
    vec2 worldPos = (instanceGrid * u_spacing) - (u_grid_size * u_spacing * 0.5);
    worldPos += rotatedPos;

    // Transform to clip space
    vec4 mvPosition = modelViewMatrix * vec4(worldPos, 0.0, 1.0);
    gl_Position = projectionMatrix * mvPosition;
}
