|
@@ -1161,8 +1161,6 @@ THREE.GLTFLoader = ( function () {
|
|
|
morphAttributes.position = [];
|
|
|
morphAttributes.normal = [];
|
|
|
|
|
|
- material.morphTargets = true;
|
|
|
-
|
|
|
for ( var i = 0, il = targets.length; i < il; i ++ ) {
|
|
|
|
|
|
var target = targets[ i ];
|
|
@@ -1217,8 +1215,6 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
if ( target.NORMAL !== undefined ) {
|
|
|
|
|
|
- material.morphNormals = true;
|
|
|
-
|
|
|
// see target.POSITION's comment
|
|
|
|
|
|
normalAttribute = cloneBufferAttribute( accessors[ target.NORMAL ] );
|
|
@@ -1345,14 +1341,16 @@ THREE.GLTFLoader = ( function () {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Checks if we can build a single Mesh with MultiMaterial from the primitives.
|
|
|
+ * Checks if we can build a single Mesh with MultiMaterial from multiple primitives.
|
|
|
* Returns true if all primitives use the same attributes/morphAttributes/mode
|
|
|
* and also have index. Otherwise returns false.
|
|
|
*
|
|
|
- * @param {Array<Object>} primitives whose length is > 1
|
|
|
+ * @param {Array<GLTF.Primitive>} primitives
|
|
|
* @return {Boolean}
|
|
|
*/
|
|
|
- function isCombinable( primitives ) {
|
|
|
+ function isCombinablePrimitives( primitives ) {
|
|
|
+
|
|
|
+ if ( primitives.length < 2 ) return false;
|
|
|
|
|
|
var primitive0 = primitives[ 0 ];
|
|
|
var targets0 = primitive0.targets || [];
|
|
@@ -1383,60 +1381,6 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Builds a single Mesh with MultiMaterial from meshes.
|
|
|
- *
|
|
|
- * @param {Array<THREE.Object3D>} meshes whose length is > 1
|
|
|
- * @param {Array<Object>} primitives whose length is same as the meshes'
|
|
|
- * @param {Array<THREE.Material>} materials
|
|
|
- * @return {Object3D}
|
|
|
- */
|
|
|
- function combineMeshes( meshes, primitives, materials ) {
|
|
|
-
|
|
|
- var newGeometry = meshes[ 0 ].geometry.clone();
|
|
|
- var newMaterials = [];
|
|
|
- var indices = []
|
|
|
- var offset = 0;
|
|
|
-
|
|
|
- var hasMorphTargets = Object.keys( newGeometry.morphAttributes ).length > 0;
|
|
|
- var hasMorphNormals = hasMorphTargets && ( newGeometry.morphAttributes.normal !== undefined );
|
|
|
-
|
|
|
- for ( var i = 0, il = meshes.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- var mesh = meshes[ i ];
|
|
|
- var primitive = primitives[ i ];
|
|
|
-
|
|
|
- var index = mesh.geometry.index;
|
|
|
- var material = materials[ primitive.material ];
|
|
|
-
|
|
|
- if ( mesh.isSkinnedMesh ) material.skinning = true;
|
|
|
- if ( hasMorphTargets ) material.morphTargets = true;
|
|
|
- if ( hasMorphNormals ) material.morphNormals = true;
|
|
|
-
|
|
|
- newGeometry.addGroup( offset, index.count, i );
|
|
|
- newMaterials.push( material );
|
|
|
-
|
|
|
- for ( var j = 0, jl = index.array.length; j < jl; j ++ ) {
|
|
|
-
|
|
|
- indices.push( index.array[ j ] );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- offset += index.count;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- newGeometry.setIndex( indices );
|
|
|
-
|
|
|
- var newMesh = new meshes[ 0 ].constructor( newGeometry, newMaterials );
|
|
|
-
|
|
|
- newMesh.morphTargetDictionary = Object.assign( {}, meshes[ 0 ].morphTargetDictionary );
|
|
|
- newMesh.name = meshes[ 0 ].name.slice( 0, meshes[ 0 ].name.lastIndexOf( '_' ) );
|
|
|
-
|
|
|
- return newMesh;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
/* GLTF PARSER */
|
|
|
|
|
|
function GLTFParser( json, extensions, options ) {
|
|
@@ -2098,7 +2042,7 @@ THREE.GLTFLoader = ( function () {
|
|
|
* @param {GLTF.Primitive} primitiveDef
|
|
|
* @param {Array<THREE.BufferAttribute>} accessors
|
|
|
*/
|
|
|
- function addPrimitiveAttributes ( geometry, primitiveDef, accessors ) {
|
|
|
+ function addPrimitiveAttributes( geometry, primitiveDef, accessors ) {
|
|
|
|
|
|
var attributes = primitiveDef.attributes;
|
|
|
|
|
@@ -2115,7 +2059,31 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
}
|
|
|
|
|
|
- if ( primitiveDef.indices !== undefined && !geometry.index ) {
|
|
|
+ // .indicesArray isn't in glTF spec. See .loadGeometries()
|
|
|
+ if ( primitiveDef.indicesArray !== undefined && ! geometry.index ) {
|
|
|
+
|
|
|
+ var indices = [];
|
|
|
+ var offset = 0;
|
|
|
+
|
|
|
+ for ( var i = 0, il = primitiveDef.indicesArray.length; i < il; i ++ ) {
|
|
|
+
|
|
|
+ var accessor = accessors[ primitiveDef.indicesArray[ i ] ];
|
|
|
+
|
|
|
+ for ( var j = 0, jl = accessor.count; j < jl; j ++ ) {
|
|
|
+
|
|
|
+ indices.push( accessor.array[ j ] );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ geometry.addGroup( offset, accessor.count, i );
|
|
|
+
|
|
|
+ offset += accessor.count;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ geometry.setIndex( indices );
|
|
|
+
|
|
|
+ } else if ( primitiveDef.indices !== undefined && ! geometry.index ) {
|
|
|
|
|
|
geometry.setIndex( accessors[ primitiveDef.indices ] );
|
|
|
|
|
@@ -2125,6 +2093,11 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
/**
|
|
|
* Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry
|
|
|
+ *
|
|
|
+ * Creates BufferGeometries from primitives.
|
|
|
+ * If we can build a single BufferGeometry with .groups from multiple primitives, returns one BufferGeometry.
|
|
|
+ * Otherwise, returns BufferGeometries without .groups as many as primitives.
|
|
|
+ *
|
|
|
* @param {Array<Object>} primitives
|
|
|
* @return {Promise<Array<THREE.BufferGeometry>>}
|
|
|
*/
|
|
@@ -2134,6 +2107,26 @@ THREE.GLTFLoader = ( function () {
|
|
|
var extensions = this.extensions;
|
|
|
var cache = this.primitiveCache;
|
|
|
|
|
|
+ if ( isCombinablePrimitives( primitives ) ) {
|
|
|
+
|
|
|
+ // We builds a single BufferGeometry with .groups from multiple primitives
|
|
|
+ // because all primitives share the same attributes/morph/mode and have indices.
|
|
|
+
|
|
|
+ var primitive = Object.assign( {}, primitives[ 0 ] );
|
|
|
+ primitive.indicesArray = [];
|
|
|
+
|
|
|
+ // combines indices in addPrimitiveAttributes() later
|
|
|
+
|
|
|
+ for ( var i = 0, il = primitives.length; i < il; i ++ ) {
|
|
|
+
|
|
|
+ primitive.indicesArray[ i ] = primitives[ i ].indices;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ primitives = [ primitive ];
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
return this.getDependencies( 'accessor' ).then( function ( accessors ) {
|
|
|
|
|
|
var pending = [];
|
|
@@ -2177,12 +2170,7 @@ THREE.GLTFLoader = ( function () {
|
|
|
var geometryPromise = Promise.resolve( geometry );
|
|
|
|
|
|
// Cache this geometry
|
|
|
- cache.push( {
|
|
|
-
|
|
|
- primitive: primitive,
|
|
|
- promise: geometryPromise
|
|
|
-
|
|
|
- } );
|
|
|
+ cache.push( { primitive: primitive, promise: geometryPromise } );
|
|
|
|
|
|
pending.push( geometryPromise );
|
|
|
|
|
@@ -2216,190 +2204,226 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
] ).then( function ( dependencies ) {
|
|
|
|
|
|
- var group = new THREE.Group();
|
|
|
-
|
|
|
var primitives = meshDef.primitives;
|
|
|
+ var meshes = [];
|
|
|
+ var originalMaterials = [];
|
|
|
+
|
|
|
+ for ( var i = 0, il = primitives.length; i < il; i ++ ) {
|
|
|
+
|
|
|
+ originalMaterials[ i ] = primitives[ i ].material === undefined
|
|
|
+ ? createDefaultMaterial()
|
|
|
+ : dependencies.materials[ primitives[ i ].material ];
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
return scope.loadGeometries( primitives ).then( function ( geometries ) {
|
|
|
|
|
|
- for ( var i = 0, il = primitives.length; i < il; i ++ ) {
|
|
|
+ var isMultiMaterial = geometries.length === 1 && geometries[ 0 ].groups.length > 0;
|
|
|
+
|
|
|
+ for ( var i = 0, il = geometries.length; i < il; i ++ ) {
|
|
|
|
|
|
- var primitive = primitives[ i ];
|
|
|
var geometry = geometries[ i ];
|
|
|
+ var primitive = primitives[ i ];
|
|
|
|
|
|
- var material = primitive.material === undefined
|
|
|
- ? createDefaultMaterial()
|
|
|
- : dependencies.materials[ primitive.material ];
|
|
|
+ // 1. create Mesh
|
|
|
|
|
|
- if ( material.aoMap
|
|
|
- && geometry.attributes.uv2 === undefined
|
|
|
- && geometry.attributes.uv !== undefined ) {
|
|
|
+ var mesh;
|
|
|
|
|
|
- console.log( 'THREE.GLTFLoader: Duplicating UVs to support aoMap.' );
|
|
|
- geometry.addAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) );
|
|
|
+ var material = isMultiMaterial ? originalMaterials : originalMaterials[ i ]
|
|
|
|
|
|
- }
|
|
|
+ if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES ||
|
|
|
+ primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ||
|
|
|
+ primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ||
|
|
|
+ primitive.mode === undefined ) {
|
|
|
|
|
|
- // If the material will be modified later on, clone it now.
|
|
|
- var useVertexColors = geometry.attributes.color !== undefined;
|
|
|
- var useFlatShading = geometry.attributes.normal === undefined;
|
|
|
- var useSkinning = meshDef.isSkinnedMesh === true;
|
|
|
- var useMorphTargets = primitive.targets !== undefined;
|
|
|
+ // .isSkinnedMesh isn't in glTF spec. See .markDefs()
|
|
|
+ mesh = meshDef.isSkinnedMesh === true
|
|
|
+ ? new THREE.SkinnedMesh( geometry, material )
|
|
|
+ : new THREE.Mesh( geometry, material );
|
|
|
|
|
|
- if ( useVertexColors || useFlatShading || useSkinning || useMorphTargets ) {
|
|
|
+ if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ) {
|
|
|
|
|
|
- if ( material.isGLTFSpecularGlossinessMaterial ) {
|
|
|
+ mesh.drawMode = THREE.TriangleStripDrawMode;
|
|
|
|
|
|
- var specGlossExtension = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ];
|
|
|
- material = specGlossExtension.cloneMaterial( material );
|
|
|
+ } else if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ) {
|
|
|
+
|
|
|
+ mesh.drawMode = THREE.TriangleFanDrawMode;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if ( primitive.mode === WEBGL_CONSTANTS.LINES ||
|
|
|
+ primitive.mode === WEBGL_CONSTANTS.LINE_STRIP ||
|
|
|
+ primitive.mode === WEBGL_CONSTANTS.LINE_LOOP ) {
|
|
|
+
|
|
|
+ if ( primitive.mode === WEBGL_CONSTANTS.LINES ) {
|
|
|
+
|
|
|
+ mesh = new THREE.LineSegments( geometry, material );
|
|
|
+
|
|
|
+ } else if ( primitive.mode === WEBGL_CONSTANTS.LINE_STRIP ) {
|
|
|
+
|
|
|
+ mesh = new THREE.Line( geometry, material );
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- material = material.clone();
|
|
|
+ mesh = new THREE.LineLoop( geometry, material );
|
|
|
|
|
|
}
|
|
|
|
|
|
- }
|
|
|
+ } else if ( primitive.mode === WEBGL_CONSTANTS.POINTS ) {
|
|
|
+
|
|
|
+ mesh = new THREE.Points( geometry, material );
|
|
|
|
|
|
- if ( useVertexColors ) {
|
|
|
+ } else {
|
|
|
|
|
|
- material.vertexColors = THREE.VertexColors;
|
|
|
- material.needsUpdate = true;
|
|
|
+ throw new Error( 'THREE.GLTFLoader: Primitive mode unsupported: ' + primitive.mode );
|
|
|
|
|
|
}
|
|
|
|
|
|
- if ( useFlatShading ) {
|
|
|
+ if ( primitive.targets !== undefined ) {
|
|
|
|
|
|
- material.flatShading = true;
|
|
|
+ addMorphTargets( mesh, meshDef, primitive, dependencies.accessors );
|
|
|
|
|
|
}
|
|
|
|
|
|
- var mesh;
|
|
|
+ mesh.name = meshDef.name || ( 'mesh_' + meshIndex );
|
|
|
|
|
|
- if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES ||
|
|
|
- primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ||
|
|
|
- primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ||
|
|
|
- primitive.mode === undefined ) {
|
|
|
+ if ( geometries.length > 1 ) mesh.name += '_' + i;
|
|
|
|
|
|
- if ( useSkinning ) {
|
|
|
+ if ( meshDef.extras !== undefined ) mesh.userData = meshDef.extras;
|
|
|
+ if ( primitive.extras !== undefined ) mesh.geometry.userData = primitive.extras;
|
|
|
|
|
|
- mesh = new THREE.SkinnedMesh( geometry, material );
|
|
|
- material.skinning = true;
|
|
|
+ meshes.push( mesh );
|
|
|
|
|
|
- } else {
|
|
|
+ // 2. update Material depending on Mesh and BufferGeometry
|
|
|
|
|
|
- mesh = new THREE.Mesh( geometry, material );
|
|
|
+ var materials = isMultiMaterial ? mesh.material : [ mesh.material ];
|
|
|
|
|
|
- }
|
|
|
+ var useVertexColors = geometry.attributes.color !== undefined;
|
|
|
+ var useFlatShading = geometry.attributes.normal === undefined;
|
|
|
+ var useSkinning = mesh.isSkinnedMesh === true;
|
|
|
+ var useMorphTargets = Object.keys( geometry.morphAttributes ).length > 0;
|
|
|
+ var useMorphNormals = useMorphTargets && geometry.morphAttributes.normal !== undefined;
|
|
|
|
|
|
- if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ) {
|
|
|
+ for ( var j = 0, jl = materials.length; j < jl; j ++ ) {
|
|
|
|
|
|
- mesh.drawMode = THREE.TriangleStripDrawMode;
|
|
|
+ var material = materials[ j ];
|
|
|
|
|
|
- } else if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ) {
|
|
|
+ if ( mesh.isPoints ) {
|
|
|
|
|
|
- mesh.drawMode = THREE.TriangleFanDrawMode;
|
|
|
+ var cacheKey = 'PointsMaterial:' + material.uuid;
|
|
|
|
|
|
- }
|
|
|
+ var pointsMaterial = scope.cache.get( cacheKey );
|
|
|
|
|
|
- } else if ( primitive.mode === WEBGL_CONSTANTS.LINES ||
|
|
|
- primitive.mode === WEBGL_CONSTANTS.LINE_STRIP ||
|
|
|
- primitive.mode === WEBGL_CONSTANTS.LINE_LOOP ) {
|
|
|
+ if ( ! pointsMaterial ) {
|
|
|
|
|
|
- var cacheKey = 'LineBasicMaterial:' + material.uuid;
|
|
|
+ pointsMaterial = new THREE.PointsMaterial();
|
|
|
+ THREE.Material.prototype.copy.call( pointsMaterial, material );
|
|
|
+ pointsMaterial.color.copy( material.color );
|
|
|
+ pointsMaterial.map = material.map;
|
|
|
+ pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet
|
|
|
|
|
|
- var lineMaterial = scope.cache.get( cacheKey );
|
|
|
+ scope.cache.add( cacheKey, pointsMaterial );
|
|
|
|
|
|
- if ( ! lineMaterial ) {
|
|
|
+ }
|
|
|
|
|
|
- lineMaterial = new THREE.LineBasicMaterial();
|
|
|
- THREE.Material.prototype.copy.call( lineMaterial, material );
|
|
|
- lineMaterial.color.copy( material.color );
|
|
|
- lineMaterial.lights = false; // LineBasicMaterial doesn't support lights yet
|
|
|
+ material = pointsMaterial;
|
|
|
|
|
|
- scope.cache.add( cacheKey, lineMaterial );
|
|
|
+ } else if ( mesh.isLine ) {
|
|
|
|
|
|
- }
|
|
|
+ var cacheKey = 'LineBasicMaterial:' + material.uuid;
|
|
|
|
|
|
- material = lineMaterial;
|
|
|
+ var lineMaterial = scope.cache.get( cacheKey );
|
|
|
|
|
|
- if ( primitive.mode === WEBGL_CONSTANTS.LINES ) {
|
|
|
+ if ( ! lineMaterial ) {
|
|
|
|
|
|
- mesh = new THREE.LineSegments( geometry, material );
|
|
|
+ lineMaterial = new THREE.LineBasicMaterial();
|
|
|
+ THREE.Material.prototype.copy.call( lineMaterial, material );
|
|
|
+ lineMaterial.color.copy( material.color );
|
|
|
+ lineMaterial.lights = false; // LineBasicMaterial doesn't support lights yet
|
|
|
|
|
|
- } else if ( primitive.mode === WEBGL_CONSTANTS.LINE_STRIP ) {
|
|
|
+ scope.cache.add( cacheKey, lineMaterial );
|
|
|
|
|
|
- mesh = new THREE.Line( geometry, material );
|
|
|
+ }
|
|
|
|
|
|
- } else {
|
|
|
+ material = lineMaterial;
|
|
|
|
|
|
- mesh = new THREE.LineLoop( geometry, material );
|
|
|
+ }
|
|
|
+
|
|
|
+ // If the material will be modified later on, clone it now.
|
|
|
+ if ( useVertexColors || useFlatShading || useSkinning || useMorphTargets ) {
|
|
|
+
|
|
|
+ material = material.isGLTFSpecularGlossinessMaterial
|
|
|
+ ? extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].cloneMaterial( materials )
|
|
|
+ : material.clone();
|
|
|
|
|
|
}
|
|
|
|
|
|
- } else if ( primitive.mode === WEBGL_CONSTANTS.POINTS ) {
|
|
|
+ if ( useSkinning ) {
|
|
|
+
|
|
|
+ material.skinning = true;
|
|
|
|
|
|
- var cacheKey = 'PointsMaterial:' + material.uuid;
|
|
|
+ }
|
|
|
|
|
|
- var pointsMaterial = scope.cache.get( cacheKey );
|
|
|
+ if ( useVertexColors ) {
|
|
|
|
|
|
- if ( ! pointsMaterial ) {
|
|
|
+ material.vertexColors = THREE.VertexColors;
|
|
|
+ material.needsUpdate = true;
|
|
|
|
|
|
- pointsMaterial = new THREE.PointsMaterial();
|
|
|
- THREE.Material.prototype.copy.call( pointsMaterial, material );
|
|
|
- pointsMaterial.color.copy( material.color );
|
|
|
- pointsMaterial.map = material.map;
|
|
|
- pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet
|
|
|
+ }
|
|
|
|
|
|
- scope.cache.add( cacheKey, pointsMaterial );
|
|
|
+ if ( useFlatShading ) {
|
|
|
+
|
|
|
+ material.flatShading = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
- material = pointsMaterial;
|
|
|
+ if ( useMorphTargets ) {
|
|
|
|
|
|
- mesh = new THREE.Points( geometry, material );
|
|
|
+ material.morphTargets = true;
|
|
|
|
|
|
- } else {
|
|
|
+ }
|
|
|
|
|
|
- throw new Error( 'THREE.GLTFLoader: Primitive mode unsupported: ' + primitive.mode );
|
|
|
+ if ( useMorphNormals ) {
|
|
|
|
|
|
- }
|
|
|
+ material.morphNormals = true;
|
|
|
|
|
|
- mesh.name = meshDef.name || ( 'mesh_' + meshIndex );
|
|
|
+ }
|
|
|
|
|
|
- if ( useMorphTargets ) {
|
|
|
+ materials[ j ] = material;
|
|
|
|
|
|
- addMorphTargets( mesh, meshDef, primitive, dependencies.accessors );
|
|
|
+ // workarounds for mesh and geometry
|
|
|
|
|
|
- }
|
|
|
+ if ( material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined ) {
|
|
|
|
|
|
- if ( meshDef.extras !== undefined ) mesh.userData = meshDef.extras;
|
|
|
- if ( primitive.extras !== undefined ) mesh.geometry.userData = primitive.extras;
|
|
|
+ console.log( 'THREE.GLTFLoader: Duplicating UVs to support aoMap.' );
|
|
|
+ geometry.addAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) );
|
|
|
|
|
|
- // for Specular-Glossiness.
|
|
|
- if ( material.isGLTFSpecularGlossinessMaterial === true ) {
|
|
|
+ }
|
|
|
|
|
|
- mesh.onBeforeRender = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].refreshUniforms;
|
|
|
+ if ( material.isGLTFSpecularGlossinessMaterial ) {
|
|
|
|
|
|
- }
|
|
|
+ // for GLTFSpecularGlossinessMaterial(ShaderMaterial) uniforms runtime update
|
|
|
+ mesh.onBeforeRender = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].refreshUniforms;
|
|
|
|
|
|
- if ( primitives.length > 1 ) {
|
|
|
+ }
|
|
|
|
|
|
- mesh.name += '_' + i;
|
|
|
+ }
|
|
|
|
|
|
- group.add( mesh );
|
|
|
+ mesh.material = isMultiMaterial ? materials : materials[ 0 ];
|
|
|
|
|
|
- } else {
|
|
|
+ }
|
|
|
|
|
|
- return mesh;
|
|
|
+ if ( meshes.length === 1 ) {
|
|
|
|
|
|
- }
|
|
|
+ return meshes[ 0 ];
|
|
|
|
|
|
}
|
|
|
|
|
|
- if ( isCombinable( primitives ) ) {
|
|
|
+ var group = new THREE.Group();
|
|
|
+
|
|
|
+ for ( var i = 0, il = meshes.length; i < il; i ++ ) {
|
|
|
|
|
|
- return combineMeshes( group.children, primitives, dependencies.materials );
|
|
|
+ group.add( meshes[ i ] );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -2642,6 +2666,7 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
var node;
|
|
|
|
|
|
+ // .isBone isn't in glTF spec. See .markDefs
|
|
|
if ( nodeDef.isBone === true ) {
|
|
|
|
|
|
node = new THREE.Bone();
|