Skip to content

Commit

Permalink
Merge pull request #11461 from Mugen87/dev
Browse files Browse the repository at this point in the history
ColladaLoader2: Added skinWeights and skinIndices
  • Loading branch information
mrdoob authored Jun 7, 2017
2 parents ff2ce56 + b689e15 commit cd1f9ec
Showing 1 changed file with 108 additions and 5 deletions.
113 changes: 108 additions & 5 deletions examples/js/loaders/ColladaLoader2.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

}
Expand Down Expand Up @@ -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;

}

}

Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit cd1f9ec

Please sign in to comment.