1#version 120
2
3mat2x4 blendTwoWeightsAntipod(vec4 blendWgt, vec4 blendIdx, vec4 dualQuaternions[48]);
4vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ);
5vec3 calculateBlendNormal(vec3 normal, mat2x4 blendDQ);
6
7mat3 adjointTransposeMatrix(mat3 M)
8{
9	mat3 atM;
10	atM[0][0] = M[2][2] * M[1][1] - M[2][1] * M[1][2];
11	atM[1][0] = M[2][1] * M[0][2] - M[0][1] * M[2][2];
12	atM[2][0] = M[0][1] * M[1][2] - M[0][2] * M[1][1];
13
14	atM[0][1] = M[2][0] * M[1][2] - M[2][2] * M[1][0];
15	atM[1][1] = M[2][2] * M[0][0] - M[2][0] * M[0][2];
16	atM[2][1] = M[0][2] * M[1][0] - M[0][0] * M[1][2];
17
18	atM[0][2] = M[2][1] * M[1][0] - M[2][0] * M[1][1];
19	atM[1][2] = M[0][1] * M[2][0] - M[2][1] * M[0][0];
20	atM[2][2] = M[0][0] * M[1][1] - M[0][1] * M[1][0];
21
22	return atM;
23}
24
25uniform vec4 worldDualQuaternion2x4Array[48];
26uniform vec4 scaleM[72];
27uniform mat4 viewProjectionMatrix;
28uniform vec4   lightPos[2];
29uniform vec4   lightDiffuseColour[2];
30uniform vec4   ambient;
31
32attribute vec4 vertex;
33attribute vec3 normal;
34attribute vec4 blendIndices;
35attribute vec4 blendWeights;
36attribute vec4 uv0;
37
38void main()
39{
40	//First phase - applies scaling and shearing:
41	int blendIndicesX = int(blendIndices.x) * 3;
42	int blendIndicesY = int(blendIndices.y) * 3;
43
44	mat3x4 blendS = blendWeights.x*mat3x4(scaleM[blendIndicesX],
45		scaleM[blendIndicesX + 1], scaleM[blendIndicesX + 2]);
46
47	blendS += blendWeights.y*mat3x4(scaleM[blendIndicesY], 						scaleM[blendIndicesY + 1], scaleM[blendIndicesY + 2]);
48
49	mat4x3 blendF = transpose(blendS);
50
51	vec3 pass1_position = blendF * vertex;
52
53	mat3x3 blendSrotAT = adjointTransposeMatrix(mat3x3(blendF));
54	vec3 pass1_normal = normalize(blendSrotAT * normal);
55
56	//Second phase
57	mat2x4 blendDQ = blendTwoWeightsAntipod(blendWeights, blendIndices, worldDualQuaternion2x4Array);
58
59	blendDQ /= length(blendDQ[0]);
60
61	vec3 blendPosition = calculateBlendPosition(pass1_position, blendDQ);
62
63	//No need to normalize, the magnitude of the normal is preserved because only rotation is performed
64	vec3 blendNormal = calculateBlendNormal(pass1_normal, blendDQ);
65
66	gl_Position =  viewProjectionMatrix * vec4(blendPosition, 1.0);
67
68	// Lighting - support point and directional
69	vec3 lightDir0 = normalize(lightPos[0].xyz - (blendPosition * lightPos[0].w));
70	vec3 lightDir1 = normalize(lightPos[1].xyz - (blendPosition * lightPos[1].w));
71
72	gl_TexCoord[0] = uv0;
73
74	gl_FrontColor = gl_FrontMaterial.diffuse * (ambient + (clamp(dot(lightDir0, blendNormal), 0.0, 1.0) * lightDiffuseColour[0]) +
75		(clamp(dot(lightDir1, blendNormal), 0.0, 1.0) * lightDiffuseColour[1]));
76}
77
78