Browse Source

Merge pull request #11461 from Mugen87/dev

ColladaLoader2: Added skinWeights and skinIndices
Mr.doob 8 years ago
parent
commit
cd1f9ec124
1 changed files with 108 additions and 5 deletions
  1. 108 5
      examples/js/loaders/ColladaLoader2.js

+ 108 - 5
examples/js/loaders/ColladaLoader2.js

@@ -323,8 +323,9 @@ THREE.ColladaLoader.prototype = {
 				switch ( child.nodeName ) {
 
 					case 'skin':
-						var id = parseId( child.getAttribute( 'source' ) );
-						data.skin[ id ] = parseSkin( child );
+						// there is exactly one skin per controller
+						data.skin.id = parseId( child.getAttribute( 'source' ) );
+						data.skin.data = parseSkin( child );
 						break;
 
 				}
@@ -441,11 +442,106 @@ THREE.ColladaLoader.prototype = {
 
 		function buildController( data ) {
 
-			// for now, we only return the id of the skin in order to get the corresponding geometry
+			var build = {};
+
+			build.id = data.skin.id;
+			build.sources = buildSkin( data.skin.data );
 
-			var keys = Object.keys( data.skin );
+			// we enhance the 'sources' property of the corresponding geometry with our skin data
 
-			return { id: keys[ 0 ] };
+			var geometry = library.geometries[ build.id ];
+			geometry.sources.skinIndices = build.sources.skinIndices;
+			geometry.sources.skinWeights = build.sources.skinWeights;
+
+			return build;
+
+		}
+
+		function buildSkin( data ) {
+
+			var BONE_LIMIT = 4;
+
+			var build = {
+				skinIndices: {
+					array: [],
+					stride: BONE_LIMIT
+				},
+				skinWeights: {
+					array: [],
+					stride: BONE_LIMIT
+				}
+			};
+
+			var sources = data.sources;
+			var vertexWeights = data.vertexWeights;
+
+			var vcount = vertexWeights.vcount;
+			var v = vertexWeights.v;
+			var jointOffset = vertexWeights.inputs.JOINT.offset;
+			var weightOffset = vertexWeights.inputs.WEIGHT.offset;
+
+			var weights = sources[ vertexWeights.inputs.WEIGHT.id ].array;
+			var stride = 0;
+
+			var skinIndices = [];
+			var skinWeights = [];
+
+			// procces skin data for each vertex
+
+			for ( var i = 0, l = vcount.length; i < l; i ++ ) {
+
+				var jointCount = vcount[ i ]; // this is the amount of joints that affect a single vertex
+				var vertexSkinData = [];
+
+				for ( var j = 0; j < jointCount; j ++ ) {
+
+					var skinIndex = v[ stride + jointOffset ];
+					var weightId = v[ stride + weightOffset ];
+					var skinWeight = weights[ weightId ];
+
+					vertexSkinData.push( { index: skinIndex, weight: skinWeight } );
+
+					stride += 2;
+
+				}
+
+				// we sort the joints in descending order based on the weights.
+				// this ensures, we only procced the most important joints of the vertex
+
+				vertexSkinData.sort( descending );
+
+				// now we provide for each vertex a set of four index and weight values.
+				// the order of the skin data matches the order of vertices
+
+				for ( var j = 0; j < BONE_LIMIT; j ++ ) {
+
+					var d = vertexSkinData[ j ];
+
+					if ( d !== undefined ) {
+
+						build.skinIndices.array.push( d.index );
+						build.skinWeights.array.push( d.weight );
+
+					} else {
+
+						build.skinIndices.array.push( 0 );
+						build.skinWeights.array.push( 0 );
+
+					}
+
+				}
+
+			}
+
+			return build;
+
+			// array sort function
+
+			function descending( a, b ) {
+
+				return b.weight - a.weight;
+
+			}
 
 		}
 
@@ -1393,6 +1489,13 @@ THREE.ColladaLoader.prototype = {
 
 								geometry.addAttribute( key.toLowerCase(), buildGeometryAttribute( primitive, sources[ vertices[ key ] ], input.offset ) );
 
+								if ( key.toLowerCase() === 'position' && sources.skinWeights && sources.skinIndices ) {
+
+									geometry.addAttribute( 'skinWeight', buildGeometryAttribute( primitive, sources.skinWeights, input.offset ) );
+									geometry.addAttribute( 'skinIndex', buildGeometryAttribute( primitive, sources.skinIndices, input.offset ) );
+
+								}
+
 							}
 							break;