提交 a4eb5b3a 编写于 作者: M Mr.doob 提交者: GitHub

Merge pull request #11502 from Mugen87/dev

ColladaLoader2: Added multi material support
...@@ -1844,6 +1844,7 @@ THREE.ColladaLoader.prototype = { ...@@ -1844,6 +1844,7 @@ THREE.ColladaLoader.prototype = {
var primitive = { var primitive = {
type: xml.nodeName, type: xml.nodeName,
material: xml.getAttribute( 'material' ), material: xml.getAttribute( 'material' ),
count: parseInt( xml.getAttribute( 'count' ) ),
inputs: {}, inputs: {},
stride: 0 stride: 0
}; };
...@@ -1880,29 +1881,53 @@ THREE.ColladaLoader.prototype = { ...@@ -1880,29 +1881,53 @@ THREE.ColladaLoader.prototype = {
} }
var DEFAULT_LINEMATERIAL = new THREE.LineBasicMaterial();
var DEFAULT_MESHMATERIAL = new THREE.MeshPhongMaterial();
function buildGeometry( data ) { function buildGeometry( data ) {
var group = {};
var sources = data.sources; var sources = data.sources;
var vertices = data.vertices; var vertices = data.vertices;
var primitives = data.primitives; var primitives = data.primitives;
var skinning = false; if ( primitives.length === 0 ) return {};
var position = { array: [], stride: 0 };
var normal = { array: [], stride: 0 };
var uv = { array: [], stride: 0 };
var color = { array: [], stride: 0 };
var skinIndex = { array: [], stride: 4 };
var skinWeight = { array: [], stride: 4 };
if ( primitives.length === 0 ) return group; var geometry = new THREE.BufferGeometry();
geometry.name = data.name || '';
var materials = [];
var start = 0, count = 0;
var array;
for ( var p = 0; p < primitives.length; p ++ ) { for ( var p = 0; p < primitives.length; p ++ ) {
var primitive = primitives[ p ]; var primitive = primitives[ p ];
var inputs = primitive.inputs; var inputs = primitive.inputs;
var triangleCount = 1;
var geometry = new THREE.BufferGeometry(); if ( primitive.vcount && primitive.vcount[ 0 ] === 4 ) {
triangleCount = 2; // one quad -> two triangles
}
// groups
count = primitive.count * 3 * triangleCount;
geometry.addGroup( start, count, p );
start += count;
// material
if ( data.name ) geometry.name = data.name; materials.push( getMaterial( primitive.material ) );
// geometry data
for ( var name in inputs ) { for ( var name in inputs ) {
...@@ -1913,14 +1938,17 @@ THREE.ColladaLoader.prototype = { ...@@ -1913,14 +1938,17 @@ THREE.ColladaLoader.prototype = {
case 'VERTEX': case 'VERTEX':
for ( var key in vertices ) { for ( var key in vertices ) {
geometry.addAttribute( key.toLowerCase(), buildGeometryAttribute( primitive, sources[ vertices[ key ] ], input.offset ) ); if ( key === 'POSITION' ) {
buildGeometryData( primitive, sources[ vertices[ key ] ], input.offset, position.array );
position.stride = sources[ vertices[ key ] ].stride;
if ( key.toLowerCase() === 'position' && sources.skinWeights && sources.skinIndices ) { if ( sources.skinWeights && sources.skinIndices ) {
geometry.addAttribute( 'skinWeight', buildGeometryAttribute( primitive, sources.skinWeights, input.offset ) ); buildGeometryData( primitive, sources.skinIndices, input.offset, skinIndex.array );
geometry.addAttribute( 'skinIndex', buildGeometryAttribute( primitive, sources.skinIndices, input.offset ) ); buildGeometryData( primitive, sources.skinWeights, input.offset, skinWeight.array );
skinning = true; }
} }
...@@ -1928,49 +1956,82 @@ THREE.ColladaLoader.prototype = { ...@@ -1928,49 +1956,82 @@ THREE.ColladaLoader.prototype = {
break; break;
case 'NORMAL': case 'NORMAL':
geometry.addAttribute( 'normal', buildGeometryAttribute( primitive, sources[ input.id ], input.offset ) ); buildGeometryData( primitive, sources[ input.id ], input.offset, normal.array );
normal.stride = sources[ input.id ].stride;
break; break;
case 'COLOR': case 'COLOR':
geometry.addAttribute( 'color', buildGeometryAttribute( primitive, sources[ input.id ], input.offset ) ); buildGeometryData( primitive, sources[ input.id ], input.offset, color.array );
color.stride = sources[ input.id ].stride;
break; break;
case 'TEXCOORD': case 'TEXCOORD':
geometry.addAttribute( 'uv', buildGeometryAttribute( primitive, sources[ input.id ], input.offset ) ); buildGeometryData( primitive, sources[ input.id ], input.offset, uv.array );
uv.stride = sources[ input.id ].stride;
break; break;
} }
} }
}
// build geometry
if ( position.array.length > 0 ) geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( position.array, position.stride ) );
if ( normal.array.length > 0 ) geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normal.array, normal.stride ) );
if ( color.array.length > 0 ) geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( color.array, color.stride ) );
if ( uv.array.length > 0 ) geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uv.array, uv.stride ) );
if ( skinIndex.array.length > 0 ) geometry.addAttribute( 'skinIndex', new THREE.Float32BufferAttribute( skinIndex.array, skinIndex.stride ) );
if ( skinWeight.array.length > 0 ) geometry.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeight.array, skinWeight.stride ) );
// setup material
var material = ( materials.length === 1 ) ? materials[ 0 ] : materials;
// setup object
var object; var object;
switch ( primitive.type ) { switch ( primitives[ 0 ].type ) {
case 'lines': case 'lines':
object = new THREE.LineSegments( geometry, DEFAULT_LINEMATERIAL ); object = new THREE.LineSegments( geometry, material );
break; break;
case 'linestrips': case 'linestrips':
object = new THREE.Line( geometry, DEFAULT_LINEMATERIAL ); object = new THREE.Line( geometry, material );
break; break;
case 'triangles': case 'triangles':
case 'polylist': case 'polylist':
object = ( skinning === true ) ? new THREE.SkinnedMesh( geometry, DEFAULT_MESHMATERIAL ) : new THREE.Mesh( geometry, DEFAULT_MESHMATERIAL );
break; if ( geometry.attributes.skinIndex ) {
for ( var i = 0, l = materials.length; i < l; i ++ ) {
materials[ i ].skinning = true;
} }
group[ primitive.material ] = object; object = new THREE.SkinnedMesh( geometry, material );
} else {
object = new THREE.Mesh( geometry, material );
} }
return group; break;
} }
function buildGeometryAttribute( primitive, source, offset ) { return object;
}
function buildGeometryData( primitive, source, offset, array ) {
var indices = primitive.p; var indices = primitive.p;
var stride = primitive.stride; var stride = primitive.stride;
...@@ -1994,8 +2055,6 @@ THREE.ColladaLoader.prototype = { ...@@ -1994,8 +2055,6 @@ THREE.ColladaLoader.prototype = {
var sourceArray = source.array; var sourceArray = source.array;
var sourceStride = source.stride; var sourceStride = source.stride;
var array = [];
if ( primitive.vcount !== undefined ) { if ( primitive.vcount !== undefined ) {
var index = 0; var index = 0;
...@@ -2048,8 +2107,6 @@ THREE.ColladaLoader.prototype = { ...@@ -2048,8 +2107,6 @@ THREE.ColladaLoader.prototype = {
} }
return new THREE.Float32BufferAttribute( array, sourceStride );
} }
function getGeometry( id ) { function getGeometry( id ) {
...@@ -2257,33 +2314,20 @@ THREE.ColladaLoader.prototype = { ...@@ -2257,33 +2314,20 @@ THREE.ColladaLoader.prototype = {
var instance = instanceControllers[ i ]; var instance = instanceControllers[ i ];
var controller = getController( instance.id ); var controller = getController( instance.id );
var geometries = getGeometry( controller.id ); var object = getGeometry( controller.id ).clone();
var node = getNode( instance.skeleton ); var node = getNode( instance.skeleton );
var skeleton = getSkeleton( node, controller ); var skeleton = getSkeleton( node, controller );
for ( var key in geometries ) {
var object = geometries[ key ].clone();
if ( instance.materials[ key ] !== undefined ) {
object.bind( skeleton, controller.skin.bindMatrix ); object.bind( skeleton, controller.skin.bindMatrix );
object.normalizeSkinWeights(); object.normalizeSkinWeights();
object.bones = skeleton.bones; // this is necessary for property binding object.bones = skeleton.bones; // this is necessary for property binding
object.add( node ); // bone hierarchy is a child of the skinned mesh object.add( node ); // bone hierarchy is a child of the skinned mesh
object.material = getMaterial( instance.materials[ key ] );
object.material.skinning = true;
}
objects.push( object ); objects.push( object );
} }
}
for ( var i = 0, l = instanceLights.length; i < l; i ++ ) { for ( var i = 0, l = instanceLights.length; i < l; i ++ ) {
objects.push( getLight( instanceLights[ i ] ).clone() ); objects.push( getLight( instanceLights[ i ] ).clone() );
...@@ -2293,24 +2337,11 @@ THREE.ColladaLoader.prototype = { ...@@ -2293,24 +2337,11 @@ THREE.ColladaLoader.prototype = {
for ( var i = 0, l = instanceGeometries.length; i < l; i ++ ) { for ( var i = 0, l = instanceGeometries.length; i < l; i ++ ) {
var instance = instanceGeometries[ i ]; var instance = instanceGeometries[ i ];
var geometries = getGeometry( instance.id ); var object = getGeometry( instance.id ).clone();
for ( var key in geometries ) {
var object = geometries[ key ].clone();
if ( instance.materials[ key ] !== undefined ) {
object.material = getMaterial( instance.materials[ key ] );
}
objects.push( object ); objects.push( object );
} }
}
for ( var i = 0, l = instanceNodes.length; i < l; i ++ ) { for ( var i = 0, l = instanceNodes.length; i < l; i ++ ) {
objects.push( getNode( instanceNodes[ i ] ).clone() ); objects.push( getNode( instanceNodes[ i ] ).clone() );
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册