#version 430 core

uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform samplerBuffer weights; // bone bias, bone index

// 

// max 64 skinning matrices
uniform mat4 boneMatrix[64];

layout (location = 0) in vec3 POSITION;
layout (location = 1) in vec3 NORMAL;
layout (location = 3) in vec4 TANGENT;
layout (location = 4) in vec2 TEXCOORD;
layout (location = 5) in vec2 BONE_INDEX;

out vec3 normal;
out vec4 tangent;
out vec2 uv;

void main()
{
	ivec2 weightIndexing = ivec2(BONE_INDEX);
	vec4 pos = vec4(0.0);
	vec3 norm = vec3(0.0);
	vec3 tang = vec3(0.0);

	for (int i=weightIndexing.x; i < weightIndexing.y; i++)
	{
		vec4 biasAndIndex = texelFetch(weights, i);
		int index = int(biasAndIndex.y);

		pos  += (boneMatrix[ index ] * vec4(POSITION, 1.0)) * biasAndIndex.x;
		norm += (mat3(boneMatrix[ index ]) * NORMAL) * biasAndIndex.x;
		tang += (mat3(boneMatrix[ index ]) * TANGENT.xyz) * biasAndIndex.x;
	}
	pos.w = 1.0;

	uv = TEXCOORD;
	normal = NormalMatrix * normalize(norm);
	tangent.xyz = NormalMatrix * normalize(tang);
	tangent.w = TANGENT.w;

	gl_Position = ModelViewProjectionMatrix * pos;
}
