uniform mat4 mvp_mat;
uniform mat3 norm_mat;
uniform mat4 bonemats[80];
attribute vec4 vcolor;
attribute vec4 vweights;
attribute vec4 vbones;
attribute vec4 vtangent;
attribute vec3 vnormal;
attribute vec2 texcoord;
attribute vec3 vposition;

varying vec3 position;
varying vec3 bitangent;
varying vec3 tangent;
varying vec3 normal;
varying vec2 st;
varying vec4 color;

vec3
qmult (vec4 q, vec3 v)
{
	float       qs = q.w;
	vec3        qv = q.xyz;
	vec3        t = cross (qv, v);
	return (qs * qs) * v + 2.0 * qs * t + dot (qv, v) * qv + cross (qv, t);
}

vec3
dqtrans (vec4 q0, vec4 qe)
{//2.0 * (q0.w * qe.xyz - qe.w * q0.xyz - cross (qe.xyz, q0.xyz));
	float       qs = q0.w, Ts = qe.w;
	vec3        qv = -q0.xyz, Tv = qe.xyz;

	return 2.0 * (Ts * qv + qs * Tv + cross (Tv, qv));
}

void
main (void)
{
	mat4        m;
	vec4        q0, qe;
	vec3        sh, sc, tr, v, n, t;

	m  = bonemats[int (vbones.x)] * vweights.x;
	m += bonemats[int (vbones.y)] * vweights.y;
	m += bonemats[int (vbones.z)] * vweights.z;
	m += bonemats[int (vbones.w)] * vweights.w;
#if 0
	q0 = m[0].yzwx; //swizzle for conversion betwen QF and GL
	qe = m[1].yzwx; //swizzle for conversion betwen QF and GL
	sh = m[2].xyz;
	sc = m[3].xyz;

	// extract translation from dual quaternion
	tr = dqtrans (q0, qe);
	// apply rotation and translation
	v = qmult (q0, vposition) + tr;
	// apply shear
	v.z += v.y * sh.z + v.x * sh.y;
	v.y += v.x * sh.x;
	// apply scale
	v *= sc;
	// rotate normal (won't bother with shear or scale: not super accurate,
	// but probably good enough)
	n = qmult (q0, vnormal);
	// rotate tangent (won't bother with shear or scale: not super accurate,
	// but probably good enough)
	t = qmult (q0, vtangent.xyz);
#else
	mat3 nm = mat3 (m[0].xyz, m[1].xyz, m[2].xyz);
	v = (m * vec4 (vposition, 1.0)).xyz;
	n = nm * vnormal;
	t = nm * vtangent.xyz;
#endif
	position = v;
	normal = norm_mat * n;
	tangent = norm_mat * t;
	bitangent = cross (normal, tangent) * vtangent.w;
	color = vcolor;
	st = texcoord;
	gl_Position = mvp_mat * vec4 (position, 1.0);
}
