From c73a491cb4fd82a26538913930c11477f03f690d Mon Sep 17 00:00:00 2001 From: tk Date: Wed, 5 Apr 2017 06:39:17 -0400 Subject: [PATCH 01/50] make Object3D properties (pos,rot,quat,scale) configurable to allow extensions by subclasses and proxies --- src/core/Object3D.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/Object3D.js b/src/core/Object3D.js index ef45f86a1b6cd5..ee53e2488f1f6e 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -53,18 +53,22 @@ function Object3D() { Object.defineProperties( this, { position: { + configurable: true, enumerable: true, value: position }, rotation: { + configurable: true, enumerable: true, value: rotation }, quaternion: { + configurable: true, enumerable: true, value: quaternion }, scale: { + configurable: true, enumerable: true, value: scale }, From bfb36dbefac79bdfbac2258b3e058bd3a0da175c Mon Sep 17 00:00:00 2001 From: Takahiro Date: Sat, 25 Aug 2018 07:58:10 +0900 Subject: [PATCH 02/50] GLTFLoader: Efficient load --- examples/js/loaders/GLTFLoader.js | 827 +++++++++++++++++------------- 1 file changed, 466 insertions(+), 361 deletions(-) diff --git a/examples/js/loaders/GLTFLoader.js b/examples/js/loaders/GLTFLoader.js index 59a4ebc26d8f36..95fbb025dbfa20 100644 --- a/examples/js/loaders/GLTFLoader.js +++ b/examples/js/loaders/GLTFLoader.js @@ -272,63 +272,61 @@ THREE.GLTFLoader = ( function () { this.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL; - this.lights = []; - var extension = ( json.extensions && json.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ] ) || {}; - var lightDefs = extension.lights || []; + this.lightDefs = extension.lights || []; - for ( var i = 0; i < lightDefs.length; i ++ ) { + } - var lightDef = lightDefs[ i ]; - var lightNode; + GLTFLightsExtension.prototype.loadLight = function ( lightIndex ) { - var color = new THREE.Color( 0xffffff ); - if ( lightDef.color !== undefined ) color.fromArray( lightDef.color ); + var lightDef = this.lightDefs[ lightIndex ]; + var lightNode; - var range = lightDef.range !== undefined ? lightDef.range : 0; + var color = new THREE.Color( 0xffffff ); + if ( lightDef.color !== undefined ) color.fromArray( lightDef.color ); - switch ( lightDef.type ) { + var range = lightDef.range !== undefined ? lightDef.range : 0; - case 'directional': - lightNode = new THREE.DirectionalLight( color ); - lightNode.target.position.set( 0, 0, 1 ); - lightNode.add( lightNode.target ); - break; + switch ( lightDef.type ) { - case 'point': - lightNode = new THREE.PointLight( color ); - lightNode.distance = range; - break; + case 'directional': + lightNode = new THREE.DirectionalLight( color ); + lightNode.target.position.set( 0, 0, 1 ); + lightNode.add( lightNode.target ); + break; - case 'spot': - lightNode = new THREE.SpotLight( color ); - lightNode.distance = range; - // Handle spotlight properties. - lightDef.spot = lightDef.spot || {}; - lightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0; - lightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0; - lightNode.angle = lightDef.spot.outerConeAngle; - lightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle; - lightNode.target.position.set( 0, 0, 1 ); - lightNode.add( lightNode.target ); - break; + case 'point': + lightNode = new THREE.PointLight( color ); + lightNode.distance = range; + break; - default: - throw new Error( 'THREE.GLTFLoader: Unexpected light type, "' + lightDef.type + '".' ); + case 'spot': + lightNode = new THREE.SpotLight( color ); + lightNode.distance = range; + // Handle spotlight properties. + lightDef.spot = lightDef.spot || {}; + lightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0; + lightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0; + lightNode.angle = lightDef.spot.outerConeAngle; + lightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle; + lightNode.target.position.set( 0, 0, 1 ); + lightNode.add( lightNode.target ); + break; - } + default: + throw new Error( 'THREE.GLTFLoader: Unexpected light type, "' + lightDef.type + '".' ); - lightNode.decay = 2; + } - if ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity; + lightNode.decay = 2; - lightNode.name = lightDef.name || ( 'light_' + i ); + if ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity; - this.lights.push( lightNode ); + lightNode.name = lightDef.name || ( 'light_' + lightIndex ); - } + return Promise.resolve( lightNode ); - } + }; /** * Unlit Materials Extension (pending) @@ -349,7 +347,7 @@ THREE.GLTFLoader = ( function () { GLTFMaterialsUnlitExtension.prototype.extendParams = function ( materialParams, material, parser ) { - var pending = []; + var pendings = []; materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 ); materialParams.opacity = 1.0; @@ -369,13 +367,13 @@ THREE.GLTFLoader = ( function () { if ( metallicRoughness.baseColorTexture !== undefined ) { - pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture.index ) ); + pendings.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture.index ) ); } } - return Promise.all( pending ); + return Promise.all( pendings ); }; @@ -639,7 +637,7 @@ THREE.GLTFLoader = ( function () { params.color = new THREE.Color( 1.0, 1.0, 1.0 ); params.opacity = 1.0; - var pending = []; + var pendings = []; if ( Array.isArray( pbrSpecularGlossiness.diffuseFactor ) ) { @@ -652,7 +650,7 @@ THREE.GLTFLoader = ( function () { if ( pbrSpecularGlossiness.diffuseTexture !== undefined ) { - pending.push( parser.assignTexture( params, 'map', pbrSpecularGlossiness.diffuseTexture.index ) ); + pendings.push( parser.assignTexture( params, 'map', pbrSpecularGlossiness.diffuseTexture.index ) ); } @@ -669,12 +667,12 @@ THREE.GLTFLoader = ( function () { if ( pbrSpecularGlossiness.specularGlossinessTexture !== undefined ) { var specGlossIndex = pbrSpecularGlossiness.specularGlossinessTexture.index; - pending.push( parser.assignTexture( params, 'glossinessMap', specGlossIndex ) ); - pending.push( parser.assignTexture( params, 'specularMap', specGlossIndex ) ); + pendings.push( parser.assignTexture( params, 'glossinessMap', specGlossIndex ) ); + pendings.push( parser.assignTexture( params, 'specularMap', specGlossIndex ) ); } - return Promise.all( pending ); + return Promise.all( pendings ); }, @@ -1201,7 +1199,7 @@ THREE.GLTFLoader = ( function () { /** * @param {THREE.Object3D|THREE.Material|THREE.BufferGeometry} object - * @param {GLTF.definition} def + * @param {GLTF.definition} gltfDef */ function assignExtrasToUserData( object, gltfDef ) { @@ -1226,9 +1224,10 @@ THREE.GLTFLoader = ( function () { * * @param {THREE.BufferGeometry} geometry * @param {Array} targets - * @param {Array} accessors + * @param {GLTFParser} parser + * @return {Promise} */ - function addMorphTargets( geometry, targets, accessors ) { + function addMorphTargets( geometry, targets, parser ) { var hasMorphPosition = false; var hasMorphNormal = false; @@ -1244,97 +1243,127 @@ THREE.GLTFLoader = ( function () { } - if ( ! hasMorphPosition && ! hasMorphNormal ) return; + if ( ! hasMorphPosition && ! hasMorphNormal ) return Promise.resolve( geometry ); - var morphPositions = []; - var morphNormals = []; + var positionAccessorPendings = []; + var normalAccessorPendings = []; for ( var i = 0, il = targets.length; i < il; i ++ ) { var target = targets[ i ]; - var attributeName = 'morphTarget' + i; if ( hasMorphPosition ) { - // Three.js morph position is absolute value. The formula is - // basePosition - // + weight0 * ( morphPosition0 - basePosition ) - // + weight1 * ( morphPosition1 - basePosition ) - // ... - // while the glTF one is relative - // basePosition - // + weight0 * glTFmorphPosition0 - // + weight1 * glTFmorphPosition1 - // ... - // then we need to convert from relative to absolute here. + positionAccessorPendings.push( + target.POSITION !== undefined + ? parser.getDependency( 'accessor', target.POSITION ) + .then( function ( accessor ) { + // Cloning not to pollute original accessor below + return cloneBufferAttribute( accessor ); + } ) + : geometry.attributes.position + ); - if ( target.POSITION !== undefined ) { + } - // Cloning not to pollute original accessor - var positionAttribute = cloneBufferAttribute( accessors[ target.POSITION ] ); - positionAttribute.name = attributeName; + if ( hasMorphNormal ) { - var position = geometry.attributes.position; + normalAccessorPendings.push( + target.NORMAL !== undefined + ? parser.getDependency( 'accessor', target.NORMAL ) + .then( function ( accessor ) { + return cloneBufferAttribute( accessor ); + } ) + : geometry.attributes.normal + ); - for ( var j = 0, jl = positionAttribute.count; j < jl; j ++ ) { + } - positionAttribute.setXYZ( - j, - positionAttribute.getX( j ) + position.getX( j ), - positionAttribute.getY( j ) + position.getY( j ), - positionAttribute.getZ( j ) + position.getZ( j ) - ); + } - } + return Promise.all( [ + Promise.all( positionAccessorPendings ), + Promise.all( normalAccessorPendings ) + ] ).then( function ( accessors ) { - } else { + var morphPositions = accessors[ 0 ]; + var morphNormals = accessors[ 1 ]; - positionAttribute = geometry.attributes.position; + for ( var i = 0, il = targets.length; i < il; i ++ ) { - } + var target = targets[ i ]; + var attributeName = 'morphTarget' + i; - morphPositions.push( positionAttribute ); + if ( hasMorphPosition ) { - } + // Three.js morph position is absolute value. The formula is + // basePosition + // + weight0 * ( morphPosition0 - basePosition ) + // + weight1 * ( morphPosition1 - basePosition ) + // ... + // while the glTF one is relative + // basePosition + // + weight0 * glTFmorphPosition0 + // + weight1 * glTFmorphPosition1 + // ... + // then we need to convert from relative to absolute here. - if ( hasMorphNormal ) { + if ( target.POSITION !== undefined ) { - // see target.POSITION's comment + var positionAttribute = morphPositions[ i ]; + positionAttribute.name = attributeName; - var normalAttribute; + var position = geometry.attributes.position; - if ( target.NORMAL !== undefined ) { + for ( var j = 0, jl = positionAttribute.count; j < jl; j ++ ) { - var normalAttribute = cloneBufferAttribute( accessors[ target.NORMAL ] ); - normalAttribute.name = attributeName; + positionAttribute.setXYZ( + j, + positionAttribute.getX( j ) + position.getX( j ), + positionAttribute.getY( j ) + position.getY( j ), + positionAttribute.getZ( j ) + position.getZ( j ) + ); - var normal = geometry.attributes.normal; + } - for ( var j = 0, jl = normalAttribute.count; j < jl; j ++ ) { + } - normalAttribute.setXYZ( - j, - normalAttribute.getX( j ) + normal.getX( j ), - normalAttribute.getY( j ) + normal.getY( j ), - normalAttribute.getZ( j ) + normal.getZ( j ) - ); + } - } + if ( hasMorphNormal ) { - } else { + // see target.POSITION's comment - normalAttribute = geometry.attributes.normal; + if ( target.NORMAL !== undefined ) { - } + var normalAttribute = morphNormals[ i ]; + normalAttribute.name = attributeName; + + var normal = geometry.attributes.normal; - morphNormals.push( normalAttribute ); + for ( var j = 0, jl = normalAttribute.count; j < jl; j ++ ) { + + normalAttribute.setXYZ( + j, + normalAttribute.getX( j ) + normal.getX( j ), + normalAttribute.getY( j ) + normal.getY( j ), + normalAttribute.getZ( j ) + normal.getZ( j ) + ); + + } + + } + + } } - } + if ( hasMorphPosition ) geometry.morphAttributes.position = morphPositions; + if ( hasMorphNormal ) geometry.morphAttributes.normal = morphNormals; + + return geometry; - if ( hasMorphPosition ) geometry.morphAttributes.position = morphPositions; - if ( hasMorphNormal ) geometry.morphAttributes.normal = morphNormals; + } ); } @@ -1650,7 +1679,7 @@ THREE.GLTFLoader = ( function () { * Requests the specified dependency asynchronously, with caching. * @param {string} type * @param {number} index - * @return {Promise} + * @return {Promise} */ GLTFParser.prototype.getDependency = function ( type, index ) { @@ -1705,6 +1734,10 @@ THREE.GLTFLoader = ( function () { dependency = this.loadCamera( index ); break; + case 'light': + dependency = this.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].loadLight( index ); + break + default: throw new Error( 'Unknown type: ' + type ); @@ -2073,7 +2106,7 @@ THREE.GLTFLoader = ( function () { * @param {Object} materialParams * @param {string} textureName * @param {number} textureIndex - * @return {Promise} + * @return {Promise} */ GLTFParser.prototype.assignTexture = function ( materialParams, textureName, textureIndex ) { @@ -2081,6 +2114,8 @@ THREE.GLTFLoader = ( function () { materialParams[ textureName ] = texture; + return texture; + } ); }; @@ -2101,19 +2136,19 @@ THREE.GLTFLoader = ( function () { var materialParams = {}; var materialExtensions = materialDef.extensions || {}; - var pending = []; + var pendings = []; if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] ) { var sgExtension = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ]; materialType = sgExtension.getMaterialType( materialDef ); - pending.push( sgExtension.extendParams( materialParams, materialDef, parser ) ); + pendings.push( sgExtension.extendParams( materialParams, materialDef, parser ) ); } else if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) { var kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ]; materialType = kmuExtension.getMaterialType( materialDef ); - pending.push( kmuExtension.extendParams( materialParams, materialDef, parser ) ); + pendings.push( kmuExtension.extendParams( materialParams, materialDef, parser ) ); } else { @@ -2138,7 +2173,7 @@ THREE.GLTFLoader = ( function () { if ( metallicRoughness.baseColorTexture !== undefined ) { - pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture.index ) ); + pendings.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture.index ) ); } @@ -2148,8 +2183,8 @@ THREE.GLTFLoader = ( function () { if ( metallicRoughness.metallicRoughnessTexture !== undefined ) { var textureIndex = metallicRoughness.metallicRoughnessTexture.index; - pending.push( parser.assignTexture( materialParams, 'metalnessMap', textureIndex ) ); - pending.push( parser.assignTexture( materialParams, 'roughnessMap', textureIndex ) ); + pendings.push( parser.assignTexture( materialParams, 'metalnessMap', textureIndex ) ); + pendings.push( parser.assignTexture( materialParams, 'roughnessMap', textureIndex ) ); } @@ -2181,7 +2216,7 @@ THREE.GLTFLoader = ( function () { if ( materialDef.normalTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { - pending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture.index ) ); + pendings.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture.index ) ); materialParams.normalScale = new THREE.Vector2( 1, 1 ); @@ -2195,7 +2230,7 @@ THREE.GLTFLoader = ( function () { if ( materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { - pending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture.index ) ); + pendings.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture.index ) ); if ( materialDef.occlusionTexture.strength !== undefined ) { @@ -2213,11 +2248,11 @@ THREE.GLTFLoader = ( function () { if ( materialDef.emissiveTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { - pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture.index ) ); + pendings.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture.index ) ); } - return Promise.all( pending ).then( function () { + return Promise.all( pendings ).then( function () { var material; @@ -2257,41 +2292,64 @@ THREE.GLTFLoader = ( function () { }; /** - * @param {THREE.BufferGeometry} geometry - * @param {GLTF.Primitive} primitiveDef - * @param {Array} accessors + * @param {THREE.BufferGeometry} geometry + * @param {GLTF.Primitive} primitiveDef + * @param {GLTFParser} parser + * @return {Promise} */ - function addPrimitiveAttributes( geometry, primitiveDef, accessors ) { + function addPrimitiveAttributes( geometry, primitiveDef, parser ) { var attributes = primitiveDef.attributes; + var pendings = []; + + function loadAttributeAccessor( accessorIndex, attributeName ) { + + return parser.getDependency( 'accessor', accessorIndex ) + .then( function ( accessor ) { + + geometry.addAttribute( attributeName, accessor ); + + } ); + + } + for ( var gltfAttributeName in attributes ) { var threeAttributeName = ATTRIBUTES[ gltfAttributeName ]; - var bufferAttribute = accessors[ attributes[ gltfAttributeName ] ]; - // Skip attributes already provided by e.g. Draco extension. if ( ! threeAttributeName ) continue; + + // Skip attributes already provided by e.g. Draco extension. if ( threeAttributeName in geometry.attributes ) continue; - geometry.addAttribute( threeAttributeName, bufferAttribute ); + pendings.push( loadAttributeAccessor( attributes[ gltfAttributeName ], threeAttributeName ) ); } if ( primitiveDef.indices !== undefined && ! geometry.index ) { - geometry.setIndex( accessors[ primitiveDef.indices ] ); + pendings.push( + parser.getDependency( 'accessor', primitiveDef.indices ) + .then( function ( accessor ) { - } + geometry.setIndex( accessor ); - if ( primitiveDef.targets !== undefined ) { - - addMorphTargets( geometry, primitiveDef.targets, accessors ); + } ) + ); } assignExtrasToUserData( geometry, primitiveDef ); + return Promise.all( pendings ).then( function () { + + return primitiveDef.targets !== undefined + ? addMorphTargets( geometry, primitiveDef.targets, parser ) + : geometry; + + } ); + } /** @@ -2301,7 +2359,7 @@ THREE.GLTFLoader = ( function () { * 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} primitives + * @param {Array} primitives * @return {Promise>} */ GLTFParser.prototype.loadGeometries = function ( primitives ) { @@ -2326,85 +2384,89 @@ THREE.GLTFLoader = ( function () { } - return this.getDependencies( 'accessor' ).then( function ( accessors ) { + var pendings = []; - var pending = []; + for ( var i = 0, il = primitives.length; i < il; i ++ ) { - for ( var i = 0, il = primitives.length; i < il; i ++ ) { + var primitive = primitives[ i ]; - var primitive = primitives[ i ]; + // See if we've already created this geometry + var cached = getCachedGeometry( cache, primitive ); - // See if we've already created this geometry - var cached = getCachedGeometry( cache, primitive ); + if ( cached ) { - if ( cached ) { + // Use the cached geometry if it exists + pendings.push( cached ); + + } else { - // Use the cached geometry if it exists - pending.push( cached ); + var geometryPromise; - } else if ( primitive.extensions && primitive.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] ) { + if ( primitive.extensions && primitive.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] ) { // Use DRACO geometry if available - var geometryPromise = extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] + geometryPromise = extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] .decodePrimitive( primitive, parser ) .then( function ( geometry ) { - addPrimitiveAttributes( geometry, primitive, accessors ); - - return geometry; + return addPrimitiveAttributes( geometry, primitive, parser ); } ); - cache.push( { primitive: primitive, promise: geometryPromise } ); - - pending.push( geometryPromise ); - } else { // Otherwise create a new geometry - var geometry = new THREE.BufferGeometry(); + geometryPromise = addPrimitiveAttributes( new THREE.BufferGeometry(), primitive, parser ); + + } - addPrimitiveAttributes( geometry, primitive, accessors ); + // Cache this geometry + cache.push( { primitive: primitive, promise: geometryPromise } ); - var geometryPromise = Promise.resolve( geometry ); + pendings.push( geometryPromise ); - // Cache this geometry - cache.push( { primitive: primitive, promise: geometryPromise } ); + } - pending.push( geometryPromise ); + } - } + return Promise.all( pendings ).then( function ( geometries ) { - } + if ( isMultiPass ) { + + var baseGeometry = geometries[ 0 ]; - return Promise.all( pending ).then( function ( geometries ) { + // See if we've already created this combined geometry + var cache = parser.multiPassGeometryCache; + var cached = getCachedMultiPassGeometry( cache, baseGeometry, originalPrimitives ); - if ( isMultiPass ) { + if ( cached !== null ) return [ cached.geometry ]; - var baseGeometry = geometries[ 0 ]; + // Cloning geometry because of index override. + // Attributes can be reused so cloning by myself here. + var geometry = new THREE.BufferGeometry(); - // See if we've already created this combined geometry - var cache = parser.multiPassGeometryCache; - var cached = getCachedMultiPassGeometry( cache, baseGeometry, originalPrimitives ); + geometry.name = baseGeometry.name; + geometry.userData = baseGeometry.userData; - if ( cached !== null ) return [ cached.geometry ]; + for ( var key in baseGeometry.attributes ) geometry.addAttribute( key, baseGeometry.attributes[ key ] ); + for ( var key in baseGeometry.morphAttributes ) geometry.morphAttributes[ key ] = baseGeometry.morphAttributes[ key ]; - // Cloning geometry because of index override. - // Attributes can be reused so cloning by myself here. - var geometry = new THREE.BufferGeometry(); + var pendingIndices = []; - geometry.name = baseGeometry.name; - geometry.userData = baseGeometry.userData; + for ( var i = 0, il = originalPrimitives.length; i < il; i ++ ) { - for ( var key in baseGeometry.attributes ) geometry.addAttribute( key, baseGeometry.attributes[ key ] ); - for ( var key in baseGeometry.morphAttributes ) geometry.morphAttributes[ key ] = baseGeometry.morphAttributes[ key ]; + 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[ originalPrimitives[ i ].indices ]; + var accessor = accessors[ i ]; for ( var j = 0, jl = accessor.count; j < jl; j ++ ) indices.push( accessor.array[ j ] ); @@ -2420,40 +2482,40 @@ THREE.GLTFLoader = ( function () { return [ geometry ]; - } else if ( geometries.length > 1 && THREE.BufferGeometryUtils !== undefined ) { + } ); - // Tries to merge geometries with BufferGeometryUtils if possible + } else if ( geometries.length > 1 && THREE.BufferGeometryUtils !== undefined ) { - for ( var i = 1, il = primitives.length; i < il; i ++ ) { + // Tries to merge geometries with BufferGeometryUtils if possible - // can't merge if draw mode is different - if ( primitives[ 0 ].mode !== primitives[ i ].mode ) return geometries; + 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 ) { + // See if we've already created this combined geometry + var cache = parser.multiplePrimitivesCache; + var cached = getCachedCombinedGeometry( cache, geometries ); - if ( cached.geometry !== null ) return [ cached.geometry ]; + if ( cached ) { - } else { + if ( cached.geometry !== null ) return [ cached.geometry ]; - var geometry = THREE.BufferGeometryUtils.mergeBufferGeometries( geometries, true ); + } else { - cache.push( { geometry: geometry, baseGeometries: geometries } ); + var geometry = THREE.BufferGeometryUtils.mergeBufferGeometries( geometries, true ); - if ( geometry !== null ) return [ geometry ]; + cache.push( { geometry: geometry, baseGeometries: geometries } ); - } + if ( geometry !== null ) return [ geometry ]; } - return geometries; + } - } ); + return geometries; } ); @@ -2466,31 +2528,28 @@ THREE.GLTFLoader = ( function () { */ GLTFParser.prototype.loadMesh = function ( meshIndex ) { - var scope = this; + var parser = this; var json = this.json; var extensions = this.extensions; var meshDef = json.meshes[ meshIndex ]; + var primitives = meshDef.primitives; - return this.getMultiDependencies( [ - - 'accessor', - 'material' - - ] ).then( function ( dependencies ) { - - var primitives = meshDef.primitives; - var originalMaterials = []; + var pendings = []; - for ( var i = 0, il = primitives.length; i < il; i ++ ) { + for ( var i = 0, il = primitives.length; i < il; i ++ ) { - originalMaterials[ i ] = primitives[ i ].material === undefined + pendings.push( + primitives[ i ].material === undefined ? createDefaultMaterial() - : dependencies.materials[ primitives[ i ].material ]; + : this.getDependency( 'material', primitives[ i ].material ) + ); - } + } + + return Promise.all( pendings ).then( function ( originalMaterials ) { - return scope.loadGeometries( primitives ).then( function ( geometries ) { + return parser.loadGeometries( primitives ).then( function ( geometries ) { var isMultiMaterial = geometries.length === 1 && geometries[ 0 ].groups.length > 0; @@ -2581,7 +2640,7 @@ THREE.GLTFLoader = ( function () { var cacheKey = 'PointsMaterial:' + material.uuid; - var pointsMaterial = scope.cache.get( cacheKey ); + var pointsMaterial = parser.cache.get( cacheKey ); if ( ! pointsMaterial ) { @@ -2591,7 +2650,7 @@ THREE.GLTFLoader = ( function () { pointsMaterial.map = material.map; pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet - scope.cache.add( cacheKey, pointsMaterial ); + parser.cache.add( cacheKey, pointsMaterial ); } @@ -2601,7 +2660,7 @@ THREE.GLTFLoader = ( function () { var cacheKey = 'LineBasicMaterial:' + material.uuid; - var lineMaterial = scope.cache.get( cacheKey ); + var lineMaterial = parser.cache.get( cacheKey ); if ( ! lineMaterial ) { @@ -2610,7 +2669,7 @@ THREE.GLTFLoader = ( function () { lineMaterial.color.copy( material.color ); lineMaterial.lights = false; // LineBasicMaterial doesn't support lights yet - scope.cache.add( cacheKey, lineMaterial ); + parser.cache.add( cacheKey, lineMaterial ); } @@ -2630,7 +2689,7 @@ THREE.GLTFLoader = ( function () { if ( useMorphTargets ) cacheKey += 'morph-targets:'; if ( useMorphNormals ) cacheKey += 'morph-normals:'; - var cachedMaterial = scope.cache.get( cacheKey ); + var cachedMaterial = parser.cache.get( cacheKey ); if ( ! cachedMaterial ) { @@ -2644,7 +2703,7 @@ THREE.GLTFLoader = ( function () { if ( useMorphTargets ) cachedMaterial.morphTargets = true; if ( useMorphNormals ) cachedMaterial.morphNormals = true; - scope.cache.add( cacheKey, cachedMaterial ); + parser.cache.add( cacheKey, cachedMaterial ); } @@ -2772,126 +2831,148 @@ THREE.GLTFLoader = ( function () { var animationDef = json.animations[ animationIndex ]; - return this.getMultiDependencies( [ + var nodePendings = []; + var inputAccessorPendings = []; + var outputAccessorPendings = []; + var samplerPendings = []; + var targetPendings = []; - 'accessor', - 'node' + for ( var i = 0, il = animationDef.channels.length; i < il; i ++ ) { - ] ).then( function ( dependencies ) { + var channel = animationDef.channels[ i ]; + var sampler = animationDef.samplers[ channel.sampler ]; - var tracks = []; + if ( sampler === undefined ) continue; - for ( var i = 0, il = animationDef.channels.length; i < il; i ++ ) { + var target = channel.target; + var name = target.node !== undefined ? target.node : target.id; // NOTE: target.id is deprecated. + var input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input; + var output = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.output ] : sampler.output; - var channel = animationDef.channels[ i ]; - var sampler = animationDef.samplers[ channel.sampler ]; + nodePendings.push( this.getDependency( 'node', name ) ); + inputAccessorPendings.push( this.getDependency( 'accessor', input ) ); + outputAccessorPendings.push( this.getDependency( 'accessor', output ) ); + samplerPendings.push( sampler ); + targetPendings.push( target ); - if ( sampler ) { + } - var target = channel.target; - var name = target.node !== undefined ? target.node : target.id; // NOTE: target.id is deprecated. - var input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input; - var output = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.output ] : sampler.output; + return Promise.all( [ - var inputAccessor = dependencies.accessors[ input ]; - var outputAccessor = dependencies.accessors[ output ]; + Promise.all( nodePendings ), + Promise.all( inputAccessorPendings ), + Promise.all( outputAccessorPendings ), + Promise.all( samplerPendings ), + Promise.all( targetPendings ) - var node = dependencies.nodes[ name ]; + ] ).then( function ( dependencies ) { - if ( node ) { + var nodes = dependencies[ 0 ]; + var inputAccessors = dependencies[ 1 ]; + var outputAccessors = dependencies[ 2 ]; + var samplers = dependencies[ 3 ]; + var targets = dependencies[ 4 ]; - node.updateMatrix(); - node.matrixAutoUpdate = true; + var tracks = []; - var TypedKeyframeTrack; + for ( var i = 0, il = nodes.length; i < il; i ++ ) { - switch ( PATH_PROPERTIES[ target.path ] ) { + var node = nodes[ i ]; + var inputAccessor = inputAccessors[ i ]; + var outputAccessor = outputAccessors[ i ]; + var sampler = samplers[ i ]; + var target = targets[ i ]; - case PATH_PROPERTIES.weights: + if ( node === undefined ) continue; - TypedKeyframeTrack = THREE.NumberKeyframeTrack; - break; + node.updateMatrix(); + node.matrixAutoUpdate = true; - case PATH_PROPERTIES.rotation: + var TypedKeyframeTrack; - TypedKeyframeTrack = THREE.QuaternionKeyframeTrack; - break; + switch ( PATH_PROPERTIES[ target.path ] ) { - case PATH_PROPERTIES.position: - case PATH_PROPERTIES.scale: - default: + case PATH_PROPERTIES.weights: - TypedKeyframeTrack = THREE.VectorKeyframeTrack; - break; + TypedKeyframeTrack = THREE.NumberKeyframeTrack; + break; - } + case PATH_PROPERTIES.rotation: - var targetName = node.name ? node.name : node.uuid; + TypedKeyframeTrack = THREE.QuaternionKeyframeTrack; + break; - var interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : THREE.InterpolateLinear; + case PATH_PROPERTIES.position: + case PATH_PROPERTIES.scale: + default: - var targetNames = []; + TypedKeyframeTrack = THREE.VectorKeyframeTrack; + break; - if ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) { + } - // node can be THREE.Group here but - // PATH_PROPERTIES.weights(morphTargetInfluences) should be - // the property of a mesh object under group. + var targetName = node.name ? node.name : node.uuid; - node.traverse( function ( object ) { + var interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : THREE.InterpolateLinear; - if ( object.isMesh === true && object.morphTargetInfluences ) { + var targetNames = []; - targetNames.push( object.name ? object.name : object.uuid ); + if ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) { - } + // node can be THREE.Group here but + // PATH_PROPERTIES.weights(morphTargetInfluences) should be + // the property of a mesh object under group. - } ); + node.traverse( function ( object ) { - } else { + if ( object.isMesh === true && object.morphTargetInfluences ) { - targetNames.push( targetName ); + targetNames.push( object.name ? object.name : object.uuid ); } - // 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 ], - THREE.AnimationUtils.arraySlice( inputAccessor.array, 0 ), - THREE.AnimationUtils.arraySlice( outputAccessor.array, 0 ), - interpolation - ); + } else { - // Here is the trick to enable custom interpolation. - // Overrides .createInterpolant in a factory method which creates custom interpolation. - if ( sampler.interpolation === 'CUBICSPLINE' ) { + targetNames.push( targetName ); - track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) { + } - // A CUBICSPLINE keyframe in glTF has three output values for each input value, - // representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize() - // must be divided by three to get the interpolant's sampleSize argument. + // 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 ++ ) { - return new GLTFCubicSplineInterpolant( this.times, this.values, this.getValueSize() / 3, result ); + var track = new TypedKeyframeTrack( + targetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ], + THREE.AnimationUtils.arraySlice( inputAccessor.array, 0 ), + THREE.AnimationUtils.arraySlice( outputAccessor.array, 0 ), + interpolation + ); - }; + // Here is the trick to enable custom interpolation. + // Overrides .createInterpolant in a factory method which creates custom interpolation. + if ( sampler.interpolation === 'CUBICSPLINE' ) { - // 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. - track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true; + track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) { - } + // A CUBICSPLINE keyframe in glTF has three output values for each input value, + // representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize() + // must be divided by three to get the interpolant's sampleSize argument. - tracks.push( track ); + return new GLTFCubicSplineInterpolant( this.times, this.values, this.getValueSize() / 3, result ); - } + }; + + // 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. + track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true; } + tracks.push( track ); + } } @@ -2913,72 +2994,71 @@ THREE.GLTFLoader = ( function () { var json = this.json; var extensions = this.extensions; + var parser = this; var meshReferences = json.meshReferences; var meshUses = json.meshUses; var nodeDef = json.nodes[ nodeIndex ]; - return this.getMultiDependencies( [ - - 'mesh', - 'skin', - 'camera', - 'light' - - ] ).then( function ( dependencies ) { - - var node; + return new Promise( function ( resolve ) { // .isBone isn't in glTF spec. See .markDefs if ( nodeDef.isBone === true ) { - node = new THREE.Bone(); + resolve( new THREE.Bone() ); } else if ( nodeDef.mesh !== undefined ) { - var mesh = dependencies.meshes[ nodeDef.mesh ]; + parser.getDependency( 'mesh', nodeDef.mesh ).then( function ( mesh ) { - if ( meshReferences[ nodeDef.mesh ] > 1 ) { + var node; - var instanceNum = meshUses[ nodeDef.mesh ] ++; + if ( meshReferences[ nodeDef.mesh ] > 1 ) { - node = mesh.clone(); - node.name += '_instance_' + instanceNum; + var instanceNum = meshUses[ nodeDef.mesh ] ++; - // onBeforeRender copy for Specular-Glossiness - node.onBeforeRender = mesh.onBeforeRender; + node = mesh.clone(); + node.name += '_instance_' + instanceNum; - for ( var i = 0, il = node.children.length; i < il; i ++ ) { + // onBeforeRender copy for Specular-Glossiness + node.onBeforeRender = mesh.onBeforeRender; - node.children[ i ].name += '_instance_' + instanceNum; - node.children[ i ].onBeforeRender = mesh.children[ i ].onBeforeRender; + for ( var i = 0, il = node.children.length; i < il; i ++ ) { - } + node.children[ i ].name += '_instance_' + instanceNum; + node.children[ i ].onBeforeRender = mesh.children[ i ].onBeforeRender; - } else { + } + + } else { - node = mesh; + node = mesh; - } + } + + resolve( node ); + + } ); } else if ( nodeDef.camera !== undefined ) { - node = dependencies.cameras[ nodeDef.camera ]; + parser.getDependency( 'camera', nodeDef.camera ).then( resolve ); } else if ( nodeDef.extensions - && nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ] - && nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light !== undefined ) { + && nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ] + && nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light !== undefined ) { - var lights = extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].lights; - node = lights[ nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light ]; + parser.getDependency( 'light', nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light ).then( resolve ); } else { - node = new THREE.Object3D(); + resolve( new THREE.Object3D() ); } + } ).then( function ( node ) { + if ( nodeDef.name !== undefined ) { node.name = THREE.PropertyBinding.sanitizeNodeName( nodeDef.name ); @@ -3032,74 +3112,101 @@ THREE.GLTFLoader = ( function () { // scene node hierachy builder - function buildNodeHierachy( nodeId, parentObject, json, allNodes, skins ) { + function buildNodeHierachy( nodeId, parentObject, json, parser ) { - var node = allNodes[ nodeId ]; var nodeDef = json.nodes[ nodeId ]; - // build skeleton here as well + return parser.getDependency( 'node', nodeId ).then( function ( node ) { - if ( nodeDef.skin !== undefined ) { + if ( nodeDef.skin === undefined ) return node; - var meshes = node.isGroup === true ? node.children : [ node ]; + // build skeleton here as well - for ( var i = 0, il = meshes.length; i < il; i ++ ) { + var skinEntry; - var mesh = meshes[ i ]; - var skinEntry = skins[ nodeDef.skin ]; + return parser.getDependency( 'skin', nodeDef.skin ).then( function ( skin ) { - var bones = []; - var boneInverses = []; + skinEntry = skin; - for ( var j = 0, jl = skinEntry.joints.length; j < jl; j ++ ) { + var jointPendings = []; - var jointId = skinEntry.joints[ j ]; - var jointNode = allNodes[ jointId ]; + for ( var i = 0, il = skinEntry.joints.length; i < il; i ++ ) { - if ( jointNode ) { + jointPendings.push( parser.getDependency( 'node', skinEntry.joints[ i ] ) ); - bones.push( jointNode ); + } - var mat = new THREE.Matrix4(); + return Promise.all( jointPendings ); - if ( skinEntry.inverseBindMatrices !== undefined ) { + } ).then( function ( jointNodes ) { - mat.fromArray( skinEntry.inverseBindMatrices.array, j * 16 ); + var meshes = node.isGroup === true ? node.children : [ node ]; - } + for ( var i = 0, il = meshes.length; i < il; i ++ ) { + + var mesh = meshes[ i ]; + + var bones = []; + var boneInverses = []; + + for ( var j = 0, jl = jointNodes.length; j < jl; j ++ ) { - boneInverses.push( mat ); + var jointNode = jointNodes[ j ]; - } else { + if ( jointNode ) { - console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', jointId ); + bones.push( jointNode ); + + var mat = new THREE.Matrix4(); + + if ( skinEntry.inverseBindMatrices !== undefined ) { + + mat.fromArray( skinEntry.inverseBindMatrices.array, j * 16 ); + + } + + boneInverses.push( mat ); + + } else { + + console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', skinEntry.joints[ j ] ); + + } } - } + mesh.bind( new THREE.Skeleton( bones, boneInverses ), mesh.matrixWorld ); - mesh.bind( new THREE.Skeleton( bones, boneInverses ), mesh.matrixWorld ); + }; - } + return node; - } + } ); + + } ).then( function ( node ) { - // build node hierachy + // build node hierachy - parentObject.add( node ); + parentObject.add( node ); - if ( nodeDef.children ) { + var pendings = []; - var children = nodeDef.children; + if ( nodeDef.children ) { - for ( var i = 0, il = children.length; i < il; i ++ ) { + var children = nodeDef.children; - var child = children[ i ]; - buildNodeHierachy( child, node, json, allNodes, skins ); + for ( var i = 0, il = children.length; i < il; i ++ ) { + + var child = children[ i ]; + pendings.push( buildNodeHierachy( child, node, json, parser ) ); + + } } - } + return Promise.all( pendings ); + + } ); } @@ -3108,28 +3215,26 @@ THREE.GLTFLoader = ( function () { var json = this.json; var extensions = this.extensions; var sceneDef = this.json.scenes[ sceneIndex ]; + var parser = this; - return this.getMultiDependencies( [ - - 'node', - 'skin' + var scene = new THREE.Scene(); + if ( sceneDef.name !== undefined ) scene.name = sceneDef.name; - ] ).then( function ( dependencies ) { + assignExtrasToUserData( scene, sceneDef ); - var scene = new THREE.Scene(); - if ( sceneDef.name !== undefined ) scene.name = sceneDef.name; + if ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef ); - assignExtrasToUserData( scene, sceneDef ); + var nodeIds = sceneDef.nodes || []; - if ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef ); + var pendings = []; - var nodeIds = sceneDef.nodes || []; + for ( var i = 0, il = nodeIds.length; i < il; i ++ ) { - for ( var i = 0, il = nodeIds.length; i < il; i ++ ) { + pendings.push( buildNodeHierachy( nodeIds[ i ], scene, json, parser ) ); - buildNodeHierachy( nodeIds[ i ], scene, json, dependencies.nodes, dependencies.skins ); + } - } + return Promise.all( pendings ).then( function () { return scene; From af280b193b1df0430a8ea2260ff7e12a18d5d937 Mon Sep 17 00:00:00 2001 From: yomboprime Date: Thu, 20 Sep 2018 04:05:12 +0200 Subject: [PATCH 03/50] Fixes #14800 --- examples/webgl_gpgpu_water.html | 137 +++++++++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 3 deletions(-) diff --git a/examples/webgl_gpgpu_water.html b/examples/webgl_gpgpu_water.html index 5f148207805425..968372cf43d8bd 100644 --- a/examples/webgl_gpgpu_water.html +++ b/examples/webgl_gpgpu_water.html @@ -55,6 +55,7 @@ uniform vec2 mousePos; uniform float mouseSize; uniform float viscosityConstant; + uniform float heightCompensation; #define deltaTime ( 1.0 / 60.0 ) #define GRAVITY_CONSTANT ( resolution.x * deltaTime * 3.0 ) @@ -91,6 +92,9 @@ float mousePhase = clamp( length( ( uv - vec2( 0.5 ) ) * BOUNDS - vec2( mousePos.x, - mousePos.y ) ) * PI / mouseSize, 0.0, PI ); heightmapValue.x += cos( mousePhase ) + 1.0; + // Water height reset compensation + heightmapValue.x += heightCompensation; + gl_FragColor = heightmapValue; } @@ -122,6 +126,72 @@ } + + + + + + + + + + diff --git a/src/cameras/ArrayCamera.js b/src/cameras/ArrayCamera.js index fc98224bf79fd8..0de9131c194b73 100644 --- a/src/cameras/ArrayCamera.js +++ b/src/cameras/ArrayCamera.js @@ -3,6 +3,7 @@ */ import { PerspectiveCamera } from './PerspectiveCamera.js'; +import { Vector3 } from '../math/Vector3.js'; function ArrayCamera( array ) { @@ -16,7 +17,66 @@ ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototyp constructor: ArrayCamera, - isArrayCamera: true + isArrayCamera: true, + + /** + * Assumes 2 cameras that are perpendicular and share an X-axis, and that + * the cameras' projection and world matrices have already been set. + * And that near and far planes are identical for both cameras. + */ + setProjectionFromUnion: function () { + var cameraLPos = new Vector3(); + var cameraRPos = new Vector3(); + + return function () { + cameraLPos.setFromMatrixPosition( this.cameras[ 0 ].matrixWorld ); + cameraRPos.setFromMatrixPosition( this.cameras[ 1 ].matrixWorld ); + + var ipd = cameraLPos.distanceTo( cameraRPos ); + + var projL = this.cameras[ 0 ].projectionMatrix; + var projR = this.cameras[ 1 ].projectionMatrix; + + // VR systems will have identical far and near planes, and + // most likely identical top and bottom frustum extents. + // via: https://computergraphics.stackexchange.com/a/4765 + var near = projL[ 14 ] / ( projL[ 10 ] - 1 ); + var far = projL[ 14 ] / ( projL[ 10 ] + 1 ); + + var leftFovL = ( projL[ 8 ] - 1 ) / projL[ 0 ]; + var rightFovR = ( projR[ 8 ] + 1 ) / projR[ 0 ]; + var leftL = leftFovL * near; + var rightR = rightFovR * near; + var topL = near * ( projL[ 9 ] + 1 ) / projL[ 5 ]; + var topR = near * ( projR[ 9 ] + 1 ) / projR[ 5 ]; + var bottomL = near * ( projL[ 9 ] - 1 ) / projL[ 5 ]; + var bottomR = near * ( projR[ 9 ] - 1 ) / projR[ 5 ]; + + // Calculate the new camera's position offset from the + // left camera. + var zOffset = ipd / (leftFovL + rightFovR); + var xOffset = zOffset * leftFovL; + + // TODO: Better way to apply this offset? + this.cameras[ 0 ].matrixWorld.decompose( this.position, this.quaternion, this.scale ); + this.translateX(xOffset); + this.translateZ(-zOffset); + this.matrixWorld.compose( this.position, this.quaternion, this.scale ); + this.matrixWorldInverse.getInverse(this.matrixWorld); + + // Find the union of the frustum values of the cameras and scale + // the values so that the near plane's position does not change in world space, + // although must now be relative to the new union camera. + var near2 = near + zOffset; + var far2 = far + zOffset; + var left = leftL - xOffset; + var right = rightR + (ipd - xOffset) + var top = Math.max( topL, topR ); + var bottom = Math.min( bottomL, bottomR ); + + this.projectionMatrix.makePerspective( left, right, top, bottom, near2, far2 ); + } + }(), } ); diff --git a/src/renderers/webvr/WebVRManager.js b/src/renderers/webvr/WebVRManager.js index bbf9d31554e113..d978dc4cc93273 100644 --- a/src/renderers/webvr/WebVRManager.js +++ b/src/renderers/webvr/WebVRManager.js @@ -290,9 +290,6 @@ function WebVRManager( renderer ) { cameraL.far = camera.far; cameraR.far = camera.far; - cameraVR.matrixWorld.copy( camera.matrixWorld ); - cameraVR.matrixWorldInverse.copy( camera.matrixWorldInverse ); - cameraL.matrixWorldInverse.fromArray( frameData.leftViewMatrix ); cameraR.matrixWorldInverse.fromArray( frameData.rightViewMatrix ); @@ -326,10 +323,7 @@ function WebVRManager( renderer ) { cameraL.projectionMatrix.fromArray( frameData.leftProjectionMatrix ); cameraR.projectionMatrix.fromArray( frameData.rightProjectionMatrix ); - // HACK (mrdoob) - // https://github.com/w3c/webvr/issues/203 - - cameraVR.projectionMatrix.copy( cameraL.projectionMatrix ); + cameraVR.setProjectionFromUnion(); // diff --git a/src/renderers/webvr/WebXRManager.js b/src/renderers/webvr/WebXRManager.js index 0adc0e7751e47c..1d8f6242dd22b5 100644 --- a/src/renderers/webvr/WebXRManager.js +++ b/src/renderers/webvr/WebXRManager.js @@ -161,8 +161,6 @@ function WebXRManager( renderer ) { var parent = camera.parent; var cameras = cameraVR.cameras; - // apply camera.parent to cameraVR - updateCamera( cameraVR, parent ); for ( var i = 0; i < cameras.length; i ++ ) { @@ -183,6 +181,8 @@ function WebXRManager( renderer ) { } + cameraVR.setProjectionFromUnion(); + return cameraVR; } @@ -221,11 +221,6 @@ function WebXRManager( renderer ) { cameraVR.matrix.copy( camera.matrix ); - // HACK (mrdoob) - // https://github.com/w3c/webvr/issues/203 - - cameraVR.projectionMatrix.copy( camera.projectionMatrix ); - } } From 469b5bf2a5fc59613a497dd1dee9e3b3459ae906 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Tue, 25 Sep 2018 00:15:16 +0900 Subject: [PATCH 06/50] GLTFLoader: Rename pendings to pending --- examples/js/loaders/GLTFLoader.js | 124 +++++++++++++++--------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/examples/js/loaders/GLTFLoader.js b/examples/js/loaders/GLTFLoader.js index 95fbb025dbfa20..e535ebafa7c0cf 100644 --- a/examples/js/loaders/GLTFLoader.js +++ b/examples/js/loaders/GLTFLoader.js @@ -347,7 +347,7 @@ THREE.GLTFLoader = ( function () { GLTFMaterialsUnlitExtension.prototype.extendParams = function ( materialParams, material, parser ) { - var pendings = []; + var pending = []; materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 ); materialParams.opacity = 1.0; @@ -367,13 +367,13 @@ THREE.GLTFLoader = ( function () { if ( metallicRoughness.baseColorTexture !== undefined ) { - pendings.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture.index ) ); + pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture.index ) ); } } - return Promise.all( pendings ); + return Promise.all( pending ); }; @@ -637,7 +637,7 @@ THREE.GLTFLoader = ( function () { params.color = new THREE.Color( 1.0, 1.0, 1.0 ); params.opacity = 1.0; - var pendings = []; + var pending = []; if ( Array.isArray( pbrSpecularGlossiness.diffuseFactor ) ) { @@ -650,7 +650,7 @@ THREE.GLTFLoader = ( function () { if ( pbrSpecularGlossiness.diffuseTexture !== undefined ) { - pendings.push( parser.assignTexture( params, 'map', pbrSpecularGlossiness.diffuseTexture.index ) ); + pending.push( parser.assignTexture( params, 'map', pbrSpecularGlossiness.diffuseTexture.index ) ); } @@ -667,12 +667,12 @@ THREE.GLTFLoader = ( function () { if ( pbrSpecularGlossiness.specularGlossinessTexture !== undefined ) { var specGlossIndex = pbrSpecularGlossiness.specularGlossinessTexture.index; - pendings.push( parser.assignTexture( params, 'glossinessMap', specGlossIndex ) ); - pendings.push( parser.assignTexture( params, 'specularMap', specGlossIndex ) ); + pending.push( parser.assignTexture( params, 'glossinessMap', specGlossIndex ) ); + pending.push( parser.assignTexture( params, 'specularMap', specGlossIndex ) ); } - return Promise.all( pendings ); + return Promise.all( pending ); }, @@ -1245,8 +1245,8 @@ THREE.GLTFLoader = ( function () { if ( ! hasMorphPosition && ! hasMorphNormal ) return Promise.resolve( geometry ); - var positionAccessorPendings = []; - var normalAccessorPendings = []; + var pendingPositionAccessors = []; + var pendingNormalAccessors = []; for ( var i = 0, il = targets.length; i < il; i ++ ) { @@ -1254,7 +1254,7 @@ THREE.GLTFLoader = ( function () { if ( hasMorphPosition ) { - positionAccessorPendings.push( + pendingPositionAccessors.push( target.POSITION !== undefined ? parser.getDependency( 'accessor', target.POSITION ) .then( function ( accessor ) { @@ -1268,7 +1268,7 @@ THREE.GLTFLoader = ( function () { if ( hasMorphNormal ) { - normalAccessorPendings.push( + pendingNormalAccessors.push( target.NORMAL !== undefined ? parser.getDependency( 'accessor', target.NORMAL ) .then( function ( accessor ) { @@ -1282,8 +1282,8 @@ THREE.GLTFLoader = ( function () { } return Promise.all( [ - Promise.all( positionAccessorPendings ), - Promise.all( normalAccessorPendings ) + Promise.all( pendingPositionAccessors ), + Promise.all( pendingNormalAccessors ) ] ).then( function ( accessors ) { var morphPositions = accessors[ 0 ]; @@ -1787,7 +1787,7 @@ THREE.GLTFLoader = ( function () { GLTFParser.prototype.getMultiDependencies = function ( types ) { var results = {}; - var pendings = []; + var pending = []; for ( var i = 0, il = types.length; i < il; i ++ ) { @@ -1800,11 +1800,11 @@ THREE.GLTFLoader = ( function () { }.bind( this, type + ( type === 'mesh' ? 'es' : 's' ) ) ); - pendings.push( value ); + pending.push( value ); } - return Promise.all( pendings ).then( function () { + return Promise.all( pending ).then( function () { return results; @@ -2136,19 +2136,19 @@ THREE.GLTFLoader = ( function () { var materialParams = {}; var materialExtensions = materialDef.extensions || {}; - var pendings = []; + var pending = []; if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] ) { var sgExtension = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ]; materialType = sgExtension.getMaterialType( materialDef ); - pendings.push( sgExtension.extendParams( materialParams, materialDef, parser ) ); + pending.push( sgExtension.extendParams( materialParams, materialDef, parser ) ); } else if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) { var kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ]; materialType = kmuExtension.getMaterialType( materialDef ); - pendings.push( kmuExtension.extendParams( materialParams, materialDef, parser ) ); + pending.push( kmuExtension.extendParams( materialParams, materialDef, parser ) ); } else { @@ -2173,7 +2173,7 @@ THREE.GLTFLoader = ( function () { if ( metallicRoughness.baseColorTexture !== undefined ) { - pendings.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture.index ) ); + pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture.index ) ); } @@ -2183,8 +2183,8 @@ THREE.GLTFLoader = ( function () { if ( metallicRoughness.metallicRoughnessTexture !== undefined ) { var textureIndex = metallicRoughness.metallicRoughnessTexture.index; - pendings.push( parser.assignTexture( materialParams, 'metalnessMap', textureIndex ) ); - pendings.push( parser.assignTexture( materialParams, 'roughnessMap', textureIndex ) ); + pending.push( parser.assignTexture( materialParams, 'metalnessMap', textureIndex ) ); + pending.push( parser.assignTexture( materialParams, 'roughnessMap', textureIndex ) ); } @@ -2216,7 +2216,7 @@ THREE.GLTFLoader = ( function () { if ( materialDef.normalTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { - pendings.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture.index ) ); + pending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture.index ) ); materialParams.normalScale = new THREE.Vector2( 1, 1 ); @@ -2230,7 +2230,7 @@ THREE.GLTFLoader = ( function () { if ( materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { - pendings.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture.index ) ); + pending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture.index ) ); if ( materialDef.occlusionTexture.strength !== undefined ) { @@ -2248,11 +2248,11 @@ THREE.GLTFLoader = ( function () { if ( materialDef.emissiveTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { - pendings.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture.index ) ); + pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture.index ) ); } - return Promise.all( pendings ).then( function () { + return Promise.all( pending ).then( function () { var material; @@ -2301,7 +2301,7 @@ THREE.GLTFLoader = ( function () { var attributes = primitiveDef.attributes; - var pendings = []; + var pending = []; function loadAttributeAccessor( accessorIndex, attributeName ) { @@ -2323,13 +2323,13 @@ THREE.GLTFLoader = ( function () { // Skip attributes already provided by e.g. Draco extension. if ( threeAttributeName in geometry.attributes ) continue; - pendings.push( loadAttributeAccessor( attributes[ gltfAttributeName ], threeAttributeName ) ); + pending.push( loadAttributeAccessor( attributes[ gltfAttributeName ], threeAttributeName ) ); } if ( primitiveDef.indices !== undefined && ! geometry.index ) { - pendings.push( + pending.push( parser.getDependency( 'accessor', primitiveDef.indices ) .then( function ( accessor ) { @@ -2342,7 +2342,7 @@ THREE.GLTFLoader = ( function () { assignExtrasToUserData( geometry, primitiveDef ); - return Promise.all( pendings ).then( function () { + return Promise.all( pending ).then( function () { return primitiveDef.targets !== undefined ? addMorphTargets( geometry, primitiveDef.targets, parser ) @@ -2384,7 +2384,7 @@ THREE.GLTFLoader = ( function () { } - var pendings = []; + var pending = []; for ( var i = 0, il = primitives.length; i < il; i ++ ) { @@ -2396,7 +2396,7 @@ THREE.GLTFLoader = ( function () { if ( cached ) { // Use the cached geometry if it exists - pendings.push( cached ); + pending.push( cached ); } else { @@ -2423,13 +2423,13 @@ THREE.GLTFLoader = ( function () { // Cache this geometry cache.push( { primitive: primitive, promise: geometryPromise } ); - pendings.push( geometryPromise ); + pending.push( geometryPromise ); } } - return Promise.all( pendings ).then( function ( geometries ) { + return Promise.all( pending ).then( function ( geometries ) { if ( isMultiPass ) { @@ -2535,11 +2535,11 @@ THREE.GLTFLoader = ( function () { var meshDef = json.meshes[ meshIndex ]; var primitives = meshDef.primitives; - var pendings = []; + var pending = []; for ( var i = 0, il = primitives.length; i < il; i ++ ) { - pendings.push( + pending.push( primitives[ i ].material === undefined ? createDefaultMaterial() : this.getDependency( 'material', primitives[ i ].material ) @@ -2547,7 +2547,7 @@ THREE.GLTFLoader = ( function () { } - return Promise.all( pendings ).then( function ( originalMaterials ) { + return Promise.all( pending ).then( function ( originalMaterials ) { return parser.loadGeometries( primitives ).then( function ( geometries ) { @@ -2831,11 +2831,11 @@ THREE.GLTFLoader = ( function () { var animationDef = json.animations[ animationIndex ]; - var nodePendings = []; - var inputAccessorPendings = []; - var outputAccessorPendings = []; - var samplerPendings = []; - var targetPendings = []; + var pendingNodes = []; + var pendingInputAccessors = []; + var pendingOutputAccessors = []; + var pendingSamplers = []; + var pendingTargets = []; for ( var i = 0, il = animationDef.channels.length; i < il; i ++ ) { @@ -2849,21 +2849,21 @@ THREE.GLTFLoader = ( function () { var input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input; var output = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.output ] : sampler.output; - nodePendings.push( this.getDependency( 'node', name ) ); - inputAccessorPendings.push( this.getDependency( 'accessor', input ) ); - outputAccessorPendings.push( this.getDependency( 'accessor', output ) ); - samplerPendings.push( sampler ); - targetPendings.push( target ); + pendingNodes.push( this.getDependency( 'node', name ) ); + pendingInputAccessors.push( this.getDependency( 'accessor', input ) ); + pendingOutputAccessors.push( this.getDependency( 'accessor', output ) ); + pendingSamplers.push( sampler ); + pendingTargets.push( target ); } return Promise.all( [ - Promise.all( nodePendings ), - Promise.all( inputAccessorPendings ), - Promise.all( outputAccessorPendings ), - Promise.all( samplerPendings ), - Promise.all( targetPendings ) + Promise.all( pendingNodes ), + Promise.all( pendingInputAccessors ), + Promise.all( pendingOutputAccessors ), + Promise.all( pendingSamplers ), + Promise.all( pendingTargets ) ] ).then( function ( dependencies ) { @@ -3128,15 +3128,15 @@ THREE.GLTFLoader = ( function () { skinEntry = skin; - var jointPendings = []; + var pendingJoints = []; for ( var i = 0, il = skinEntry.joints.length; i < il; i ++ ) { - jointPendings.push( parser.getDependency( 'node', skinEntry.joints[ i ] ) ); + pendingJoints.push( parser.getDependency( 'node', skinEntry.joints[ i ] ) ); } - return Promise.all( jointPendings ); + return Promise.all( pendingJoints ); } ).then( function ( jointNodes ) { @@ -3189,7 +3189,7 @@ THREE.GLTFLoader = ( function () { parentObject.add( node ); - var pendings = []; + var pending = []; if ( nodeDef.children ) { @@ -3198,13 +3198,13 @@ THREE.GLTFLoader = ( function () { for ( var i = 0, il = children.length; i < il; i ++ ) { var child = children[ i ]; - pendings.push( buildNodeHierachy( child, node, json, parser ) ); + pending.push( buildNodeHierachy( child, node, json, parser ) ); } } - return Promise.all( pendings ); + return Promise.all( pending ); } ); @@ -3226,15 +3226,15 @@ THREE.GLTFLoader = ( function () { var nodeIds = sceneDef.nodes || []; - var pendings = []; + var pending = []; for ( var i = 0, il = nodeIds.length; i < il; i ++ ) { - pendings.push( buildNodeHierachy( nodeIds[ i ], scene, json, parser ) ); + pending.push( buildNodeHierachy( nodeIds[ i ], scene, json, parser ) ); } - return Promise.all( pendings ).then( function () { + return Promise.all( pending ).then( function () { return scene; From 9b9b439118015676495c1b441cfca856166070c7 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Tue, 25 Sep 2018 00:54:17 +0900 Subject: [PATCH 07/50] GLTFLoader: Remove unnecessary sampler === undefined check --- examples/js/loaders/GLTFLoader.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/js/loaders/GLTFLoader.js b/examples/js/loaders/GLTFLoader.js index e535ebafa7c0cf..98a94f165bea8e 100644 --- a/examples/js/loaders/GLTFLoader.js +++ b/examples/js/loaders/GLTFLoader.js @@ -2841,9 +2841,6 @@ THREE.GLTFLoader = ( function () { var channel = animationDef.channels[ i ]; var sampler = animationDef.samplers[ channel.sampler ]; - - if ( sampler === undefined ) continue; - var target = channel.target; var name = target.node !== undefined ? target.node : target.id; // NOTE: target.id is deprecated. var input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input; From 77592aba0ce0cf390429f6606d5e4ec38b96da61 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Tue, 25 Sep 2018 01:28:33 +0900 Subject: [PATCH 08/50] GLTFLoader: Clean up --- examples/js/loaders/GLTFLoader.js | 44 +++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/examples/js/loaders/GLTFLoader.js b/examples/js/loaders/GLTFLoader.js index 98a94f165bea8e..c871635c3e0d47 100644 --- a/examples/js/loaders/GLTFLoader.js +++ b/examples/js/loaders/GLTFLoader.js @@ -1254,28 +1254,28 @@ THREE.GLTFLoader = ( function () { if ( hasMorphPosition ) { - pendingPositionAccessors.push( - target.POSITION !== undefined - ? parser.getDependency( 'accessor', target.POSITION ) - .then( function ( accessor ) { - // Cloning not to pollute original accessor below - return cloneBufferAttribute( accessor ); - } ) - : geometry.attributes.position - ); + var accessor = 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 ); } if ( hasMorphNormal ) { - pendingNormalAccessors.push( - target.NORMAL !== undefined - ? parser.getDependency( 'accessor', target.NORMAL ) - .then( function ( accessor ) { - return cloneBufferAttribute( accessor ); - } ) - : geometry.attributes.normal - ); + var accessor = target.NORMAL !== undefined + ? parser.getDependency( 'accessor', target.NORMAL ) + .then( function ( accessor ) { + return cloneBufferAttribute( accessor ); + } ) + : geometry.attributes.normal; + + pendingNormalAccessors.push( accessor ); } @@ -2539,11 +2539,11 @@ THREE.GLTFLoader = ( function () { for ( var i = 0, il = primitives.length; i < il; i ++ ) { - pending.push( - primitives[ i ].material === undefined - ? createDefaultMaterial() - : this.getDependency( 'material', primitives[ i ].material ) - ); + var material = primitives[ i ].material === undefined + ? createDefaultMaterial() + : this.getDependency( 'material', primitives[ i ].material ); + + pending.push( material ); } From 404fe233bc3d88dc73ebcefbb554accb06359ce2 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Tue, 25 Sep 2018 01:35:30 +0900 Subject: [PATCH 09/50] GLTFLoader: Clean up --- examples/js/loaders/GLTFLoader.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/js/loaders/GLTFLoader.js b/examples/js/loaders/GLTFLoader.js index c871635c3e0d47..96dc6f79278b72 100644 --- a/examples/js/loaders/GLTFLoader.js +++ b/examples/js/loaders/GLTFLoader.js @@ -2329,14 +2329,13 @@ THREE.GLTFLoader = ( function () { if ( primitiveDef.indices !== undefined && ! geometry.index ) { - pending.push( - parser.getDependency( 'accessor', primitiveDef.indices ) - .then( function ( accessor ) { + var accessor = parser.getDependency( 'accessor', primitiveDef.indices ).then( function ( accessor ) { - geometry.setIndex( accessor ); + geometry.setIndex( accessor ); - } ) - ); + } ); + + pending.push( accessor ); } From 1a1ad42b30eca67c6b5133882ae043ae9907cbff Mon Sep 17 00:00:00 2001 From: Takahiro Date: Tue, 25 Sep 2018 01:41:05 +0900 Subject: [PATCH 10/50] GLTFLoader: Rename loadAttributeAccessor to assignAttributeAccessor --- examples/js/loaders/GLTFLoader.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/js/loaders/GLTFLoader.js b/examples/js/loaders/GLTFLoader.js index 96dc6f79278b72..952303b9fa6db8 100644 --- a/examples/js/loaders/GLTFLoader.js +++ b/examples/js/loaders/GLTFLoader.js @@ -2303,7 +2303,7 @@ THREE.GLTFLoader = ( function () { var pending = []; - function loadAttributeAccessor( accessorIndex, attributeName ) { + function assignAttributeAccessor( accessorIndex, attributeName ) { return parser.getDependency( 'accessor', accessorIndex ) .then( function ( accessor ) { @@ -2323,7 +2323,7 @@ THREE.GLTFLoader = ( function () { // Skip attributes already provided by e.g. Draco extension. if ( threeAttributeName in geometry.attributes ) continue; - pending.push( loadAttributeAccessor( attributes[ gltfAttributeName ], threeAttributeName ) ); + pending.push( assignAttributeAccessor( attributes[ gltfAttributeName ], threeAttributeName ) ); } From 699b449cb50e21f24936fa05fc4900a29f500471 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Tue, 25 Sep 2018 04:46:52 +0900 Subject: [PATCH 11/50] GLTFLoader: Revert returning Promise from assignTexture() --- examples/js/loaders/GLTFLoader.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/js/loaders/GLTFLoader.js b/examples/js/loaders/GLTFLoader.js index 952303b9fa6db8..672fa7e6131e85 100644 --- a/examples/js/loaders/GLTFLoader.js +++ b/examples/js/loaders/GLTFLoader.js @@ -2114,8 +2114,6 @@ THREE.GLTFLoader = ( function () { materialParams[ textureName ] = texture; - return texture; - } ); }; From e04da02276beb8a66988c294b749c05f5717d6bb Mon Sep 17 00:00:00 2001 From: shizhenlei Date: Tue, 25 Sep 2018 09:15:34 +0800 Subject: [PATCH 12/50] Cameras Chinese translation --- docs/api/zh/cameras/ArrayCamera.html | 22 ++-- docs/api/zh/cameras/Camera.html | 45 ++++---- docs/api/zh/cameras/CubeCamera.html | 37 ++++--- docs/api/zh/cameras/OrthographicCamera.html | 93 ++++++++--------- docs/api/zh/cameras/PerspectiveCamera.html | 108 +++++++++----------- docs/api/zh/cameras/StereoCamera.html | 28 +++-- 6 files changed, 158 insertions(+), 175 deletions(-) diff --git a/docs/api/zh/cameras/ArrayCamera.html b/docs/api/zh/cameras/ArrayCamera.html index cdd31cc6dcbbef..75a82c1188e85b 100644 --- a/docs/api/zh/cameras/ArrayCamera.html +++ b/docs/api/zh/cameras/ArrayCamera.html @@ -13,34 +13,34 @@

[name]

- [name] can be used in order to efficiently render a scene with a predefined set of cameras. This is an important performance aspect for rendering VR scenes.
- An instance of [name] always has an array of sub cameras. It's mandatory to define for each sub camera the *bounds* property which determines the part of the viewport that is rendered with this camera. + 可以使用[name]以使用预定义的一组摄像机有效地渲染场景。这是渲染VR场景的重要性能方面。
+ [name]的实例总是有一组子摄像机。必须为每个子摄像机定义bounds属性,该属性确定使用此摄像机渲染的视口部分。

-

Example

+

例子

[example:webgl_camera_array camera / array ]

-

Constructor

+

构造函数

[name]( [param:Array array] )

- An array of cameras. + 摄像机组。

-

Properties

-

See the base [page:PerspectiveCamera] class for common properties.

+

属性

+

请参阅基类[page:PerspectiveCamera]的公共属性。

[property:Array cameras]

- An array of cameras. + 摄像机组。

-

Methods

-

See the base [page:PerspectiveCamera] class for common methods.

+

方法

+

请参阅基类[page:PerspectiveCamera]的公共方法。

-

Source

+

源码

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/zh/cameras/Camera.html b/docs/api/zh/cameras/Camera.html index 143f9f7e27a61d..9b47b11766c54f 100644 --- a/docs/api/zh/cameras/Camera.html +++ b/docs/api/zh/cameras/Camera.html @@ -13,74 +13,71 @@

[name]

- Abstract base class for cameras. This class should always be inherited when you build a new camera. + 摄像机的抽象基类。在构建新摄像机时,应始终继承此类。

-

Constructor

+

构造函数

[name]()

- Creates a new [name]. Note that this class is not intended to be called directly; - you probably want a [page:PerspectiveCamera] or [page:OrthographicCamera] instead. + 创建一个新的[name]。请注意,此类不应直接调用; + 你可能需要一个[page:PerspectiveCamera]或者[page:OrthographicCamera]。

-

Properties

-

See the base [page:Object3D] class for common properties.

+

属性

+

请参阅基类[page:Object3D]的公共属性。

[property:Boolean isCamera]

- Used to check whether this or derived classes are cameras. Default is *true*.

+ 用于检查此类或派生类是否为摄像机。默认为true。

- You should not change this, as it used internally by the renderer for optimisation. + 你不应该更改此内容,因为渲染器在内部使用它进行优化。

[property:Layers layers]

- The [page:Layers layers] that the camera is a member of. This is an inherited - property from [page:Object3D].

+ 摄像机所属的[page:Layers layers]。 这是[page:Object3D]的继承属性。

- Objects must share at least one layer with the camera to be seen - when the camera's viewpoint is rendered. + 在渲染摄像机的视点时,对象必须与摄像机共享至少一个层。

[property:Matrix4 matrixWorldInverse]

- This is the inverse of matrixWorld. MatrixWorld contains the Matrix which has - the world transform of the Camera. + 这是matrixWorld的逆矩阵。MatrixWorld包含摄像机的世界变换矩阵。

[property:Matrix4 projectionMatrix]

-

This is the matrix which contains the projection.

+

这是包含投影的矩阵。

[property:Matrix4 projectionMatrixInverse]

-

The inverse of projectionMatrix.

+

projectionMatrix的逆矩阵

-

Methods

-

See the base [page:Object3D] class for common methods.

+

方法

+

请参阅基类[page:Object3D]的公共方法。

[method:Camera clone]( )

- Return a new camera with the same properties as this one. + 返回具有与此相同属性的新摄像机。

[method:Camera copy]( [param:Camera source], [param:Boolean recursive] )

- Copy the properties from the source camera into this one. + 将源摄像机中的属性复制到此摄像机中。

[method:Vector3 getWorldDirection]( [param:Vector3 target] )

- [page:Vector3 target] — the result will be copied into this Vector3.

+ [page:Vector3 target] — 结果将被复制到此Vector3中。

- Returns a [page:Vector3] representing the world space direction in which the camera is looking. - (Note: A camera looks down its local, negative z-axis).

+ 返回表示摄像机正在查看的世界空间方向的[page:Vector3]。 + (注意:摄像机向下看其局部的负z轴)。

-

Source

+

源代码

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/zh/cameras/CubeCamera.html b/docs/api/zh/cameras/CubeCamera.html index 117bfa117ce7d4..b93727ab9ffa89 100644 --- a/docs/api/zh/cameras/CubeCamera.html +++ b/docs/api/zh/cameras/CubeCamera.html @@ -12,9 +12,9 @@

[name]

-

Creates 6 cameras that render to a [page:WebGLRenderTargetCube].

+

创建6个渲染到[page:WebGLRenderTargetCube]的摄像机

-

Examples

+

例子

[example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]

[example:webgl_materials_cubemap_dynamic2 materials / cubemap / dynamic2 ]

@@ -40,49 +40,48 @@

Examples

-

Constructor

+

构造函数

[name]( [param:Number near], [param:Number far], [param:Number cubeResolution] )

- near -- The near clipping distance.
- far -- The far clipping distance
- cubeResolution -- Sets the length of the cube's edges. + near -- 近剪裁面距离
+ far -- 远剪裁面距离
+ cubeResolution -- 设置立方体边缘的长度。

- Constructs a CubeCamera that contains 6 [page:PerspectiveCamera PerspectiveCameras] that - render to a [page:WebGLRenderTargetCube]. + 构造一个包含6个[page:PerspectiveCamera PerspectiveCameras]的CubeCamera,渲染到[page:WebGLRenderTargetCube]。

-

Properties

-

See the base [page:Object3D] class for common properties.

+

属性

+

参阅基类[page:Object3D]的公共属性。

[property:WebGLRenderTargetCube renderTarget]

- The cube texture that gets generated. + 生成的立方体纹理。

-

Methods

-

See the base [page:Object3D] class for common methods.

+

方法

+

参阅基类[page:Object3D]的公共方法。

[method:null update]( [param:WebGLRenderer renderer], [param:Scene scene] )

- renderer -- The current WebGL renderer
- scene -- The current scene + renderer -- 当前WebGL渲染器
+ scene -- 当前场景

- Call this to update the [page:CubeCamera.renderTarget renderTarget]. + 调用它来更新[page:CubeCamera.renderTarget renderTarget]。

[method:null clear]( [param:WebGLRenderer renderer], [param:Boolean color], [param:Boolean depth], [param:Boolean stencil] )

- Call this to clear the [page:CubeCamera.renderTarget renderTarget] color, depth, and/or stencil buffers. - The color buffer is set to the renderer's current clear color. Arguments default to *true*. + 调用此方法以清除[page:CubeCamera.renderTarget renderTarget] 颜色,深度,和/或者模板缓冲区。 + 颜色缓冲区设置为渲染器的当前清除颜色。默认参数为*true*。

-

Source

+

源代码

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/zh/cameras/OrthographicCamera.html b/docs/api/zh/cameras/OrthographicCamera.html index 23a78ecea91045..bbcccdc9827282 100644 --- a/docs/api/zh/cameras/OrthographicCamera.html +++ b/docs/api/zh/cameras/OrthographicCamera.html @@ -13,16 +13,15 @@

[name]

- Camera that uses [link:https://en.wikipedia.org/wiki/Orthographic_projection orthographic projection].

+ 使用[link:https://en.wikipedia.org/wiki/Orthographic_projection orthographic projection]的摄像机。

- In this projection mode, an object's size in the rendered image stays constant - regardless of its distance from the camera.

+ 在此投影模式下,无论距离摄像机的距离如何,渲染图像中的对象大小都保持不变。

- This can be useful for rendering 2D scenes and UI elements, amongst other things. + 这对于渲染2D场景和UI元素等非常有用。

-

Example

+

例子

[example:canvas_camera_orthographic camera / orthographic ]

[example:webgl_camera camera ]

@@ -40,104 +39,102 @@

Example

scene.add( camera ); -

Constructor

+

构造函数

[name]( [param:Number left], [param:Number right], [param:Number top], [param:Number bottom], [param:Number near], [param:Number far] )

- left — Camera frustum left plane.
- right — Camera frustum right plane.
- top — Camera frustum top plane.
- bottom — Camera frustum bottom plane.
- near — Camera frustum near plane.
- far — Camera frustum far plane.

- - Together these define the camera's [link:https://en.wikipedia.org/wiki/Viewing_frustum viewing frustum]. + left — 摄像机视锥体左平面。
+ right — 摄像机视锥体右平面。
+ top — 摄像机视锥体顶部平面。
+ bottom — 摄像机视锥体底部平面。
+ near — 摄像机视锥体近平面。
+ far — 摄像机视锥体远平面。

+ + 这些一起定义了摄像机的[link:https://en.wikipedia.org/wiki/Viewing_frustum viewing frustum]。

-

Properties

+

属性

- See the base [page:Camera] class for common properties.
- Note that after making changes to most of these properties you will have to call - [page:OrthographicCamera.updateProjectionMatrix .updateProjectionMatrix] for the changes to take effect. + 参阅基类[page:Camera]的公共属性。
+ 请注意,在对大多数这些属性进行更改后,必须调用 [page:OrthographicCamera.updateProjectionMatrix .updateProjectionMatrix]才能使更改生效。

[property:Float bottom]

-

Camera frustum bottom plane.

+

摄像机视锥体底部平面。

[property:Float far]

- Camera frustum far plane. Default is *2000*.

+ 摄像机视锥体远平面。 默认值是*2000*。

- The valid range is between the current value of the [page:.near near] plane and infinity. + 有效范围介于[page:.near]平面的当前值和无穷远之间。

[property:Boolean isOrthographicCamera]

- Used to test whether this or derived classes are OrthographicCameras. Default is *true*.

+ 用于测试此类或派生类是否为正交摄像机。 默认值为*true*。

- This should not be changed as it is used internally by the renderer for optimisation. + 这不应该更改,因为渲染器在内部使用它进行优化。

[property:Float left]

-

Camera frustum left plane.

+

摄像机视锥体左平面。

[property:Float near]

- Camera frustum near plane. Default is *0.1*.

+ 摄像机视锥体近平面。默认值为*0.1*。

- The valid range is between 0 and the current value of the [page:.far far] plane. - Note that, unlike for the [page:PerspectiveCamera], *0* is a valid value for an - OrthographicCamera's near plane. + 有效范围介于0和[page:.far]平面的当前值之间。 + 请注意,与[page:PerspectiveCamera]不同,*0*是正交摄像机近平面的有效值。

[property:Float right]

-

Camera frustum right plane.

+

摄像机视锥体右平面。

[property:Float top]

-

Camera frustum top plane.

+

摄像机视锥体顶部平面。

[property:Object view]

-

Set by [page:OrthographicCamera.setViewOffset setViewOffset]. Default is *null*.

+

由[page:OrthographicCamera.setViewOffset setViewOffset]设置。默认值为*null*。

[property:number zoom]

-

Gets or sets the zoom factor of the camera. Default is *1*.

+

获取和设置摄像机的缩放系数。默认值为*1*。

-

Methods

-

See the base [page:Camera] class for common methods.

+

方法

+

参阅基类[page:Camera]的公共方法。

[method:null setViewOffset]( [param:Float fullWidth], [param:Float fullHeight], [param:Float x], [param:Float y], [param:Float width], [param:Float height] )

- fullWidth — full width of multiview setup
- fullHeight — full height of multiview setup
- x — horizontal offset of subcamera
- y — vertical offset of subcamera
- width — width of subcamera
- height — height of subcamera

- - Sets an offset in a larger [link:https://en.wikipedia.org/wiki/Viewing_frustum viewing frustum]. - This is useful for multi-window or multi-monitor/multi-machine setups. - For an example on how to use it see [page:PerspectiveCamera.setViewOffset PerspectiveCamera]. + fullWidth — 多视图设置的全宽度
+ fullHeight — 多视图设置的全高度
+ x — 子摄像机的水平偏移
+ y — 子摄像机的竖直偏移
+ width — 子摄像机宽度
+ height — 子摄像机高度

+ + 在较大的[link:https://en.wikipedia.org/wiki/Viewing_frustum viewing frustum]中设置偏移。 + 这对于多窗口或多显示器/多机器设置很有用。 + 有关如何使用它的示例,请参阅[page:PerspectiveCamera.setViewOffset PerspectiveCamera]。

[method:null clearViewOffset]()

- Removes any offset set by the .setViewOffset method. + 删除[page:PerspectiveCamera.setViewOffset .setViewOffset] 方法设置的任何偏移量。

[method:null updateProjectionMatrix]()

- Updates the camera projection matrix. Must be called after any change of parameters. + 更新摄像机的投影矩阵。必须在更改参数后调用。

[method:JSON toJSON]()

- Return the camera's data in JSON format. + 以JSON格式返回摄像机的数据。

-

Source

+

源代码

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/zh/cameras/PerspectiveCamera.html b/docs/api/zh/cameras/PerspectiveCamera.html index 63277b5b71906c..37341502403363 100644 --- a/docs/api/zh/cameras/PerspectiveCamera.html +++ b/docs/api/zh/cameras/PerspectiveCamera.html @@ -13,14 +13,13 @@

[name]

- Camera that uses [link:https://en.wikipedia.org/wiki/Perspective_(graphical) perspective projection].

+ 使用[link:https://en.wikipedia.org/wiki/Perspective_(graphical) perspective projection]的摄像机。

- This projection mode is designed to mimic the way the human eye sees. It is the most - common projection mode used for rendering a 3D scene. + 这种投影模式旨在模仿人眼看到的方式。它是用于渲染3D场景的最常见投影模式。

-

Example

+

例子

[example:canvas_geometry_birds geometry / birds ]

[example:canvas_geometry_cube geometry / cube ]

@@ -34,126 +33,119 @@

Example

scene.add( camera ); -

Constructor

+

构造函数

[name]( [param:Number fov], [param:Number aspect], [param:Number near], [param:Number far] )

- fov — Camera frustum vertical field of view.
- aspect — Camera frustum aspect ratio.
- near — Camera frustum near plane.
- far — Camera frustum far plane.

+ fov — 摄像机视锥体垂直视野。
+ aspect — 摄像机视锥体宽高比。
+ near — 摄像机视锥体近平面。
+ far — 摄像机视锥体远平面。

- Together these define the camera's [link:https://en.wikipedia.org/wiki/Viewing_frustum viewing frustum]. + 这些一起定义了摄像机的[link:https://en.wikipedia.org/wiki/Viewing_frustum viewing frustum]。

-

Properties

+

属性

- See the base [page:Camera] class for common properties.
- Note that after making changes to most of these properties you will have to call - [page:PerspectiveCamera.updateProjectionMatrix .updateProjectionMatrix] for the changes to take effect. + 参阅基类[page:Camera]的公共属性。
+ 请注意,在对大多数这些属性进行更改后,必须调用[page:PerspectiveCamera.updateProjectionMatrix .updateProjectionMatrix]才能使更改生效。.

[property:Float aspect]

-

Camera frustum aspect ratio, usually the canvas width / canvas height. Default is *1* (square canvas).

+

摄像机视锥体宽高比。默认是画布宽度/画布高度。默认值为*1*(方形画布)。

[property:Float far]

- Camera frustum far plane. Default is *2000*.

+ 摄像机视锥体远平面。 默认值为*2000*。

- The valid range is between the current value of the [page:.near near] plane and infinity. + 有效范围介于[page:.near]平面的当前值和无穷远之间。

[property:Float filmGauge]

-

Film size used for the larger axis. Default is 35 (millimeters). This parameter does not influence the projection matrix unless .filmOffset is set to a nonzero value.

+

用于较大轴的胶片尺寸。默认值为35 (毫米)。 除非.filmOffset设置为非零值,否则此参数不会影响投影矩阵。

[property:Float filmOffset]

-

Horizontal off-center offset in the same unit as .filmGauge. Default is *0*.

+

与.filmGauge相同单位的水平偏中心偏移。默认值为0。

[property:Float focus]

-

Object distance used for stereoscopy and depth-of-field effects. - This parameter does not influence the projection matrix unless a [page:StereoCamera] is being used. - Default is *10*. +

用于立体视觉和景深效果的物距。 + 除非使用[page:StereoCamera],否则此参数不会影响投影矩阵。默认值为*10*。

[property:Float fov]

-

Camera frustum vertical field of view, from bottom to top of view, in degrees. Default is *50*.

+

摄像机视锥体垂直视野,从底部到顶部,以度为单位。默认值为*50*。

[property:Boolean isPerspectiveCamera]

- Used to test whether this or derived classes are PerspectiveCameras. Default is *true*.

+ 用于测试此类或派生类是否为透视摄像机。默认为*true*。

- This should not be changed as it is used internally by the renderer for optimisation. + 这不应该更改,因为渲染器在内部使用它进行优化。

[property:Float near]

- Camera frustum near plane. Default is *0.1*.

+ 摄像机视锥体的近平面,默认值为*0.1*。

- The valid range is greater than 0 and less than the current value of the [page:.far far] plane. - Note that, unlike for the [page:OrthographicCamera], *0* is not a valid value - for a PerspectiveCamera's near plane. + 有效范围大于0且小于远平面的当前值。需要注意的是,与正交摄像机不同,对于透视摄像机的近平面,0不是一个有效值。

[property:Object view]

- Frustum window specification or null. - This is set using the [page:PerspectiveCamera.setViewOffset .setViewOffset] method - and cleared using [page:PerspectiveCamera.clearViewOffset .clearViewOffset]. + 视锥体窗口规范或null。这是使用[page:PerspectiveCamera.setViewOffset .setViewOffset]方法设置, + 并使用[page:PerspectiveCamera.clearViewOffset .clearViewOffset]清除。

[property:number zoom]

-

Gets or sets the zoom factor of the camera. Default is *1*.

+

获取或设置摄像机的缩放系数。默认值为*1*。

-

Methods

-

See the base [page:Camera] class for common methods.

+

方法

+

参阅基类[page:Camera]的公共方法。

[method:null clearViewOffset]()

-

Removes any offset set by the [page:PerspectiveCamera.setViewOffset .setViewOffset] method.

+

删除[page:PerspectiveCamera.setViewOffset .setViewOffset]方法设置的任何偏移量。

[method:Float getEffectiveFOV]()

-

Returns the current vertical field of view angle in degrees considering .zoom.

+

考虑.zoom,返回当前垂直视角范围(以度为单位)。

[method:Float getFilmHeight]()

- Returns the height of the image on the film. If .aspect is less than or equal to one - (portrait format), the result equals .filmGauge. + 返回胶片上图像的高度。如果.aspect小于或等于1(纵向格式),则结果等于.filmGauge。

[method:Float getFilmWidth]()

- Returns the width of the image on the film. If .aspect is greater than or equal to one - (landscape format), the result equals .filmGauge. + 返回胶片上图像的宽度。如果.aspect大于或等于1(横向格式),则结果等于.filmGauge。

[method:Float getFocalLength]()

-

Returns the focal length of the current .fov in respect to .filmGauge.

+

返回.filmGauge当前.fov的焦距。

[method:null setFocalLength]( [param:Float focalLength] )

- Sets the FOV by focal length in respect to the current [page:PerspectiveCamera.filmGauge .filmGauge].

- - By default, the focal length is specified for a 35mm (full frame) camera. + 根据当前[page:PerspectiveCamera.filmGauge .filmGauge]的焦距设置FOV。

+ 默认情况下,焦距是为35mm(全画幅)摄像机指定的。

[method:null setViewOffset]( [param:Float fullWidth], [param:Float fullHeight], [param:Float x], [param:Float y], [param:Float width], [param:Float height] )

- fullWidth — full width of multiview setup
- fullHeight — full height of multiview setup
- x — horizontal offset of subcamera
- y — vertical offset of subcamera
- width — width of subcamera
- height — height of subcamera + fullWidth — 多视图设置的全宽度
+ fullHeight — 多视图设置的全高度
+ x — 子摄像机的水平偏移
+ y — 子摄像机的竖直偏移
+ width — 子摄像机宽度
+ height — 子摄像机高度

- Sets an offset in a larger frustum. This is useful for multi-window or multi-monitor/multi-machine setups. + 在较大的视锥体中设置偏移。 + 这对于多窗口或多显示器/多机器设置很有用。

- For example, if you have 3x2 monitors and each monitor is 1920x1080 and the monitors are in grid like this:
+ 例如,如果你有3x2显示器,每个显示器是1920x1080,显示器是这样的网格:

 +---+---+---+
@@ -163,7 +155,7 @@ 

[method:null setViewOffset]( [param:Float fullWidth], [param:Float fullHeigh +---+---+---+

- then for each monitor you would call it like this:
+ 然后对于每个监视器,你会这样调用它:
var w = 1920; var h = 1080; @@ -184,20 +176,20 @@

[method:null setViewOffset]( [param:Float fullWidth], [param:Float fullHeigh camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); - Note there is no reason monitors have to be the same size or in a grid. + 注意监视器没有理由必须是相同的大小或在一个网格中。

[method:null updateProjectionMatrix]()

- Updates the camera projection matrix. Must be called after any change of parameters. + 更新摄像机的投影矩阵。必须在更改参数后调用。

[method:JSON toJSON]()

- Return camera data in JSON format. + 以JSON格式返回摄像机的数据。

-

Source

+

源代码

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/zh/cameras/StereoCamera.html b/docs/api/zh/cameras/StereoCamera.html index 529290606ee451..81a6c47d77abb2 100644 --- a/docs/api/zh/cameras/StereoCamera.html +++ b/docs/api/zh/cameras/StereoCamera.html @@ -12,55 +12,53 @@

[name]

- Dual [page:PerspectiveCamera PerspectiveCamera]s used for effects such as - [link:https://en.wikipedia.org/wiki/Anaglyph_3D 3D Anaglyph] or [link:https://en.wikipedia.org/wiki/parallax_barrier Parallax Barrier]. + 双[page:PerspectiveCamera PerspectiveCamera](透视摄像机)用于 + [link:https://en.wikipedia.org/wiki/Anaglyph_3D 3D Anaglyph](立体影像)or [link:https://en.wikipedia.org/wiki/parallax_barrier Parallax Barrier](视差屏障)等效果。

-

Example

+

例子

[example:webgl_effects_anaglyph effects / anaglyph ]

[example:webgl_effects_parallaxbarrier effects / parallaxbarrier ]

[example:webgl_effects_stereo effects / stereo ]

- This class is used internally in the files

+ 这个类在内部使用的文件

[link:https://github.com/mrdoob/three.js/blob/master/examples/js/effects/AnaglyphEffect.js examples/js/effects/AnaglyphEffect.js]

[link:https://github.com/mrdoob/three.js/blob/master/examples/js/effects/ParallaxBarrierEffect.js examples/js/effects/ParallaxBarrierEffect.js]

[link:https://github.com/mrdoob/three.js/blob/master/examples/js/effects/StereoEffect.js examples/js/effects/StereoEffect.js]

- used in the above examples. + 在上面的例子中使用。

-

Constructor

+

构造函数

[name]( )

Properties

[property:Float aspect]

-

Default is *1*.

+

默认值为*1*。

[property:Float eyeSep]

-

Default is *0.064*.

+

默认值为*0.064*。

[property:PerspectiveCamera cameraL]

-

Left camera. This is added to [page:Layers layer 1] - objects to be rendered - by the left camera must also be added to this layer.

+

左摄像机。这将添加到[page:Layers layer 1] - 要被左摄像机渲染的对象也必须添加到此层。

[property:PerspectiveCamera cameraR]

-

Right camera.This is added to [page:Layers layer 2] - objects to be rendered - by the right camera must also be added to this layer.

+

右摄像机。这被添加到[page:Layers layer 2] - 要被右摄像机渲染的对象也必须添加到该层。

-

Methods

+

方法

[method:null update]( [param:PerspectiveCamera camera] )

- Update the stereo cameras based on the camera passed in. + 根据传入的摄像机更新立体摄像机。

-

Source

+

源代码

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] From e2e0edbe55827612d417c683d395d8fd4360b7a2 Mon Sep 17 00:00:00 2001 From: "Ji,Chang" Date: Tue, 25 Sep 2018 10:59:04 +0800 Subject: [PATCH 13/50] Translation light folder --- docs/api/zh/lights/AmbientLight.html | 32 +++---- docs/api/zh/lights/DirectionalLight.html | 83 ++++++++--------- docs/api/zh/lights/HemisphereLight.html | 50 +++++------ docs/api/zh/lights/Light.html | 40 ++++----- docs/api/zh/lights/PointLight.html | 80 ++++++++--------- docs/api/zh/lights/RectAreaLight.html | 42 +++++---- docs/api/zh/lights/SpotLight.html | 108 ++++++++++------------- 7 files changed, 206 insertions(+), 229 deletions(-) diff --git a/docs/api/zh/lights/AmbientLight.html b/docs/api/zh/lights/AmbientLight.html index c10f92983cf06d..aec1c47d9b94f2 100644 --- a/docs/api/zh/lights/AmbientLight.html +++ b/docs/api/zh/lights/AmbientLight.html @@ -1,5 +1,5 @@ - + @@ -13,13 +13,13 @@

[name]

- This light globally illuminates all objects in the scene equally.

+ 环境光会均匀的照亮场景中的所有物体。

- This light cannot be used to cast shadows as it does not have a direction. + 环境光不能用来投射阴影,因为它没有方向。

-

Example

+

示例

[example:canvas_camera_orthographic camera / orthographic ]
[example:canvas_interactive_voxelpainter interactive / voxelpainter ]
@@ -32,41 +32,41 @@

Example

var light = new THREE.AmbientLight( 0x404040 ); // soft white light scene.add( light ); -

Constructor

+

构造函数

[name]( [param:Integer color], [param:Float intensity] )

- [page:Integer color] - (optional) Numeric value of the RGB component of the color. Default is 0xffffff.
- [page:Float intensity] - (optional) Numeric value of the light's strength/intensity. Default is 1.

+ [page:Integer color] - (参数可选)颜色的rgb数值。缺省值为 0xffffff。
+ [page:Float intensity] - (参数可选)光照的强度。缺省值为 1。

- Creates a new [name]. + 创建一个环境光对象。

-

Properties

+

属性

- See the base [page:Light Light] class for common properties. + 公共属性请查看基类 [page:Light Light]。

[property:Boolean castShadow]

- This is set to *undefined* in the constructor as ambient lights cannot cast shadows. + 这个参数在对象构造的时候就被设置成了 *undefined* 。因为环境光不能投射阴影。

[property:Boolean isAmbientLight]

- Used to check whether this or derived classes are ambient lights. Default is *true*.

+ 用来校验这个类或者派生类是不是环境光.默认是 *true*。

- You should not change this, as it used internally for optimisation. + 不应该去改变这个变量,因为内部使用这个变量做了些优化的工作。

-

Methods

+

方法

- See the base [page:Light Light] class for common methods. + 公共方法请查看基类[page:Light Light]。

-

Source

+

源码

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/zh/lights/DirectionalLight.html b/docs/api/zh/lights/DirectionalLight.html index 5c5a4cfa3c2f62..c7ab95e38c4d7e 100644 --- a/docs/api/zh/lights/DirectionalLight.html +++ b/docs/api/zh/lights/DirectionalLight.html @@ -1,5 +1,5 @@ - + @@ -10,35 +10,31 @@ [page:Object3D] → [page:Light] → -

[name]

+

平行光([name])

- A light that gets emitted in a specific direction. This light will behave as though it is - infinitely far away and the rays produced from it are all parallel. The common use case - for this is to simulate daylight; the sun is far enough away that its position can be - considered to be infinite, and all light rays coming from it are parallel.

+ 平行光是沿着特定方向发射的光。这种光的表现像是无限远,从它发出的光线都是平行的。常常用平行光来模拟太阳光 + 的效果; 太阳足够远,因此我们可以认为太阳的位置是无限远,所以我们认为从太阳发出的光线也都是平行的。

- This light can cast shadows - see the [page:DirectionalLightShadow] page for details. + 平行光可以投射阴影 - 跳转至 [page:DirectionalLightShadow] 查看更多细节。

-

A Note about Position, Target and rotation

+

关于位置、目标和旋转说明

- A common point of confusion for directional lights is that setting the rotation has no effect. - This is because three.js's DirectionalLight is the equivalent to what is often called a 'Target - Direct Light' in other applications.

+ Three.js 的平行光常见的困惑是设置旋转没有效果。这是因为 three.js 的平行光类似与其他引擎的"目标平行光"。 +

- This means that its direction is calculated as pointing - from the light's [page:Object3D.position position] to the [page:.target target]'s position - (as opposed to a 'Free Direct Light' that just has a rotation component).

+ 这意味着它的方向是从一个平行光的位置 [page:Object3D.position position] 到 [page:.target target]的位置。 + (而不是一个只有旋转分量的'自由平行光')。

- The reason for this is to allow the light to cast shadows - the [page:.shadow shadow] - camera needs a position to calculate shadows from.

+ 这样做的原因是为了让光线投射阴影。 - the [page:.shadow shadow] + 摄像机需要一个位置来计算阴影。

- See the [page:.target target] property below for details on updating the target. + 有关更新目标的详细信息,请参阅 [page:.target target] 下面的目标属性。

-

Example

+

示例

[example:canvas_morphtargets_horse morphtargets / horse ]
[example:misc_controls_fly controls / fly ]
@@ -58,62 +54,58 @@

Example

-

Constructor

+

构造器

[name]( [param:Integer color], [param:Float intensity] )

- [page:Integer color] - (optional) hexadecimal color of the light. Default is 0xffffff (white).
- [page:Float intensity] - (optional) numeric value of the light's strength/intensity. Default is 1.

+ [page:Integer color] - (可选参数) 16进制表示光的颜色。 缺省值为 0xffffff (白色)。
+ [page:Float intensity] - (可选参数) 光照的强度。缺省值为1。

- Creates a new [name]. + 创建一个新的 [name]。

-

Properties

+

属性

- See the base [page:Light Light] class for common properties. + 公共属性请查看基类 [page:Light Light]。

[property:Boolean castShadow]

- If set to *true* light will cast dynamic shadows. *Warning*: This is expensive and - requires tweaking to get shadows looking right. See the [page:DirectionalLightShadow] for details. - The default is *false*. + 如果设置为 *true* 该平行光会产生动态阴影。 警告: 这样做的代价比较高而且需要一直调整到阴影看起来正确. + 查看 [page:DirectionalLightShadow] 了解详细信息。该属性默认为 *false*。

[property:Boolean isDirectionalLight]

- Used to check whether this or derived classes are directional lights. Default is *true*.

+ 用来校验这个类或者派生类是不是平行光.默认是 *true*。

- You should not change this, as it is used internally for optimisation. + 不应该去改变这个变量,因为内部使用这个变量做了些优化的工作。

[property:Vector3 position]

- This is set equal to [page:Object3D.DefaultUp] (0, 1, 0), so that the light shines from the top down. + 假如这个值设置等于 [page:Object3D.DefaultUp] (0, 1, 0),那么光线将会从上往下照射。

[property:DirectionalLightShadow shadow]

- A [page:DirectionalLightShadow] used to calculate shadows for this light. + 这个 [page:DirectionalLightShadow] 对象用来计算该平行光产生的阴影。

[property:Object3D target]

- The DirectionalLight points from its [page:.position position] to target.position. The default - position of the target is *(0, 0, 0)*.
+ 平行光的方向是从它的位置到目标位置。默认的目标位置为原点 *(0,0,0)*。
- *Note*: For the target's position to be changed to anything other than the default, - it must be added to the [page:Scene scene] using + 注意: 对于目标的位置,要将其更改为除缺省值之外的任何位置,它必须被添加到 [page:Scene scene] + 场景中去。

scene.add( light.target );

- This is so that the target's [page:Object3D.matrixWorld matrixWorld] gets automatically - updated each frame.

- - It is also possible to set the target to be another object in the scene (anything with a - [page:Object3D.position position] property), like so: + 这使得属性target中的 [page:Object3D.matrixWorld matrixWorld] 会每帧自动更新。 +

+ 它也可以设置target为场景中的其他对象(任意拥有 [page:Object3D.position position] 属性的对象), 示例如下:

var targetObject = new THREE.Object3D(); @@ -122,21 +114,20 @@

[property:Object3D target]

light.target = targetObject;

- The directionalLight will now track the target object. + 完成上述操作后,平行光现在就可以追踪到目标对像了。

-

Methods

+

方法

- See the base [page:Light Light] class for common methods. + 公共方法请查看基类 [page:Light Light]。

[method:DirectionalLight copy]( [param:DirectionalLight source] )

- Copies value of all the properties from the [page:DirectionalLight source] to this - DirectionalLight. + 复制 source 的值到这个平行光源对象。

-

Source

+

源码

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/zh/lights/HemisphereLight.html b/docs/api/zh/lights/HemisphereLight.html index 2cd77b8037ba4f..60d0b26c67963b 100644 --- a/docs/api/zh/lights/HemisphereLight.html +++ b/docs/api/zh/lights/HemisphereLight.html @@ -10,16 +10,16 @@ [page:Object3D] → [page:Light] → -

[name]

+

半球光([name])

- A light source positioned directly above the scene, with color fading from the - sky color to the ground color.

+ 光源直接放置于场景之上,光照颜色从天空光线颜色颜色渐变到地面光线颜色。 +

- This light cannot be used to cast shadows. + 半球光不能投射阴影。

-

Example

+

示例

[example:webgl_lights_hemisphere lights / hemisphere ]
@@ -35,64 +35,64 @@

Example

scene.add( light ); -

Constructor

+

构造器(Constructor)

[name]( [param:Integer skyColor], [param:Integer groundColor], [param:Float intensity] )

- [page:Integer skyColor] - (optional) hexadecimal color of the sky. Default is 0xffffff.
- [page:Integer groundColor] - (optional) hexadecimal color of the ground. Default is 0xffffff.
- [page:Float intensity] - (optional) numeric value of the light's strength/intensity. Default is 1.

+ [page:Integer skyColor] - (可选参数) 天空中发出光线的颜色。 缺省值 0xffffff。
+ [page:Integer groundColor] - (可选参数) 地面发出光线的颜色。 缺省值 0xffffff。
+ [page:Float intensity] - (可选参数) 光照强度。 缺省值 1。

- Creates a new [name]. + 创建一个半球光。

-

Properties

+

属性(Properties)

- See the base [page:Light Light] class for common properties. + 公共属性请查看基类[page:Light Light]。

[property:Boolean castShadow]

- This is set to *undefined* in the constructor as hemisphere lights cannot cast shadows. + 该参数在构造时被设置为 *undefined* 因为半球光不能投射阴影。

[property:Float color]

- The light's sky color, as passed in the constructor. - Default is a new [page:Color] set to white (0xffffff). + 在构造时传递的天空发出光线的颜色。 + 默认会创建 [page:Color] 并设置为白色(0xffffff)。

[property:Float groundColor]

- The light's ground color, as passed in the constructor. - Default is a new [page:Color] set to white (0xffffff). + 在构造时传递的地面发出光线的颜色。 + 默认会创建 [page:Color] 并设置为白色(0xffffff)。

[property:Boolean isHemisphereLight]

- Used to check whether this or derived classes are hemisphere lights. Default is *true*.

+ 用来校验这个类或者派生类是不是半球光。缺省值为 *true*。

- You should not change this, as it used internally for optimisation. + 不应该去改变这个变量,因为内部使用这个变量做了些优化的工作。

[property:Vector3 position]

- This is set equal to [page:Object3D.DefaultUp] (0, 1, 0), so that the light shines from the top down. + 假如这个值设置等于 [page:Object3D.DefaultUp] (0, 1, 0),那么光线将会从上往下照射。

-

Methods

+

方法(Methods)

- See the base [page:Light Light] class for common methods. + 公共方法请查看基类 [page:Light Light]。

[method:HemisphereLight copy]( [param:HemisphereLight source] )

- Copies the value of [page:.color color], [page:.intensity intensity] and - [page:.groundColor groundColor] from the [page:Light source] light into this one. + 从[page:Light source]复制 [page:.color color], [page:.intensity intensity] 和 + [page:.groundColor groundColor] 的值到当前半球光对象中。

-

Source

+

源码

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/zh/lights/Light.html b/docs/api/zh/lights/Light.html index 70e673e4b2415d..ff8570b473ca4f 100644 --- a/docs/api/zh/lights/Light.html +++ b/docs/api/zh/lights/Light.html @@ -13,66 +13,66 @@

[name]

- Abstract base class for lights - all other light types inherit the properties and methods - described here. + 光源的基类 - 所有其他的光类型都继承了该类描述的属性和方法。

-

Constructor

+

构造器(Constructor)

[name]( [param:Integer color], [param:float intensity] )

- [page:Integer color] - (optional) hexadecimal color of the light. Default is 0xffffff (white).
- [page:Float intensity] - (optional) numeric value of the light's strength/intensity. Default is 1.

+ [page:Integer color] - (可选参数) 16进制表示光的颜色。 缺省值 0xffffff (白色)。
+ [page:Float intensity] - (可选参数) 光照强度。 缺省值 1。

- Creates a new [name]. Note that this is not intended to be called directly (use one of derived classes instead). + 创造一个新的光源。注意,这并不是直接调用的(而是使用派生类之一)。

-

Properties

+

属性(Properties)

- See the base [page:Object3D Object3D] class for common properties. + 公共属性请查看基类[page:Object3D Object3D]。

[property:Color color]

- Color of the light. Defaults to a new [page:Color] set to white, if not passed in the constructor.
+ 光源的颜色。如果构造的时候没有传递,默认会创建一个新的 [page:Color] 并设置为白色。

[property:Float intensity]

- The light's intensity, or strength.
- In [page:WebGLRenderer.physicallyCorrectLights physically correct] mode, the product of - [page:.color color] * intensity is interpreted as luminous intensity measured in candela.
- Default - *1.0*. + 光照的强度,或者说能量。 + 在 [page:WebGLRenderer.physicallyCorrectLights physically correct] 模式下, [page:.color color] 和强度 + 的乘积被解析为以坎德拉(candela)为单位的发光强度。 + 默认值 - *1.0* +

[property:Boolean isLight]

- Used to check whether this or derived classes are lights. Default is *true*.

+ 用来校验这个类或者派生类是不是平行光。默认是 *true*。

- You should not change this, as it used internally for optimisation. + 不应该去改变这个变量,因为内部使用这个变量做了些优化的工作。

Methods

- See the base [page:Object3D Object3D] class for common methods. + 公共方法请查看基类 [page:Object3D Object3D]。

[method:Light copy]( [param:Light source] )

- Copies the value of [page:.color color] and [page:.intensity intensity] from the - [page:Light source] light into this one. + 从[page:Light source]复制 [page:.color color], [page:.intensity intensity] + 的值到当前光源对象中。

[method:JSON toJSON]( [param:String meta] )

- Return Light data in JSON format. + 以JSON格式返回光数据。

-

Source

+

源码

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/zh/lights/PointLight.html b/docs/api/zh/lights/PointLight.html index db0ca22d0bb4e5..24ad2113e3603b 100644 --- a/docs/api/zh/lights/PointLight.html +++ b/docs/api/zh/lights/PointLight.html @@ -10,17 +10,16 @@ [page:Object3D] → [page:Light] → -

[name]

+

点光源([name])

- A light that gets emitted from a single point in all directions. A common use case for this - is to replicate the light emitted from a bare lightbulb.

- - This light can cast shadows - see [page:LightShadow] page for details. + 从一个点向各个方向发射的光源。一个常见的例子是模拟一个灯泡发出的光。 +

+ 该光源可以投射阴影 - 跳转至 [page:LightShadow] 查看更多细节。

-

Example

+

示例

[example:canvas_lights_pointlights lights / pointlights ]
@@ -39,77 +38,76 @@

Example

-

Constructor

+

构造器(Constructor)

[name]( [param:Integer color], [param:Float intensity], [param:Number distance], [param:Float decay] )

- [page:Integer color] - (optional) hexadecimal color of the light. Default is 0xffffff (white).
- [page:Float intensity] - (optional) numeric value of the light's strength/intensity. Default is 1.

- [page:Number distance] - The distance from the light where the intensity is 0. - When set to 0, then the light never stops. Default is 0.
- [page:Float decay] - The amount the light dims along the distance of the light. Default is 1. - For [page:WebGLRenderer.physicallyCorrectLights physically correct] lighting, set this to 2.

- - Creates a new [name]. + [page:Integer color] - (可选参数)) 十六进制光照颜色。 缺省值 0xffffff (白色)。
+ [page:Float intensity] - (可选参数) 光照强度。 缺省值 1。

+ [page:Number distance] - 这个距离表示从光源到光照强度为0的位置。 + 当设置为0时,光永远不会消失(距离无穷大)。缺省值 0.
+ [page:Float decay] - 沿着光照距离的衰退量。缺省值 1。 + + 在 [page:WebGLRenderer.physicallyCorrectLights physically correct] 模式中,decay = 2。

+ + 创建一个新的点光源(PointLight)。

-

Properties

+

属性(Properties)

- See the base [page:Light Light] class for common properties. + 公共属性请查看基类[page:Light Light]。

[property:Float decay]

- The amount the light dims along the distance of the light
- In [page:WebGLRenderer.physicallyCorrectLights physically correct] mode, decay = 2 leads to physically realistic light falloff.
- Default is *1*. + 沿着光照距离的衰减量
+ 在 [page:WebGLRenderer.physicallyCorrectLights physically correct] 模式下,decay 设置为等于2将实现现实世界的光衰减。
+ 缺省值为 *1*。

[property:Float distance]

- If non-zero, light will attenuate linearly from maximum intensity at the light's - position down to zero at this distance from the light. Default is *0.0*. + 如果非零,那么光强度将会从最大值当前灯光位置处按照距离线性衰减到0。 + 缺省值为 *0.0*。

[property:Boolean isPointLight]

- Used to check whether this or derived classes are point lights. Default is *true*.

+ 用来校验这个类或者派生类是不是点光源。默认是 *true*。

- You should not change this, as it used internally for optimisation. + 不应该去改变这个变量,因为内部使用这个变量做了些优化的工作。

[property:Float power]

- The light's power.
- In [page:WebGLRenderer.physicallyCorrectLights physically correct] mode, the luminous - power of the light measured in lumens. Default is *4Math.PI*.

- - This is directly related to the [page:.intensity intensity] in the ratio - + 光功率
+ 在 [page:WebGLRenderer.physicallyCorrectLights physically correct] 模式中, + 表示以"流明(光通量单位)"为单位的光功率。 缺省值 - *4Math.PI*。

+ + 该值与 [page:.intensity intensity] 直接关联 + power = intensity * 4π - and changing this will also change the intensity. + 修改该值也会导致光强度的改变。

[property:LightShadow shadow]

- A [page:LightShadow] used to calculate shadows for this light.

- - The lightShadow's [page:LightShadow.camera camera] - is set to a [page:PerspectiveCamera] with [page:PerspectiveCamera.fov fov] of 90, - [page:PerspectiveCamera.aspect aspect] of 1, [page:PerspectiveCamera.near near] - clipping plane at 0.5 and [page:PerspectiveCamera.far far] clipping plane at 500. + [page:LightShadow]用与计算此光照的阴影。

+ + 此对象的摄像机被设置为 [page:PerspectiveCamera.fov fov] 为90度,[page:PerspectiveCamera.aspect aspect]为1 + ,近裁剪面 [page:PerspectiveCamera.near near] 为0,远裁剪面[page:PerspectiveCamera.far far] + 为500的透视摄像机 [page:PerspectiveCamera]。

-

Methods

+

方法(Methods)

- See the base [page:Light Light] class for common methods. + 公共方法请查看基类 [page:Light Light]。

[method:PointLight copy]( [param:PointLight source] )

- Copies value of all the properties from the [page:PointLight source] to this - PointLight. + 将所有属性的值从源 [page:PointLight source] 复制到此点光源对象。

Source

diff --git a/docs/api/zh/lights/RectAreaLight.html b/docs/api/zh/lights/RectAreaLight.html index 4f188f540cc04c..bf0bb6f8d3c95f 100644 --- a/docs/api/zh/lights/RectAreaLight.html +++ b/docs/api/zh/lights/RectAreaLight.html @@ -10,23 +10,22 @@ [page:Object3D] → [page:Light] → -

[name]

+

平面光光源([name])

- RectAreaLight emits light uniformly across the face a rectangular plane. This light type can be - used to simulate light sources such as bright windows or strip lighting.

+ 平面光光源从一个矩形平面上均匀地发射光线。这种光源可以用来模拟像明亮的窗户或者条状灯光光源。

- Important Notes: + 注意事项:

    -
  • There is no shadow support.
  • -
  • Only [page:MeshStandardMaterial MeshStandardMaterial] and [page:MeshPhysicalMaterial MeshPhysicalMaterial] are supported.
  • -
  • You have to include [link:https://threejs.org/examples/js/lights/RectAreaLightUniformsLib.js RectAreaLightUniformsLib] into your scene.
  • +
  • 不支持阴影。
  • +
  • 只支持 [page:MeshStandardMaterial MeshStandardMaterial] 和 [page:MeshPhysicalMaterial MeshPhysicalMaterial] 两种材质。
  • +
  • 你必须在你的场景中加入 [link:https://threejs.org/examples/js/lights/RectAreaLightUniformsLib.js RectAreaLightUniformsLib] 。

-

Examples

+

示例

[example:webgl_lights_rectarealight WebGL / rectarealight ] @@ -47,41 +46,40 @@

Examples

-

Constructor

+

构造器(Constructor)

[name]( [param:Integer color], [param:Float intensity], [param:Float width], [param:Float height] )

- [page:Integer color] - (optional) hexadecimal color of the light. Default is 0xffffff (white).
- [page:Float intensity] - (optional) the light's intensity, or brightness. Default is 1.
- [page:Float width] - (optional) width of the light. Default is 10.
- [page:Float height] - (optional) height of the light. Default is 10.

+ [page:Integer color] - (可选参数) 十六进制数字表示的光照颜色。缺省值为 0xffffff (白色)
+ [page:Float intensity] - (可选参数) 光源强度/亮度 。缺省值为 1。
+ [page:Float width] - (可选参数) 光源宽度。缺省值为 10。
+ [page:Float height] - (可选参数) 光源高度。缺省值为 10。

- Creates a new [name]. + 创建一个新的平行光。

-

Properties

+

属性(Properties)

- See the base [page:Light Light] class for common properties. + 公共属性请查看基类[page:Light Light]。

[property:Boolean isRectAreaLight]

- Used to check whether this or derived classes are RectAreaLights. Default is *true*.

+ 用来校验这个类或者它的派生类是不是平面光光源。缺省值是 *true*。

- You should not change this, as it used internally for optimisation. + 不应该去改变这个变量,因为内部使用这个变量做了些优化的工作。

-

Methods

+

方法(Methods)

- See the base [page:Light Light] class for common methods. + 公共方法请查看基类 [page:Light Light]。

[method:RectAreaLight copy]( [param:RectAreaLight source] )

- Copies value of all the properties from the [page:RectAreaLight source] to this - RectAreaLight. + 将所有属性的值从源 [page:RectAreaLight source] 复制到此平面光光源对象。

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/zh/lights/SpotLight.html b/docs/api/zh/lights/SpotLight.html index f21fed3d5dd2c9..d257e03cb77c90 100644 --- a/docs/api/zh/lights/SpotLight.html +++ b/docs/api/zh/lights/SpotLight.html @@ -10,26 +10,25 @@ [page:Object3D] → [page:Light] → -

[name]

+

聚光灯([name])

- This light gets emitted from a single point in one direction, along a cone that increases in size - the further from the light it gets.

+ 聚光灯是从一个方向上的一个点发出,沿着一个圆锥体,它离光越远,它的尺寸就越大。

- This light can cast shadows - see the [page:SpotLightShadow] page for details. + 该光源可以投射阴影 - 跳转至 [page:SpotLightShadow] 查看更多细节。

-

Example

+

示例

[example:webgl_lights_spotlight View in Examples ]

-

Other Examples

+

其他例子

[example:webgl_interactive_cubes_gpu interactive / cubes / gpu ]
@@ -45,7 +44,7 @@

Other Examples

[example:webgl_shadowmap_viewer shadowmap / viewer]

-

Code Example

+

代码示例

// white spotlight shining from the side, casting a shadow @@ -64,126 +63,117 @@

Code Example

scene.add( spotLight );
-

Constructor

+

构造器(Constructor)

[name]( [param:Integer color], [param:Float intensity], [param:Float distance], [param:Radians angle], [param:Float penumbra], [param:Float decay] )

- [page:Integer color] - (optional) hexadecimal color of the light. Default is 0xffffff (white).
- [page:Float intensity] - (optional) numeric value of the light's strength/intensity. Default is 1.

- [page:Float distance] - Maximum distance from origin where light will shine whose intensity - is attenuated linearly based on distance from origin.
- [page:Radians angle] - Maximum angle of light dispersion from its direction whose upper - bound is Math.PI/2.
- [page:Float penumbra] - Percent of the spotlight cone that is attenuated due to penumbra. - Takes values between zero and 1. Default is zero.
- [page:Float decay] - The amount the light dims along the distance of the light.

- - Creates a new [name]. + [page:Integer color] - (可选参数) 十六进制光照颜色。 缺省值 0xffffff (白色)。
+ [page:Float intensity] - (可选参数) 光照强度。 缺省值 1。

+ [page:Float distance] - 从光源发出光的最大距离,其强度根据光源的距离线性衰减。
+ [page:Radians angle] - 光线散射角度,最大为Math.PI/2。
+ [page:Float penumbra] - 聚光锥的半影衰减百分比。在0和1之间的值。默认为0。
+ [page:Float decay] - 沿着光照距离的衰减量。

+ + 创建一个新的聚光灯。

-

Properties

+

属性(Properties)

- See the base [page:Light Light] class for common properties. + 公共属性请查看基类[page:Light Light]。

[property:Float angle]

- Maximum extent of the spotlight, in radians, from its direction. Should be no more than - *Math.PI/2*. The default is *Math.PI/3*. + 从聚光灯的位置以弧度表示聚光灯的最大范围。应该不超过 *Math.PI/2*。默认值为 *Math.PI/3*。

[property:Boolean castShadow]

- If set to *true* light will cast dynamic shadows. *Warning*: This is expensive and - requires tweaking to get shadows looking right. See the [page:SpotLightShadow] for details. - The default is *false*. + 此属性设置为 *true* 聚光灯将投射阴影。警告: 这样做的代价比较高而且需要一直调整到阴影看起来正确。 + 查看 [page:SpotLightShadow] 了解详细信息。 + 默认值为 *false*

[property:Float decay]

- The amount the light dims along the distance of the light.
- In [page:WebGLRenderer.physicallyCorrectLights physically correct] mode, decay = 2 leads to - physically realistic light falloff. The default is *1*. + 沿着光照距离的衰减量
+ 在 [page:WebGLRenderer.physicallyCorrectLights physically correct] 模式下,decay 设置为等于2将实现现实世界的光衰减。
+ 缺省值为 *1*。

[property:Float distance]

- If non-zero, light will attenuate linearly from maximum intensity at the light's - position down to zero at this distance from the light. Default is *0.0*. + 如果非零,那么光强度将会从最大值当前灯光位置处按照距离线性衰减到0。 + 缺省值为 *0.0*。

[property:Boolean isSpotLight]

- Used to check whether this or derived classes are spot lights. Default is *true*.

+ 用来校验这个类或者它的派生类是不是聚光灯光源。缺省值是 *true*。

- You should not change this, as it used internally for optimisation. + 不应该去改变这个变量,因为内部使用这个变量做了些优化的工作。

[property:Float penumbra]

- Percent of the spotlight cone that is attenuated due to penumbra. Takes values between - zero and 1. The default is *0.0*. + 聚光锥的半影衰减百分比。在0和1之间的值。 + 默认值 — 0.0。

[property:Vector3 position]

- This is set equal to [page:Object3D.DefaultUp] (0, 1, 0), so that the light shines from the top down. + 假如这个值设置等于 [page:Object3D.DefaultUp] (0, 1, 0),那么光线将会从上往下照射。

[property:Float power]

- The light's power.
- In [page:WebGLRenderer.physicallyCorrectLights physically correct] mode, the luminous - power of the light measured in lumens. Default is *4Math.PI*.

- - This is directly related to the [page:.intensity intensity] in the ratio - - power = intensity * π + 光功率
+ 在 [page:WebGLRenderer.physicallyCorrectLights physically correct] 模式中, + 表示以"流明(光通量单位)"为单位的光功率。 缺省值 - *4Math.PI*。

+ + 该值与 [page:.intensity intensity] 直接关联 + + power = intensity * 4π - and changing this will also change the intensity. + 修改该值也会导致光强度的改变。

[property:SpotLightShadow shadow]

- A [page:SpotLightShadow] used to calculate shadows for this light. + [page:SpotLightShadow]用与计算此光照的阴影。

[property:Object3D target]

- The Spotlight points from its [page:.position position] to target.position. The default - position of the target is *(0, 0, 0)*.
- - *Note*: For the target's position to be changed to anything other than the default, - it must be added to the [page:Scene scene] using + 平行光的方向是从它的位置到目标位置.默认的目标位置为原点 *(0,0,0)*。
+ 注意: 对于目标的位置,要将其更改为除缺省值之外的任何位置,它必须被添加到 [page:Scene scene] + 场景中去。 scene.add( light.target ); - This is so that the target's [page:Object3D.matrixWorld matrixWorld] gets automatically - updated each frame.

+ 这使得属性target中的 [page:Object3D.matrixWorld matrixWorld] 会每帧自动更新。

- It is also possible to set the target to be another object in the scene (anything with a - [page:Object3D.position position] property), like so: + 它也可以设置target为场景中的其他对象(任意拥有 [page:Object3D.position position] 属性的对象), 示例如下: var targetObject = new THREE.Object3D(); scene.add(targetObject); light.target = targetObject; - The spotlight will now track the target object. + 完成上述操作后,聚光灯现在就可以追踪到目标对像了。

-

Methods

+

方法(Methods)

- See the base [page:Light Light] class for common methods. + 公共方法请查看基类 [page:Light Light]。

[method:SpotLight copy]( [param:SpotLight source] )

- Copies value of all the properties from the [page:SpotLight source] to this - SpotLight. + 将所有属性的值从源 [page:SpotLight source] 复制到此聚光灯光源对象。

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] From 7e4240fbca6bd81f11e09e3916ef0b492addb629 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 26 Sep 2018 23:54:51 +0900 Subject: [PATCH 14/50] GLTFLoader Extension Example: Fix Spotlight --- examples/webgl_loader_gltf_extensions.html | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/webgl_loader_gltf_extensions.html b/examples/webgl_loader_gltf_extensions.html index 7eb1fcef031808..b4869d0c4c9733 100644 --- a/examples/webgl_loader_gltf_extensions.html +++ b/examples/webgl_loader_gltf_extensions.html @@ -211,6 +211,7 @@ spot1.position.set( 10, 20, 10 ); spot1.angle = 0.25; spot1.penumbra = 0.75; + spot1.decay = 0.0001; if ( sceneInfo.shadows ) { From b912545efbf45209168fb371af2e35184a411489 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Thu, 27 Sep 2018 01:15:29 +0900 Subject: [PATCH 15/50] GLTFLoader Example: Adjust spot light and objects --- examples/webgl_loader_gltf_extensions.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/webgl_loader_gltf_extensions.html b/examples/webgl_loader_gltf_extensions.html index b4869d0c4c9733..ff0fd64b0c8290 100644 --- a/examples/webgl_loader_gltf_extensions.html +++ b/examples/webgl_loader_gltf_extensions.html @@ -115,9 +115,9 @@ url: './models/gltf/Monster/%s/Monster.gltf', author: '3drt.com', authorURL: 'http://www.3drt.com/downloads.htm', - cameraPos: new THREE.Vector3( 30, 10, 70 ), - objectScale: new THREE.Vector3( 0.4, 0.4, 0.4 ), - objectPosition: new THREE.Vector3( 2, 1, 0 ), + cameraPos: new THREE.Vector3( 3, 1, 7 ), + objectScale: new THREE.Vector3( 0.04, 0.04, 0.04 ), + objectPosition: new THREE.Vector3( 0.2, 0.1, 0 ), objectRotation: new THREE.Euler( 0, - 3 * Math.PI / 4, 0 ), animationTime: 3, addLights: true, @@ -208,10 +208,11 @@ scene.add( directionalLight ); spot1 = new THREE.SpotLight( 0xffffff, 1 ); - spot1.position.set( 10, 20, 10 ); - spot1.angle = 0.25; + spot1.position.set( 5, 10, 5 ); + spot1.angle = 0.50; spot1.penumbra = 0.75; - spot1.decay = 0.0001; + spot1.intensity = 100; + spot1.decay = 2; if ( sceneInfo.shadows ) { @@ -309,7 +310,6 @@ if ( spot1 ) { - spot1.position.set( sceneInfo.objectPosition.x - 100, sceneInfo.objectPosition.y + 200, sceneInfo.objectPosition.z - 100 ); spot1.target.position.copy( sceneInfo.objectPosition ); } From 963bcc8144224f248f6d4687d95d3b191c0712df Mon Sep 17 00:00:00 2001 From: Mugen87 Date: Wed, 26 Sep 2018 19:25:51 +0200 Subject: [PATCH 16/50] ObjectLoader: Added setPath(), setTexturePath() -> setResourcePath(). --- docs/api/en/loaders/ObjectLoader.html | 13 +++++++----- editor/js/Loader.js | 2 +- src/Three.Legacy.js | 12 +++++++++++ src/loaders/ObjectLoader.js | 30 ++++++++++++++++----------- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/docs/api/en/loaders/ObjectLoader.html b/docs/api/en/loaders/ObjectLoader.html index 95a7c0f2e40262..2fe83f2f67e169 100644 --- a/docs/api/en/loaders/ObjectLoader.html +++ b/docs/api/en/loaders/ObjectLoader.html @@ -85,9 +85,9 @@

[property:LoadingManager manager]

The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager].

-

[property:String texturePath]

+

[property:String resourcePath]

- The base path or URL from which textures will be loaded. See [page:.setTexturePath]. + The base path or URL from which additional resources like textuures will be loaded. See [page:.setResourcePath]. Default is the empty string.

@@ -217,11 +217,14 @@

[method:ObjectLoader setCrossOrigin]( [param:String value] )

[page:String value] — The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS.

-

[method:ObjectLoader setTexturePath]( [param:String value] )

+

[method:ObjectLoader setPath]( [param:String value] )

- [page:String value] — The base path or URL from which textures will be loaded.

- + Set the base path for the original file. +

+

[method:ObjectLoader setResourcePath]( [param:String value] )

+

+ Set the base path for dependent resources like textures.

Source

diff --git a/editor/js/Loader.js b/editor/js/Loader.js index 1357e067ff13aa..30b7c4841e848f 100644 --- a/editor/js/Loader.js +++ b/editor/js/Loader.js @@ -626,7 +626,7 @@ var Loader = function ( editor ) { case 'object': var loader = new THREE.ObjectLoader(); - loader.setTexturePath( scope.texturePath ); + loader.setResourcePath( scope.texturePath ); var result = loader.parse( data ); diff --git a/src/Three.Legacy.js b/src/Three.Legacy.js index bcf4da484af2c2..456d75b1254074 100644 --- a/src/Three.Legacy.js +++ b/src/Three.Legacy.js @@ -45,6 +45,7 @@ import { AudioLoader } from './loaders/AudioLoader.js'; import { CubeTextureLoader } from './loaders/CubeTextureLoader.js'; import { DataTextureLoader } from './loaders/DataTextureLoader.js'; import { JSONLoader } from './loaders/JSONLoader.js'; +import { ObjectLoader } from './loaders/ObjectLoader.js'; import { TextureLoader } from './loaders/TextureLoader.js'; import { Material } from './materials/Material.js'; import { LineBasicMaterial } from './materials/LineBasicMaterial.js'; @@ -447,6 +448,17 @@ Object.assign( JSONLoader.prototype, { } ); +Object.assign( ObjectLoader.prototype, { + + setTexturePath: function ( value ) { + + console.warn( 'THREE.ObjectLoader: .setTexturePath() has been renamed to .setResourcePath().' ); + return this.setResourcePath( value ); + + } + +} ); + // Object.assign( Box2.prototype, { diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 2ff101e72c17ff..b951a645f67fac 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -48,6 +48,7 @@ import { ImageLoader } from './ImageLoader.js'; import { LoadingManager, DefaultLoadingManager } from './LoadingManager.js'; import { AnimationClip } from '../animation/AnimationClip.js'; import { MaterialLoader } from './MaterialLoader.js'; +import { LoaderUtils } from './LoaderUtils.js'; import { BufferGeometryLoader } from './BufferGeometryLoader.js'; import { JSONLoader } from './JSONLoader.js'; import { FileLoader } from './FileLoader.js'; @@ -61,7 +62,7 @@ import * as Curves from '../extras/curves/Curves.js'; function ObjectLoader( manager ) { this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - this.texturePath = ''; + this.resourcePath = ''; } @@ -71,15 +72,13 @@ Object.assign( ObjectLoader.prototype, { load: function ( url, onLoad, onProgress, onError ) { - if ( this.texturePath === '' ) { - - this.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 ); - - } - var scope = this; + var path = ( this.path === undefined ) ? LoaderUtils.extractUrlBase( url ) : this.path; + this.resourcePath = this.resourcePath || path; + var loader = new FileLoader( scope.manager ); + loader.setPath( this.path ); loader.load( url, function ( text ) { var json = null; @@ -113,9 +112,16 @@ Object.assign( ObjectLoader.prototype, { }, - setTexturePath: function ( value ) { + setPath: function ( value ) { + + this.path = value; + return this; + + }, + + setResourcePath: function ( value ) { - this.texturePath = value; + this.resourcePath = value; return this; }, @@ -418,7 +424,7 @@ Object.assign( ObjectLoader.prototype, { case 'Geometry': - geometry = geometryLoader.parse( data, this.texturePath ).geometry; + geometry = geometryLoader.parse( data, this.resourcePath ).geometry; break; @@ -550,7 +556,7 @@ Object.assign( ObjectLoader.prototype, { var currentUrl = url[ j ]; - var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( currentUrl ) ? currentUrl : scope.texturePath + currentUrl; + var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( currentUrl ) ? currentUrl : scope.resourcePath + currentUrl; images[ image.uuid ].push( loadImage( path ) ); @@ -560,7 +566,7 @@ Object.assign( ObjectLoader.prototype, { // load single image - var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url; + var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.resourcePath + image.url; images[ image.uuid ] = loadImage( path ); From c9d90a72688f6bde9c285a72f51c6c9aa84af074 Mon Sep 17 00:00:00 2001 From: Vlado Velichkovski Date: Thu, 27 Sep 2018 12:51:06 +0200 Subject: [PATCH 17/50] Update DRACOLoader.js Browser compatibility and fix uglifier error 'Unexpected token: keyword (const)' --- examples/js/loaders/DRACOLoader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/js/loaders/DRACOLoader.js b/examples/js/loaders/DRACOLoader.js index c4c795f14bc22b..091615bf02d7dc 100644 --- a/examples/js/loaders/DRACOLoader.js +++ b/examples/js/loaders/DRACOLoader.js @@ -236,7 +236,7 @@ THREE.DRACOLoader.prototype = { } var dracoGeometry; var decodingStatus; - const start_time = performance.now(); + var start_time = performance.now(); if (geometryType === dracoDecoder.TRIANGULAR_MESH) { dracoGeometry = new dracoDecoder.Mesh(); decodingStatus = decoder.DecodeBufferToMesh(buffer, dracoGeometry); From 1e2dcbd8a38475aebabae38785372131cf24159f Mon Sep 17 00:00:00 2001 From: James Baicoianu Date: Thu, 27 Sep 2018 22:29:31 -0700 Subject: [PATCH 18/50] Use image.src if HTMLCanvasElement is undefined --- src/extras/ImageUtils.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/extras/ImageUtils.js b/src/extras/ImageUtils.js index ec95b524739611..0622114e59fff1 100644 --- a/src/extras/ImageUtils.js +++ b/src/extras/ImageUtils.js @@ -10,7 +10,11 @@ var ImageUtils = { var canvas; - if ( image instanceof HTMLCanvasElement ) { + if ( typeof HTMLCanvasElement == 'undefined' ) { + + return image.src; + + } if ( image instanceof HTMLCanvasElement ) { canvas = image; From 492bcfe2ffaba1cc5a704b01a9b9e0c91165edad Mon Sep 17 00:00:00 2001 From: Mugen87 Date: Fri, 28 Sep 2018 17:04:24 +0200 Subject: [PATCH 19/50] Loaders: Added missing .setPath() in remaining core loaders. --- docs/api/en/loaders/AnimationLoader.html | 8 +++++++ docs/api/en/loaders/AudioLoader.html | 8 +++++++ docs/api/en/loaders/BufferGeometryLoader.html | 8 +++++++ docs/api/en/loaders/DataTextureLoader.html | 8 +++++++ docs/api/en/loaders/MaterialLoader.html | 12 ++++++++--- src/loaders/AnimationLoader.js | 8 +++++++ src/loaders/AudioLoader.js | 8 +++++++ src/loaders/BufferGeometryLoader.js | 8 +++++++ src/loaders/DataTextureLoader.js | 9 +++++++- src/loaders/MaterialLoader.js | 21 +++++++++++++------ 10 files changed, 88 insertions(+), 10 deletions(-) diff --git a/docs/api/en/loaders/AnimationLoader.html b/docs/api/en/loaders/AnimationLoader.html index 7fea709445d99c..90f3ed6fd146ce 100644 --- a/docs/api/en/loaders/AnimationLoader.html +++ b/docs/api/en/loaders/AnimationLoader.html @@ -81,6 +81,14 @@

[method:null parse]( [param:JSON json], [param:Function onLoad] )

be parsed with [page:AnimationClip.parse].

+

[method:AnimationLoader setPath]( [param:String path] )

+

+ [page:String path] — Base path of the file to load.

+ + Sets the base path or URL from which to load files. This can be useful if + you are loading many animations from the same directory. +

+

Source

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/en/loaders/AudioLoader.html b/docs/api/en/loaders/AudioLoader.html index be2dad7b3f8b86..39cfe23c9319d8 100644 --- a/docs/api/en/loaders/AudioLoader.html +++ b/docs/api/en/loaders/AudioLoader.html @@ -92,6 +92,14 @@

[method:null load]( [param:String url], [param:Function onLoad], [param:Func Begin loading from url and pass the loaded [page:String AudioBuffer] to onLoad.

+

[method:AudioLoader setPath]( [param:String path] )

+

+ [page:String path] — Base path of the file to load.

+ + Sets the base path or URL from which to load files. This can be useful if + you are loading many audios from the same directory. +

+

Source

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/en/loaders/BufferGeometryLoader.html b/docs/api/en/loaders/BufferGeometryLoader.html index 848b06bf4a7d11..6ff54cb87cb046 100644 --- a/docs/api/en/loaders/BufferGeometryLoader.html +++ b/docs/api/en/loaders/BufferGeometryLoader.html @@ -85,6 +85,14 @@

[method:BufferGeometry parse]( [param:Object json] )

Parse a JSON structure and return a [page:BufferGeometry].

+

[method:BufferGeometryLoader setPath]( [param:String path] )

+

+ [page:String path] — Base path of the file to load.

+ + Sets the base path or URL from which to load files. This can be useful if + you are loading many geometries from the same directory. +

+

Source

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/en/loaders/DataTextureLoader.html b/docs/api/en/loaders/DataTextureLoader.html index af83b27fec5d82..707914fb8c8011 100644 --- a/docs/api/en/loaders/DataTextureLoader.html +++ b/docs/api/en/loaders/DataTextureLoader.html @@ -56,6 +56,14 @@

[method:null load]( [param:String url], [param:Function onLoad], [param:Func Begin loading from url and pass the loaded texture to onLoad.

+

[method:DataTextureLoader setPath]( [param:String path] )

+

+ [page:String path] — Base path of the file to load.

+ + Sets the base path or URL from which to load files. This can be useful if + you are loading many data textures from the same directory. +

+

Source

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/en/loaders/MaterialLoader.html b/docs/api/en/loaders/MaterialLoader.html index b931c50591b351..5f9bdf1ee26841 100644 --- a/docs/api/en/loaders/MaterialLoader.html +++ b/docs/api/en/loaders/MaterialLoader.html @@ -84,12 +84,18 @@

[method:Material parse]( [param:Object json] )

Parse a JSON structure and create a new [page:Material] of the type [page:String json.type] with parameters defined in the json object.

-

[method:null setTextures]( [param:Object textures] )

+

[method:MaterialLoader setPath]( [param:String path] )

- [page:Object textures] — object containing any textures used by the material. -

+ [page:String path] — Base path of the file to load.

+ Sets the base path or URL from which to load files. This can be useful if + you are loading many materials from the same directory. +

+

[method:MaterialLoader setTextures]( [param:Object textures] )

+

+ [page:Object textures] — object containing any textures used by the material. +

Source

diff --git a/src/loaders/AnimationLoader.js b/src/loaders/AnimationLoader.js index 0e3ab97c346be0..161ebf9446744b 100644 --- a/src/loaders/AnimationLoader.js +++ b/src/loaders/AnimationLoader.js @@ -19,6 +19,7 @@ Object.assign( AnimationLoader.prototype, { var scope = this; var loader = new FileLoader( scope.manager ); + loader.setPath( scope.path ); loader.load( url, function ( text ) { onLoad( scope.parse( JSON.parse( text ) ) ); @@ -41,6 +42,13 @@ Object.assign( AnimationLoader.prototype, { onLoad( animations ); + }, + + setPath: function ( value ) { + + this.path = value; + return this; + } } ); diff --git a/src/loaders/AudioLoader.js b/src/loaders/AudioLoader.js index a182ddc8e75930..b9a5d610b86a9b 100644 --- a/src/loaders/AudioLoader.js +++ b/src/loaders/AudioLoader.js @@ -18,6 +18,7 @@ Object.assign( AudioLoader.prototype, { var loader = new FileLoader( this.manager ); loader.setResponseType( 'arraybuffer' ); + loader.setPath( this.path ); loader.load( url, function ( buffer ) { // Create a copy of the buffer. The `decodeAudioData` method @@ -33,6 +34,13 @@ Object.assign( AudioLoader.prototype, { }, onProgress, onError ); + }, + + setPath: function ( value ) { + + this.path = value; + return this; + } } ); diff --git a/src/loaders/BufferGeometryLoader.js b/src/loaders/BufferGeometryLoader.js index 2c6b4b2905ffc0..381c2248b5f2f8 100644 --- a/src/loaders/BufferGeometryLoader.js +++ b/src/loaders/BufferGeometryLoader.js @@ -22,6 +22,7 @@ Object.assign( BufferGeometryLoader.prototype, { var scope = this; var loader = new FileLoader( scope.manager ); + loader.setPath( scope.path ); loader.load( url, function ( text ) { onLoad( scope.parse( JSON.parse( text ) ) ); @@ -86,6 +87,13 @@ Object.assign( BufferGeometryLoader.prototype, { return geometry; + }, + + setPath: function ( value ) { + + this.path = value; + return this; + } } ); diff --git a/src/loaders/DataTextureLoader.js b/src/loaders/DataTextureLoader.js index 96770a0a2b4e6a..49f4d90ec80bec 100644 --- a/src/loaders/DataTextureLoader.js +++ b/src/loaders/DataTextureLoader.js @@ -28,7 +28,7 @@ Object.assign( DataTextureLoader.prototype, { var loader = new FileLoader( this.manager ); loader.setResponseType( 'arraybuffer' ); - + loader.setPath( this.path ); loader.load( url, function ( buffer ) { var texData = scope._parser( buffer ); @@ -87,6 +87,13 @@ Object.assign( DataTextureLoader.prototype, { return texture; + }, + + setPath: function ( value ) { + + this.path = value; + return this; + } } ); diff --git a/src/loaders/MaterialLoader.js b/src/loaders/MaterialLoader.js index 97d8e9031f3c55..fbd754060a8612 100644 --- a/src/loaders/MaterialLoader.js +++ b/src/loaders/MaterialLoader.js @@ -25,6 +25,7 @@ Object.assign( MaterialLoader.prototype, { var scope = this; var loader = new FileLoader( scope.manager ); + loader.setPath( scope.path ); loader.load( url, function ( text ) { onLoad( scope.parse( JSON.parse( text ) ) ); @@ -33,12 +34,6 @@ Object.assign( MaterialLoader.prototype, { }, - setTextures: function ( value ) { - - this.textures = value; - - }, - parse: function ( json ) { var textures = this.textures; @@ -219,6 +214,20 @@ Object.assign( MaterialLoader.prototype, { return material; + }, + + setPath: function ( value ) { + + this.path = value; + return this; + + }, + + setTextures: function ( value ) { + + this.textures = value; + return this; + } } ); From 5f85016762ea8131cd7347bb9837bc4a6cf156cb Mon Sep 17 00:00:00 2001 From: WestLangley Date: Sun, 30 Sep 2018 16:58:21 -0400 Subject: [PATCH 20/50] Make thrown exceptions more informative --- examples/js/loaders/EXRLoader.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/js/loaders/EXRLoader.js b/examples/js/loaders/EXRLoader.js index 528c651c0a1420..c7bb432e5a058c 100644 --- a/examples/js/loaders/EXRLoader.js +++ b/examples/js/loaders/EXRLoader.js @@ -929,7 +929,12 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) { 'RLE_COMPRESSION', 'ZIPS_COMPRESSION', 'ZIP_COMPRESSION', - 'PIZ_COMPRESSION' + 'PIZ_COMPRESSION', + 'PXR24_COMPRESSION', + 'B44_COMPRESSION', + 'B44A_COMPRESSION', + 'DWAA_COMPRESSION', + 'DWAB_COMPRESSION' ]; var compression = parseUint8( dataView, offset ); @@ -1109,7 +1114,7 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) { } else { - throw 'Only supported pixel format is HALF'; + throw 'EXRLoader._parser: unsupported pixelType ' + EXRHeader.channels[ channelID ].pixelType + '. Only pixelType is 1 (HALF) is supported.'; } @@ -1151,7 +1156,7 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) { } else { - throw 'Only supported pixel format is HALF'; + throw 'EXRLoader._parser: unsupported pixelType ' + EXRHeader.channels[ channelID ].pixelType + '. Only pixelType is 1 (HALF) is supported.'; } @@ -1163,7 +1168,7 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) { } else { - throw 'Cannot decompress unsupported compression'; + throw 'EXRLoader._parser: ' + EXRHeader.compression + ' is unsupported'; } From 70ff172db2f55c0afa3c39d64c00ffca3ea5fb65 Mon Sep 17 00:00:00 2001 From: Yaroslav Khudchenko Date: Wed, 3 Oct 2018 01:05:08 +0200 Subject: [PATCH 21/50] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 526c8f04ee9920..f0811490c65ba6 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ If everything went well you should see [this](https://jsfiddle.net/f2Lommf5/). ### Change log ### -[releases](https://github.com/mrdoob/three.js/releases) +[Releases](https://github.com/mrdoob/three.js/releases) [npm-badge]: https://img.shields.io/npm/v/three.svg From 6f41c43af222b378beea61d0af7473c8868fdb62 Mon Sep 17 00:00:00 2001 From: Babatunde Ogunfemi Date: Wed, 3 Oct 2018 14:52:36 -0500 Subject: [PATCH 22/50] Fix for PCD Loader to display proper RGB values This fixes #12207 to ensure the right color values are displayed. This fixes both ascii and binary data file renderings. --- examples/js/loaders/PCDLoader.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/js/loaders/PCDLoader.js b/examples/js/loaders/PCDLoader.js index 52505b9a383398..19d22e92922780 100644 --- a/examples/js/loaders/PCDLoader.js +++ b/examples/js/loaders/PCDLoader.js @@ -205,11 +205,11 @@ THREE.PCDLoader.prototype = { if ( offset.rgb !== undefined ) { - var c = new Float32Array( [ parseFloat( line[ offset.rgb ] ) ] ); - var dataview = new DataView( c.buffer, 0 ); - color.push( dataview.getUint8( 0 ) / 255.0 ); - color.push( dataview.getUint8( 1 ) / 255.0 ); - color.push( dataview.getUint8( 2 ) / 255.0 ); + var rgb = parseFloat( line[ offset.rgb ] ); + var r = ( rgb >> 16 ) & 0x0000ff; + var g = ( rgb >> 8 ) & 0x0000ff; + var b = ( rgb >> 0 ) & 0x0000ff; + color.push( r / 255, g / 255, b / 255 ); } @@ -251,9 +251,9 @@ THREE.PCDLoader.prototype = { if ( offset.rgb !== undefined ) { - color.push( dataview.getUint8( row + offset.rgb + 0 ) / 255.0 ); - color.push( dataview.getUint8( row + offset.rgb + 1 ) / 255.0 ); color.push( dataview.getUint8( row + offset.rgb + 2 ) / 255.0 ); + color.push( dataview.getUint8( row + offset.rgb + 1 ) / 255.0 ); + color.push( dataview.getUint8( row + offset.rgb + 0 ) / 255.0 ); } @@ -285,7 +285,7 @@ THREE.PCDLoader.prototype = { if ( color.length > 0 ) { - material.vertexColors = true; + material.vertexColors = THREE.VertexColors; } else { From 8d3cae2f28e23e7215d3f92dd2c69457398345af Mon Sep 17 00:00:00 2001 From: yomboprime Date: Thu, 4 Oct 2018 02:24:16 +0200 Subject: [PATCH 23/50] Changed water reset feedback to sample 1 point --- examples/webgl_gpgpu_water.html | 51 +++++++++++++++++---------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/examples/webgl_gpgpu_water.html b/examples/webgl_gpgpu_water.html index b843f3beb4a5b2..d4dc49f1ed3cfc 100644 --- a/examples/webgl_gpgpu_water.html +++ b/examples/webgl_gpgpu_water.html @@ -127,7 +127,7 @@ - + - + - + - - - - - - - - - - - - + + + + + + [page:Texture] → + +

[name]

+ +

Creates a three-dimensional texture. This type of texture can only be used with a WebGL 2 rendering context.

+ +

Constructor

+ +

[name]( [param:TypedArray data], [param:Number width], [param:Number height], [param:Number depth] )

+

+ [page:Object data] -- data of the texture.
+ + [page:Number width] -- width of the texture.
+ + [page:Number height] -- height of the texture.
+ + [page:Number depth] -- depth of the texture. +

+ +

Example

+ +
[example:webgl2_materials_texture3d WebGL2 / materials / texture3d]
+
[example:webgl2_materials_texture3d_volume WebGL2 / materials / texture3d / volume]
+ +

Properties

+ +

+ See the base [page:Texture Texture] class for common properties. +

+ +

Methods

+ +

+ See the base [page:Texture Texture] class for common methods. +

+ +

Source

+ + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] + + diff --git a/docs/api/zh/textures/DataTexture3D.html b/docs/api/zh/textures/DataTexture3D.html new file mode 100644 index 00000000000000..9282d671931d10 --- /dev/null +++ b/docs/api/zh/textures/DataTexture3D.html @@ -0,0 +1,51 @@ + + + + + + + + + + + [page:Texture] → + +

[name]

+ +

Creates a three-dimensional texture. This type of texture can only be used with a WebGL 2 rendering context.

+ +

Constructor

+ +

[name]( [param:TypedArray data], [param:Number width], [param:Number height], [param:Number depth] )

+

+ [page:Object data] -- data of the texture.
+ + [page:Number width] -- width of the texture.
+ + [page:Number height] -- height of the texture.
+ + [page:Number depth] -- depth of the texture. +

+ +

Example

+ +
[example:webgl2_materials_texture3d WebGL2 / materials / texture3d]
+
[example:webgl2_materials_texture3d_volume WebGL2 / materials / texture3d / volume]
+ +

Properties

+ +

+ See the base [page:Texture Texture] class for common properties. +

+ +

Methods

+ +

+ See the base [page:Texture Texture] class for common methods. +

+ +

Source

+ + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] + + diff --git a/docs/list.js b/docs/list.js index 0327f2b077f12f..c0ce3fc38b25cd 100644 --- a/docs/list.js +++ b/docs/list.js @@ -332,6 +332,7 @@ var list = { "CompressedTexture": "api/en/textures/CompressedTexture", "CubeTexture": "api/en/textures/CubeTexture", "DataTexture": "api/en/textures/DataTexture", + "DataTexture3D": "api/en/textures/DataTexture3D", "DepthTexture": "api/en/textures/DepthTexture", "Texture": "api/en/textures/Texture", "VideoTexture": "api/en/textures/VideoTexture" @@ -756,6 +757,7 @@ var list = { "CompressedTexture": "api/zh/textures/CompressedTexture", "CubeTexture": "api/zh/textures/CubeTexture", "DataTexture": "api/zh/textures/DataTexture", + "DataTexture3D": "api/en/textures/DataTexture3D", "DepthTexture": "api/zh/textures/DepthTexture", "Texture": "api/zh/textures/Texture", "VideoTexture": "api/zh/textures/VideoTexture" From 5e38b007f6be03bc37e2bba2a977ba640638ef79 Mon Sep 17 00:00:00 2001 From: Mugen87 Date: Sun, 14 Oct 2018 15:20:22 +0200 Subject: [PATCH 50/50] Docs: Clean up --- docs/manual/zh/introduction/WebGL-compatibility-check.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/manual/zh/introduction/WebGL-compatibility-check.html b/docs/manual/zh/introduction/WebGL-compatibility-check.html index 2ab8572312fb06..b203cb0e988e3d 100644 --- a/docs/manual/zh/introduction/WebGL-compatibility-check.html +++ b/docs/manual/zh/introduction/WebGL-compatibility-check.html @@ -14,15 +14,15 @@

WebGL兼容性检查([name])


- 请将[link:https://github.com/mrdoob/three.js/blob/master/examples/js/Detector.js]引入到你的文件,并在尝试开始渲染之前先运行该文件。 + 请将[link:https://github.com/mrdoob/three.js/blob/master/examples/js/WebGL.js]引入到你的文件,并在尝试开始渲染之前先运行该文件。

-if (Detector.webgl) { +if (WEBGL.isWebGLAvailable()) { // Initiate function or other initializations here animate(); } else { - var warning = Detector.getWebGLErrorMessage(); + var warning = WEBGL.getWebGLErrorMessage(); document.getElementById('container').appendChild(warning); }