提交 2a29bd2b 编写于 作者: M Mr.doob

Updated generated jsm files.

上级 822530be
......@@ -546,32 +546,44 @@ var OrbitControls = function ( object, domElement ) {
function handleKeyDown( event ) {
//console.log( 'handleKeyDown' );
// console.log( 'handleKeyDown' );
var needsUpdate = false;
switch ( event.keyCode ) {
case scope.keys.UP:
pan( 0, scope.keyPanSpeed );
scope.update();
needsUpdate = true;
break;
case scope.keys.BOTTOM:
pan( 0, - scope.keyPanSpeed );
scope.update();
needsUpdate = true;
break;
case scope.keys.LEFT:
pan( scope.keyPanSpeed, 0 );
scope.update();
needsUpdate = true;
break;
case scope.keys.RIGHT:
pan( - scope.keyPanSpeed, 0 );
scope.update();
needsUpdate = true;
break;
}
if ( needsUpdate ) {
// prevent the browser from scrolling on cursor keys
event.preventDefault();
scope.update();
}
}
function handleTouchStartRotate( event ) {
......@@ -682,8 +694,15 @@ var OrbitControls = function ( object, domElement ) {
if ( scope.enabled === false ) return;
// Prevent the browser from scrolling.
event.preventDefault();
// Manually set the focus since calling preventDefault above
// prevents the browser from setting it automatically.
scope.domElement.focus ? scope.domElement.focus() : window.focus();
switch ( event.button ) {
case scope.mouseButtons.LEFT:
......
......@@ -10,12 +10,10 @@ import {
AddEquation,
AlwaysDepth,
AnimationClip,
AnimationUtils,
BackSide,
Bone,
BufferAttribute,
BufferGeometry,
BufferGeometryUtils,
Camera,
ClampToEdgeWrapping,
Color,
......@@ -34,7 +32,6 @@ import {
Interpolant,
InterpolateDiscrete,
InterpolateLinear,
InterpolateSmooth,
LessDepth,
LessEqualDepth,
Line,
......@@ -284,7 +281,7 @@ var GLTFLoader = ( function () {
break;
case EXTENSIONS.MSFT_TEXTURE_DDS:
extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] = new GLTFTextureDDSExtension( json );
extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] = new GLTFTextureDDSExtension();
break;
case EXTENSIONS.KHR_TEXTURE_TRANSFORM:
......@@ -313,23 +310,7 @@ var GLTFLoader = ( function () {
} );
parser.parse( function ( scene, scenes, cameras, animations, json ) {
var glTF = {
scene: scene,
scenes: scenes,
cameras: cameras,
animations: animations,
asset: json.asset,
parser: parser,
userData: {}
};
addUnknownExtensionsToUserData( extensions, glTF, json );
onLoad( glTF );
}, onError );
parser.parse( onLoad, onError );
}
......@@ -460,6 +441,10 @@ var GLTFLoader = ( function () {
}
// Some lights (e.g. spot) default to a position other than the origin. Reset the position
// here, because node-level parsing will only override position if explicitly specified.
lightNode.position.set( 0, 0, 0 );
lightNode.decay = 2;
if ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity;
......@@ -603,7 +588,6 @@ var GLTFLoader = ( function () {
this.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION;
this.json = json;
this.dracoLoader = dracoLoader;
THREE.DRACOLoader.getDecoderModule();
}
......@@ -619,21 +603,23 @@ var GLTFLoader = ( function () {
for ( var attributeName in gltfAttributeMap ) {
if ( ! ( attributeName in ATTRIBUTES ) ) continue;
var threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();
threeAttributeMap[ ATTRIBUTES[ attributeName ] ] = gltfAttributeMap[ attributeName ];
threeAttributeMap[ threeAttributeName ] = gltfAttributeMap[ attributeName ];
}
for ( attributeName in primitive.attributes ) {
if ( ATTRIBUTES[ attributeName ] !== undefined && gltfAttributeMap[ attributeName ] !== undefined ) {
var threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();
if ( gltfAttributeMap[ attributeName ] !== undefined ) {
var accessorDef = json.accessors[ primitive.attributes[ attributeName ] ];
var componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];
attributeTypeMap[ ATTRIBUTES[ attributeName ] ] = componentType;
attributeNormalizedMap[ ATTRIBUTES[ attributeName ] ] = accessorDef.normalized === true;
attributeTypeMap[ threeAttributeName ] = componentType;
attributeNormalizedMap[ threeAttributeName ] = accessorDef.normalized === true;
}
......@@ -1293,6 +1279,7 @@ var GLTFLoader = ( function () {
var ATTRIBUTES = {
POSITION: 'position',
NORMAL: 'normal',
TANGENT: 'tangent',
TEXCOORD_0: 'uv',
TEXCOORD_1: 'uv2',
COLOR_0: 'color',
......@@ -1308,10 +1295,8 @@ var GLTFLoader = ( function () {
};
var INTERPOLATION = {
CUBICSPLINE: InterpolateSmooth, // We use custom interpolation GLTFCubicSplineInterpolation for CUBICSPLINE.
// KeyframeTrack.optimize() can't handle glTF Cubic Spline output values layout,
// using InterpolateSmooth for KeyframeTrack instantiation to prevent optimization.
// See KeyframeTrack.optimize() for the detail.
CUBICSPLINE: undefined, // We use a custom interpolant (GLTFCubicSplineInterpolation) for CUBICSPLINE tracks. Each
// keyframe track will be initialized with a default interpolation type, then modified.
LINEAR: InterpolateLinear,
STEP: InterpolateDiscrete
};
......@@ -1357,12 +1342,14 @@ var GLTFLoader = ( function () {
}
var defaultMaterial;
/**
* Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material
*/
function createDefaultMaterial() {
return new MeshStandardMaterial( {
defaultMaterial = defaultMaterial || new MeshStandardMaterial( {
color: 0xFFFFFF,
emissive: 0x000000,
metalness: 1,
......@@ -1372,6 +1359,8 @@ var GLTFLoader = ( function () {
side: FrontSide
} );
return defaultMaterial;
}
function addUnknownExtensionsToUserData( knownExtensions, object, objectDef ) {
......@@ -1448,34 +1437,21 @@ var GLTFLoader = ( function () {
if ( hasMorphPosition ) {
// TODO: Error-prone use of a callback inside a loop.
var accessor = target.POSITION !== undefined
var pendingAccessor = target.POSITION !== undefined
? parser.getDependency( 'accessor', target.POSITION )
.then( function ( accessor ) {
// Cloning not to pollute original accessor below
return cloneBufferAttribute( accessor );
} )
: geometry.attributes.position;
pendingPositionAccessors.push( accessor );
pendingPositionAccessors.push( pendingAccessor );
}
if ( hasMorphNormal ) {
// TODO: Error-prone use of a callback inside a loop.
var accessor = target.NORMAL !== undefined
var pendingAccessor = target.NORMAL !== undefined
? parser.getDependency( 'accessor', target.NORMAL )
.then( function ( accessor ) {
return cloneBufferAttribute( accessor );
} )
: geometry.attributes.normal;
pendingNormalAccessors.push( accessor );
pendingNormalAccessors.push( pendingAccessor );
}
......@@ -1489,6 +1465,24 @@ var GLTFLoader = ( function () {
var morphPositions = accessors[ 0 ];
var morphNormals = accessors[ 1 ];
// Clone morph target accessors before modifying them.
for ( var i = 0, il = morphPositions.length; i < il; i ++ ) {
if ( geometry.attributes.position === morphPositions[ i ] ) continue;
morphPositions[ i ] = cloneBufferAttribute( morphPositions[ i ] );
}
for ( var i = 0, il = morphNormals.length; i < il; i ++ ) {
if ( geometry.attributes.normal === morphNormals[ i ] ) continue;
morphNormals[ i ] = cloneBufferAttribute( morphNormals[ i ] );
}
for ( var i = 0, il = targets.length; i < il; i ++ ) {
var target = targets[ i ];
......@@ -1609,30 +1603,6 @@ var GLTFLoader = ( function () {
}
}
function isPrimitiveEqual( a, b ) {
var dracoExtA = a.extensions ? a.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] : undefined;
var dracoExtB = b.extensions ? b.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] : undefined;
if ( dracoExtA && dracoExtB ) {
if ( dracoExtA.bufferView !== dracoExtB.bufferView ) return false;
return isObjectEqual( dracoExtA.attributes, dracoExtB.attributes );
}
if ( a.indices !== b.indices ) {
return false;
}
return isObjectEqual( a.attributes, b.attributes );
}
function isObjectEqual( a, b ) {
if ( Object.keys( a ).length !== Object.keys( b ).length ) return false;
......@@ -1647,59 +1617,40 @@ var GLTFLoader = ( function () {
}
function isArrayEqual( a, b ) {
if ( a.length !== b.length ) return false;
function createPrimitiveKey( primitiveDef ) {
for ( var i = 0, il = a.length; i < il; i ++ ) {
var dracoExtension = primitiveDef.extensions && primitiveDef.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ];
var geometryKey;
if ( a[ i ] !== b[ i ] ) return false;
if ( dracoExtension ) {
}
return true;
geometryKey = 'draco:' + dracoExtension.bufferView
+ ':' + dracoExtension.indices
+ ':' + createAttributesKey( dracoExtension.attributes );
}
function getCachedGeometry( cache, newPrimitive ) {
for ( var i = 0, il = cache.length; i < il; i ++ ) {
var cached = cache[ i ];
if ( isPrimitiveEqual( cached.primitive, newPrimitive ) ) return cached.promise;
}
} else {
return null;
geometryKey = primitiveDef.indices + ':' + createAttributesKey( primitiveDef.attributes ) + ':' + primitiveDef.mode;
}
function getCachedCombinedGeometry( cache, geometries ) {
for ( var i = 0, il = cache.length; i < il; i ++ ) {
var cached = cache[ i ];
if ( isArrayEqual( geometries, cached.baseGeometries ) ) return cached.geometry;
return geometryKey;
}
return null;
}
function createAttributesKey( attributes ) {
function getCachedMultiPassGeometry( cache, geometry, primitives ) {
var attributesKey = '';
for ( var i = 0, il = cache.length; i < il; i ++ ) {
var keys = Object.keys( attributes ).sort();
var cached = cache[ i ];
for ( var i = 0, il = keys.length; i < il; i ++ ) {
if ( geometry === cached.baseGeometry && isArrayEqual( primitives, cached.primitives ) ) return cached.geometry;
attributesKey += keys[ i ] + ':' + attributes[ keys[ i ] ] + ';';
}
return null;
return attributesKey;
}
......@@ -1728,48 +1679,6 @@ var GLTFLoader = ( function () {
}
/**
* 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<GLTF.Primitive>} primitives
* @return {Boolean}
*/
function isMultiPassGeometry( primitives ) {
if ( primitives.length < 2 ) return false;
var primitive0 = primitives[ 0 ];
var targets0 = primitive0.targets || [];
if ( primitive0.indices === undefined ) return false;
for ( var i = 1, il = primitives.length; i < il; i ++ ) {
var primitive = primitives[ i ];
if ( primitive0.mode !== primitive.mode ) return false;
if ( primitive.indices === undefined ) return false;
if ( primitive.extensions && primitive.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] ) return false;
if ( ! isObjectEqual( primitive0.attributes, primitive.attributes ) ) return false;
var targets = primitive.targets || [];
if ( targets0.length !== targets.length ) return false;
for ( var j = 0, jl = targets0.length; j < jl; j ++ ) {
if ( ! isObjectEqual( targets0[ j ], targets[ j ] ) ) return false;
}
}
return true;
}
/* GLTF PARSER */
function GLTFParser( json, extensions, options ) {
......@@ -1782,9 +1691,7 @@ var GLTFLoader = ( function () {
this.cache = new GLTFRegistry();
// BufferGeometry caching
this.primitiveCache = [];
this.multiplePrimitivesCache = [];
this.multiPassGeometryCache = [];
this.primitiveCache = {};
this.textureLoader = new TextureLoader( this.options.manager );
this.textureLoader.setCrossOrigin( this.options.crossOrigin );
......@@ -1796,7 +1703,9 @@ var GLTFLoader = ( function () {
GLTFParser.prototype.parse = function ( onLoad, onError ) {
var parser = this;
var json = this.json;
var extensions = this.extensions;
// Clear the loader cache
this.cache.removeAll();
......@@ -1804,21 +1713,27 @@ var GLTFLoader = ( function () {
// Mark the special nodes/meshes in json for efficient parse
this.markDefs();
// Fire the callback on complete
this.getMultiDependencies( [
Promise.all( [
'scene',
'animation',
'camera'
this.getDependencies( 'scene' ),
this.getDependencies( 'animation' ),
this.getDependencies( 'camera' ),
] ).then( function ( dependencies ) {
var scenes = dependencies.scenes || [];
var scene = scenes[ json.scene || 0 ];
var animations = dependencies.animations || [];
var cameras = dependencies.cameras || [];
var result = {
scene: dependencies[ 0 ][ json.scene || 0 ],
scenes: dependencies[ 0 ],
animations: dependencies[ 1 ],
cameras: dependencies[ 2 ],
asset: json.asset,
parser: parser,
userData: {}
};
addUnknownExtensionsToUserData( extensions, result, json );
onLoad( scene, scenes, cameras, animations, json );
onLoad( result );
} ).catch( onError );
......@@ -1991,40 +1906,6 @@ var GLTFLoader = ( function () {
};
/**
* Requests all multiple dependencies of the specified types asynchronously, with caching.
* @param {Array<string>} types
* @return {Promise<Object<Array<Object>>>}
*/
GLTFParser.prototype.getMultiDependencies = function ( types ) {
var results = {};
var pending = [];
for ( var i = 0, il = types.length; i < il; i ++ ) {
var type = types[ i ];
var value = this.getDependencies( type );
// TODO: Error-prone use of a callback inside a loop.
value = value.then( function ( key, value ) {
results[ key ] = value;
}.bind( this, type + ( type === 'mesh' ? 'es' : 's' ) ) );
pending.push( value );
}
return Promise.all( pending ).then( function () {
return results;
} );
};
/**
* Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
* @param {number} bufferIndex
......@@ -2327,6 +2208,18 @@ var GLTFLoader = ( function () {
return this.getDependency( 'texture', mapDef.index ).then( function ( texture ) {
switch ( mapName ) {
case 'aoMap':
case 'emissiveMap':
case 'metalnessMap':
case 'normalMap':
case 'roughnessMap':
texture.format = RGBFormat;
break;
}
if ( parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] ) {
var transform = mapDef.extensions !== undefined ? mapDef.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] : undefined;
......@@ -2345,6 +2238,124 @@ var GLTFLoader = ( function () {
};
/**
* Assigns final material to a Mesh, Line, or Points instance. The instance
* already has a material (generated from the glTF material options alone)
* but reuse of the same glTF material may require multiple threejs materials
* to accomodate different primitive types, defines, etc. New materials will
* be created if necessary, and reused from a cache.
* @param {Object3D} mesh Mesh, Line, or Points instance.
*/
GLTFParser.prototype.assignFinalMaterial = function ( mesh ) {
var geometry = mesh.geometry;
var material = mesh.material;
var extensions = this.extensions;
var useVertexTangents = geometry.attributes.tangent !== undefined;
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 ( mesh.isPoints ) {
var cacheKey = 'PointsMaterial:' + material.uuid;
var pointsMaterial = this.cache.get( cacheKey );
if ( ! pointsMaterial ) {
pointsMaterial = new PointsMaterial();
Material.prototype.copy.call( pointsMaterial, material );
pointsMaterial.color.copy( material.color );
pointsMaterial.map = material.map;
pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet
this.cache.add( cacheKey, pointsMaterial );
}
material = pointsMaterial;
} else if ( mesh.isLine ) {
var cacheKey = 'LineBasicMaterial:' + material.uuid;
var lineMaterial = this.cache.get( cacheKey );
if ( ! lineMaterial ) {
lineMaterial = new LineBasicMaterial();
Material.prototype.copy.call( lineMaterial, material );
lineMaterial.color.copy( material.color );
lineMaterial.lights = false; // LineBasicMaterial doesn't support lights yet
this.cache.add( cacheKey, lineMaterial );
}
material = lineMaterial;
}
// Clone the material if it will be modified
if ( useVertexTangents || useVertexColors || useFlatShading || useSkinning || useMorphTargets ) {
var cacheKey = 'ClonedMaterial:' + material.uuid + ':';
if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:';
if ( useSkinning ) cacheKey += 'skinning:';
if ( useVertexTangents ) cacheKey += 'vertex-tangents:';
if ( useVertexColors ) cacheKey += 'vertex-colors:';
if ( useFlatShading ) cacheKey += 'flat-shading:';
if ( useMorphTargets ) cacheKey += 'morph-targets:';
if ( useMorphNormals ) cacheKey += 'morph-normals:';
var cachedMaterial = this.cache.get( cacheKey );
if ( ! cachedMaterial ) {
cachedMaterial = material.isGLTFSpecularGlossinessMaterial
? extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].cloneMaterial( material )
: material.clone();
if ( useSkinning ) cachedMaterial.skinning = true;
if ( useVertexTangents ) cachedMaterial.vertexTangents = true;
if ( useVertexColors ) cachedMaterial.vertexColors = VertexColors;
if ( useFlatShading ) cachedMaterial.flatShading = true;
if ( useMorphTargets ) cachedMaterial.morphTargets = true;
if ( useMorphNormals ) cachedMaterial.morphNormals = true;
this.cache.add( cacheKey, cachedMaterial );
}
material = cachedMaterial;
}
// workarounds for mesh and geometry
if ( material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined ) {
console.log( 'THREE.GLTFLoader: Duplicating UVs to support aoMap.' );
geometry.addAttribute( 'uv2', new BufferAttribute( geometry.attributes.uv.array, 2 ) );
}
if ( material.isGLTFSpecularGlossinessMaterial ) {
// for GLTFSpecularGlossinessMaterial(ShaderMaterial) uniforms runtime update
mesh.onBeforeRender = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].refreshUniforms;
}
mesh.material = material;
};
/**
* Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials
* @param {number} materialIndex
......@@ -2492,14 +2503,6 @@ var GLTFLoader = ( function () {
if ( materialDef.name !== undefined ) material.name = materialDef.name;
// Normal map textures use OpenGL conventions:
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#materialnormaltexture
if ( material.normalScale ) {
material.normalScale.y = - material.normalScale.y;
}
// baseColorTexture, emissiveTexture, and specularGlossinessTexture use sRGB encoding.
if ( material.map ) material.map.encoding = sRGBEncoding;
if ( material.emissiveMap ) material.emissiveMap.encoding = sRGBEncoding;
......@@ -2540,9 +2543,7 @@ var GLTFLoader = ( function () {
for ( var gltfAttributeName in attributes ) {
var threeAttributeName = ATTRIBUTES[ gltfAttributeName ];
if ( ! threeAttributeName ) continue;
var threeAttributeName = ATTRIBUTES[ gltfAttributeName ] || gltfAttributeName.toLowerCase();
// Skip attributes already provided by e.g. Draco extension.
if ( threeAttributeName in geometry.attributes ) continue;
......@@ -2579,8 +2580,6 @@ var 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<GLTF.Primitive>} primitives
* @return {Promise<Array<BufferGeometry>>}
......@@ -2591,22 +2590,6 @@ var GLTFLoader = ( function () {
var extensions = this.extensions;
var cache = this.primitiveCache;
var isMultiPass = isMultiPassGeometry( primitives );
var originalPrimitives;
if ( isMultiPass ) {
originalPrimitives = primitives; // save original primitives and use later
// We build a single BufferGeometry with .groups from multiple primitives
// because all primitives share the same attributes/morph/mode and have indices.
primitives = [ primitives[ 0 ] ];
// Sets .groups and combined indices to a geometry later in this method.
}
function createDracoPrimitive( primitive ) {
return extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ]
......@@ -2624,14 +2607,15 @@ var GLTFLoader = ( function () {
for ( var i = 0, il = primitives.length; i < il; i ++ ) {
var primitive = primitives[ i ];
var cacheKey = createPrimitiveKey( primitive );
// See if we've already created this geometry
var cached = getCachedGeometry( cache, primitive );
var cached = cache[ cacheKey ];
if ( cached ) {
// Use the cached geometry if it exists
pending.push( cached );
pending.push( cached.promise );
} else {
......@@ -2650,7 +2634,7 @@ var GLTFLoader = ( function () {
}
// Cache this geometry
cache.push( { primitive: primitive, promise: geometryPromise } );
cache[ cacheKey ] = { primitive: primitive, promise: geometryPromise };
pending.push( geometryPromise );
......@@ -2658,95 +2642,7 @@ var GLTFLoader = ( function () {
}
return Promise.all( pending ).then( function ( geometries ) {
if ( isMultiPass ) {
var baseGeometry = geometries[ 0 ];
// See if we've already created this combined geometry
var cache = parser.multiPassGeometryCache;
var cached = getCachedMultiPassGeometry( cache, baseGeometry, originalPrimitives );
if ( cached !== null ) return [ cached.geometry ];
// Cloning geometry because of index override.
// Attributes can be reused so cloning by myself here.
var geometry = new BufferGeometry();
geometry.name = baseGeometry.name;
geometry.userData = baseGeometry.userData;
for ( var key in baseGeometry.attributes ) geometry.addAttribute( key, baseGeometry.attributes[ key ] );
for ( var key in baseGeometry.morphAttributes ) geometry.morphAttributes[ key ] = baseGeometry.morphAttributes[ key ];
var pendingIndices = [];
for ( var i = 0, il = originalPrimitives.length; i < il; i ++ ) {
pendingIndices.push( parser.getDependency( 'accessor', originalPrimitives[ i ].indices ) );
}
return Promise.all( pendingIndices ).then( function ( accessors ) {
var indices = [];
var offset = 0;
for ( var i = 0, il = originalPrimitives.length; i < il; i ++ ) {
var accessor = accessors[ 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 );
cache.push( { geometry: geometry, baseGeometry: baseGeometry, primitives: originalPrimitives } );
return [ geometry ];
} );
} else if ( geometries.length > 1 && BufferGeometryUtils !== undefined ) {
// Tries to merge geometries with BufferGeometryUtils if possible
for ( var i = 1, il = primitives.length; i < il; i ++ ) {
// can't merge if draw mode is different
if ( primitives[ 0 ].mode !== primitives[ i ].mode ) return geometries;
}
// See if we've already created this combined geometry
var cache = parser.multiplePrimitivesCache;
var cached = getCachedCombinedGeometry( cache, geometries );
if ( cached ) {
if ( cached.geometry !== null ) return [ cached.geometry ];
} else {
var geometry = BufferGeometryUtils.mergeBufferGeometries( geometries, true );
cache.push( { geometry: geometry, baseGeometries: geometries } );
if ( geometry !== null ) return [ geometry ];
}
}
return geometries;
} );
return Promise.all( pending );
};
......@@ -2780,8 +2676,6 @@ var GLTFLoader = ( function () {
return parser.loadGeometries( primitives ).then( function ( geometries ) {
var isMultiMaterial = geometries.length === 1 && geometries[ 0 ].groups.length > 0;
var meshes = [];
for ( var i = 0, il = geometries.length; i < il; i ++ ) {
......@@ -2793,7 +2687,7 @@ var GLTFLoader = ( function () {
var mesh;
var material = isMultiMaterial ? originalMaterials : originalMaterials[ i ];
var material = originalMaterials[ i ];
if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES ||
primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ||
......@@ -2851,118 +2745,9 @@ var GLTFLoader = ( function () {
assignExtrasToUserData( mesh, meshDef );
meshes.push( mesh );
parser.assignFinalMaterial( mesh );
// 2. update Material depending on Mesh and BufferGeometry
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;
for ( var j = 0, jl = materials.length; j < jl; j ++ ) {
var material = materials[ j ];
if ( mesh.isPoints ) {
var cacheKey = 'PointsMaterial:' + material.uuid;
var pointsMaterial = parser.cache.get( cacheKey );
if ( ! pointsMaterial ) {
pointsMaterial = new PointsMaterial();
Material.prototype.copy.call( pointsMaterial, material );
pointsMaterial.color.copy( material.color );
pointsMaterial.map = material.map;
pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet
parser.cache.add( cacheKey, pointsMaterial );
}
material = pointsMaterial;
} else if ( mesh.isLine ) {
var cacheKey = 'LineBasicMaterial:' + material.uuid;
var lineMaterial = parser.cache.get( cacheKey );
if ( ! lineMaterial ) {
lineMaterial = new LineBasicMaterial();
Material.prototype.copy.call( lineMaterial, material );
lineMaterial.color.copy( material.color );
lineMaterial.lights = false; // LineBasicMaterial doesn't support lights yet
parser.cache.add( cacheKey, lineMaterial );
}
material = lineMaterial;
}
// Clone the material if it will be modified
if ( useVertexColors || useFlatShading || useSkinning || useMorphTargets ) {
var cacheKey = 'ClonedMaterial:' + material.uuid + ':';
if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:';
if ( useSkinning ) cacheKey += 'skinning:';
if ( useVertexColors ) cacheKey += 'vertex-colors:';
if ( useFlatShading ) cacheKey += 'flat-shading:';
if ( useMorphTargets ) cacheKey += 'morph-targets:';
if ( useMorphNormals ) cacheKey += 'morph-normals:';
var cachedMaterial = parser.cache.get( cacheKey );
if ( ! cachedMaterial ) {
cachedMaterial = material.isGLTFSpecularGlossinessMaterial
? extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].cloneMaterial( material )
: material.clone();
if ( useSkinning ) cachedMaterial.skinning = true;
if ( useVertexColors ) cachedMaterial.vertexColors = VertexColors;
if ( useFlatShading ) cachedMaterial.flatShading = true;
if ( useMorphTargets ) cachedMaterial.morphTargets = true;
if ( useMorphNormals ) cachedMaterial.morphNormals = true;
parser.cache.add( cacheKey, cachedMaterial );
}
material = cachedMaterial;
}
materials[ j ] = material;
// workarounds for mesh and geometry
if ( material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined ) {
console.log( 'THREE.GLTFLoader: Duplicating UVs to support aoMap.' );
geometry.addAttribute( 'uv2', new BufferAttribute( geometry.attributes.uv.array, 2 ) );
}
if ( material.isGLTFSpecularGlossinessMaterial ) {
// for GLTFSpecularGlossinessMaterial(ShaderMaterial) uniforms runtime update
mesh.onBeforeRender = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].refreshUniforms;
}
}
mesh.material = isMultiMaterial ? materials : materials[ 0 ];
meshes.push( mesh );
}
......@@ -3147,10 +2932,7 @@ var GLTFLoader = ( function () {
if ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) {
// node can be Group here but
// PATH_PROPERTIES.weights(morphTargetInfluences) should be
// the property of a mesh object under group.
// Node may be a Group (glTF mesh with several primitives) or a Mesh.
node.traverse( function ( object ) {
if ( object.isMesh === true && object.morphTargetInfluences ) {
......@@ -3167,20 +2949,16 @@ var GLTFLoader = ( function () {
}
// KeyframeTrack.optimize() will modify given 'times' and 'values'
// buffers before creating a truncated copy to keep. Because buffers may
// be reused by other tracks, make copies here.
for ( var j = 0, jl = targetNames.length; j < jl; j ++ ) {
var track = new TypedKeyframeTrack(
targetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ],
AnimationUtils.arraySlice( inputAccessor.array, 0 ),
AnimationUtils.arraySlice( outputAccessor.array, 0 ),
inputAccessor.array,
outputAccessor.array,
interpolation
);
// Here is the trick to enable custom interpolation.
// Overrides .createInterpolant in a factory method which creates custom interpolation.
// Override interpolation with custom factory method.
if ( sampler.interpolation === 'CUBICSPLINE' ) {
track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) {
......@@ -3193,8 +2971,7 @@ var GLTFLoader = ( function () {
};
// Workaround, provide an alternate way to know if the interpolant type is cubis spline to track.
// track.getInterpolation() doesn't return valid value for custom interpolant.
// Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants.
track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册