31 lines
		
	
	
		
			1009 B
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			31 lines
		
	
	
		
			1009 B
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								// Geometric Skinning with Approximate Dual Quaternion Blending, Kavan
							 | 
						||
| 
								 | 
							
								// Based on https://github.com/tcoppex/aer-engine/blob/master/demos/aura/data/shaders/Skinning.glsl
							 | 
						||
| 
								 | 
							
								uniform vec4 skinBones[skinMaxBones * 3];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void getSkinningDualQuat(const ivec4 bone, vec4 weight, out vec4 A, inout vec4 B, out vec4 S) {
							 | 
						||
| 
								 | 
							
									// Retrieve the real and dual part of the dual-quaternions
							 | 
						||
| 
								 | 
							
									ivec4 bonei = bone * 3;
							 | 
						||
| 
								 | 
							
									mat4 matA = mat4(
							 | 
						||
| 
								 | 
							
										skinBones[bonei.x],
							 | 
						||
| 
								 | 
							
										skinBones[bonei.y],
							 | 
						||
| 
								 | 
							
										skinBones[bonei.z],
							 | 
						||
| 
								 | 
							
										skinBones[bonei.w]);
							 | 
						||
| 
								 | 
							
									mat4 matB = mat4(
							 | 
						||
| 
								 | 
							
										skinBones[bonei.x + 1],
							 | 
						||
| 
								 | 
							
										skinBones[bonei.y + 1],
							 | 
						||
| 
								 | 
							
										skinBones[bonei.z + 1],
							 | 
						||
| 
								 | 
							
										skinBones[bonei.w + 1]);
							 | 
						||
| 
								 | 
							
									//Apply scaling first
							 | 
						||
| 
								 | 
							
									S = skinBones[bonei.x + 2];
							 | 
						||
| 
								 | 
							
									// Handles antipodality by sticking joints in the same neighbourhood
							 | 
						||
| 
								 | 
							
									// weight.xyz *= sign(matA[3] * mat3x4(matA)).xyz;
							 | 
						||
| 
								 | 
							
									weight.xyz *= sign(matA[3] * matA).xyz;
							 | 
						||
| 
								 | 
							
									// Apply weights
							 | 
						||
| 
								 | 
							
									A = matA * weight; // Real part
							 | 
						||
| 
								 | 
							
									B = matB * weight; // Dual part
							 | 
						||
| 
								 | 
							
									// Normalize
							 | 
						||
| 
								 | 
							
									float invNormA = 1.0 / length(A);
							 | 
						||
| 
								 | 
							
									A *= invNormA;
							 | 
						||
| 
								 | 
							
									B *= invNormA;
							 | 
						||
| 
								 | 
							
								}
							 |